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.