Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v14] Fix routing to public addresses #36624

Merged
merged 1 commit into from Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 19 additions & 5 deletions api/utils/route.go
Expand Up @@ -59,7 +59,7 @@ type RouteableServer interface {
GetHostname() string
GetAddr() string
GetUseTunnel() bool
GetPublicAddr() string
GetPublicAddrs() []string
}

// RouteToServer checks if this route matcher wants to route to the supplied server.
Expand All @@ -70,22 +70,36 @@ func (m *SSHRouteMatcher) RouteToServer(server RouteableServer) bool {
return true
}

hostnameMatch := m.routeToHostname(server.GetHostname())

// if the server has connected over a reverse tunnel
// then match only by hostname.
if server.GetUseTunnel() {
return m.routeToHostname(server.GetHostname())
return hostnameMatch
}

for _, addr := range []string{server.GetAddr(), server.GetPublicAddr()} {
matchAddr := func(addr string) bool {
ip, nodePort, err := net.SplitHostPort(addr)
if err != nil {
continue
return false
}

if (m.targetHost == ip || m.routeToHostname(server.GetHostname()) || slices.Contains(m.ips, ip)) &&
if (m.targetHost == ip || hostnameMatch || slices.Contains(m.ips, ip)) &&
(m.targetPort == "" || m.targetPort == "0" || m.targetPort == nodePort) {
return true
}

return false
}

if matchAddr(server.GetAddr()) {
return true
}

for _, addr := range server.GetPublicAddrs() {
if matchAddr(addr) {
return true
}
}

return false
Expand Down
22 changes: 14 additions & 8 deletions api/utils/route_test.go
Expand Up @@ -110,7 +110,7 @@ type mockRouteableServer struct {
hostname string
addr string
useTunnel bool
publicAddr string
publicAddr []string
}

func (m mockRouteableServer) GetName() string {
Expand All @@ -129,7 +129,7 @@ func (m mockRouteableServer) GetUseTunnel() bool {
return m.useTunnel
}

func (m mockRouteableServer) GetPublicAddr() string {
func (m mockRouteableServer) GetPublicAddrs() []string {
return m.publicAddr
}

Expand All @@ -140,7 +140,7 @@ func TestRouteToServer(t *testing.T) {
matchAddrServer := mockRouteableServer{
name: "test",
addr: "example.com:1111",
publicAddr: "public.example.com:1111",
publicAddr: []string{"node:1234", "public.example.com:1111"},
}

tests := []struct {
Expand All @@ -156,7 +156,7 @@ func TestRouteToServer(t *testing.T) {
name: "test",
addr: "localhost",
hostname: "example.com",
publicAddr: "example.com",
publicAddr: []string{"example.com"},
},
assert: require.False,
},
Expand All @@ -167,7 +167,7 @@ func TestRouteToServer(t *testing.T) {
name: testUUID,
addr: "localhost",
hostname: "example.com",
publicAddr: "example.com",
publicAddr: []string{"example.com"},
},
assert: require.True,
},
Expand All @@ -178,7 +178,7 @@ func TestRouteToServer(t *testing.T) {
name: testUUID,
addr: "addr.example.com",
hostname: "example.com",
publicAddr: "public.example.com",
publicAddr: []string{"public.example.com"},
useTunnel: true,
},
assert: require.True,
Expand All @@ -190,7 +190,7 @@ func TestRouteToServer(t *testing.T) {
name: testUUID,
addr: "example.com",
hostname: "fake.example.com",
publicAddr: "example.com",
publicAddr: []string{"example.com"},
useTunnel: true,
},
assert: require.False,
Expand All @@ -214,7 +214,13 @@ func TestRouteToServer(t *testing.T) {
assert: require.False,
},
{
name: "match public addr",
name: "match first public addr",
matcher: NewSSHRouteMatcher("node", "1234", true),
server: matchAddrServer,
assert: require.True,
},
{
name: "match second public addr",
matcher: NewSSHRouteMatcher("public.example.com", "1111", true),
server: matchAddrServer,
assert: require.True,
Expand Down
6 changes: 3 additions & 3 deletions lib/services/watcher.go
Expand Up @@ -1720,8 +1720,8 @@ type Node interface {
GetTeleportVersion() string
// GetAddr return server address
GetAddr() string
// GetPublicAddr returns a public address where this server can be reached.
GetPublicAddr() string
// GetPublicAddrs returns all public addresses where this server can be reached.
GetPublicAddrs() []string
// GetHostname returns server hostname
GetHostname() string
// GetNamespace returns server namespace
Expand All @@ -1732,7 +1732,7 @@ type Node interface {
GetRotation() types.Rotation
// GetUseTunnel gets if a reverse tunnel should be used to connect to this node.
GetUseTunnel() bool
// GetProxyID returns a list of proxy ids this server is connected to.
// GetProxyIDs returns a list of proxy ids this server is connected to.
GetProxyIDs() []string
}

Expand Down