github.com/cilium/cilium@v1.16.2/Documentation/security/network/encryption-ipsec.rst (about)

     1  .. only:: not (epub or latex or html)
     2  
     3      WARNING: You are looking at unreleased Cilium documentation.
     4      Please use the official rendered version released here:
     5      https://docs.cilium.io
     6  
     7  .. _encryption_ipsec:
     8  
     9  ****************************
    10  IPsec Transparent Encryption
    11  ****************************
    12  
    13  This guide explains how to configure Cilium to use IPsec based transparent
    14  encryption using Kubernetes secrets to distribute the IPsec keys. After this
    15  configuration is complete all traffic between Cilium-managed endpoints, as well
    16  as Cilium-managed host traffic, will be encrypted using IPsec. This guide uses
    17  Kubernetes secrets to distribute keys. Alternatively, keys may be manually
    18  distributed, but that is not shown here.
    19  
    20  Packets are not encrypted when they are destined to the same node from which
    21  they were sent. This behavior is intended. Encryption would provide no benefits
    22  in that case, given that the raw traffic can be observed on the node anyway.
    23  
    24  Generate & Import the PSK
    25  =========================
    26  
    27  First, create a Kubernetes secret for the IPsec configuration to be stored. The
    28  example below demonstrates generation of the necessary IPsec configuration
    29  which will be distributed as a Kubernetes secret called ``cilium-ipsec-keys``.
    30  A Kubernetes secret should consist of one key-value pair where the key is the
    31  name of the file to be mounted as a volume in cilium-agent pods, and the
    32  value is an IPsec configuration in the following format::
    33  
    34      key-id encryption-algorithms PSK-in-hex-format key-size
    35  
    36  .. note::
    37  
    38      ``Secret`` resources need to be deployed in the same namespace as Cilium!
    39      In our example, we use ``kube-system``.
    40  
    41  In the example below, GCM-128-AES is used. However, any of the algorithms
    42  supported by Linux may be used. To generate the secret, you may use the
    43  following command:
    44  
    45  .. code-block:: shell-session
    46  
    47      $ kubectl create -n kube-system secret generic cilium-ipsec-keys \
    48          --from-literal=keys="3+ rfc4106(gcm(aes)) $(echo $(dd if=/dev/urandom count=20 bs=1 2> /dev/null | xxd -p -c 64)) 128"
    49  
    50  .. attention::
    51  
    52      The ``+`` sign in the secret is mandatory since v1.16. It will force the
    53      use of per-tunnel IPsec keys. The former global IPsec keys are considered
    54      insecure (cf. `GHSA-pwqm-x5x6-5586`_).
    55  
    56  .. _GHSA-pwqm-x5x6-5586: https://github.com/cilium/cilium/security/advisories/GHSA-pwqm-x5x6-5586
    57  
    58  The secret can be seen with ``kubectl -n kube-system get secrets`` and will be
    59  listed as ``cilium-ipsec-keys``.
    60  
    61  .. code-block:: shell-session
    62  
    63      $ kubectl -n kube-system get secrets cilium-ipsec-keys
    64      NAME                TYPE     DATA   AGE
    65      cilium-ipsec-keys   Opaque   1      176m
    66  
    67  Enable Encryption in Cilium
    68  ===========================
    69  
    70  .. tabs::
    71  
    72      .. group-tab:: Cilium CLI
    73  
    74         If you are deploying Cilium with the Cilium CLI, pass the following
    75         options:
    76  
    77         .. parsed-literal::
    78  
    79            cilium install |CHART_VERSION| \
    80               --set encryption.enabled=true \
    81               --set encryption.type=ipsec
    82  
    83      .. group-tab:: Helm
    84  
    85         If you are deploying Cilium with Helm by following
    86         :ref:`k8s_install_helm`, pass the following options:
    87  
    88         .. parsed-literal::
    89  
    90             helm install cilium |CHART_RELEASE| \\
    91               --namespace kube-system \\
    92               --set encryption.enabled=true \\
    93               --set encryption.type=ipsec
    94  
    95         ``encryption.enabled`` enables encryption of the traffic between
    96         Cilium-managed pods. ``encryption.type`` specifies the encryption method
    97         and can be omitted as it defaults to ``ipsec``.
    98  
    99  .. attention::
   100  
   101     When using Cilium in any direct routing configuration, ensure that the
   102     native routing CIDR is set properly. This is done using
   103     ``--ipv4-native-routing-cidr=CIDR`` with the CLI or ``--set
   104     ipv4NativeRoutingCIDR=CIDR`` with Helm.
   105  
   106  At this point the Cilium managed nodes will be using IPsec for all traffic. For further
   107  information on Cilium's transparent encryption, see :ref:`ebpf_datapath`.
   108  
   109  Dependencies
   110  ============
   111  
   112  When L7 proxy support is enabled (``--enable-l7-proxy=true``), IPsec requires that the
   113  DNS proxy operates in transparent mode (``--dnsproxy-enable-transparent-mode=true``).
   114  
   115  Encryption interface
   116  --------------------
   117  
   118  An additional argument can be used to identify the network-facing interface.
   119  If direct routing is used and no interface is specified, the default route
   120  link is chosen by inspecting the routing tables. This will work in many cases,
   121  but depending on routing rules, users may need to specify the encryption
   122  interface as follows:
   123  
   124  .. tabs::
   125  
   126      .. group-tab:: Cilium CLI
   127  
   128         .. parsed-literal::
   129  
   130            cilium install |CHART_VERSION| \
   131               --set encryption.enabled=true \
   132               --set encryption.type=ipsec \
   133               --set encryption.ipsec.interface=ethX
   134  
   135      .. group-tab:: Helm
   136  
   137         .. code-block:: shell-session
   138  
   139             --set encryption.ipsec.interface=ethX
   140  
   141  Validate the Setup
   142  ==================
   143  
   144  Run a ``bash`` shell in one of the Cilium pods with
   145  ``kubectl -n kube-system exec -ti ds/cilium -- bash`` and execute the following
   146  commands:
   147  
   148  1. Install tcpdump
   149  
   150     .. code-block:: shell-session
   151  
   152         $ apt-get update
   153         $ apt-get -y install tcpdump
   154  
   155  2. Check that traffic is encrypted. In the example below, this can be verified
   156     by the fact that packets carry the IP Encapsulating Security Payload (ESP).
   157     In the example below, ``eth0`` is the interface used for pod-to-pod
   158     communication. Replace this interface with e.g. ``cilium_vxlan`` if
   159     tunneling is enabled.
   160  
   161     .. code-block:: shell-session
   162  
   163         tcpdump -l -n -i eth0 esp
   164         tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
   165         listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
   166         15:16:21.626416 IP 10.60.1.1 > 10.60.0.1: ESP(spi=0x00000001,seq=0x57e2), length 180
   167         15:16:21.626473 IP 10.60.1.1 > 10.60.0.1: ESP(spi=0x00000001,seq=0x57e3), length 180
   168         15:16:21.627167 IP 10.60.0.1 > 10.60.1.1: ESP(spi=0x00000001,seq=0x579d), length 100
   169         15:16:21.627296 IP 10.60.0.1 > 10.60.1.1: ESP(spi=0x00000001,seq=0x579e), length 100
   170         15:16:21.627523 IP 10.60.0.1 > 10.60.1.1: ESP(spi=0x00000001,seq=0x579f), length 180
   171         15:16:21.627699 IP 10.60.1.1 > 10.60.0.1: ESP(spi=0x00000001,seq=0x57e4), length 100
   172         15:16:21.628408 IP 10.60.1.1 > 10.60.0.1: ESP(spi=0x00000001,seq=0x57e5), length 100
   173  
   174  .. _ipsec_key_rotation:
   175  
   176  Key Rotation
   177  ============
   178  
   179  .. attention::
   180  
   181     Key rotations should not be performed during upgrades and downgrades. That
   182     is, all nodes in the cluster (or clustermesh) should be on the same Cilium
   183     version before rotating keys.
   184  
   185  To replace cilium-ipsec-keys secret with a new key:
   186  
   187  .. code-block:: shell-session
   188  
   189      KEYID=$(kubectl get secret -n kube-system cilium-ipsec-keys -o go-template --template={{.data.keys}} | base64 -d | grep -oP "^\d+")
   190      if [[ $KEYID -ge 15 ]]; then KEYID=0; fi
   191      data=$(echo "{\"stringData\":{\"keys\":\"$((($KEYID+1)))+ "rfc4106\(gcm\(aes\)\)" $(echo $(dd if=/dev/urandom count=20 bs=1 2> /dev/null| xxd -p -c 64)) 128\"}}")
   192      kubectl patch secret -n kube-system cilium-ipsec-keys -p="${data}" -v=1
   193  
   194  During transition the new and old keys will be in use. The Cilium agent keeps
   195  per endpoint data on which key is used by each endpoint and will use the correct
   196  key if either side has not yet been updated. In this way encryption will work as
   197  new keys are rolled out.
   198  
   199  The ``KEYID`` environment variable in the above example stores the current key
   200  ID used by Cilium. The key variable is a uint8 with value between 1 and 15
   201  included and should be monotonically increasing every re-key with a rollover
   202  from 15 to 1. The Cilium agent will default to ``KEYID`` of zero if its not
   203  specified in the secret.
   204  
   205  If you are using Cluster Mesh, you must apply the key rotation procedure
   206  to all clusters in the mesh. You might need to increase the transition time to
   207  allow for the new keys to be deployed and applied across all clusters,
   208  which you can do with the agent flag ``ipsec-key-rotation-duration``.
   209  
   210  Troubleshooting
   211  ===============
   212  
   213   * If the ``cilium`` Pods fail to start after enabling encryption, double-check if
   214     the IPsec ``Secret`` and Cilium are deployed in the same namespace together.
   215  
   216   * Check for ``level=warning`` and ``level=error`` messages in the Cilium log files
   217  
   218     * If there is a warning message similar to ``Device eth0 does not exist``,
   219       use ``--set encryption.ipsec.interface=ethX`` to set the encryption
   220       interface.
   221  
   222   * Run ``cilium-dbg encrypt status`` in the Cilium Pod:
   223  
   224     .. code-block:: shell-session
   225  
   226         $ cilium-dbg encrypt status
   227         Encryption: IPsec
   228         Decryption interface(s): eth0, eth1, eth2
   229         Keys in use: 4
   230         Max Seq. Number: 0x1e3/0xffffffff
   231         Errors: 0
   232  
   233     If the error counter is non-zero, additional information will be displayed
   234     with the specific errors the kernel encountered. If the sequence number
   235     reaches its maximum value, it will also result in errors.
   236  
   237     The number of keys in use should be 2 per remote node per enabled IP family.
   238     During a key rotation, it can double to 4 per remote node per IP family. For
   239     example, in a 3-nodes cluster, if both IPv4 and IPv6 are enabled and no key
   240     rotation is ongoing, there should be 8 keys in use on each node.
   241  
   242     The list of decryption interfaces should have all native devices that may
   243     receive pod traffic (for example, ENI interfaces).
   244  
   245  All XFRM errors correspond to a packet drop in the kernel. The following
   246  details operational mistakes and expected behaviors that can cause those
   247  errors.
   248  
   249   * When a node reboots, the key used to communicate with it is expected to
   250     change on other nodes. You may notice the ``XfrmInNoStates`` and
   251     ``XfrmOutNoStates`` counters increase while the new node key is being
   252     deployed.
   253  
   254   * If the sequence number reaches its maximum value for any XFRM OUT state, it
   255     will result in packet drops and XFRM errors of type
   256     ``XfrmOutStateSeqError``. A key rotation resets all sequence numbers.
   257     Rotate keys frequently to avoid this issue.
   258  
   259   * After a key rotation, if the old key is cleaned up before the
   260     configuration of the new key is installed on all nodes, it results in
   261     ``XfrmInNoStates`` errors. The old key is removed from nodes after a default
   262     interval of 5 minutes by default. By default, all agents watch for key
   263     updates and update their configuration within 1 minute after the key is
   264     changed, leaving plenty of time before the old key is removed. If you expect
   265     the key rotation to take longer for some reason (for example, in the case of
   266     Cluster Mesh where several clusters need to be updated), you can increase the
   267     delay before cleanup with agent flag ``ipsec-key-rotation-duration``.
   268  
   269   * ``XfrmInStateProtoError`` errors can happen for the following reasons:
   270     1. If the key is updated without incrementing the SPI (also called ``KEYID``
   271     in :ref:`ipsec_key_rotation` instructions above). It can be fixed by
   272     performing a new key rotation, properly.
   273     2. If the source node encrypts the packets using a different anti-replay seq
   274     from the anti-reply oseq on the destination node. This can be fixed by
   275     properly performing a new key rotation.
   276  
   277   * ``XfrmFwdHdrError`` and ``XfrmInError`` happen when the kernel fails to
   278     lookup the route for a packet it decrypted. This can legitimately happen
   279     when a pod was deleted but some packets are still in transit. Note these
   280     errors can also happen under memory pressure when the kernel fails to
   281     allocate memory.
   282  
   283   * ``XfrmInStateInvalid`` can happen on rare occasions if packets are received
   284     while an XFRM state is being deleted. XFRM states get deleted as part of
   285     node scale-downs and for some upgrades and downgrades.
   286  
   287   * The following table documents the known explanations for several XFRM errors
   288     that were observed in the past. Many other error types exist, but they are
   289     usually for Linux subfeatures that Cilium doesn't use (e.g., XFRM
   290     expiration).
   291  
   292     =======================  ==================================================
   293     Error                    Known explanation
   294     =======================  ==================================================
   295     XfrmInError              The kernel (1) decrypted and tried to route a
   296                              packet for a pod that was deleted or (2) failed to
   297                              allocate memory.
   298     XfrmInNoStates           Bug in the XFRM configuration for decryption.
   299     XfrmInStateProtoError    There is a key or anti-replay seq mismatch between
   300                              nodes.
   301     XfrmInStateInvalid       A received packet matched an XFRM state that is
   302                              being deleted.
   303     XfrmInTmplMismatch       Bug in the XFRM configuration for decryption.
   304     XfrmInNoPols             Bug in the XFRM configuration for decryption.
   305     XfrmInPolBlock           Explicit drop, not used by Cilium.
   306     XfrmOutNoStates          Bug in the XFRM configuration for encryption.
   307     XfrmOutStateSeqError     The sequence number of an encryption XFRM
   308                              configuration reached its maximum value.
   309     XfrmOutPolBlock          Cilium dropped packets that would have otherwise
   310                              left the node in plain-text.
   311     XfrmFwdHdrError          The kernel (1) decrypted and tried to route a
   312                              packet for a pod that was deleted or (2) failed to
   313                              allocate memory.
   314     =======================  ==================================================
   315  
   316   * In addition to the above XFRM errors, packet drops of type ``No node ID
   317     found`` (code 197) may also occur under normal operations. These drops can
   318     happen if a pod attempts to send traffic to a pod on a new node for which
   319     the Cilium agent didn't yet receive the CiliumNode object or to a pod on a
   320     node that was recently deleted. It can also happen if the IP address of the
   321     destination node changed and the agent didn't receive the updated CiliumNode
   322     object yet. In both cases, the IPsec configuration in the kernel isn't ready
   323     yet, so Cilium drops the packets at the source. These drops will stop once
   324     the CiliumNode information is propagated across the cluster.
   325  
   326  Disabling Encryption
   327  ====================
   328  
   329  To disable the encryption, regenerate the YAML with the option
   330  ``encryption.enabled=false``
   331  
   332  Limitations
   333  ===========
   334  
   335      * Transparent encryption is not currently supported when chaining Cilium on
   336        top of other CNI plugins. For more information, see :gh-issue:`15596`.
   337      * :ref:`HostPolicies` are not currently supported with IPsec encryption.
   338      * IPsec encryption does not work when using :ref:`kube-proxy replacement
   339        <kubeproxy-free>`. Be aware that other features may require a kube-proxy
   340        free environment in which case they are mutual exclusive.
   341      * IPsec encryption is not currently supported in combination with IPv6-only clusters.
   342      * IPsec encryption is not supported on clusters or clustermeshes with more
   343        than 65535 nodes.
   344      * Decryption with Cilium IPsec is limited to a single CPU core per IPsec
   345        tunnel. This may affect performance in case of high throughput between
   346        two nodes.