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