Shadowsocks прокси в Kubernetes

Опубликовано: 2026-06-02

Tor — медленный. SOCKS5 не шифрует трафик. Shadowsocks — что-то среднее: лёгкий зашифрованный прокси-протокол, трафик которого не отличить от случайного HTTPS-шума. На этом сервере он работает внутри Kubernetes-пода.

Зачем Shadowsocks

Shadowsocks изначально создавался для обхода DPI (deep packet inspection) в Китае. Протокол:

  • оборачивает весь трафик в зашифрованные фреймы AES-256-GCM (или ChaCha20)
  • выглядит как случайные TCP-данные — никакого узнаваемого хэндшейка
  • поддерживает TCP и UDP
  • есть клиенты для всех платформ: Android, iOS, Windows, macOS, Linux

Для личного VPS это значит: трафик между устройством и сервером зашифрован и не распознаётся как прокси.

Kubernetes

Всё работает в отдельном неймспейсе shadowsocks. Пароль хранится в Secret и передаётся как переменная окружения:

yamlapiVersion: v1
kind: Secret
metadata:
  name: ss-auth
  namespace: shadowsocks
stringData:
  password: "ваш-пароль"

В Deployment используется shadowsocks/shadowsocks-libev, флаги передаются как args. TCP и UDP работают на одном порту, поэтому нужно два containerPort:

yamlapiVersion: apps/v1
kind: Deployment
metadata:
  name: shadowsocks
  namespace: shadowsocks
spec:
  replicas: 1
  selector:
    matchLabels:
      app: shadowsocks
  template:
    metadata:
      labels:
        app: shadowsocks
    spec:
      containers:
      - name: ss-server
        image: shadowsocks/shadowsocks-libev:latest
        args:
        - ss-server
        - -s
        - "0.0.0.0"
        - -p
        - "8388"
        - -m
        - aes-256-gcm
        - -k
        - $(SS_PASSWORD)
        - -u           # включить UDP relay
        - --no-delay
        - --reuse-port
        - -v
        ports:
        - containerPort: 8388
          hostPort: 8388
          protocol: TCP
          name: ss-tcp
        - containerPort: 8388
          hostPort: 8388
          protocol: UDP
          name: ss-udp
        env:
        - name: SS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: ss-auth
              key: password
        resources:
          requests:
            cpu: "10m"
            memory: "32Mi"
          limits:
            cpu: "200m"
            memory: "64Mi"

Service с NodePort на обоих протоколах:

yamlapiVersion: v1
kind: Service
metadata:
  name: shadowsocks
  namespace: shadowsocks
spec:
  type: NodePort
  selector:
    app: shadowsocks
  ports:
  - name: ss-tcp
    port: 8388
    targetPort: 8388
    nodePort: 30388
    protocol: TCP
  - name: ss-udp
    port: 8388
    targetPort: 8388
    nodePort: 30388
    protocol: UDP

Флаг -u и UDP relay

Флаг -u включает UDP relay. Без него Shadowsocks проксирует только TCP. DNS-запросы в режиме SOCKS5 обычно идут по UDP — без -u придётся настраивать DNS отдельно. С флагом UDP-пакеты идут через туннель, и DNS просто работает.

Выбор шифра

aes-256-gcm — стандартный вариант, хорошо работает на большинстве железа. На слабых VM без аппаратного AES-NI быстрее chacha20-ietf-poly1305:

bash# проверить поддержку AES-NI
grep -m1 aes /proc/cpuinfo

Если флаг есть — оставляйте aes-256-gcm. Если нет — переключайтесь на chacha20-ietf-poly1305. На слабом VPS без аппаратного AES разница может быть 3–5x при большом потоке.

Настройка клиента

После деплоя подключайтесь любым Shadowsocks-клиентом:

Host:     <ip-вашего-vps>
Port:     30388
Password: <значение из secret>
Method:   aes-256-gcm

На macOS/iOS хорошо работает Shadowrocket. На Android — v2rayNG, поддерживает Shadowsocks нативно. На Linux ss-local из пакета shadowsocks-libev поднимает локальный SOCKS5:

bashss-local -s <vps-ip> -p 30388 -m aes-256-gcm -k <пароль> -l 1080
# теперь прокси — 127.0.0.1:1080
curl --socks5 127.0.0.1:1080 https://ifconfig.me

Скрипт установки

k0s-setup/20-setup-shadowsocks.sh генерирует случайный пароль, если он не задан, создаёт неймспейс, Secret, Deployment и в конце выводит параметры подключения:

bashSS_PORT=30388 SS_METHOD=aes-256-gcm ssh root@server 'bash -s' < k0s-setup/20-setup-shadowsocks.sh

Скрипт автоматически определяет публичный IP и печатает готовый конфиг.

Файрволл

NodePort открывает порт через iptables kube-proxy, но файрволл хоста тоже нужно настроить. На k0s VM с ufw:

bashufw allow 30388/tcp
ufw allow 30388/udp

Без правила для UDP режим ss-local -u молча перестанет работать, и DNS-запросы начнут отваливаться по таймауту.

Потребление ресурсов

В простое shadowsocks-libev занимает ~2 МБ RAM и почти ноль CPU. При активном использовании (1 клиент) CPU не выходит за 10m на shared vCPU. Лимиты в Deployment (200m / 64Mi) — с запасом.


Итого

Параметр Значение
Образ shadowsocks/shadowsocks-libev:latest
Шифр aes-256-gcm
Порт (NodePort) 30388
UDP relay включён (-u)
Хранение пароля Kubernetes Secret
RAM в простое ~2 МБ