github.com/cilium/cilium@v1.16.2/Documentation/security/network/encryption-wireguard.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_wg: 8 9 ******************************** 10 WireGuard Transparent Encryption 11 ******************************** 12 13 This guide explains how to configure Cilium with transparent encryption of 14 traffic between Cilium-managed endpoints using `WireGuard® <https://www.wireguard.com/>`_. 15 16 .. admonition:: Video 17 :class: attention 18 19 Aside from this guide, you can also watch `eCHO episode 3: WireGuard <https://www.youtube.com/watch?v=-awkPi3D60E&t=475s>`__ on how 20 WireGuard can encrypt network traffic. 21 22 When WireGuard is enabled in Cilium, the agent running on each cluster node 23 will establish a secure WireGuard tunnel between it and all other known nodes 24 in the cluster. Each node automatically creates its own encryption key-pair and 25 distributes its public key via the ``network.cilium.io/wg-pub-key`` annotation 26 in the Kubernetes ``CiliumNode`` custom resource object. Each node's public key 27 is then used by other nodes to decrypt and encrypt traffic from and to 28 Cilium-managed endpoints running on that node. 29 30 Packets are not encrypted when they are destined to the same node from which 31 they were sent. This behavior is intended. Encryption would provide no benefits 32 in that case, given that the raw traffic can be observed on the node anyway. 33 34 The WireGuard tunnel endpoint is exposed on UDP port ``51871`` on each node. If 35 you run Cilium in an environment that requires firewall rules to enable 36 connectivity, you will have to ensure that all Cilium cluster nodes can reach 37 each other via that port. 38 39 .. note:: 40 41 When running in tunnel routing mode, pod to pod traffic is encapsulated twice. 42 It is first sent to the VXLAN / Geneve tunnel interface, and then subsequently 43 also encapsulated by the WireGuard tunnel. 44 45 Enable WireGuard in Cilium 46 ========================== 47 48 Before you enable WireGuard in Cilium, please ensure that the Linux distribution 49 running on your cluster nodes has support for WireGuard in kernel mode 50 (i.e. ``CONFIG_WIREGUARD=m`` on Linux 5.6 and newer, or via the out-of-tree 51 WireGuard module on older kernels). 52 See `WireGuard Installation <https://www.wireguard.com/install/>`_ for details 53 on how to install the kernel module on your Linux distribution. 54 55 If your kernel or distribution does not support WireGuard, Cilium agent can be 56 configured to fall back on the user-space implementation via the 57 ``--enable-wireguard-userspace-fallback`` flag. When this flag is enabled and 58 Cilium detects that the kernel has no native support for WireGuard, it 59 will fallback on the ``wireguard-go`` user-space implementation of WireGuard. 60 When running the user-space implementation, encryption and decryption of packets 61 is performed by the ``cilium-agent`` process. As a consequence, connectivity 62 between Cilium-managed endpoints will be unavailable whenever the 63 ``cilium-agent`` process is restarted, such as during upgrades or configuration 64 changes. Running WireGuard in user-space mode is therefore not recommended for 65 production workloads that require high availability. 66 67 .. tabs:: 68 69 .. group-tab:: Cilium CLI 70 71 If you are deploying Cilium with the Cilium CLI, pass the following 72 options: 73 74 .. parsed-literal:: 75 76 cilium install |CHART_VERSION| \ 77 --set encryption.enabled=true \ 78 --set encryption.type=wireguard 79 80 .. group-tab:: Helm 81 82 If you are deploying Cilium with Helm by following 83 :ref:`k8s_install_helm`, pass the following options: 84 85 .. parsed-literal:: 86 87 helm install cilium |CHART_RELEASE| \\ 88 --namespace kube-system \\ 89 --set encryption.enabled=true \\ 90 --set encryption.type=wireguard 91 92 WireGuard may also be enabled manually by setting setting the 93 ``enable-wireguard: true`` option in the Cilium ``ConfigMap`` and restarting 94 each Cilium agent instance. 95 96 .. note:: 97 98 When running with the CNI chaining (e.g., :ref:`chaining_aws_cni`), set the 99 Helm option ``cni.enableRouteMTUForCNIChaining`` to ``true`` to force Cilium 100 to set a correct MTU for Pods. Otherwise, Pod traffic encrypted with 101 WireGuard might get fragmented, which can lead to a network performance 102 degradation. 103 104 105 Validate the Setup 106 ================== 107 108 Run a ``bash`` shell in one of the Cilium pods with 109 ``kubectl -n kube-system exec -ti ds/cilium -- bash`` and execute the following 110 commands: 111 112 1. Check that WireGuard has been enabled (number of peers should correspond to 113 a number of nodes subtracted by one): 114 115 .. code-block:: shell-session 116 117 cilium-dbg status | grep Encryption 118 119 Encryption: Wireguard [cilium_wg0 (Pubkey: <..>, Port: 51871, Peers: 2)] 120 121 2. Install tcpdump 122 123 .. code-block:: shell-session 124 125 apt-get update 126 apt-get -y install tcpdump 127 128 3. Check that traffic is sent via the ``cilium_wg0`` tunnel device: 129 130 .. code-block:: shell-session 131 132 tcpdump -n -i cilium_wg0 133 134 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode 135 listening on cilium_wg0, link-type RAW (Raw IP), capture size 262144 bytes 136 15:05:24.643427 IP 10.244.1.35.51116 > 10.244.3.78.8080: Flags [S], seq 476474887, win 64860, options [mss 1410,sackOK,TS val 648097391 ecr 0,nop,wscale 7], length 0 137 15:05:24.644185 IP 10.244.3.78.8080 > 10.244.1.35.51116: Flags [S.], seq 4032860634, ack 476474888, win 64308, options [mss 1410,sackOK,TS val 4004186138 ecr 648097391,nop,wscale 7], length 0 138 15:05:24.644238 IP 10.244.1.35.51116 > 10.244.3.78.8080: Flags [.], ack 1, win 507, options [nop,nop,TS val 648097391 ecr 4004186138], length 0 139 15:05:24.644277 IP 10.244.1.35.51116 > 10.244.3.78.8080: Flags [P.], seq 1:81, ack 1, win 507, options [nop,nop,TS val 648097392 ecr 4004186138], length 80: HTTP: GET / HTTP/1.1 140 15:05:24.644370 IP 10.244.3.78.8080 > 10.244.1.35.51116: Flags [.], ack 81, win 502, options [nop,nop,TS val 4004186139 ecr 648097392], length 0 141 15:05:24.645536 IP 10.244.3.78.8080 > 10.244.1.35.51116: Flags [.], seq 1:1369, ack 81, win 502, options [nop,nop,TS val 4004186140 ecr 648097392], length 1368: HTTP: HTTP/1.1 200 OK 142 15:05:24.645569 IP 10.244.1.35.51116 > 10.244.3.78.8080: Flags [.], ack 1369, win 502, options [nop,nop,TS val 648097393 ecr 4004186140], length 0 143 15:05:24.645578 IP 10.244.3.78.8080 > 10.244.1.35.51116: Flags [P.], seq 1369:2422, ack 81, win 502, options [nop,nop,TS val 4004186140 ecr 648097392], length 1053: HTTP 144 15:05:24.645644 IP 10.244.1.35.51116 > 10.244.3.78.8080: Flags [.], ack 2422, win 494, options [nop,nop,TS val 648097393 ecr 4004186140], length 0 145 15:05:24.645752 IP 10.244.1.35.51116 > 10.244.3.78.8080: Flags [F.], seq 81, ack 2422, win 502, options [nop,nop,TS val 648097393 ecr 4004186140], length 0 146 15:05:24.646431 IP 10.244.3.78.8080 > 10.244.1.35.51116: Flags [F.], seq 2422, ack 82, win 502, options [nop,nop,TS val 4004186141 ecr 648097393], length 0 147 15:05:24.646484 IP 10.244.1.35.51116 > 10.244.3.78.8080: Flags [.], ack 2423, win 502, options [nop,nop,TS val 648097394 ecr 4004186141], length 0 148 149 Troubleshooting 150 =============== 151 152 When troubleshooting dropped or unencrypted packets between pods, the following 153 commands can be helpful: 154 155 .. code-block:: shell-session 156 157 # From node A: 158 cilium-dbg debuginfo --output json | jq .encryption 159 { 160 "wireguard": { 161 "interfaces": [ 162 { 163 "listen-port": 51871, 164 "name": "cilium_wg0", 165 "peer-count": 1, 166 "peers": [ 167 { 168 "allowed-ips": [ 169 "10.154.1.107/32", 170 "10.154.1.195/32" 171 ], 172 "endpoint": "192.168.61.12:51871", 173 "last-handshake-time": "2021-05-05T12:31:24.418Z", 174 "public-key": "RcYfs/GEkcnnv6moK5A1pKnd+YYUue21jO9I08Bv0zo=" 175 } 176 ], 177 "public-key": "DrAc2EloK45yqAcjhxerQKwoYUbLDjyrWgt9UXImbEY=" 178 } 179 ] 180 } 181 } 182 # From node B: 183 cilium-dbg debuginfo --output json | jq .encryption 184 { 185 "wireguard": { 186 "interfaces": [ 187 { 188 "listen-port": 51871, 189 "name": "cilium_wg0", 190 "peer-count": 1, 191 "peers": [ 192 { 193 "allowed-ips": [ 194 "10.154.2.103/32", 195 "10.154.2.142/32" 196 ], 197 "endpoint": "192.168.61.11:51871", 198 "last-handshake-time": "2021-05-05T12:31:24.631Z", 199 "public-key": "DrAc2EloK45yqAcjhxerQKwoYUbLDjyrWgt9UXImbEY=" 200 } 201 ], 202 "public-key": "RcYfs/GEkcnnv6moK5A1pKnd+YYUue21jO9I08Bv0zo=" 203 } 204 ] 205 } 206 } 207 208 For pod to pod packets to be successfully encrypted and decrypted, the following 209 must hold: 210 211 - WireGuard public key of a remote node in the ``peers[*].public-key`` section 212 matches the actual public key of the remote node (``public-key`` retrieved via 213 the same command on the remote node). 214 - ``peers[*].allowed-ips`` should contain a list of pod IP addresses running 215 on the remote. 216 217 Cluster Mesh 218 ============ 219 220 WireGuard enabled Cilium clusters can be connected via :ref:`Cluster Mesh`. The 221 ``clustermesh-apiserver`` will forward the necessary WireGuard public keys 222 automatically to remote clusters. 223 In such a setup, it is important to note that all participating clusters must 224 have WireGuard encryption enabled, i.e. mixed mode is currently not supported. 225 In addition, UDP traffic between nodes of different clusters on port ``51871`` 226 must be allowed. 227 228 .. _node-node-wg: 229 230 Node-to-Node Encryption (beta) 231 ============================== 232 233 By default, WireGuard-based encryption only encrypts traffic between Cilium-managed 234 pods. To enable node-to-node encryption, which additionally also encrypts 235 node-to-node, pod-to-node and node-to-pod traffic, use the following configuration 236 options: 237 238 .. tabs:: 239 240 .. group-tab:: Cilium CLI 241 242 If you are deploying Cilium with the Cilium CLI, pass the following 243 options: 244 245 .. parsed-literal:: 246 247 cilium install |CHART_VERSION| \ 248 --set encryption.enabled=true \ 249 --set encryption.type=wireguard \ 250 --set encryption.nodeEncryption=true 251 252 .. group-tab:: Helm 253 254 If you are deploying Cilium with Helm by following 255 :ref:`k8s_install_helm`, pass the following options: 256 257 .. parsed-literal:: 258 259 helm install cilium |CHART_RELEASE| \\ 260 --namespace kube-system \\ 261 --set encryption.enabled=true \\ 262 --set encryption.type=wireguard \\ 263 --set encryption.nodeEncryption=true 264 265 .. warning:: 266 267 Cilium automatically disables node-to-node encryption from and to 268 Kubernetes control-plane nodes, i.e. any node with the 269 ``node-role.kubernetes.io/control-plane`` label will opt-out of node-to-node 270 encryption. 271 272 This is done to ensure worker nodes are always able to communicate with the 273 Kubernetes API to update their WireGuard public keys. With node-to-node 274 encryption enabled, the connection to the kube-apiserver would also be 275 encrypted with WireGuard. This creates a bootstrapping problem where the 276 connection used to update the WireGuard public key is itself encrypted with 277 the public key about to be replaced. 278 This is problematic if a node needs to change its public key, for example 279 because it generated a new private key after a node reboot or node 280 re-provisioning. 281 282 Therefore, by not encrypting the connection from and to the kube-apiserver 283 host network with WireGuard, we ensure that worker nodes are 284 never accidentally locked out from the control plane. Note that even if 285 WireGuard node-to-node encryption is disabled on those nodes, the Kubernetes 286 control-plane itself is usually still encrypted by Kubernetes itself using 287 mTLS and that pod-to-pod traffic for any Cilium-manged pods on the 288 control-plane nodes are also still encrypted via Cilium's WireGuard 289 implementation. 290 291 The label selector for matching the control-plane nodes which shall not 292 participate in node-to-node encryption can be configured using the 293 ``node-encryption-opt-out-labels`` ConfigMap option. It defaults to 294 ``node-role.kubernetes.io/control-plane``. 295 You may force node-to-node encryption from and to control-plane nodes by 296 using an empty label selector with that option. Note that doing so is not 297 recommended, as it will require you to always manually update a node's public 298 key in its corresponding ``CiliumNode`` CRD when a worker node's public key 299 changes, given that the worker node will be unable to do so itself. 300 301 N/S load balancer traffic isn't encrypted when an intermediate node redirects 302 a request to a different node with the following load balancer configuration: 303 304 - LoadBalancer & NodePort XDP Acceleration 305 - Direct Server Return (DSR) in non-Geneve dispatch mode 306 307 Egress Gateway replies are not encrypted when XDP Acceleration is enabled. 308 309 Which traffic is encrypted 310 ========================== 311 312 The following table denotes which packets are encrypted with WireGuard depending 313 on the mode. Configurations or communication pairs not present in the following 314 table are not subject to encryption with WireGuard and therefore assumed to be unencrypted. 315 316 +----------------+-------------------+----------------------+-----------------+ 317 | Origin | Destination | Configuration | Encryption mode | 318 +================+===================+======================+=================+ 319 | Pod | remote Pod | any | default | 320 +----------------+-------------------+----------------------+-----------------+ 321 | Pod | remote Node | any | node-to-node | 322 +----------------+-------------------+----------------------+-----------------+ 323 | Node | remote Pod | any | node-to-node | 324 +----------------+-------------------+----------------------+-----------------+ 325 | Node | remote Node | any | node-to-node | 326 +----------------+-------------------+----------------------+-----------------+ 327 | **Services** | 328 +----------------+-------------------+----------------------+-----------------+ 329 | Pod | remote Pod via | any | default | 330 | | ClusterIP Service | | | 331 +----------------+-------------------+----------------------+-----------------+ 332 | Pod | remote Pod via | Socket LB | default | 333 | | non ClusterIP | | | 334 | | Service (e.g., | | | 335 | | NodePort) | | | 336 +----------------+-------------------+----------------------+-----------------+ 337 | Pod | remote Pod via | kube-proxy | node-to-node | 338 | | non ClusterIP | | | 339 | | Service | | | 340 +----------------+-------------------+----------------------+-----------------+ 341 | Client outside | remote Pod via | KPR, | default | 342 | cluster | Service | overlay routing, | | 343 | | | without DSR, | | 344 | | | without XDP | | 345 +----------------+-------------------+----------------------+-----------------+ 346 | Client outside | remote Pod via | native routing, | node-to-node | 347 | cluster | Service | without XDP | | 348 +----------------+-------------------+----------------------+-----------------+ 349 | Client outside | remote Pod or | DSR in Geneve mode, | default | 350 | cluster | remote Node via | without XDP | | 351 | | Service | | | 352 +----------------+-------------------+----------------------+-----------------+ 353 | Pod | remote Pod via L7 | L7 Proxy / Ingress | default | 354 | | Proxy or L7 | | | 355 | | Ingress Service | | | 356 +----------------+-------------------+----------------------+-----------------+ 357 | **Egress Gateway** | 358 +----------------+-------------------+----------------------+-----------------+ 359 | Pod |Egress Gateway node| Egress Gateway | default | 360 +----------------+-------------------+----------------------+-----------------+ 361 | Egress Gateway | Pod | Egress Gateway | default | 362 | node | | without XDP | | 363 +----------------+-------------------+----------------------+-----------------+ 364 365 * **Pod**: Cilium-managed K8s Pod running in non-host network namespace. 366 * **Node**: K8s host running Cilium, or Pod running in host network namespace 367 managed by Cilium. 368 * **Service**: K8s Service (ClusterIP, NodePort, LoadBalancer, ExternalIP). 369 * **Client outside cluster**: Any client which runs outside K8s cluster. 370 Request between client and Node is not encrypted. Depending on Cilium 371 configuration (see the table at the beginning of this section), it might be 372 encrypted only between intermediate Node (which received client request first) 373 and destination Node. 374 375 Legal 376 ===== 377 378 "WireGuard" is a registered trademark of Jason A. Donenfeld.