...

Source file src/k8s.io/kubernetes/pkg/kubelet/kubelet_network_linux.go

Documentation: k8s.io/kubernetes/pkg/kubelet

     1  //go:build linux
     2  // +build linux
     3  
     4  /*
     5  Copyright 2018 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package kubelet
    21  
    22  import (
    23  	"time"
    24  
    25  	"k8s.io/apimachinery/pkg/util/wait"
    26  	"k8s.io/klog/v2"
    27  	utiliptables "k8s.io/kubernetes/pkg/util/iptables"
    28  	utilexec "k8s.io/utils/exec"
    29  )
    30  
    31  const (
    32  	// KubeIPTablesHintChain is the chain whose existence in either iptables-legacy
    33  	// or iptables-nft indicates which version of iptables the system is using
    34  	KubeIPTablesHintChain utiliptables.Chain = "KUBE-IPTABLES-HINT"
    35  
    36  	// KubeFirewallChain is kubernetes firewall rules
    37  	KubeFirewallChain utiliptables.Chain = "KUBE-FIREWALL"
    38  )
    39  
    40  func (kl *Kubelet) initNetworkUtil() {
    41  	exec := utilexec.New()
    42  	iptClients := []utiliptables.Interface{
    43  		utiliptables.New(exec, utiliptables.ProtocolIPv4),
    44  		utiliptables.New(exec, utiliptables.ProtocolIPv6),
    45  	}
    46  
    47  	for i := range iptClients {
    48  		iptClient := iptClients[i]
    49  		if kl.syncIPTablesRules(iptClient) {
    50  			klog.InfoS("Initialized iptables rules.", "protocol", iptClient.Protocol())
    51  			go iptClient.Monitor(
    52  				utiliptables.Chain("KUBE-KUBELET-CANARY"),
    53  				[]utiliptables.Table{utiliptables.TableMangle, utiliptables.TableNAT, utiliptables.TableFilter},
    54  				func() { kl.syncIPTablesRules(iptClient) },
    55  				1*time.Minute, wait.NeverStop,
    56  			)
    57  		} else {
    58  			klog.InfoS("Failed to initialize iptables rules; some functionality may be missing.", "protocol", iptClient.Protocol())
    59  		}
    60  	}
    61  }
    62  
    63  // syncIPTablesRules ensures the KUBE-IPTABLES-HINT chain exists, and the martian packet
    64  // protection rule is installed.
    65  func (kl *Kubelet) syncIPTablesRules(iptClient utiliptables.Interface) bool {
    66  	// Create hint chain so other components can see whether we are using iptables-legacy
    67  	// or iptables-nft.
    68  	if _, err := iptClient.EnsureChain(utiliptables.TableMangle, KubeIPTablesHintChain); err != nil {
    69  		klog.ErrorS(err, "Failed to ensure that iptables hint chain exists")
    70  		return false
    71  	}
    72  
    73  	if !iptClient.IsIPv6() { // ipv6 doesn't have this issue
    74  		// Set up the KUBE-FIREWALL chain and martian packet protection rule.
    75  		// (See below.)
    76  
    77  		// NOTE: kube-proxy (in iptables mode) creates an identical copy of this
    78  		// rule. If you want to change this rule in the future, you MUST do so in
    79  		// a way that will interoperate correctly with skewed versions of the rule
    80  		// created by kube-proxy.
    81  
    82  		if _, err := iptClient.EnsureChain(utiliptables.TableFilter, KubeFirewallChain); err != nil {
    83  			klog.ErrorS(err, "Failed to ensure that filter table KUBE-FIREWALL chain exists")
    84  			return false
    85  		}
    86  
    87  		if _, err := iptClient.EnsureRule(utiliptables.Prepend, utiliptables.TableFilter, utiliptables.ChainOutput, "-j", string(KubeFirewallChain)); err != nil {
    88  			klog.ErrorS(err, "Failed to ensure that OUTPUT chain jumps to KUBE-FIREWALL")
    89  			return false
    90  		}
    91  		if _, err := iptClient.EnsureRule(utiliptables.Prepend, utiliptables.TableFilter, utiliptables.ChainInput, "-j", string(KubeFirewallChain)); err != nil {
    92  			klog.ErrorS(err, "Failed to ensure that INPUT chain jumps to KUBE-FIREWALL")
    93  			return false
    94  		}
    95  
    96  		// Kube-proxy's use of `route_localnet` to enable NodePorts on localhost
    97  		// creates a security hole (https://issue.k8s.io/90259) which this
    98  		// iptables rule mitigates. This rule should have been added to
    99  		// kube-proxy, but it mistakenly ended up in kubelet instead, and we are
   100  		// keeping it in kubelet for now in case other third-party components
   101  		// depend on it.
   102  		if _, err := iptClient.EnsureRule(utiliptables.Append, utiliptables.TableFilter, KubeFirewallChain,
   103  			"-m", "comment", "--comment", "block incoming localnet connections",
   104  			"--dst", "127.0.0.0/8",
   105  			"!", "--src", "127.0.0.0/8",
   106  			"-m", "conntrack",
   107  			"!", "--ctstate", "RELATED,ESTABLISHED,DNAT",
   108  			"-j", "DROP"); err != nil {
   109  			klog.ErrorS(err, "Failed to ensure rule to drop invalid localhost packets in filter table KUBE-FIREWALL chain")
   110  			return false
   111  		}
   112  	}
   113  
   114  	return true
   115  }
   116  

View as plain text