diff --git a/client/pkg/transport/listener.go b/client/pkg/transport/listener.go index ec69f4e2ad3..6f6c4e916cd 100644 --- a/client/pkg/transport/listener.go +++ b/client/pkg/transport/listener.go @@ -193,6 +193,9 @@ type TLSInfo struct { // EmptyCN indicates that the cert must have empty CN. // If true, ClientConfig() will return an error for a cert with non empty CN. EmptyCN bool + + // LocalAddr is the local IP address to use when communicating peer. + LocalAddr string } func (info TLSInfo) String() string { diff --git a/client/pkg/transport/transport.go b/client/pkg/transport/transport.go index 91462dcdb08..67170d7436d 100644 --- a/client/pkg/transport/transport.go +++ b/client/pkg/transport/transport.go @@ -30,10 +30,19 @@ func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, er return nil, err } + var ipAddr net.Addr + if info.LocalAddr != "" { + ipAddr, err = net.ResolveTCPAddr("tcp", info.LocalAddr+":0") + if err != nil { + return nil, err + } + } + t := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ - Timeout: dialtimeoutd, + Timeout: dialtimeoutd, + LocalAddr: ipAddr, // value taken from http.DefaultTransport KeepAlive: 30 * time.Second, }).DialContext, diff --git a/server/config/config.go b/server/config/config.go index af8604a621a..61e8447b9a5 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -204,6 +204,9 @@ type ServerConfig struct { // V2Deprecation defines a phase of v2store deprecation process. V2Deprecation V2DeprecationEnum `json:"v2-deprecation"` + + // LocalAddr is the local IP address to use when communicating peer. + LocalAddr string `json:"local-address"` } // VerifyBootstrap sanity-checks the initial config for bootstrap case diff --git a/server/embed/config.go b/server/embed/config.go index 2eb3458c25f..bfdb11a6561 100644 --- a/server/embed/config.go +++ b/server/embed/config.go @@ -327,6 +327,9 @@ type Config struct { // AuthTokenTTL in seconds of the simple token AuthTokenTTL uint `json:"auth-token-ttl"` + // PeerLocalAddr is the local IP address to use when communicating peer. + PeerLocalAddr string `json:"peer-local-addr"` + ExperimentalInitialCorruptCheck bool `json:"experimental-initial-corrupt-check"` ExperimentalCorruptCheckTime time.Duration `json:"experimental-corrupt-check-time"` ExperimentalCompactHashCheckEnabled bool `json:"experimental-compact-hash-check-enabled"` @@ -662,6 +665,8 @@ func (cfg *Config) AddFlags(fs *flag.FlagSet) { fs.StringVar(&cfg.PeerTLSInfo.ClientKeyFile, "peer-client-key-file", "", "Path to an explicit peer client TLS key file otherwise peer key file will be used when client auth is required.") fs.BoolVar(&cfg.PeerTLSInfo.ClientCertAuth, "peer-client-cert-auth", false, "Enable peer client cert authentication.") fs.StringVar(&cfg.PeerTLSInfo.TrustedCAFile, "peer-trusted-ca-file", "", "Path to the peer server TLS trusted CA file.") + fs.StringVar(&cfg.PeerTLSInfo.LocalAddr, "peer-local-addr", "", "peer-local-addr is the local IP address to use when communicating peer.") + fs.BoolVar(&cfg.PeerAutoTLS, "peer-auto-tls", false, "Peer TLS using generated certificates") fs.UintVar(&cfg.SelfSignedCertValidity, "self-signed-cert-validity", 1, "The validity period of the client and peer certificates, unit is year") fs.StringVar(&cfg.PeerTLSInfo.CRLFile, "peer-crl-file", "", "Path to the peer certificate revocation list file.") diff --git a/server/etcdmain/help.go b/server/etcdmain/help.go index 8819b90cd35..5f5e2a5ee85 100644 --- a/server/etcdmain/help.go +++ b/server/etcdmain/help.go @@ -221,6 +221,9 @@ Security: Minimum TLS version supported by etcd. Possible values: TLS1.2, TLS1.3. --tls-max-version '' Maximum TLS version supported by etcd. Possible values: TLS1.2, TLS1.3 (empty will be auto-populated by Go). + --peer-local-addr '' + LocalAddr is the local IP address to use when communicating peer. + Auth: --auth-token 'simple'