Skip to content

Commit

Permalink
Merge pull request #69 from glothriel/28-network-policies
Browse files Browse the repository at this point in the history
#28: Initial integration with network policies
  • Loading branch information
glothriel authored Jun 9, 2024
2 parents 7d668f5 + be85307 commit 4a198b4
Show file tree
Hide file tree
Showing 22 changed files with 762 additions and 487 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,40 @@ wormhole.glothriel.github.com/ports=http
wormhole.glothriel.github.com/ports=80,443
```

### Enable creation of network policies

You can secure the services exposed on another end by configuring network policies. Network policies are currently implemented on a per-peer basis, so for example a client may have them enabled and the server may not, or only a subset of clients may have them enabled.

You can enable network policies by setting `--set networkPolicies.enabled=true` helm chart value. Network policies of course in order to work require the cluster that supports them.

When wormhole is deployed with network policies support, each time it exposes a remote service it also creates a matching network policy. The network policy is created in the same namespace as the service and allows filtering of the traffic from other workloads in the cluster to the remote service.

```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
...
spec:
ingress:
- from:
- namespaceSelector: {}
podSelector:
matchLabels:
wormhole.glothriel.github.com/network-policy-consumes-app: <<APP-NAME>>
ports:
- port: 25001
protocol: TCP
podSelector:
matchLabels:
application: wormhole-client-dev1
policyTypes:
- Ingress
```

Such policies allow communication from any pod in any namespace, providing, that the pod that tries to communicate has a label `wormhole.glothriel.github.com/network-policy-consumes-app` with the value of the name of the service that is exposed. The app name (unless override by `wormhole.glothriel.github.com/name=my-custom-name`) is `<service-namespace-name>-<service-name>` (for example `default-nginx`) of the service exposed from remote cluster.

Effectively this means, that the permission to communicate is granted per application, not per peer. Having permission to communicate with app having given name, allows the pod to communicate with all the apps with given name, no matter the peer the app is exposed from. This is especially important in the context of the server, as it may have multiple clients, all exposing the same app.

## Local development

### Development environment
Expand Down Expand Up @@ -133,3 +167,10 @@ cd tests && python setup.py develop && cd -
pytest tests
```

If you are re-running the tests multiple times, you may want to reuse the K3d cluster, you can do this by setting the `REUSE_CLUSTER` environment variable to a truthy value. It will then abstain from removing the cluster after the tests are done and reuse it for the next run.

```
export REUSE_CLUSTER=1
pytest tests
```
2 changes: 2 additions & 0 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ for server in servers:
"docker.image=wormhole-controller",
"docker.wgImage=wormhole-wireguard",
"docker.nginxImage=wormhole-nginx",
"networkPolicies.enabled=true",
"docker.registry=",
"devMode.enabled=true",
]))
Expand All @@ -70,6 +71,7 @@ for client in clients:
"docker.image=wormhole-controller",
"docker.wgImage=wormhole-wireguard",
"docker.nginxImage=wormhole-nginx",
"networkPolicies.enabled=true",
"docker.registry=",
"devMode.enabled=true",
]))
Expand Down
3 changes: 3 additions & 0 deletions kubernetes/helm/templates/client-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ spec:
- --debug
{{- end }}
- client
{{- if .Values.networkPolicies.enabled }}
- --network-policies
{{- end }}
- --name
- {{ .Values.client.name | required "Please set client.name" }}
- --kubernetes
Expand Down
22 changes: 22 additions & 0 deletions kubernetes/helm/templates/client-networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{- if and .Values.client.enabled .Values.networkPolicies.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
application: {{ template "name-client" . }}
name: {{ template "name-client" . }}
namespace: {{ $.Release.Namespace }}
spec:
ingress:
- ports:
# metrics
- port: 8090
protocol: TCP
podSelector:
matchLabels:
application: {{ template "name-client" . }}
policyTypes:
- Ingress

{{ end }}
11 changes: 11 additions & 0 deletions kubernetes/helm/templates/client-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ metadata:
labels:
application: {{ template "name-client" . }}
rules:
# svcs
- apiGroups:
- ""
resources:
Expand All @@ -58,6 +59,16 @@ rules:
- list
- delete
- watch
- apiGroups:
- networking.k8s.io
resources:
- networkpolicies
verbs:
- get
- create
- update
- list
- delete
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
3 changes: 3 additions & 0 deletions kubernetes/helm/templates/server-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ spec:
- --debug
{{- end }}
- server
{{- if .Values.networkPolicies.enabled }}
- --network-policies
{{- end }}
- --name
- {{ .Values.server.name }}
- --kubernetes
Expand Down
28 changes: 28 additions & 0 deletions kubernetes/helm/templates/server-networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{- if and .Values.server.enabled .Values.networkPolicies.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
application: {{ template "name-server" . }}
name: {{ template "name-server" . }}
namespace: {{ $.Release.Namespace }}
spec:
ingress:
- ports:
# metrics
- port: 8090
protocol: TCP
# pairing
- port: 8080
protocol: TCP
# vpn
- port: 51820
protocol: UDP
podSelector:
matchLabels:
application: {{ template "name-server" . }}
policyTypes:
- Ingress

{{ end }}
10 changes: 10 additions & 0 deletions kubernetes/helm/templates/server-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ rules:
- list
- delete
- watch
- apiGroups:
- networking.k8s.io
resources:
- networkpolicies
verbs:
- get
- create
- update
- list
- delete
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
2 changes: 2 additions & 0 deletions kubernetes/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ docker:
peering:
psk: defaultPeeringKeyPleaseChangeMe

networkPolicies:
enabled: false

# Dev mode expects dev image with watchexec + go run instead of binary
devMode:
Expand Down
27 changes: 27 additions & 0 deletions kubernetes/raw/curl/all.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
apiVersion: v1
kind: Pod
metadata:
name: curl-with-labels
namespace: default
labels:
wormhole.glothriel.github.com/network-policy-consumes-app: nginx-nginx
spec:
terminationGracePeriodSeconds: 1
containers:
- name: curl-container
image: curlimages/curl
command: ["sleep", "999999"]

---
apiVersion: v1
kind: Pod
metadata:
name: curl-no-labels
namespace: default
spec:
terminationGracePeriodSeconds: 1
containers:
- name: curl-container
image: curlimages/curl
command: ["sleep", "999999"]
2 changes: 2 additions & 0 deletions pkg/cmd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var clientCommand *cli.Command = &cli.Command{
kubernetesNamespaceFlag,
kubernetesLabelsFlag,
peerNameFlag,
enableNetworkPoliciesFlag,
helloRetryIntervalFlag,
nginxExposerConfdPathFlag,
wireguardConfigFilePathFlag,
Expand Down Expand Up @@ -67,6 +68,7 @@ var clientCommand *cli.Command = &cli.Command{
effectiveExposer = k8s.NewK8sExposer(
c.String(kubernetesNamespaceFlag.Name),
k8s.CSVToMap(c.String(kubernetesLabelsFlag.Name)),
c.Bool(enableNetworkPoliciesFlag.Name),
remoteNginxExposer,
)
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,9 @@ var peerNameFlag *cli.StringFlag = &cli.StringFlag{
Name: "name",
Required: true,
}

var enableNetworkPoliciesFlag *cli.BoolFlag = &cli.BoolFlag{
Name: "network-policies",
Usage: "Enables dynamic creation of network policies for proxy services",
Value: false,
}
2 changes: 2 additions & 0 deletions pkg/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ var serverCommand *cli.Command = &cli.Command{
intServerListenPort,
kubernetesNamespaceFlag,
kubernetesLabelsFlag,
enableNetworkPoliciesFlag,
peerStorageDBFlag,
peerNameFlag,
wgAddressFlag,
Expand Down Expand Up @@ -106,6 +107,7 @@ var serverCommand *cli.Command = &cli.Command{
effectiveExposer = k8s.NewK8sExposer(
c.String(kubernetesNamespaceFlag.Name),
k8s.CSVToMap(c.String(kubernetesLabelsFlag.Name)),
c.Bool(enableNetworkPoliciesFlag.Name),
remoteNginxExposer,
)
}
Expand Down
Loading

0 comments on commit 4a198b4

Please sign in to comment.