From e7d80414041a6911181c80d2089f0fed6e9640e6 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 3 Apr 2024 16:12:09 +0400 Subject: [PATCH] fix: always update firewall rules (kubespan) Fixes #8498 Before KubeSpan was reimplemented to use resources for firewall rules, the update was happening always, but it got moved to a wrong section of the controller which gets executed on resource updates, but ignores updates of the peer statuses. Signed-off-by: Andrey Smirnov --- .../pkg/controllers/kubespan/manager.go | 189 +++++++++--------- 1 file changed, 95 insertions(+), 94 deletions(-) diff --git a/internal/app/machined/pkg/controllers/kubespan/manager.go b/internal/app/machined/pkg/controllers/kubespan/manager.go index b62bd4ec3e..5dfe44d7fd 100644 --- a/internal/app/machined/pkg/controllers/kubespan/manager.go +++ b/internal/app/machined/pkg/controllers/kubespan/manager.go @@ -354,6 +354,101 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo } } + mtu := cfgSpec.MTU + + // always update the firewall rules, as allowedIPsSet might change at any moment due to peer up/down events + if err = safe.WriterModify(ctx, r, + network.NewNfTablesChain( + network.NamespaceName, + "kubespan_prerouting", + ), + func(r *network.NfTablesChain) error { + spec := r.TypedSpec() + + spec.Type = nethelpers.ChainTypeFilter + spec.Hook = nethelpers.ChainHookPrerouting + spec.Priority = nethelpers.ChainPriorityFilter + spec.Policy = nethelpers.VerdictAccept + + spec.Rules = []network.NfTablesRule{ + { + MatchMark: &network.NfTablesMark{ + Mask: constants.KubeSpanDefaultFirewallMask, + Value: constants.KubeSpanDefaultFirewallMark, + }, + Verdict: pointer.To(nethelpers.VerdictAccept), + }, + { + MatchDestinationAddress: &network.NfTablesAddressMatch{ + IncludeSubnets: allowedIPsSet.Prefixes(), + }, + SetMark: &network.NfTablesMark{ + Mask: ^uint32(constants.KubeSpanDefaultFirewallMask), + Xor: constants.KubeSpanDefaultForceFirewallMark, + }, + Verdict: pointer.To(nethelpers.VerdictAccept), + }, + } + + return nil + }, + ); err != nil { + return fmt.Errorf("error modifying nftables chain: %w", err) + } + + if err = safe.WriterModify(ctx, r, + network.NewNfTablesChain( + network.NamespaceName, + "kubespan_outgoing", + ), + func(r *network.NfTablesChain) error { + spec := r.TypedSpec() + + spec.Type = nethelpers.ChainTypeRoute + spec.Hook = nethelpers.ChainHookOutput + spec.Priority = nethelpers.ChainPriorityFilter + spec.Policy = nethelpers.VerdictAccept + + spec.Rules = []network.NfTablesRule{ + { + MatchMark: &network.NfTablesMark{ + Mask: constants.KubeSpanDefaultFirewallMask, + Value: constants.KubeSpanDefaultFirewallMark, + }, + Verdict: pointer.To(nethelpers.VerdictAccept), + }, + { + MatchOIfName: &network.NfTablesIfNameMatch{ + InterfaceNames: []string{"lo"}, + }, + Verdict: pointer.To(nethelpers.VerdictAccept), + }, + { + MatchDestinationAddress: &network.NfTablesAddressMatch{ + IncludeSubnets: allowedIPsSet.Prefixes(), + }, + ClampMSS: &network.NfTablesClampMSS{ + MTU: uint16(mtu), + }, + }, + { + MatchDestinationAddress: &network.NfTablesAddressMatch{ + IncludeSubnets: allowedIPsSet.Prefixes(), + }, + SetMark: &network.NfTablesMark{ + Mask: ^uint32(constants.KubeSpanDefaultFirewallMask), + Xor: constants.KubeSpanDefaultForceFirewallMark, + }, + Verdict: pointer.To(nethelpers.VerdictAccept), + }, + } + + return nil + }, + ); err != nil { + return fmt.Errorf("error modifying nftables chain: %w", err) + } + if !updateSpecs { // micro-optimization: skip updating specs if there are no changes to the incoming resources and no endpoint changes r.ResetRestartBackoff() @@ -382,8 +477,6 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo return fmt.Errorf("error modifying address: %w", err) } - mtu := cfgSpec.MTU - for _, spec := range []network.RouteSpecSpec{ { Family: nethelpers.FamilyInet4, @@ -461,98 +554,6 @@ func (ctrl *ManagerController) Run(ctx context.Context, r controller.Runtime, lo return fmt.Errorf("error modifying link spec: %w", err) } - if err = safe.WriterModify(ctx, r, - network.NewNfTablesChain( - network.NamespaceName, - "kubespan_prerouting", - ), - func(r *network.NfTablesChain) error { - spec := r.TypedSpec() - - spec.Type = nethelpers.ChainTypeFilter - spec.Hook = nethelpers.ChainHookPrerouting - spec.Priority = nethelpers.ChainPriorityFilter - spec.Policy = nethelpers.VerdictAccept - - spec.Rules = []network.NfTablesRule{ - { - MatchMark: &network.NfTablesMark{ - Mask: constants.KubeSpanDefaultFirewallMask, - Value: constants.KubeSpanDefaultFirewallMark, - }, - Verdict: pointer.To(nethelpers.VerdictAccept), - }, - { - MatchDestinationAddress: &network.NfTablesAddressMatch{ - IncludeSubnets: allowedIPsSet.Prefixes(), - }, - SetMark: &network.NfTablesMark{ - Mask: ^uint32(constants.KubeSpanDefaultFirewallMask), - Xor: constants.KubeSpanDefaultForceFirewallMark, - }, - Verdict: pointer.To(nethelpers.VerdictAccept), - }, - } - - return nil - }, - ); err != nil { - return fmt.Errorf("error modifying nftables chain: %w", err) - } - - if err = safe.WriterModify(ctx, r, - network.NewNfTablesChain( - network.NamespaceName, - "kubespan_outgoing", - ), - func(r *network.NfTablesChain) error { - spec := r.TypedSpec() - - spec.Type = nethelpers.ChainTypeRoute - spec.Hook = nethelpers.ChainHookOutput - spec.Priority = nethelpers.ChainPriorityFilter - spec.Policy = nethelpers.VerdictAccept - - spec.Rules = []network.NfTablesRule{ - { - MatchMark: &network.NfTablesMark{ - Mask: constants.KubeSpanDefaultFirewallMask, - Value: constants.KubeSpanDefaultFirewallMark, - }, - Verdict: pointer.To(nethelpers.VerdictAccept), - }, - { - MatchOIfName: &network.NfTablesIfNameMatch{ - InterfaceNames: []string{"lo"}, - }, - Verdict: pointer.To(nethelpers.VerdictAccept), - }, - { - MatchDestinationAddress: &network.NfTablesAddressMatch{ - IncludeSubnets: allowedIPsSet.Prefixes(), - }, - ClampMSS: &network.NfTablesClampMSS{ - MTU: uint16(mtu), - }, - }, - { - MatchDestinationAddress: &network.NfTablesAddressMatch{ - IncludeSubnets: allowedIPsSet.Prefixes(), - }, - SetMark: &network.NfTablesMark{ - Mask: ^uint32(constants.KubeSpanDefaultFirewallMask), - Xor: constants.KubeSpanDefaultForceFirewallMark, - }, - Verdict: pointer.To(nethelpers.VerdictAccept), - }, - } - - return nil - }, - ); err != nil { - return fmt.Errorf("error modifying nftables chain: %w", err) - } - if rulesMgr == nil { rulesMgr = ctrl.RulesManagerFactory(constants.KubeSpanDefaultRoutingTable, constants.KubeSpanDefaultForceFirewallMark, constants.KubeSpanDefaultFirewallMask)