Skip to content

Commit

Permalink
fixup! dev-docs: full L3 connectivity in VPN chart
Browse files Browse the repository at this point in the history
  • Loading branch information
burgerdev committed Jan 5, 2024
1 parent ac5466b commit efc297a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
13 changes: 8 additions & 5 deletions dev-docs/howto/vpn/helm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ This Helm chart deploys a VPN server to your Constellation cluster.

## Setup

1. Configure Constellation's Cilium for the VPN.
* Add all on-prem CIDRs to the `nonMasqueradeCIDRs` in the `ip-masq-agent` ConfigMap. See
<https://docs.cilium.io/en/stable/network/concepts/masquerading/#ebpf-based>
for more background information.
* TODO: explain how to enable `enable-sctp`
1. Configure Cilium to route services for the VPN (see [Architecture](#architecture) for details).
* Edit the Cilium config: `kubectl -n kube-system edit configmap cilium-config`.
* Set the config item `enable-sctp: "true"`.
* Restart the Cilium agents: `kubectl -n kube-system rollout restart daemonset/cilium`.

2. Create the Constellation VPN configuration file.

Expand Down Expand Up @@ -75,6 +74,10 @@ A VPN operator deployment is added that configures the `CiliumEndpoint` with
on-prem IP ranges, thus configuring routes on non-frontend hosts. The endpoint
shares the frontend pod's lifecycle.

In Cilium's default configuration, service endpoints are resolved in cgroup
eBPF hooks that are not applicable to VPN traffic. We force Cilium to apply
service NAT at the LXC interface by enabling SCTP support.

## Limitations

* VPN traffic is handled by a single pod, which may become a bottleneck.
Expand Down
31 changes: 29 additions & 2 deletions dev-docs/howto/vpn/helm/files/routing/operator.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#!/bin/sh

# TODO: this needs to be determined from Helm values!
vpn_frontend=vpn-frontend-0

all_ips() {
kubectl get pods vpn-frontend-0 -o go-template --template '{{ range .status.podIPs }}{{ printf "%s " .ip }}{{ end }}'
kubectl get pods "${vpn_frontend}" -o go-template --template '{{ range .status.podIPs }}{{ printf "%s " .ip }}{{ end }}'
echo "${VPN_PEER_CIDRS}"
}

Expand All @@ -11,7 +14,31 @@ cep_patch() {
echo '}]'
}

# Format the space-separated CIDRs into a JSON array.
vpn_cidrs=$(for ip in ${VPN_PEER_CIDRS}; do printf '"%s" ' "${ip}"; done | jq -s -c -j)

masq_patch() {
kubectl -n kube-system get configmap ip-masq-agent -o json | \
jq -r .data.config | \
jq "{ masqLinkLocal: .masqLinkLocal, nonMasqueradeCIDRs: ((.nonMasqueradeCIDRs - ${vpn_cidrs}) + ${vpn_cidrs}) }" | \
jq '@json | [{op: "replace", path: "/data/config", value: . }]'
}

reconcile_masq() {
if ! kubectl -n kube-system get configmap ip-masq-agent >/dev/null; then
# We don't know enough to create an ip-masq-agent.
return 0
fi

kubectl -n kube-system patch configmap ip-masq-agent --type json --patch "$(masq_patch)" > /dev/null
}

while true; do
kubectl patch ciliumendpoint vpn-frontend-0 --type json --patch "$(cep_patch)" > /dev/null
# Reconcile CiliumEndpoint to advertise VPN CIDRs.
kubectl patch ciliumendpoint "${vpn_frontend}" --type json --patch "$(cep_patch)" > /dev/null

# Reconcile ip-masq-agent configuration to exclude VPN traffic.
reconcile_masq

sleep 10
done
10 changes: 7 additions & 3 deletions dev-docs/howto/vpn/helm/templates/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@ metadata:
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
kind: ClusterRole
metadata:
name: {{ include "..fullname" . }}
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "patch"]
- apiGroups: ["cilium.io"]
resources: ["ciliumendpoints"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
kind: ClusterRoleBinding
metadata:
name: {{ include "..fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ include "..fullname" . }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
kind: ClusterRole
name: {{ include "..fullname" . }}
apiGroup: rbac.authorization.k8s.io

0 comments on commit efc297a

Please sign in to comment.