From dd0f664324f17ad3c7f5699214a2d16ad5b287d6 Mon Sep 17 00:00:00 2001 From: Aleksandr Bogomiakov Date: Thu, 15 Oct 2026 10:58:52 +0100 Subject: [PATCH] Add Shadowsocks deployment on spb with Vaultwarden credentials --- k8s-ng/apps/shadowsocks/README.md | 18 +++++ k8s-ng/apps/shadowsocks/deployment.yaml | 71 +++++++++++++++++++ k8s-ng/apps/shadowsocks/external-secrets.yaml | 29 ++++++++ k8s-ng/apps/shadowsocks/kustomization.yaml | 6 ++ k8s-ng/core-state/values.yaml | 6 ++ 5 files changed, 130 insertions(+) create mode 100644 k8s-ng/apps/shadowsocks/README.md create mode 100644 k8s-ng/apps/shadowsocks/deployment.yaml create mode 100644 k8s-ng/apps/shadowsocks/external-secrets.yaml create mode 100644 k8s-ng/apps/shadowsocks/kustomization.yaml diff --git a/k8s-ng/apps/shadowsocks/README.md b/k8s-ng/apps/shadowsocks/README.md new file mode 100644 index 0000000..7194cec --- /dev/null +++ b/k8s-ng/apps/shadowsocks/README.md @@ -0,0 +1,18 @@ +# Shadowsocks on spb + +One shadowsocks-rust pod runs on `spb`, exposing `8388/TCP` and `8388/UDP` +through host ports. Client settings: + +- Server: `spb.hexor.cy` +- Port: `8388` +- Method: `chacha20-ietf-poly1305` +- Password: the `Password` custom field of the Vaultwarden item named + `k8s/shadowsocks/secrets` (exact name, not an item UUID). + +Create that item in the server secrets vault accessible to the External Secrets +bot. Use a long random password, for example generated with `openssl rand -base64 32`. +External Secrets creates `shadowsocks-config`; Reloader restarts the deployment +when the Secret changes. No persistent storage is required. + +The spb NixOS configuration opens port 8388 for both protocols. Apply that +configuration when deploying this application for the first time. diff --git a/k8s-ng/apps/shadowsocks/deployment.yaml b/k8s-ng/apps/shadowsocks/deployment.yaml new file mode 100644 index 0000000..b4bde4c --- /dev/null +++ b/k8s-ng/apps/shadowsocks/deployment.yaml @@ -0,0 +1,71 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shadowsocks + annotations: + reloader.stakater.com/auto: "true" + labels: + app: shadowsocks +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: shadowsocks + template: + metadata: + labels: + app: shadowsocks + spec: + nodeSelector: + kubernetes.io/hostname: spb + automountServiceAccountToken: false + securityContext: + runAsNonRoot: true + runAsUser: 65534 + runAsGroup: 65534 + seccompProfile: + type: RuntimeDefault + containers: + - name: shadowsocks + # shadowsocks-rust v1.25.0; multi-arch image includes linux/arm64. + image: ghcr.io/shadowsocks/ssserver-rust:v1.25.0@sha256:22240c07d8ce3a36421ede770bd775dcc5fc56d5d829943196957b05452dc36f + imagePullPolicy: IfNotPresent + command: ["/usr/bin/ssserver"] + args: + - --log-without-time + - -c + - /etc/shadowsocks-rust/config.json + ports: + - name: proxy-tcp + containerPort: 8388 + hostPort: 8388 + protocol: TCP + - name: proxy-udp + containerPort: 8388 + hostPort: 8388 + protocol: UDP + readinessProbe: + tcpSocket: + port: proxy-tcp + resources: + requests: + cpu: 50m + memory: 32Mi + limits: + memory: 256Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + volumeMounts: + - name: config + mountPath: /etc/shadowsocks-rust + readOnly: true + volumes: + - name: config + secret: + secretName: shadowsocks-config + defaultMode: 0444 diff --git a/k8s-ng/apps/shadowsocks/external-secrets.yaml b/k8s-ng/apps/shadowsocks/external-secrets.yaml new file mode 100644 index 0000000..86be2de --- /dev/null +++ b/k8s-ng/apps/shadowsocks/external-secrets.yaml @@ -0,0 +1,29 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: shadowsocks-config +spec: + refreshInterval: 1h + secretStoreRef: + name: vaultwarden-fields + kind: ClusterSecretStore + target: + name: shadowsocks-config + creationPolicy: Owner + deletionPolicy: Retain + template: + type: Opaque + data: + config.json: | + { + "server": "0.0.0.0", + "server_port": 8388, + "method": "chacha20-ietf-poly1305", + "password": {{ .password | toJson }}, + "mode": "tcp_and_udp" + } + data: + - secretKey: password + remoteRef: + key: k8s/shadowsocks/secrets + property: Password diff --git a/k8s-ng/apps/shadowsocks/kustomization.yaml b/k8s-ng/apps/shadowsocks/kustomization.yaml new file mode 100644 index 0000000..9579c60 --- /dev/null +++ b/k8s-ng/apps/shadowsocks/kustomization.yaml @@ -0,0 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: shadowsocks +resources: + - external-secrets.yaml + - deployment.yaml diff --git a/k8s-ng/core-state/values.yaml b/k8s-ng/core-state/values.yaml index 027c327..a79b19a 100644 --- a/k8s-ng/core-state/values.yaml +++ b/k8s-ng/core-state/values.yaml @@ -114,3 +114,9 @@ apps: namespace: rustdesk wave: 6 skipDryRunOnMissingResource: true + - name: shadowsocks + project: apps + path: k8s-ng/apps/shadowsocks + namespace: shadowsocks + wave: 6 + skipDryRunOnMissingResource: true