- cert-manager ClusterIssuers (LetsEncrypt + homelab-ca) - Longhorn storage dashboard - Portainer dashboard config - Forgejo git service - Claude terminal remote access - Shadowsocks tunnel for remote access
160 lines
5.2 KiB
YAML
160 lines
5.2 KiB
YAML
# k8s/shadowsocks/shadowsocks.yaml
|
|
# Personal Shadowsocks proxy (for Shadowrocket/other SS clients) — an
|
|
# alternative tunnel to the WireGuard setup in cluster-config/, useful when
|
|
# a network blocks/throttles WireGuard but not generic TLS-looking traffic.
|
|
#
|
|
# Everything that varies between deployments (port, password, method) lives
|
|
# in the shadowsocks-config Secret below — the Deployment/Service never
|
|
# hardcode a value, so re-pointing this at a new port or rotating the
|
|
# password is a Secret edit + rollout restart, no YAML edit.
|
|
#
|
|
# Prerequisites:
|
|
# talos put cluster/SHADOWSOCKS_PASSWORD SHADOWSOCKS_PASSWORD="$(openssl rand -base64 24)"
|
|
# talos put cluster/SHADOWSOCKS_PORT SHADOWSOCKS_PORT="8388"
|
|
#
|
|
# Apply:
|
|
# kubectl create namespace vpn --dry-run=client -o yaml | kubectl apply -f -
|
|
# kubectl -n vpn create secret generic shadowsocks-config \
|
|
# --from-literal=SERVER_PORT="$(talos get cluster/SHADOWSOCKS_PORT --key SHADOWSOCKS_PORT)" \
|
|
# --from-literal=PASSWORD="$(talos get cluster/SHADOWSOCKS_PASSWORD --key SHADOWSOCKS_PASSWORD)" \
|
|
# --from-literal=METHOD="aes-256-gcm" \
|
|
# --from-literal=TIMEOUT="300"
|
|
# kubectl apply -f k8s/shadowsocks/shadowsocks.yaml
|
|
#
|
|
# Rotate password (or change port) later:
|
|
# kubectl -n vpn delete secret shadowsocks-config && <recreate with new values>
|
|
# kubectl -n vpn rollout restart deploy/shadowsocks
|
|
#
|
|
# Client config: SERVER_PORT/METHOD/PASSWORD above feed directly into the
|
|
# Shadowrocket/SS client's server, method, and password fields. SERVER_ADDR
|
|
# for the client is the LB IP below (192.168.1.166), or your router's WAN
|
|
# address/DDNS hostname (riotpiao.duckdns.org) with port-forwarding to it —
|
|
# same pattern as the wg1 WireGuard peer in cluster-config/phone_config.conf.
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: vpn
|
|
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: shadowsocks
|
|
namespace: vpn
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: shadowsocks
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: shadowsocks
|
|
spec:
|
|
containers:
|
|
- name: shadowsocks
|
|
image: shadowsocks/shadowsocks-libev:latest
|
|
env:
|
|
- name: SERVER_ADDR
|
|
value: "0.0.0.0"
|
|
- name: SERVER_PORT
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: shadowsocks-config
|
|
key: SERVER_PORT
|
|
- name: PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: shadowsocks-config
|
|
key: PASSWORD
|
|
- name: METHOD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: shadowsocks-config
|
|
key: METHOD
|
|
- name: TIMEOUT
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: shadowsocks-config
|
|
key: TIMEOUT
|
|
# containerPort is informational only (no portRange support for
|
|
# env-driven SERVER_PORT) — the Service below is what actually
|
|
# routes traffic, matched on the same Secret key via downward API
|
|
# isn't available for Service ports, so targetPort uses the literal
|
|
# port name instead; see Service ports comment.
|
|
ports:
|
|
- containerPort: 8388
|
|
protocol: TCP
|
|
- containerPort: 8388
|
|
protocol: UDP
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 128Mi
|
|
|
|
---
|
|
# LoadBalancer via Cilium LB-IPAM (see k8s/cilium/lb-ipam-pool.yaml) — pinned
|
|
# to .166 so router port-forwarding and the DDNS hostname stay stable across
|
|
# pod/service recreates, same pattern forgejo uses at .165.
|
|
#
|
|
# NOTE: SERVER_PORT in the Secret must match port/targetPort/nodePort here.
|
|
# If you change the port, update both the Secret and this Service together.
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: shadowsocks
|
|
namespace: vpn
|
|
annotations:
|
|
io.cilium/lb-ipam-ips: "192.168.1.166"
|
|
spec:
|
|
type: LoadBalancer
|
|
selector:
|
|
app: shadowsocks
|
|
ports:
|
|
- name: tcp
|
|
protocol: TCP
|
|
port: 8388
|
|
targetPort: 8388
|
|
- name: udp
|
|
protocol: UDP
|
|
port: 8388
|
|
targetPort: 8388
|
|
|
|
---
|
|
# Restrict egress like the forgejo-runner pattern (k8s/forge/runner.yaml) —
|
|
# a proxy server is, by design, an open relay to the internet for whoever
|
|
# holds the password; LAN/pod-network egress is blocked so a compromised
|
|
# password can't be used to pivot into the cluster or LAN. CoreDNS is
|
|
# explicitly allowed — shadowsocks-libev resolves client-requested hostnames
|
|
# itself, so blanket-blocking the service subnet would break that.
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: NetworkPolicy
|
|
metadata:
|
|
name: shadowsocks-egress
|
|
namespace: vpn
|
|
spec:
|
|
podSelector:
|
|
matchLabels:
|
|
app: shadowsocks
|
|
policyTypes: [Egress]
|
|
egress:
|
|
- to:
|
|
- namespaceSelector:
|
|
matchLabels:
|
|
kubernetes.io/metadata.name: kube-system
|
|
ports:
|
|
- protocol: UDP
|
|
port: 53
|
|
- protocol: TCP
|
|
port: 53
|
|
- to:
|
|
- ipBlock:
|
|
cidr: 0.0.0.0/0
|
|
except:
|
|
- 192.168.1.0/24
|
|
- 10.244.0.0/16
|
|
- 10.96.0.0/12
|