k8s/aux: add cert-manager longhorn dashboard forge dev-tools and shadowsocks
- cert-manager ClusterIssuers (LetsEncrypt + homelab-ca) - Longhorn storage dashboard - Portainer dashboard config - Forgejo git service - Claude terminal remote access - Shadowsocks tunnel for remote access
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user