mirror of https://github.com/ginuerzh/gost
7 changed files with 609 additions and 46 deletions
@ -0,0 +1,21 @@ |
|||||
|
FROM golang:1-alpine as builder |
||||
|
|
||||
|
RUN apk add --no-cache musl-dev git gcc |
||||
|
|
||||
|
ADD . /data |
||||
|
|
||||
|
WORKDIR /data |
||||
|
|
||||
|
ENV GO111MODULE=on |
||||
|
|
||||
|
RUN cd cmd/gost && go build |
||||
|
|
||||
|
FROM alpine:latest |
||||
|
|
||||
|
WORKDIR /bin/ |
||||
|
|
||||
|
COPY --from=builder /data/cmd/gost/gost . |
||||
|
|
||||
|
RUN /bin/gost -V |
||||
|
|
||||
|
ENTRYPOINT ["/bin/gost"] |
||||
@ -0,0 +1,371 @@ |
|||||
|
package gost |
||||
|
|
||||
|
import ( |
||||
|
"crypto/rand" |
||||
|
"fmt" |
||||
|
"net/http/httptest" |
||||
|
"net/url" |
||||
|
"testing" |
||||
|
) |
||||
|
|
||||
|
func httpOverObfsHTTPRoundtrip(targetURL string, data []byte, |
||||
|
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error { |
||||
|
|
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: HTTPConnector(clientInfo), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: HTTPHandler( |
||||
|
UsersHandlerOption(serverInfo...), |
||||
|
), |
||||
|
} |
||||
|
|
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
return proxyRoundtrip(client, server, targetURL, data) |
||||
|
} |
||||
|
|
||||
|
func TestHTTPOverObfsHTTP(t *testing.T) { |
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
for i, tc := range httpProxyTests { |
||||
|
tc := tc |
||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { |
||||
|
err := httpOverObfsHTTPRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers) |
||||
|
if err == nil { |
||||
|
if tc.errStr != "" { |
||||
|
t.Errorf("#%d should failed with error %s", i, tc.errStr) |
||||
|
} |
||||
|
} else { |
||||
|
if tc.errStr == "" { |
||||
|
t.Errorf("#%d got error %v", i, err) |
||||
|
} |
||||
|
if err.Error() != tc.errStr { |
||||
|
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func BenchmarkHTTPOverObfsHTTP(b *testing.B) { |
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
b.Error(err) |
||||
|
} |
||||
|
// b.Log(ln.Addr())
|
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: HTTPConnector(url.UserPassword("admin", "123456")), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: HTTPHandler( |
||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")), |
||||
|
), |
||||
|
} |
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
for i := 0; i < b.N; i++ { |
||||
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil { |
||||
|
b.Error(err) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func BenchmarkHTTPOverObfsHTTPParallel(b *testing.B) { |
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
b.Error(err) |
||||
|
} |
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: HTTPConnector(url.UserPassword("admin", "123456")), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: HTTPHandler( |
||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")), |
||||
|
), |
||||
|
} |
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
b.RunParallel(func(pb *testing.PB) { |
||||
|
for pb.Next() { |
||||
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil { |
||||
|
b.Error(err) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
func socks5OverObfsHTTPRoundtrip(targetURL string, data []byte, |
||||
|
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error { |
||||
|
|
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: SOCKS5Connector(clientInfo), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: SOCKS5Handler( |
||||
|
UsersHandlerOption(serverInfo...), |
||||
|
), |
||||
|
} |
||||
|
|
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
return proxyRoundtrip(client, server, targetURL, data) |
||||
|
} |
||||
|
|
||||
|
func TestSOCKS5OverObfsHTTP(t *testing.T) { |
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
for i, tc := range socks5ProxyTests { |
||||
|
err := socks5OverObfsHTTPRoundtrip(httpSrv.URL, sendData, |
||||
|
tc.cliUser, |
||||
|
tc.srvUsers, |
||||
|
) |
||||
|
if err == nil { |
||||
|
if !tc.pass { |
||||
|
t.Errorf("#%d should failed", i) |
||||
|
} |
||||
|
} else { |
||||
|
// t.Logf("#%d %v", i, err)
|
||||
|
if tc.pass { |
||||
|
t.Errorf("#%d got error: %v", i, err) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func socks4OverObfsHTTPRoundtrip(targetURL string, data []byte) error { |
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: SOCKS4Connector(), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: SOCKS4Handler(), |
||||
|
} |
||||
|
|
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
return proxyRoundtrip(client, server, targetURL, data) |
||||
|
} |
||||
|
|
||||
|
func TestSOCKS4OverObfsHTTP(t *testing.T) { |
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
err := socks4OverObfsHTTPRoundtrip(httpSrv.URL, sendData) |
||||
|
// t.Logf("#%d %v", i, err)
|
||||
|
if err != nil { |
||||
|
t.Errorf("got error: %v", err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func socks4aOverObfsHTTPRoundtrip(targetURL string, data []byte) error { |
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: SOCKS4AConnector(), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: SOCKS4Handler(), |
||||
|
} |
||||
|
|
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
return proxyRoundtrip(client, server, targetURL, data) |
||||
|
} |
||||
|
|
||||
|
func TestSOCKS4AOverObfsHTTP(t *testing.T) { |
||||
|
|
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
err := socks4aOverObfsHTTPRoundtrip(httpSrv.URL, sendData) |
||||
|
// t.Logf("#%d %v", i, err)
|
||||
|
if err != nil { |
||||
|
t.Errorf("got error: %v", err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func ssOverObfsHTTPRoundtrip(targetURL string, data []byte, |
||||
|
clientInfo, serverInfo *url.Userinfo) error { |
||||
|
|
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: ShadowConnector(clientInfo), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: ShadowHandler( |
||||
|
UsersHandlerOption(serverInfo), |
||||
|
), |
||||
|
} |
||||
|
|
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
return proxyRoundtrip(client, server, targetURL, data) |
||||
|
} |
||||
|
|
||||
|
func TestSSOverObfsHTTP(t *testing.T) { |
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
for i, tc := range ssProxyTests { |
||||
|
err := ssOverObfsHTTPRoundtrip(httpSrv.URL, sendData, |
||||
|
tc.clientCipher, |
||||
|
tc.serverCipher, |
||||
|
) |
||||
|
if err == nil { |
||||
|
if !tc.pass { |
||||
|
t.Errorf("#%d should failed", i) |
||||
|
} |
||||
|
} else { |
||||
|
// t.Logf("#%d %v", i, err)
|
||||
|
if tc.pass { |
||||
|
t.Errorf("#%d got error: %v", i, err) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func sniOverObfsHTTPRoundtrip(targetURL string, data []byte, host string) error { |
||||
|
ln, err := ObfsHTTPListener("") |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
u, err := url.Parse(targetURL) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
client := &Client{ |
||||
|
Connector: SNIConnector(host), |
||||
|
Transporter: ObfsHTTPTransporter(), |
||||
|
} |
||||
|
|
||||
|
server := &Server{ |
||||
|
Listener: ln, |
||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)), |
||||
|
} |
||||
|
|
||||
|
go server.Run() |
||||
|
defer server.Close() |
||||
|
|
||||
|
return sniRoundtrip(client, server, targetURL, data) |
||||
|
} |
||||
|
|
||||
|
func TestSNIOverObfsHTTP(t *testing.T) { |
||||
|
httpSrv := httptest.NewServer(httpTestHandler) |
||||
|
defer httpSrv.Close() |
||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler) |
||||
|
defer httpsSrv.Close() |
||||
|
|
||||
|
sendData := make([]byte, 128) |
||||
|
rand.Read(sendData) |
||||
|
|
||||
|
var sniProxyTests = []struct { |
||||
|
targetURL string |
||||
|
host string |
||||
|
pass bool |
||||
|
}{ |
||||
|
{httpSrv.URL, "", true}, |
||||
|
{httpSrv.URL, "example.com", true}, |
||||
|
{httpsSrv.URL, "", true}, |
||||
|
{httpsSrv.URL, "example.com", true}, |
||||
|
} |
||||
|
|
||||
|
for i, tc := range sniProxyTests { |
||||
|
tc := tc |
||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { |
||||
|
err := sniOverObfsHTTPRoundtrip(tc.targetURL, sendData, tc.host) |
||||
|
if err == nil { |
||||
|
if !tc.pass { |
||||
|
t.Errorf("#%d should failed", i) |
||||
|
} |
||||
|
} else { |
||||
|
// t.Logf("#%d %v", i, err)
|
||||
|
if tc.pass { |
||||
|
t.Errorf("#%d got error: %v", i, err) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue