netconfig: switch from iptables to nft
This commit is contained in:
parent
1b004597c1
commit
21ca224281
@ -168,7 +168,7 @@ func TestNetconfig(t *testing.T) {
|
|||||||
t.Fatalf("routes: diff (-got +want):\n%s", diff)
|
t.Fatalf("routes: diff (-got +want):\n%s", diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err = exec.Command("ip", "netns", "exec", ns, "iptables", "-t", "nat", "-L", "POSTROUTING", "-v").Output()
|
out, err = exec.Command("ip", "netns", "exec", ns, "nft", "list", "ruleset").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -177,10 +177,21 @@ func TestNetconfig(t *testing.T) {
|
|||||||
t.Logf("rule %d: %s", n, rule)
|
t.Logf("rule %d: %s", n, rule)
|
||||||
}
|
}
|
||||||
if len(rules) < 3 {
|
if len(rules) < 3 {
|
||||||
t.Fatalf("iptables rules in nat table POSTROUTING not found")
|
t.Fatalf("nftables rules not found")
|
||||||
}
|
}
|
||||||
wantRule := " 0 0 MASQUERADE all -- any uplink0 anywhere anywhere"
|
wantRules := []string{
|
||||||
if got, want := rules[2], wantRule; got != want {
|
`table ip nat {`,
|
||||||
t.Fatalf("unexpected iptables rule: got %q, want %q", got, want)
|
` chain prerouting {`,
|
||||||
|
` type nat hook prerouting priority 0; policy accept;`,
|
||||||
|
` }`,
|
||||||
|
``,
|
||||||
|
` chain postrouting {`,
|
||||||
|
` type nat hook postrouting priority 100; policy accept;`,
|
||||||
|
` oif "uplink0" masquerade`,
|
||||||
|
` }`,
|
||||||
|
`}`,
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(rules, wantRules); diff != "" {
|
||||||
|
t.Fatalf("unexpected nftables rules: diff (-got +want):\n%s", diff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/nftables"
|
||||||
|
"github.com/google/nftables/expr"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
"router7/internal/dhcp4"
|
"router7/internal/dhcp4"
|
||||||
"router7/internal/dhcp6"
|
"router7/internal/dhcp6"
|
||||||
@ -69,8 +70,8 @@ func applyDhcp4(dir string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("netlink.NewHandle: %v", err)
|
return fmt.Errorf("netlink.NewHandle: %v", err)
|
||||||
}
|
}
|
||||||
if err := h.AddrAdd(link, addr); err != nil {
|
if err := h.AddrReplace(link, addr); err != nil {
|
||||||
return fmt.Errorf("AddrAdd(%v): %v", addr, err)
|
return fmt.Errorf("AddrReplace(%v): %v", addr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// from include/uapi/linux/rtnetlink.h
|
// from include/uapi/linux/rtnetlink.h
|
||||||
@ -261,26 +262,54 @@ func applyInterfaces(dir, root string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func applyFirewall() error {
|
func applyFirewall() error {
|
||||||
// Fake it till you make it!
|
c := &nftables.Conn{}
|
||||||
// Captured via:
|
|
||||||
// ./strace -xx -v -f -s 2048 ./xtables-multi iptables -t nat -A POSTROUTING -o uplink0 -j MASQUERADE
|
|
||||||
optRule := "\x6e\x61\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x06\x00\x00\x00\xb8\x03\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x30\x01\x00\x00\xc8\x01\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x30\x01\x00\x00\x70\x02\x00\x00\x05\x00\x00\x00\x70\xed\xdb\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x70\x6c\x69\x6e\x6b\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x38\x00\x4d\x41\x53\x51\x55\x45\x52\x41\x44\x45\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x45\x52\x52\x4f\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x45\x52\x52\x4f\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
||||||
optCounters := "\x6e\x61\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
||||||
|
|
||||||
fd, err := unix.Socket(unix.AF_INET, unix.SOCK_RAW, unix.IPPROTO_RAW)
|
// TODO: currently, each iteration adds a nftables.Rule — clear before?
|
||||||
|
|
||||||
|
nat := c.AddTable(&nftables.Table{
|
||||||
|
Family: nftables.TableFamilyIPv4,
|
||||||
|
Name: "nat",
|
||||||
|
})
|
||||||
|
|
||||||
|
c.AddChain(&nftables.Chain{
|
||||||
|
Name: "prerouting",
|
||||||
|
Hooknum: nftables.ChainHookPrerouting,
|
||||||
|
Priority: nftables.ChainPriorityFilter,
|
||||||
|
Table: nat,
|
||||||
|
Type: nftables.ChainTypeNAT,
|
||||||
|
})
|
||||||
|
|
||||||
|
postrouting := c.AddChain(&nftables.Chain{
|
||||||
|
Name: "postrouting",
|
||||||
|
Hooknum: nftables.ChainHookPostrouting,
|
||||||
|
Priority: nftables.ChainPriorityNATSource,
|
||||||
|
Table: nat,
|
||||||
|
Type: nftables.ChainTypeNAT,
|
||||||
|
})
|
||||||
|
|
||||||
|
iface, err := net.InterfaceByName("uplink0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// TODO: close socket later
|
|
||||||
|
|
||||||
if err := unix.SetsockoptString(fd, unix.SOL_IP, 0x40, optRule); err != nil {
|
c.AddRule(&nftables.Rule{
|
||||||
return err
|
Table: nat,
|
||||||
}
|
Chain: postrouting,
|
||||||
if err := unix.SetsockoptString(fd, unix.SOL_IP, 0x41, optCounters); err != nil {
|
Exprs: []expr.Any{
|
||||||
return err
|
// meta load oif => reg 1
|
||||||
}
|
&expr.Meta{Key: expr.MetaKeyOIF, Register: 1},
|
||||||
|
// cmp eq reg 1 0x00000003
|
||||||
|
&expr.Cmp{
|
||||||
|
Op: expr.CmpOpEq,
|
||||||
|
Register: 1,
|
||||||
|
Data: uint32(iface.Index), // TODO: try using oifname instead of oif
|
||||||
|
},
|
||||||
|
// masq
|
||||||
|
&expr.Masq{},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return c.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func applySysctl() error {
|
func applySysctl() error {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user