merge with ginuerzh/gost master
This commit is contained in:
commit
f9ebac8a69
@ -17,13 +17,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ginuerzh/gost"
|
|
||||||
"github.com/go-log/log"
|
"github.com/go-log/log"
|
||||||
|
"github.com/go-redis/redis"
|
||||||
|
"github.com/jinzhu/configor"
|
||||||
|
"github.com/ginuerzh/gost"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
options route
|
options route
|
||||||
routes []route
|
routes []route
|
||||||
|
redisClient *redis.Client
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -322,6 +325,10 @@ func (r *route) serve() error {
|
|||||||
if node.User != nil {
|
if node.User != nil {
|
||||||
users = append(users, node.User)
|
users = append(users, node.User)
|
||||||
}
|
}
|
||||||
|
redisClient, err := parseRedisUsersAuth(node.Values.Get("redis"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
certFile, keyFile := node.Values.Get("cert"), node.Values.Get("key")
|
certFile, keyFile := node.Values.Get("cert"), node.Values.Get("key")
|
||||||
tlsCfg, err := tlsConfig(certFile, keyFile)
|
tlsCfg, err := tlsConfig(certFile, keyFile)
|
||||||
if err != nil && certFile != "" && keyFile != "" {
|
if err != nil && certFile != "" && keyFile != "" {
|
||||||
@ -436,6 +443,7 @@ func (r *route) serve() error {
|
|||||||
gost.TLSConfigHandlerOption(tlsCfg),
|
gost.TLSConfigHandlerOption(tlsCfg),
|
||||||
gost.WhitelistHandlerOption(whitelist),
|
gost.WhitelistHandlerOption(whitelist),
|
||||||
gost.BlacklistHandlerOption(blacklist),
|
gost.BlacklistHandlerOption(blacklist),
|
||||||
|
gost.RedisClientHandlerOption(redisClient),
|
||||||
)
|
)
|
||||||
var handler gost.Handler
|
var handler gost.Handler
|
||||||
switch node.Protocol {
|
switch node.Protocol {
|
||||||
@ -603,7 +611,32 @@ func parseUsers(authFile string) (users []*url.Userinfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIP(s string, port string) (ips []string) {
|
func parseRedisUsersAuth(configFile string) (client *redis.Client, err error) {
|
||||||
|
if configFile == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var Config = struct {
|
||||||
|
RedisServer struct {
|
||||||
|
Address string `default:"localhost:6379"`
|
||||||
|
Password string `default:""`
|
||||||
|
DB int `default:0`
|
||||||
|
}
|
||||||
|
}{}
|
||||||
|
|
||||||
|
configor.Load(&Config, configFile)
|
||||||
|
client = redis.NewClient(&redis.Options{
|
||||||
|
Addr: Config.RedisServer.Address,
|
||||||
|
Password: Config.RedisServer.Password,
|
||||||
|
DB: Config.RedisServer.DB,
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err = client.Ping().Result()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseIP(s string) (ips []string) {
|
||||||
if s == "" {
|
if s == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
5
cmd/gost/redis.yml
Normal file
5
cmd/gost/redis.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
redisserver:
|
||||||
|
address: localhost:6379
|
||||||
|
password:
|
||||||
|
db:
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/ginuerzh/gosocks4"
|
"github.com/ginuerzh/gosocks4"
|
||||||
"github.com/ginuerzh/gosocks5"
|
"github.com/ginuerzh/gosocks5"
|
||||||
"github.com/go-log/log"
|
"github.com/go-log/log"
|
||||||
|
"github.com/go-redis/redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler is a proxy server handler
|
// Handler is a proxy server handler
|
||||||
@ -24,6 +25,7 @@ type HandlerOptions struct {
|
|||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
Whitelist *Permissions
|
Whitelist *Permissions
|
||||||
Blacklist *Permissions
|
Blacklist *Permissions
|
||||||
|
RedisClient *redis.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandlerOption allows a common way to set handler options.
|
// HandlerOption allows a common way to set handler options.
|
||||||
@ -71,6 +73,13 @@ func BlacklistHandlerOption(blacklist *Permissions) HandlerOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RedisClientHandlerOption sets the RedisClient option of HandlerOptions.
|
||||||
|
func RedisClientHandlerOption(client *redis.Client) HandlerOption {
|
||||||
|
return func(opts *HandlerOptions) {
|
||||||
|
opts.RedisClient = client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type autoHandler struct {
|
type autoHandler struct {
|
||||||
options []HandlerOption
|
options []HandlerOption
|
||||||
}
|
}
|
||||||
|
15
socks.go
15
socks.go
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/ginuerzh/gosocks4"
|
"github.com/ginuerzh/gosocks4"
|
||||||
"github.com/ginuerzh/gosocks5"
|
"github.com/ginuerzh/gosocks5"
|
||||||
"github.com/go-log/log"
|
"github.com/go-log/log"
|
||||||
|
"github.com/go-redis/redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -93,6 +94,7 @@ type serverSelector struct {
|
|||||||
methods []uint8
|
methods []uint8
|
||||||
Users []*url.Userinfo
|
Users []*url.Userinfo
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
|
RedisClient *redis.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (selector *serverSelector) Methods() []uint8 {
|
func (selector *serverSelector) Methods() []uint8 {
|
||||||
@ -116,7 +118,7 @@ func (selector *serverSelector) Select(methods ...uint8) (method uint8) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// when user/pass is set, auth is mandatory
|
// when user/pass is set, auth is mandatory
|
||||||
if len(selector.Users) > 0 {
|
if len(selector.Users) > 0 || selector.RedisClient != nil {
|
||||||
if method == gosocks5.MethodNoAuth {
|
if method == gosocks5.MethodNoAuth {
|
||||||
method = gosocks5.MethodUserPass
|
method = gosocks5.MethodUserPass
|
||||||
}
|
}
|
||||||
@ -150,6 +152,13 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con
|
|||||||
log.Log("[socks5]", req.String())
|
log.Log("[socks5]", req.String())
|
||||||
}
|
}
|
||||||
valid := false
|
valid := false
|
||||||
|
if selector.RedisClient != nil {
|
||||||
|
password, err := selector.RedisClient.Get(req.Username).Result()
|
||||||
|
if err == nil && req.Password == password {
|
||||||
|
valid = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(selector.Users) > 0 {
|
||||||
for _, user := range selector.Users {
|
for _, user := range selector.Users {
|
||||||
username := user.Username()
|
username := user.Username()
|
||||||
password, _ := user.Password()
|
password, _ := user.Password()
|
||||||
@ -160,7 +169,8 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(selector.Users) > 0 && !valid {
|
}
|
||||||
|
if (selector.RedisClient != nil || len(selector.Users) > 0) && !valid {
|
||||||
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
|
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
|
||||||
if err := resp.Write(conn); err != nil {
|
if err := resp.Write(conn); err != nil {
|
||||||
log.Log("[socks5]", err)
|
log.Log("[socks5]", err)
|
||||||
@ -355,6 +365,7 @@ func SOCKS5Handler(opts ...HandlerOption) Handler {
|
|||||||
selector := &serverSelector{ // socks5 server selector
|
selector := &serverSelector{ // socks5 server selector
|
||||||
Users: options.Users,
|
Users: options.Users,
|
||||||
TLSConfig: tlsConfig,
|
TLSConfig: tlsConfig,
|
||||||
|
RedisClient: options.RedisClient,
|
||||||
}
|
}
|
||||||
// methods that socks5 server supported
|
// methods that socks5 server supported
|
||||||
selector.AddMethod(
|
selector.AddMethod(
|
||||||
|
Loading…
Reference in New Issue
Block a user