pkg/mesh: enable outgoing NAT to WAN

This commit enables NAT-ing packets outgoing to the WAN from both the
Pod subnet as well as from peers. This means that Pods can access the
Internet and that peers can use the Kilo mesh as a gateway to the
Internet.

Signed-off-by: Lucas Servén Marín <lserven@gmail.com>
This commit is contained in:
Lucas Servén Marín 2020-03-09 18:42:42 +01:00
parent 8908cf19cb
commit 7051b9fe29
No known key found for this signature in database
GPG Key ID: 586FEAF680DA74AD
3 changed files with 30 additions and 16 deletions

View File

@ -273,21 +273,6 @@ func (c *Controller) CleanUp() error {
return c.deleteFromIndex(0, &c.rules)
}
// ForwardRules returns a set of iptables rules that are necessary
// when traffic must be forwarded for the overlay.
func ForwardRules(subnets ...*net.IPNet) []Rule {
var rules []Rule
for _, subnet := range subnets {
s := subnet.String()
rules = append(rules, []Rule{
// Forward traffic to and from the overlay.
&rule{"filter", "FORWARD", []string{"-s", s, "-j", "ACCEPT"}},
&rule{"filter", "FORWARD", []string{"-d", s, "-j", "ACCEPT"}},
}...)
}
return rules
}
func nonBlockingSend(errors chan<- error, err error) {
select {
case errors <- err:

View File

@ -588,7 +588,10 @@ func (m *Mesh) applyTopology() {
m.errorCounter.WithLabelValues("apply").Inc()
return
}
ipRules := iptables.ForwardRules(m.subnet)
var ipRules []iptables.Rule
if m.cni {
ipRules = append(ipRules, t.Rules(m.cni)...)
}
// If we are handling local routes, ensure the local
// tunnel has an IP address and IPIP traffic is allowed.
if m.enc.Strategy() != encapsulation.Never && m.local {

View File

@ -20,6 +20,7 @@ import (
"sort"
"github.com/squat/kilo/pkg/encapsulation"
"github.com/squat/kilo/pkg/iptables"
"github.com/squat/kilo/pkg/wireguard"
"github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
@ -432,6 +433,31 @@ func (t *Topology) PeerConf(name string) *wireguard.Conf {
return c
}
// Rules returns the iptables rules required by the local node.
func (t *Topology) Rules(cni bool) []iptables.Rule {
var rules []iptables.Rule
rules = append(rules, iptables.NewChain("nat", "KILO-NAT"))
if cni {
rules = append(rules, iptables.NewRule("nat", "POSTROUTING", "-m", "comment", "--comment", "Kilo: jump to NAT chain", "-s", t.subnet.String(), "-j", "KILO-NAT"))
}
for _, s := range t.segments {
rules = append(rules, iptables.NewRule("nat", "KILO-NAT", "-m", "comment", "--comment", "Kilo: do not NAT packets destined for WireGuared IPs", "-d", s.wireGuardIP.String(), "-j", "RETURN"))
for _, aip := range s.allowedIPs {
rules = append(rules, iptables.NewRule("nat", "KILO-NAT", "-m", "comment", "--comment", "Kilo: do not NAT packets destined for known IPs", "-d", aip.String(), "-j", "RETURN"))
}
}
for _, p := range t.peers {
for _, aip := range p.AllowedIPs {
rules = append(rules,
iptables.NewRule("nat", "POSTROUTING", "-m", "comment", "--comment", "Kilo: jump to NAT chain", "-s", aip.String(), "-j", "KILO-NAT"),
iptables.NewRule("nat", "KILO-NAT", "-m", "comment", "--comment", "Kilo: do not NAT packets destined for peers", "-d", aip.String(), "-j", "RETURN"),
)
}
}
rules = append(rules, iptables.NewRule("nat", "KILO-NAT", "-m", "comment", "--comment", "Kilo: NAT remaining packets", "-j", "MASQUERADE"))
return rules
}
// oneAddressCIDR takes an IP address and returns a CIDR
// that contains only that address.
func oneAddressCIDR(ip net.IP) *net.IPNet {