Skip to content

Commit

Permalink
fix host network reserved port fingerprint (#11728)
Browse files Browse the repository at this point in the history
  • Loading branch information
lgfa29 committed Jan 17, 2022
1 parent 6cf4af9 commit 6bd26da
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .changelog/11728.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
client: Fixed host network reserved port fingerprinting
```
8 changes: 7 additions & 1 deletion client/fingerprint/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,16 @@ func (f *NetworkFingerprint) createNodeNetworkResources(ifaces []net.Interface,
} else {
family = structs.NodeNetworkAF_IPv6
}

alias := deriveAddressAlias(iface, ip, conf)
newAddr := structs.NodeNetworkAddress{
Address: ip.String(),
Family: family,
Alias: deriveAddressAlias(iface, ip, conf),
Alias: alias,
}

if hostNetwork, ok := conf.HostNetworks[alias]; ok {
newAddr.ReservedPorts = hostNetwork.ReservedPorts
}

if newAddr.Alias != "" {
Expand Down
92 changes: 92 additions & 0 deletions client/fingerprint/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"fmt"
"net"
"os"
"sort"
"testing"

"github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/helper/testlog"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/stretchr/testify/require"
)

// Set skipOnlineTestEnvVar to a non-empty value to skip network tests. Useful
Expand Down Expand Up @@ -437,3 +439,93 @@ func TestNetworkFingerPrint_LinkLocal_Disallowed(t *testing.T) {
t.Fatalf("should not apply attributes")
}
}

func TestNetworkFingerPrint_HostNetworkReservedPorts(t *testing.T) {
testCases := []struct {
name string
hostNetworks map[string]*structs.ClientHostNetworkConfig
expected []string
}{
{
name: "no host networks",
hostNetworks: map[string]*structs.ClientHostNetworkConfig{},
expected: []string{""},
},
{
name: "no reserved ports",
hostNetworks: map[string]*structs.ClientHostNetworkConfig{
"alias1": {
Name: "alias1",
Interface: "eth3",
CIDR: "169.254.155.20/32",
},
"alias2": {
Name: "alias2",
Interface: "eth3",
CIDR: "169.254.155.20/32",
},
"alias3": {
Name: "alias3",
Interface: "eth0",
CIDR: "100.64.0.11/10",
},
},
expected: []string{"", "", ""},
},
{
name: "reserved ports in some aliases",
hostNetworks: map[string]*structs.ClientHostNetworkConfig{
"alias1": {
Name: "alias1",
Interface: "eth3",
CIDR: "169.254.155.20/32",
ReservedPorts: "22",
},
"alias2": {
Name: "alias2",
Interface: "eth3",
CIDR: "169.254.155.20/32",
ReservedPorts: "80,3000-4000",
},
"alias3": {
Name: "alias3",
Interface: "eth0",
CIDR: "100.64.0.11/10",
},
},
expected: []string{"22", "80,3000-4000", ""},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
f := &NetworkFingerprint{
logger: testlog.HCLogger(t),
interfaceDetector: &NetworkInterfaceDetectorMultipleInterfaces{},
}
node := &structs.Node{
Attributes: make(map[string]string),
}
cfg := &config.Config{
NetworkInterface: "eth3",
HostNetworks: tc.hostNetworks,
}

request := &FingerprintRequest{Config: cfg, Node: node}
var response FingerprintResponse
err := f.Fingerprint(request, &response)
require.NoError(t, err)

got := []string{}
for _, network := range response.NodeResources.NodeNetworks {
for _, address := range network.Addresses {
got = append(got, address.ReservedPorts)
}
}

sort.Strings(tc.expected)
sort.Strings(got)
require.Equal(t, tc.expected, got, "host networks should match reserved ports")
})
}
}

0 comments on commit 6bd26da

Please sign in to comment.