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

Firewall rules #103

Merged
merged 15 commits into from
Feb 15, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go 1.21
- name: Set up Go 1.22
uses: actions/setup-go@v5
with:
go-version: '1.21.x'
go-version: '1.22.x'
cache: false

- name: Lint
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go 1.21
- name: Set up Go 1.22
uses: actions/setup-go@v5
with:
go-version: '1.21.x'
go-version: '1.22.x'
cache: false

- name: Lint
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go 1.21
- name: Set up Go 1.22
uses: actions/setup-go@v5
with:
go-version: '1.21.x'
go-version: '1.22.x'
cache: false

- name: Lint
Expand Down
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module github.com/metal-stack/metal-networker

go 1.21
go 1.22

require (
github.com/coreos/go-systemd/v22 v22.5.0
github.com/google/go-cmp v0.6.0
github.com/metal-stack/metal-go v0.26.2
github.com/metal-stack/metal-hammer v0.12.0
github.com/metal-stack/metal-lib v0.14.3
github.com/metal-stack/metal-go v0.27.0
github.com/metal-stack/metal-hammer v0.12.2
github.com/metal-stack/metal-lib v0.14.4
github.com/metal-stack/v v1.0.3
github.com/stretchr/testify v1.8.4
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -23,15 +23,15 @@ require (
github.com/go-openapi/loads v0.21.5 // indirect
github.com/go-openapi/spec v0.20.14 // indirect
github.com/go-openapi/strfmt v0.22.0 // indirect
github.com/go-openapi/swag v0.22.8 // indirect
github.com/go-openapi/validate v0.22.6 // indirect
github.com/go-openapi/swag v0.22.9 // indirect
github.com/go-openapi/validate v0.23.0 // indirect
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/sys v0.17.0 // indirect
)
28 changes: 14 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/
github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw=
github.com/go-openapi/strfmt v0.22.0 h1:Ew9PnEYc246TwrEspvBdDHS4BVKXy/AOVsfqGDgAcaI=
github.com/go-openapi/strfmt v0.22.0/go.mod h1:HzJ9kokGIju3/K6ap8jL+OlGAbjpSv27135Yr9OivU4=
github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw=
github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI=
github.com/go-openapi/validate v0.22.6 h1:+NhuwcEYpWdO5Nm4bmvhGLW0rt1Fcc532Mu3wpypXfo=
github.com/go-openapi/validate v0.22.6/go.mod h1:eaddXSqKeTg5XpSmj1dYyFTK/95n/XHwcOY+BMxKMyM=
github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE=
github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE=
github.com/go-openapi/validate v0.23.0 h1:2l7PJLzCis4YUGEoW6eoQw3WhyM65WSIcjX6SQnlfDw=
github.com/go-openapi/validate v0.23.0/go.mod h1:EeiAZ5bmpSIOJV1WLfyYF9qp/B1ZgSaEpHTJHtN5cbE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
Expand All @@ -41,12 +41,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/metal-stack/metal-go v0.26.2 h1:KZRV1wtCsj0dMo4GpW2+XemmAkPZAYFjbGe7QhhcH1k=
github.com/metal-stack/metal-go v0.26.2/go.mod h1:olJ3Az7RBh39Q5WFCJOQBd7cJi0xgGYwMTEIFvkDQQY=
github.com/metal-stack/metal-hammer v0.12.0 h1:t6t73RGmDU1IFkHC7dJxu7xDIZZvwmqmu9/0xZVF/L0=
github.com/metal-stack/metal-hammer v0.12.0/go.mod h1:MeY/EDYqyFUTk24vEQuaUrfRJf20lIisbqXj28+Bxmc=
github.com/metal-stack/metal-lib v0.14.3 h1:oHtOnGsQC/ySLXzj14mfy7/8bwmCPfD5SD6U4yh8BHU=
github.com/metal-stack/metal-lib v0.14.3/go.mod h1:2wKxFXSCpA1Dr+Rq0ddpQCPKPGMWJp4cpIaVTM4lDi0=
github.com/metal-stack/metal-go v0.27.0 h1:cny3CK8U0TkxXF4D57yTfTDplrmavt/UAXXzdmE4Uqk=
github.com/metal-stack/metal-go v0.27.0/go.mod h1:Iw4xnzbtcn3qz7YaK0ekCAcLZUyz5E7e0ZCvJ5pX0gU=
github.com/metal-stack/metal-hammer v0.12.2 h1:P+/9gG04l+PUPs2NYeIYeTx2sJof4xd1EShnYK5R7Uw=
github.com/metal-stack/metal-hammer v0.12.2/go.mod h1:p346Be2o5VeuvgPHe5HDxelV+Eq0zqlJwiiHKqLC65c=
github.com/metal-stack/metal-lib v0.14.4 h1:vm2868vcua6khoyWL7d0to8Hq5RayrjMse0FZTyWEec=
github.com/metal-stack/metal-lib v0.14.4/go.mod h1:Z3PAh8dkyWC4B19fXsu6EYwXXee0Lk9JZbjoHPLbDbc=
github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs=
github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
Expand Down Expand Up @@ -84,8 +84,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
86 changes: 81 additions & 5 deletions pkg/netconf/nftables.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"log/slog"
"net/netip"
"strconv"
"strings"

"github.com/metal-stack/metal-go/api/models"
mn "github.com/metal-stack/metal-lib/pkg/net"
Expand Down Expand Up @@ -35,6 +37,12 @@ type (
DNSProxyDNAT DNAT
VPN bool
ForwardPolicy string
FirewallRules FirewallRules
}

FirewallRules struct {
Egress []string
Ingress []string
}

// SNAT holds the information required to configure Source NAT.
Expand Down Expand Up @@ -75,6 +83,7 @@ func newNftablesConfigApplier(c config, validator net.Validator, enableDNSProxy
Comment: versionHeader(c.MachineUUID),
SNAT: getSNAT(c, enableDNSProxy),
ForwardPolicy: string(forwardPolicy),
FirewallRules: getFirewallRules(c),
}

if enableDNSProxy {
Expand Down Expand Up @@ -132,14 +141,10 @@ func getSNAT(c config, enableDNSProxy bool) []SNAT {
svi := fmt.Sprintf("vlan%d", *n.Vrf)

for _, p := range privatePfx {
ipprefix, err := netip.ParsePrefix(p)
af, err := getAddressFamily(p)
if err != nil {
continue
}
af := "ip"
if ipprefix.Addr().Is6() {
af = "ip6"
}
sspec := AddrSpec{
Address: p,
AddressFamily: af,
Expand Down Expand Up @@ -195,6 +200,77 @@ func getDNSProxyDNAT(c config, port, zone string) DNAT {
}
}

func getFirewallRules(c config) FirewallRules {
if c.FirewallRules == nil {
return FirewallRules{}
}
var (
egressRules = []string{"# egress rules specified during firewall creation"}
ingressRules = []string{"# ingress rules specified during firewall creation"}
)
for _, r := range c.FirewallRules.Egress {
ports := make([]string, len(r.Ports))
for i, v := range r.Ports {
ports[i] = strconv.Itoa(int(v))
}
for _, daddr := range r.To {
af, err := getAddressFamily(daddr)
if err != nil {
continue
}
// We could potentially also take private primary network interface as iifname instead if saddr
egressRules = append(egressRules,
fmt.Sprintf("ip saddr { 10.0.0.0/8 } %s daddr %s %s dport { %s } counter accept comment %q", af, daddr, strings.ToLower(r.Protocol), strings.Join(ports, ","), r.Comment))
}
}

privatePrimaryNetwork := c.getPrivatePrimaryNetwork()
outputInterfacenames := ""
if privatePrimaryNetwork != nil && privatePrimaryNetwork.Vrf != nil {
outputInterfacenames = fmt.Sprintf("oifname { \"vrf%d\", \"vni%d\", \"vlan%d\" }", *privatePrimaryNetwork.Vrf, *privatePrimaryNetwork.Vrf, *privatePrimaryNetwork.Vrf)
}

for _, r := range c.FirewallRules.Ingress {
ports := make([]string, len(r.Ports))
for i, v := range r.Ports {
ports[i] = strconv.Itoa(int(v))
}
destinationSpec := ""
if len(r.To) > 0 {
destinationSpec = fmt.Sprintf("ip daddr { %s }", strings.Join(r.To, ", "))
} else if outputInterfacenames != "" {
destinationSpec = outputInterfacenames
} else {
c.log.Warn("no to address specified but not private primary network present, skipping this rule", "rule", r)
Gerrit91 marked this conversation as resolved.
Show resolved Hide resolved
continue
}

for _, saddr := range r.From {
af, err := getAddressFamily(saddr)
if err != nil {
continue
}
ingressRules = append(ingressRules, fmt.Sprintf("%s %s saddr %s %s dport { %s } counter accept comment %q", destinationSpec, af, saddr, strings.ToLower(r.Protocol), strings.Join(ports, ","), r.Comment))
}
}
return FirewallRules{
Egress: egressRules,
Ingress: ingressRules,
}
}

func getAddressFamily(p string) (string, error) {
prefix, err := netip.ParsePrefix(p)
if err != nil {
return "", err
}
family := "ip"
if prefix.Addr().Is6() {
family = "ip6"
}
return family, nil
}

// Validate validates network interfaces configuration.
func (v NftablesValidator) Validate() error {
v.log.Info("running 'nft --check --file' to validate changes.", "file", v.path)
Expand Down
6 changes: 6 additions & 0 deletions pkg/netconf/nftables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ func TestCompileNftRules(t *testing.T) {
enableDNSProxy: false,
forwardPolicy: ForwardPolicyDrop,
},
{
input: "testdata/firewall_with_rules.yaml",
expected: "testdata/nftrules_with_rules",
enableDNSProxy: false,
forwardPolicy: ForwardPolicyDrop,
},
}
log := slog.Default()

Expand Down
Loading
Loading