Skip to content

Commit

Permalink
daemon: Encrypt NodePort BPF traffic with WireGuard
Browse files Browse the repository at this point in the history
This commit attaches the bpf_host's "from-netdev" section to the
Cilium's WireGuard tunnel netdev ("cilium_wg0").

This is needed to enable the encryption of the KPR traffic. In
particular, we encrypt the N/S KPR requests which will be forwarded to
a remote node running a selected service endpoint.

IMPORTANT: this encrypts KPR traffic only when running in the
non-tunneling mode.

For the request path no changes are required. The existing datapath
configuration already handles it, as shown in the following:

1. The "from-netdev" attached to eth0 is invoked for the NodePort
   request.
2. A remote service endpoint is selected, the DNAT and SNAT translations
   are performed.
3. The translated request is redirected to eth0.
4. The "to-netdev" section on eth0 is invoked. It detects that the
   packet needs to encrypted, so it redirects to the cilium_wg0.

For the reply path a minimal changes were required. After the WG netdev
has decrypted the reply packet, the packet is returned to the networking
stack. Because the networking stack is not aware of the connection, the
reply packet is dropped. To avoid that, we attach the "from-netdev"
section to the WG netdev, so that the following can be performed:

1. Reverse SNAT and DNAT translations are applied to the reply.
2. The reply packet is redirected to the outgoing interface.

Signed-off-by: Sebastian Wicki <sebastian@isovalent.com>
Signed-off-by: Martynas Pumputis <m@lambda.lt>
  • Loading branch information
brb authored and gandro committed May 3, 2022
1 parent b069567 commit 1ee8cd2
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
13 changes: 13 additions & 0 deletions daemon/cmd/kube_proxy_replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/cilium/cilium/pkg/option"
"github.com/cilium/cilium/pkg/probe"
"github.com/cilium/cilium/pkg/sysctl"
wgTypes "github.com/cilium/cilium/pkg/wireguard/types"
)

// initKubeProxyReplacementOptions will grok the global config and determine
Expand Down Expand Up @@ -531,6 +532,18 @@ func finishKubeProxyReplacementInit(isKubeProxyReplacementStrict bool) error {
// | After this point, BPF NodePort should not be disabled |
// +-------------------------------------------------------+

// When WG & encrypt-node are on, a NodePort BPF to-be forwarded request
// to a remote node running a selected service endpoint must be encrypted.
// To make the NodePort's rev-{S,D}NAT translations to happen for a reply
// from the remote node, we need to attach bpf_host to the Cilium's WG
// netdev (otherwise, the WG netdev after decrypting the reply will pass
// it to the stack which drops the packet).
if option.Config.EnableNodePort &&
option.Config.EnableWireguard && option.Config.EncryptNode {

option.Config.Devices = append(option.Config.Devices, wgTypes.IfaceName)
}

// For MKE, we only need to change/extend the socket LB behavior in case
// of kube-proxy replacement. Otherwise, nothing else is needed.
if option.Config.EnableMKE && option.Config.EnableHostReachableServices {
Expand Down
10 changes: 8 additions & 2 deletions pkg/datapath/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/cilium/cilium/pkg/maps/callsmap"
"github.com/cilium/cilium/pkg/node"
"github.com/cilium/cilium/pkg/option"
wgTypes "github.com/cilium/cilium/pkg/wireguard/types"
)

const (
Expand Down Expand Up @@ -238,8 +239,13 @@ func (l *Loader) reloadHostDatapath(ctx context.Context, ep datapath.Endpoint, o
interfaceNames = append(interfaceNames, device)
symbols = append(symbols, symbolFromHostNetdevEp)
directions = append(directions, dirIngress)
if option.Config.EnableNodePort || option.Config.EnableHostFirewall ||
option.Config.EnableBandwidthManager || option.Config.EnableWireguard {
if (option.Config.EnableNodePort || option.Config.EnableHostFirewall ||
option.Config.EnableBandwidthManager || option.Config.EnableWireguard) &&
// Attaching bpf_host to cilium_wg0 is required for encrypting KPR
// traffic. Only ingress prog (aka "from-netdev") is needed to handle
// the rev-NAT xlations.
device != wgTypes.IfaceName {

interfaceNames = append(interfaceNames, device)
symbols = append(symbols, symbolToHostNetdevEp)
directions = append(directions, dirEgress)
Expand Down

0 comments on commit 1ee8cd2

Please sign in to comment.