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.