mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-08 07:58:40 +00:00
p2p: add optional SOCKS5 proxy support for outbound peer dials
- Add `UseProxy` field to `p2p.Config` and corresponding `--use-proxy` CLI flag. - Implement proxy-aware `tcpDialer` (uses `golang.org/x/net/proxy` and attempts context-aware DialContext when supported). - Wire `UseProxy` through `Server` to the dialer so peer dials can go via SOCKS5 proxy defined by `ALL_PROXY`/`all_proxy`. - Minor debug `start.sh` for running geth with `--use-proxy`. Signed-off-by: cloorc <wittcnezh@foxmail.com>
This commit is contained in:
parent
da3822dcec
commit
a0cb88e2cf
7 changed files with 37 additions and 3 deletions
|
|
@ -126,6 +126,7 @@ var (
|
||||||
utils.NoDiscoverFlag,
|
utils.NoDiscoverFlag,
|
||||||
utils.DiscoveryV4Flag,
|
utils.DiscoveryV4Flag,
|
||||||
utils.DiscoveryV5Flag,
|
utils.DiscoveryV5Flag,
|
||||||
|
utils.UseProxyFlag,
|
||||||
utils.LegacyDiscoveryV5Flag, // deprecated
|
utils.LegacyDiscoveryV5Flag, // deprecated
|
||||||
utils.NetrestrictFlag,
|
utils.NetrestrictFlag,
|
||||||
utils.NodeKeyFileFlag,
|
utils.NodeKeyFileFlag,
|
||||||
|
|
|
||||||
|
|
@ -873,6 +873,11 @@ var (
|
||||||
Category: flags.NetworkingCategory,
|
Category: flags.NetworkingCategory,
|
||||||
Value: node.DefaultConfig.P2P.DiscoveryV5,
|
Value: node.DefaultConfig.P2P.DiscoveryV5,
|
||||||
}
|
}
|
||||||
|
UseProxyFlag = &cli.BoolFlag{
|
||||||
|
Name: "use-proxy",
|
||||||
|
Usage: "Use SOCKS5 proxy from ALL_PROXY or all_proxy environment variable for peer connections",
|
||||||
|
Category: flags.NetworkingCategory,
|
||||||
|
}
|
||||||
NetrestrictFlag = &cli.StringFlag{
|
NetrestrictFlag = &cli.StringFlag{
|
||||||
Name: "netrestrict",
|
Name: "netrestrict",
|
||||||
Usage: "Restricts network communication to the given IP networks (CIDR masks)",
|
Usage: "Restricts network communication to the given IP networks (CIDR masks)",
|
||||||
|
|
@ -1379,6 +1384,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
|
||||||
if ctx.IsSet(DiscoveryV5Flag.Name) {
|
if ctx.IsSet(DiscoveryV5Flag.Name) {
|
||||||
cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name)
|
cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name)
|
||||||
}
|
}
|
||||||
|
cfg.UseProxy = ctx.Bool(UseProxyFlag.Name)
|
||||||
|
|
||||||
if netrestrict := ctx.String(NetrestrictFlag.Name); netrestrict != "" {
|
if netrestrict := ctx.String(NetrestrictFlag.Name); netrestrict != "" {
|
||||||
list, err := netutil.ParseNetlist(netrestrict)
|
list, err := netutil.ParseNetlist(netrestrict)
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -144,7 +144,7 @@ require (
|
||||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||||
golang.org/x/mod v0.22.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
golang.org/x/net v0.38.0 // indirect
|
golang.org/x/net v0.38.0
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,9 @@ type Config struct {
|
||||||
// Logger is a custom logger to use with the p2p.Server.
|
// Logger is a custom logger to use with the p2p.Server.
|
||||||
Logger log.Logger `toml:"-"`
|
Logger log.Logger `toml:"-"`
|
||||||
|
|
||||||
|
// If UseProxy is set to true, the server will use SOCKS5 proxy from ALL_PROXY or all_proxy environment variable for dialing peers.
|
||||||
|
UseProxy bool `toml:",omitempty"`
|
||||||
|
|
||||||
clock mclock.Clock
|
clock mclock.Clock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
NoDial bool `toml:",omitempty"`
|
NoDial bool `toml:",omitempty"`
|
||||||
EnableMsgEvents bool
|
EnableMsgEvents bool
|
||||||
Logger log.Logger `toml:"-"`
|
Logger log.Logger `toml:"-"`
|
||||||
|
UseProxy bool `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
var enc Config
|
var enc Config
|
||||||
enc.PrivateKey = c.PrivateKey
|
enc.PrivateKey = c.PrivateKey
|
||||||
|
|
@ -62,6 +63,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
enc.NoDial = c.NoDial
|
enc.NoDial = c.NoDial
|
||||||
enc.EnableMsgEvents = c.EnableMsgEvents
|
enc.EnableMsgEvents = c.EnableMsgEvents
|
||||||
enc.Logger = c.Logger
|
enc.Logger = c.Logger
|
||||||
|
enc.UseProxy = c.UseProxy
|
||||||
return &enc, nil
|
return &enc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,6 +92,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
NoDial *bool `toml:",omitempty"`
|
NoDial *bool `toml:",omitempty"`
|
||||||
EnableMsgEvents *bool
|
EnableMsgEvents *bool
|
||||||
Logger log.Logger `toml:"-"`
|
Logger log.Logger `toml:"-"`
|
||||||
|
UseProxy *bool `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
var dec Config
|
var dec Config
|
||||||
if err := unmarshal(&dec); err != nil {
|
if err := unmarshal(&dec); err != nil {
|
||||||
|
|
@ -161,5 +164,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
if dec.Logger != nil {
|
if dec.Logger != nil {
|
||||||
c.Logger = dec.Logger
|
c.Logger = dec.Logger
|
||||||
}
|
}
|
||||||
|
if dec.UseProxy != nil {
|
||||||
|
c.UseProxy = *dec.UseProxy
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
p2p/dial.go
20
p2p/dial.go
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -63,11 +64,28 @@ type nodeResolver interface {
|
||||||
|
|
||||||
// tcpDialer implements NodeDialer using real TCP connections.
|
// tcpDialer implements NodeDialer using real TCP connections.
|
||||||
type tcpDialer struct {
|
type tcpDialer struct {
|
||||||
d *net.Dialer
|
d *net.Dialer
|
||||||
|
useProxy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dialerWithContext is an interface implemented by proxy dialers that support context-aware dialing.
|
||||||
|
// see proxy/direct#direct, proxy.SOCKS5() and internal/socks#Dialer.
|
||||||
|
type dialerWithContext interface {
|
||||||
|
DialContext(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var proxyDialer = proxy.FromEnvironment()
|
||||||
|
|
||||||
func (t tcpDialer) Dial(ctx context.Context, dest *enode.Node) (net.Conn, error) {
|
func (t tcpDialer) Dial(ctx context.Context, dest *enode.Node) (net.Conn, error) {
|
||||||
addr, _ := dest.TCPEndpoint()
|
addr, _ := dest.TCPEndpoint()
|
||||||
|
if t.useProxy {
|
||||||
|
log.Debug("Dialing peer via proxy", "direct", proxyDialer == proxy.Direct, "addr", addr.String())
|
||||||
|
if v, ok := proxyDialer.(dialerWithContext); ok {
|
||||||
|
return v.DialContext(ctx, "tcp", addr.String())
|
||||||
|
} else {
|
||||||
|
log.Warn("Proxy dialer does not support context, falling back to direct", "addr", addr.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
return t.d.DialContext(ctx, "tcp", addr.String())
|
return t.d.DialContext(ctx, "tcp", addr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -537,7 +537,7 @@ func (srv *Server) setupDialScheduler() {
|
||||||
config.resolver = srv.discv4
|
config.resolver = srv.discv4
|
||||||
}
|
}
|
||||||
if config.dialer == nil {
|
if config.dialer == nil {
|
||||||
config.dialer = tcpDialer{&net.Dialer{Timeout: defaultDialTimeout}}
|
config.dialer = tcpDialer{&net.Dialer{Timeout: defaultDialTimeout}, srv.UseProxy}
|
||||||
}
|
}
|
||||||
srv.dialsched = newDialScheduler(config, srv.discmix, srv.SetupConn)
|
srv.dialsched = newDialScheduler(config, srv.discmix, srv.SetupConn)
|
||||||
for _, n := range srv.StaticNodes {
|
for _, n := range srv.StaticNodes {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue