add tls authentication

This commit is contained in:
rui.zheng 2015-05-20 11:01:44 +08:00
parent 72da5242a9
commit 4cceeda98d
5 changed files with 86 additions and 21 deletions

View File

@ -22,12 +22,20 @@ gost - GO Simple Tunnel
二进制文件下载https://bintray.com/ginuerzh/gost/gost/v1.2/view 二进制文件下载https://bintray.com/ginuerzh/gost/gost/v1.2/view
#####v1.3
* tls加密方式增加密码认证功能
* 增加版本查看(-v参数)
* -p参数的默认值修改为空
二进制文件下载https://bintray.com/ginuerzh/gost/gost/v1.3/view
####参数说明 ####参数说明
> -L=":8080": listen address > -L=":8080": listen address
> -P="": proxy for forward > -P="": proxy for forward
> -S="": the server that connecting to > -S="": the server that connect to
> -cert="": cert file for tls > -cert="": cert file for tls
@ -35,7 +43,7 @@ gost - GO Simple Tunnel
> -m="": tunnel cipher method > -m="": tunnel cipher method
> -p="ginuerzh@gmail.com": tunnel cipher password > -p="": tunnel cipher password
> -sm="rc4-md5": shadowsocks cipher method > -sm="rc4-md5": shadowsocks cipher method
@ -45,25 +53,33 @@ gost - GO Simple Tunnel
> -ws=false: use websocket for tunnel > -ws=false: use websocket for tunnel
> -v=false: print version
####使用方法 ####使用方法
#####服务器端: #####服务器端:
`gost -L=:8080` `gost -L=:8080`
#####服务器端有上层http代理: #####服务器端设置加密:
`gost -L=:8080 -P=proxy_ip:port` `gost -L=:8080 -m=aes-256-cfb -p=123456`
#####客户端(默认使用tls加密方法): #####服务器端有上层http代理:
`gost -L=:8080 -m=aes-256-cfb -p=123456 -P=proxy_ip:port`
#####客户端:
`gost -L=:8899 -S=your_server_ip:8080` `gost -L=:8899 -S=your_server_ip:8080`
#####客户端设置加密:
`gost -L=:8899 -S=your_server_ip:8080 -m=aes-256-cfb -p=123456`
#####客户端有上层http代理: #####客户端有上层http代理:
`gost -L=:8899 -S=your_server_ip:8080 -P=proxy_ip:port` `gost -L=:8899 -S=your_server_ip:8080 -m=aes-256-cfb -p=123456 -P=proxy_ip:port`
#####使用websocket tunnel #####使用websocket tunnel
* 服务器端 * 服务器端
`gost -L=:8080 -ws` `gost -L=:8080 -m=aes-256-cfb -p=123456 -ws`
* 客户端 * 客户端
`gost -L=:8899 -S=your_server_ip:8080 -ws` `gost -L=:8899 -S=your_server_ip:8080 -m=aes-256-cfb -p=123456 -ws`
#####作为shadowsocks服务器: #####作为shadowsocks服务器:
gost支持作为shadowsocks服务器运行(-ss参数)这样就可以让android手机通过shadowsocks客户端(影梭)使用代理了。 gost支持作为shadowsocks服务器运行(-ss参数)这样就可以让android手机通过shadowsocks客户端(影梭)使用代理了。
@ -80,7 +96,7 @@ gost支持作为shadowsocks服务器运行(-ss参数)这样就可以让androi
无需特殊设置shadowsocks模式只与客户端有关与服务端无关。 无需特殊设置shadowsocks模式只与客户端有关与服务端无关。
* 客户端: * 客户端:
`gost -L :8899 -S demo-project-gostwebsocket.c9.io -ws -sm=rc4-md5 -sp=ginuerzh@gmail.com -ss` `gost -L :8899 -S demo-project-gostwebsocket.c9.io -sm=rc4-md5 -sp=ginuerzh@gmail.com -ss`
在手机的shadowsocks软件中设置好服务器(运行gost电脑的IP),端口(8899),加密方法和密码就可以使用了。 在手机的shadowsocks软件中设置好服务器(运行gost电脑的IP),端口(8899),加密方法和密码就可以使用了。
@ -97,9 +113,9 @@ Client端通过-m参数设置加密方式默认为不加密(-m参数为空)
如果设置的加密方式不被支持,则默认为不加密。 如果设置的加密方式不被支持,则默认为不加密。
当设置的加密方式为tls时-p参数无效 当设置的加密方式为tls时可通过-p参数设置验证密码(若服务端支持密码验证功能)
当设置的加密方式为非tls时通过-p参数设置加密密码且不能为空默认密码为ginuerzh@gmail.com-p参数必须与Server端的-p参数相同。 当设置的加密方式为非tls时通过-p参数设置加密密码且不能为空-p参数必须与Server端的-p参数相同。
#####Server #####Server
@ -111,6 +127,7 @@ Server端通过-m参数设置加密方式默认为不加密(-m参数为空)
如果设置了加密方式(-m参数不为空)client端必须使用与Server端相同的加密方式。 如果设置了加密方式(-m参数不为空)client端必须使用与Server端相同的加密方式。
当设置的加密方式为tls时-p参数无效-key参数可手动指定公钥文件-cert参数可手动指定私钥文件如果未指定则使用默认的公钥与私钥。 当设置的加密方式为tls时-key参数可手动指定公钥文件-cert参数可手动指定私钥文件如果未指定则使用默认的公钥与私钥。
可通过-p参数设定验证密码(可选),若设置,则客户端必须通过-p参数设置相同的密码。
当设置的加密方式为非tls时-key-cert参数无效通过-p参数设置加密密码且不能为空默认密码为ginuerzh@gmail.com 当设置的加密方式为非tls时-key-cert参数无效通过-p参数设置加密密码且不能为空。

View File

@ -60,6 +60,9 @@ func clientMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
switch method { switch method {
case MethodTLS: case MethodTLS:
conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true}) conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
if err := cliTLSAuth(conn); err != nil {
return nil, err
}
case MethodAES128, MethodAES192, MethodAES256, case MethodAES128, MethodAES192, MethodAES256,
MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable: MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
cipher, err := shadowsocks.NewCipher(Methods[method], Password) cipher, err := shadowsocks.NewCipher(Methods[method], Password)
@ -75,6 +78,22 @@ func clientMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
return conn, nil return conn, nil
} }
func cliTLSAuth(conn net.Conn) error {
if err := gosocks5.NewUserPassRequest(
gosocks5.UserPassVer, "", Password).Write(conn); err != nil {
return err
}
res, err := gosocks5.ReadUserPassResponse(conn)
if err != nil {
return err
}
if res.Status != gosocks5.Succeeded {
return gosocks5.ErrAuthFailure
}
return nil
}
func cliHandle(conn net.Conn) { func cliHandle(conn net.Conn) {
defer conn.Close() defer conn.Close()
/* /*
@ -284,14 +303,14 @@ func handleHttp(req *http.Request, conn net.Conn, sconn net.Conn) {
rep, err := gosocks5.ReadReply(sconn) rep, err := gosocks5.ReadReply(sconn)
if err != nil || rep.Rep != gosocks5.Succeeded { if err != nil || rep.Rep != gosocks5.Succeeded {
conn.Write([]byte("HTTP/1.1 503 Service unavailable\r\n" + conn.Write([]byte("HTTP/1.1 503 Service unavailable\r\n" +
"Proxy-Agent: gost/1.0\r\n\r\n")) "Proxy-Agent: gost/" + Version + "\r\n\r\n"))
return return
} }
if req.Method == "CONNECT" { if req.Method == "CONNECT" {
if _, err = conn.Write( if _, err = conn.Write(
[]byte("HTTP/1.1 200 Connection established\r\n" + []byte("HTTP/1.1 200 Connection established\r\n" +
"Proxy-Agent: gost/2.0\r\n\r\n")); err != nil { "Proxy-Agent: gost/" + Version + "\r\n\r\n")); err != nil {
return return
} }
} else { } else {

14
main.go
View File

@ -15,22 +15,22 @@ var (
SMethod, SPassword string SMethod, SPassword string
Method, Password string Method, Password string
CertFile, KeyFile string CertFile, KeyFile string
PrintVersion bool
) )
func init() { func init() {
printVersion()
flag.StringVar(&Proxy, "P", "", "proxy for forward") flag.StringVar(&Proxy, "P", "", "proxy for forward")
flag.StringVar(&Saddr, "S", "", "the server that connecting to") flag.StringVar(&Saddr, "S", "", "the server that connect to")
flag.StringVar(&Laddr, "L", ":8080", "listen address") flag.StringVar(&Laddr, "L", ":8080", "listen address")
flag.StringVar(&Method, "m", "", "tunnel cipher method") flag.StringVar(&Method, "m", "", "tunnel cipher method")
flag.StringVar(&Password, "p", "ginuerzh@gmail.com", "tunnel cipher password") flag.StringVar(&Password, "p", "", "tunnel cipher password")
flag.StringVar(&CertFile, "cert", "", "cert file for tls") flag.StringVar(&CertFile, "cert", "", "cert file for tls")
flag.StringVar(&KeyFile, "key", "", "key file for tls") flag.StringVar(&KeyFile, "key", "", "key file for tls")
flag.BoolVar(&Shadows, "ss", false, "run as shadowsocks server") flag.BoolVar(&Shadows, "ss", false, "run as shadowsocks server")
flag.BoolVar(&Websocket, "ws", false, "use websocket for tunnel") flag.BoolVar(&Websocket, "ws", false, "use websocket for tunnel")
flag.StringVar(&SMethod, "sm", "rc4-md5", "shadowsocks cipher method") flag.StringVar(&SMethod, "sm", "rc4-md5", "shadowsocks cipher method")
flag.StringVar(&SPassword, "sp", "ginuerzh@gmail.com", "shadowsocks cipher password") flag.StringVar(&SPassword, "sp", "ginuerzh@gmail.com", "shadowsocks cipher password")
flag.BoolVar(&PrintVersion, "v", false, "print version")
flag.Parse() flag.Parse()
log.SetFlags(log.LstdFlags | log.Lshortfile) log.SetFlags(log.LstdFlags | log.Lshortfile)
@ -43,7 +43,11 @@ var (
) )
func main() { func main() {
//log.Fatal(gost.Run()) if PrintVersion {
printVersion()
return
}
if len(Saddr) == 0 { if len(Saddr) == 0 {
var server Server var server Server
if Websocket { if Websocket {

View File

@ -125,6 +125,9 @@ func serverMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
return nil, err return nil, err
} }
conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}}) conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}})
if err := svrTLSAuth(conn); err != nil {
return nil, err
}
case MethodAES128, MethodAES192, MethodAES256, case MethodAES128, MethodAES192, MethodAES256,
MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable: MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
cipher, err := shadowsocks.NewCipher(Methods[method], Password) cipher, err := shadowsocks.NewCipher(Methods[method], Password)
@ -139,6 +142,28 @@ func serverMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
return conn, nil return conn, nil
} }
func svrTLSAuth(conn net.Conn) error {
req, err := gosocks5.ReadUserPassRequest(conn)
if err != nil {
return err
}
if len(Password) > 0 && req.Password != Password {
if err := gosocks5.NewUserPassResponse(
gosocks5.UserPassVer, gosocks5.Failure).Write(conn); err != nil {
return err
}
return gosocks5.ErrAuthFailure
}
if err := gosocks5.NewUserPassResponse(
gosocks5.UserPassVer, gosocks5.Succeeded).Write(conn); err != nil {
return err
}
return nil
}
func socks5Handle(conn net.Conn) { func socks5Handle(conn net.Conn) {
defer conn.Close() defer conn.Close()

View File

@ -5,7 +5,7 @@ import (
) )
const ( const (
Version = "1.2" Version = "1.3"
) )
func printVersion() { func printVersion() {