Skip to content

Commit 47bd5a8

Browse files
committed
Set dialer local address with STEP_CLIENT_ADDR
The environment variable STEP_CLIENT_ADDR can be used to set the local address to use when dialing an address. This can be useful when step is behind an CIDR-based ACL. Fixes smallstep/cli#730
1 parent fa8d0a6 commit 47bd5a8

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

ca/tls.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ import (
2424
// getDefaultTransport.
2525
var mTLSDialContext func() func(ctx context.Context, network, address string) (net.Conn, error)
2626

27+
// localAddr is the local address to use when dialing an address. This address
28+
// is defined by the environment variable STEP_CLIENT_ADDR.
29+
var localAddr net.Addr
30+
2731
func init() {
2832
// STEP_TLS_TUNNEL is an environment variable that can be set to do an TLS
2933
// over (m)TLS tunnel to step-ca using identity-like credentials. The value
@@ -70,6 +74,29 @@ func init() {
7074
}
7175
}
7276
}
77+
78+
// STEP_CLIENT_ADDR is an environment variable that can be set to define the
79+
// local address to use when dialing an address. This can be useful when
80+
// step is run behind a CIDR-based ACL.
81+
//
82+
// STEP_CLIENT_ADDR can be set to an IP ("127.0.0.1", "[::1]"), a hostname
83+
// ("localhost"), or a host:port ("[::1]:0"). If the port is set to
84+
// something other than ":0" and the dialer is created multiple times it
85+
// will fail with an "address already in use" error.
86+
//
87+
// See https://github.com/smallstep/cli/issues/730
88+
if v := os.Getenv("STEP_CLIENT_ADDR"); v != "" {
89+
_, _, err := net.SplitHostPort(v)
90+
if err != nil {
91+
// assuming that the error is a missing port, if it's not it will
92+
// panic below.
93+
v += ":0"
94+
}
95+
localAddr, err = net.ResolveTCPAddr("tcp", v)
96+
if err != nil {
97+
panic(err)
98+
}
99+
}
73100
}
74101

75102
// GetClientTLSConfig returns a tls.Config for client use configured with the
@@ -279,7 +306,8 @@ func getDefaultTLSConfig(sign *api.SignResponse) *tls.Config {
279306
func getDefaultDialer() *net.Dialer {
280307
// With the KeepAlive parameter set to 0, it will be use Golang's default.
281308
return &net.Dialer{
282-
Timeout: 30 * time.Second,
309+
Timeout: 30 * time.Second,
310+
LocalAddr: localAddr,
283311
}
284312
}
285313

0 commit comments

Comments
 (0)