pkg/mesh/routes.go: add flag for generic ACCEPT in FORWARD chain (#244)

* pkg/mesh/routes.go: add flag for generic ACCEPT in FORWARD chain

Some linux distros or docker will set the default policy in the FORWARD
chain in the filter table to DROP. With the new ip-tables-forward-rules
flag a generic ACCEPT for all packages going from and to the pod subnet
is added to the FORWARD chain.

Signed-off-by: leonnicolas <leonloechner@gmx.de>

* Update cmd/kg/main.go

Co-authored-by: Lucas Servén Marín <lserven@gmail.com>

* Update cmd/kg/main.go

Co-authored-by: Lucas Servén Marín <lserven@gmail.com>
This commit is contained in:
leonnicolas 2021-09-30 15:39:06 +03:00 committed by GitHub
parent e2745b453f
commit 9b14c227a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 48 deletions

View File

@ -111,6 +111,7 @@ var (
port uint
subnet string
resyncPeriod time.Duration
iptablesForwardRule bool
prioritisePrivateAddr bool
printVersion bool
@ -140,7 +141,8 @@ func init() {
cmd.Flags().UintVar(&port, "port", mesh.DefaultKiloPort, "The port over which WireGuard peers should communicate.")
cmd.Flags().StringVar(&subnet, "subnet", mesh.DefaultKiloSubnet.String(), "CIDR from which to allocate addresses for WireGuard interfaces.")
cmd.Flags().DurationVar(&resyncPeriod, "resync-period", 30*time.Second, "How often should the Kilo controllers reconcile?")
cmd.Flags().BoolVar(&prioritisePrivateAddr, "prioritise-private-addresses", false, "Prefer to assign a private IP address to the node's endpoint")
cmd.Flags().BoolVar(&iptablesForwardRule, "iptables-forward-rules", false, "Add default accept rules to the FORWARD chain in iptables. Warning: this may break firewalls with a deny all policy and is potentially insecure!")
cmd.Flags().BoolVar(&prioritisePrivateAddr, "prioritise-private-addresses", false, "Prefer to assign a private IP address to the node's endpoint.")
cmd.PersistentFlags().BoolVar(&printVersion, "version", false, "Print version and exit")
cmd.PersistentFlags().StringVar(&logLevel, "log-level", logLevelInfo, fmt.Sprintf("Log level to use. Possible values: %s", availableLogLevels))
@ -236,7 +238,7 @@ func runRoot(_ *cobra.Command, _ []string) error {
return fmt.Errorf("backend %v unknown; possible values are: %s", backend, availableBackends)
}
m, err := mesh.New(b, enc, gr, hostname, uint32(port), s, local, cni, cniPath, iface, cleanUpIface, createIface, mtu, resyncPeriod, prioritisePrivateAddr, log.With(logger, "component", "kilo"))
m, err := mesh.New(b, enc, gr, hostname, uint32(port), s, local, cni, cniPath, iface, cleanUpIface, createIface, mtu, resyncPeriod, prioritisePrivateAddr, iptablesForwardRule, log.With(logger, "component", "kilo"))
if err != nil {
return fmt.Errorf("failed to create Kilo mesh: %v", err)
}

View File

@ -66,6 +66,7 @@ type Mesh struct {
privIface int
pub []byte
resyncPeriod time.Duration
iptablesForwardRule bool
stop chan struct{}
subnet *net.IPNet
table *route.Table
@ -86,7 +87,7 @@ type Mesh struct {
}
// New returns a new Mesh instance.
func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularity, hostname string, port uint32, subnet *net.IPNet, local, cni bool, cniPath, iface string, cleanUpIface bool, createIface bool, mtu uint, resyncPeriod time.Duration, prioritisePrivateAddr bool, logger log.Logger) (*Mesh, error) {
func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularity, hostname string, port uint32, subnet *net.IPNet, local, cni bool, cniPath, iface string, cleanUpIface bool, createIface bool, mtu uint, resyncPeriod time.Duration, prioritisePrivateAddr, iptablesForwardRule bool, logger log.Logger) (*Mesh, error) {
if err := os.MkdirAll(kiloPath, 0700); err != nil {
return nil, fmt.Errorf("failed to create directory to store configuration: %v", err)
}
@ -173,6 +174,7 @@ func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularit
privIface: privIface,
pub: public,
resyncPeriod: resyncPeriod,
iptablesForwardRule: iptablesForwardRule,
local: local,
stop: make(chan struct{}),
subnet: subnet,
@ -498,7 +500,7 @@ func (m *Mesh) applyTopology() {
m.errorCounter.WithLabelValues("apply").Inc()
return
}
ipRules := t.Rules(m.cni)
ipRules := t.Rules(m.cni, m.iptablesForwardRule)
// 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

@ -242,12 +242,16 @@ func encapsulateRoute(route *netlink.Route, encapsulate encapsulation.Strategy,
}
// Rules returns the iptables rules required by the local node.
func (t *Topology) Rules(cni bool) []iptables.Rule {
func (t *Topology) Rules(cni, iptablesForwardRule bool) []iptables.Rule {
var rules []iptables.Rule
rules = append(rules, iptables.NewIPv4Chain("nat", "KILO-NAT"))
rules = append(rules, iptables.NewIPv6Chain("nat", "KILO-NAT"))
if cni {
rules = append(rules, iptables.NewRule(iptables.GetProtocol(len(t.subnet.IP)), "nat", "POSTROUTING", "-s", t.subnet.String(), "-m", "comment", "--comment", "Kilo: jump to KILO-NAT chain", "-j", "KILO-NAT"))
if iptablesForwardRule {
rules = append(rules, iptables.NewRule(iptables.GetProtocol(len(t.subnet.IP)), "filter", "FORWARD", "-m", "comment", "--comment", "Kilo: forward packets from the pod subnet", "-s", t.subnet.String(), "-j", "ACCEPT"))
rules = append(rules, iptables.NewRule(iptables.GetProtocol(len(t.subnet.IP)), "filter", "FORWARD", "-m", "comment", "--comment", "Kilo: forward packets to the pod subnet", "-d", t.subnet.String(), "-j", "ACCEPT"))
}
}
for _, s := range t.segments {
rules = append(rules, iptables.NewRule(iptables.GetProtocol(len(s.wireGuardIP)), "nat", "KILO-NAT", "-d", oneAddressCIDR(s.wireGuardIP).String(), "-m", "comment", "--comment", "Kilo: do not NAT packets destined for WireGuared IPs", "-j", "RETURN"))