From 5b6f18084c6af59be5b70c2b6d37ed3701b96cd7 Mon Sep 17 00:00:00 2001 From: doggeddog Date: Fri, 16 Nov 2018 19:48:29 +0800 Subject: [PATCH] add multiple network interface support for socks5 plugin Similar with wget(--bind-address) or cURL(--interface), you can bind with a specific network interface. The parameter can be a host name. plugin_bind_addr = 172.21.0.107 --- conf/frpc_full.ini | 11 +++++++++++ models/plugin/socks5.go | 28 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/conf/frpc_full.ini b/conf/frpc_full.ini index 2b5d327b..59fdcee7 100644 --- a/conf/frpc_full.ini +++ b/conf/frpc_full.ini @@ -168,6 +168,17 @@ plugin = socks5 plugin_user = abc plugin_passwd = abc +[plugin_socks5_bind_addr] +type = tcp +remote_port = 6007 +plugin = socks5 +plugin_user = abc +plugin_passwd = abc +# Similar with wget(--bind-address) or cURL(--interface), +# you can bind with a specific network interface. +# The parameter can be a host name. +plugin_bind_addr = 172.21.0.107 + [plugin_static_file] type = tcp remote_port = 6006 diff --git a/models/plugin/socks5.go b/models/plugin/socks5.go index fba9f5df..e6fe5618 100644 --- a/models/plugin/socks5.go +++ b/models/plugin/socks5.go @@ -15,11 +15,13 @@ package plugin import ( + logger "github.com/fatedier/frp/utils/log" + frpNet "github.com/fatedier/frp/utils/net" + "golang.org/x/net/context" "io" "io/ioutil" "log" - - frpNet "github.com/fatedier/frp/utils/net" + "net" gosocks5 "github.com/armon/go-socks5" ) @@ -40,6 +42,7 @@ type Socks5Plugin struct { func NewSocks5Plugin(params map[string]string) (p Plugin, err error) { user := params["plugin_user"] passwd := params["plugin_passwd"] + bindAddr := params["plugin_bind_addr"] cfg := &gosocks5.Config{ Logger: log.New(ioutil.Discard, "", log.LstdFlags), @@ -47,6 +50,27 @@ func NewSocks5Plugin(params map[string]string) (p Plugin, err error) { if user != "" || passwd != "" { cfg.Credentials = gosocks5.StaticCredentials(map[string]string{user: passwd}) } + + if bindAddr != "" { + // bindAddr can be hostname + localAddr, err := net.ResolveIPAddr("ip", bindAddr) + if err != nil { + logger.Warn("Failed to resolve socks5 bind address: %v", bindAddr) + } else { + logger.Info("Bind address resolve to: %v", localAddr.IP) + localTCPAddr := net.TCPAddr{ + IP: localAddr.IP, + } + + cfg.Dial = func(ctx context.Context, net_, addr string) (net.Conn, error) { + d := net.Dialer{ + LocalAddr: &localTCPAddr, + } + return d.Dial(net_, addr) + } + } + } + sp := &Socks5Plugin{} sp.Server, err = gosocks5.New(cfg) p = sp