netbird/iface/nat_linux.go
2021-05-01 12:45:37 +02:00

86 lines
1.8 KiB
Go

package iface
import (
"github.com/google/nftables"
"github.com/google/nftables/expr"
log "github.com/sirupsen/logrus"
"github.com/vishvananda/netns"
"io/ioutil"
)
// Configure routing and IP masquerading
//todo more docs on what exactly happens here and why it is needed
func ConfigureNAT(primaryIface string) error {
log.Debugf("adding NAT / IP masquerading using nftables")
ns, err := netns.Get()
if err != nil {
return err
}
conn := nftables.Conn{NetNS: int(ns)}
log.Debugf("flushing nftable rulesets")
conn.FlushRuleset()
log.Debugf("setting up nftable rules for ip masquerading")
nat := conn.AddTable(&nftables.Table{
Family: nftables.TableFamilyIPv4,
Name: "nat",
})
conn.AddChain(&nftables.Chain{
Name: "prerouting",
Table: nat,
Type: nftables.ChainTypeNAT,
Hooknum: nftables.ChainHookPrerouting,
Priority: nftables.ChainPriorityFilter,
})
post := conn.AddChain(&nftables.Chain{
Name: "postrouting",
Table: nat,
Type: nftables.ChainTypeNAT,
Hooknum: nftables.ChainHookPostrouting,
Priority: nftables.ChainPriorityNATSource,
})
conn.AddRule(&nftables.Rule{
Table: nat,
Chain: post,
Exprs: []expr.Any{
&expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: ifname(primaryIface),
},
&expr.Masq{},
},
})
if err := conn.Flush(); err != nil {
return err
}
return nil
}
// Enables IP forwarding system property.
// Mostly used when you setup one peer as a VPN server.
func EnableIPForward() error {
f := "/proc/sys/net/ipv4/ip_forward"
content, err := ioutil.ReadFile(f)
if err != nil {
return err
}
if string(content) == "0\n" {
log.Info("enabling IP Forward")
return ioutil.WriteFile(f, []byte("1"), 0600)
}
return nil
}