diff --git a/Dockerfile.validate b/Dockerfile.validate index bfd8e83..67ca4d7 100644 --- a/Dockerfile.validate +++ b/Dockerfile.validate @@ -23,9 +23,9 @@ RUN apt-get update --quiet \ && curl -fLsS https://deb.frrouting.org/frr/keys.asc | apt-key add - \ && add-apt-repository "deb [arch=amd64] https://deb.frrouting.org/frr $(lsb_release -s -c) ${FRR_VERSION}" \ && apt update \ - && apt install --yes --no-install-recommends frr frr-pythontools + && apt install --yes --no-install-recommends frr frr-pythontools nftables netbase - -COPY ./pkg/netconf/testdata /testdata -COPY validate_os.sh / -RUN "/validate_os.sh" + ENV OS_NAME=${OS_NAME} + ENV OS_VERSION=${OS_VERSION} + ENV FRR_VERSION=${FRR_VERSION} + COPY validate_os.sh / diff --git a/pkg/netconf/nftables.go b/pkg/netconf/nftables.go index c101625..eef5cee 100644 --- a/pkg/netconf/nftables.go +++ b/pkg/netconf/nftables.go @@ -62,6 +62,7 @@ type ( DNAT struct { Comment string InInterfaces []string + SAddr string DAddr string Port string Zone string @@ -200,13 +201,18 @@ func getDNSProxyDNAT(c config, port, zone string) DNAT { ip, _ := netip.ParseAddr(n.Ips[0]) af := "ip" + saddr := "10.0.0.0/8" + daddr := "@proxy_dns_servers" if ip.Is6() { af = "ip6" + saddr = "fd00::/8" + daddr = "@proxy_dns_servers_v6" } return DNAT{ Comment: "dnat to dns proxy", InInterfaces: svis, - DAddr: "@proxy_dns_servers", + SAddr: saddr, + DAddr: daddr, Port: port, Zone: zone, DestSpec: AddrSpec{ diff --git a/pkg/netconf/testdata/nftrules_ipv6 b/pkg/netconf/testdata/nftrules_ipv6 index 7f1bf79..4dc27b7 100644 --- a/pkg/netconf/testdata/nftrules_ipv6 +++ b/pkg/netconf/testdata/nftrules_ipv6 @@ -12,8 +12,8 @@ table inet metal { ct state established,related counter accept comment "stateful input" - ip saddr 10.0.0.0/8 tcp dport domain ip6 daddr 2a02:c00:20::1 accept comment "dnat to dns proxy" - ip saddr 10.0.0.0/8 udp dport domain ip6 daddr 2a02:c00:20::1 accept comment "dnat to dns proxy" + ip6 saddr fd00::/8 tcp dport domain ip6 daddr 2a02:c00:20::1 accept comment "dnat to dns proxy" + ip6 saddr fd00::/8 udp dport domain ip6 daddr 2a02:c00:20::1 accept comment "dnat to dns proxy" tcp dport ssh ct state new counter accept comment "SSH incoming connections" iifname "vrf3981" tcp dport 9100 counter accept comment "node metrics" @@ -63,12 +63,19 @@ table inet nat { elements = { 8.8.8.8, 8.8.4.4, 1.1.1.1, 1.0.0.1 } } + set proxy_dns_servers_v6 { + type ipv6_addr + flags interval + auto-merge + elements = { 2001:4860:4860::8888, 2001:4860:4860::8844, 2606:4700:4700::1111, 2606:4700:4700::1001 } + } + chain prerouting { type nat hook prerouting priority 0; policy accept; - ip6 daddr @proxy_dns_servers iifname "vlan3981" tcp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" - ip6 daddr @proxy_dns_servers iifname "vlan3981" udp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" - ip6 daddr @proxy_dns_servers iifname "vlan3982" tcp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" - ip6 daddr @proxy_dns_servers iifname "vlan3982" udp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" + ip6 daddr @proxy_dns_servers_v6 iifname "vlan3981" tcp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" + ip6 daddr @proxy_dns_servers_v6 iifname "vlan3981" udp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" + ip6 daddr @proxy_dns_servers_v6 iifname "vlan3982" tcp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" + ip6 daddr @proxy_dns_servers_v6 iifname "vlan3982" udp dport domain dnat ip6 to 2a02:c00:20::1 comment "dnat to dns proxy" } chain prerouting_ct { type filter hook prerouting priority raw; policy accept; diff --git a/pkg/netconf/tpl/nftrules.tpl b/pkg/netconf/tpl/nftrules.tpl index 03d9b9f..9f433db 100644 --- a/pkg/netconf/tpl/nftrules.tpl +++ b/pkg/netconf/tpl/nftrules.tpl @@ -13,8 +13,8 @@ table inet metal { ct state established,related counter accept comment "stateful input" {{- if .DNSProxyDNAT.DestSpec.Address }} - ip saddr 10.0.0.0/8 tcp dport {{ .DNSProxyDNAT.Port }} {{ .DNSProxyDNAT.DestSpec.AddressFamily }} daddr {{ .DNSProxyDNAT.DestSpec.Address }} accept comment "{{ .DNSProxyDNAT.Comment }}" - ip saddr 10.0.0.0/8 udp dport {{ .DNSProxyDNAT.Port }} {{ .DNSProxyDNAT.DestSpec.AddressFamily }} daddr {{ .DNSProxyDNAT.DestSpec.Address }} accept comment "{{ .DNSProxyDNAT.Comment }}" + {{ .DNSProxyDNAT.DestSpec.AddressFamily }} saddr {{ .DNSProxyDNAT.SAddr }} tcp dport {{ .DNSProxyDNAT.Port }} {{ .DNSProxyDNAT.DestSpec.AddressFamily }} daddr {{ .DNSProxyDNAT.DestSpec.Address }} accept comment "{{ .DNSProxyDNAT.Comment }}" + {{ .DNSProxyDNAT.DestSpec.AddressFamily }} saddr {{ .DNSProxyDNAT.SAddr }} udp dport {{ .DNSProxyDNAT.Port }} {{ .DNSProxyDNAT.DestSpec.AddressFamily }} daddr {{ .DNSProxyDNAT.DestSpec.Address }} accept comment "{{ .DNSProxyDNAT.Comment }}" {{- end }} {{ if .VPN -}} @@ -78,6 +78,15 @@ table inet nat { auto-merge elements = { 8.8.8.8, 8.8.4.4, 1.1.1.1, 1.0.0.1 } } + {{- if eq .DNSProxyDNAT.DestSpec.AddressFamily "ip6" }} + + set proxy_dns_servers_v6 { + type ipv6_addr + flags interval + auto-merge + elements = { 2001:4860:4860::8888, 2001:4860:4860::8844, 2606:4700:4700::1111, 2606:4700:4700::1001 } + } + {{- end }} chain prerouting { type nat hook prerouting priority 0; policy accept; diff --git a/validate.sh b/validate.sh index 9491f50..8d79029 100755 --- a/validate.sh +++ b/validate.sh @@ -6,12 +6,22 @@ validate () { echo "----------------------------------------------------------------" echo "Validating sample artifacts of metal-networker with ${1}:${2} frr:${3}" echo "----------------------------------------------------------------" + tag="${1}_${2}_${3}" docker build \ --build-arg OS_NAME="${1}" \ --build-arg OS_VERSION="${2}" \ --build-arg FRR_VERSION="${3}" \ --file Dockerfile.validate \ - . -t metal-networker + . -t metal-networker-validate:${tag} + + docker run --interactive \ + --rm \ + --network=none \ + --cap-add=NET_ADMIN \ + --cap-add=NET_RAW \ + --name vali \ + --volume ./pkg/netconf/testdata:/testdata \ + metal-networker-validate:${tag} /validate_os.sh } validate "ubuntu" "24.04" "frr-10" diff --git a/validate_os.sh b/validate_os.sh index eb52578..67c1d19 100755 --- a/validate_os.sh +++ b/validate_os.sh @@ -2,7 +2,7 @@ testcases="/testdata/frr.conf.*" for tc in $testcases; do - echo -n "Testing FRR ${FRR_VERSION} on ${OS_NAME}:${OS_VERSION} with input ${tc}: " + echo -n "Testing ${FRR_VERSION} on ${OS_NAME}:${OS_VERSION} with input ${tc}: " if vtysh --dryrun --inputfile "${tc}"; then printf "\e[32m\xE2\x9C\x94\e[0m\n" @@ -11,4 +11,17 @@ for tc in $testcases; do echo "FRR ${FRR_VERSION} on ${OS_NAME}:${OS_VERSION} produces an invalid configuration" exit 1 fi +done + +testcases="/testdata/nftrules*" +for tc in $testcases; do + echo -n "Testing nft rules on ${OS_NAME}:${OS_VERSION} with input ${tc}: " + if nft -c -f "${tc}"; + then + printf "\e[32m\xE2\x9C\x94\e[0m\n" + else + printf "\e[31m\xE2\x9D\x8C\e[0m\n" + echo "nft input ${tc} on ${OS_NAME}:${OS_VERSION} produces an invalid configuration" + exit 1 + fi done \ No newline at end of file