Инструкция поднимает связку dnstt-server + SOCKS5-backend в podman-контейнерах через quadlet.
На клиенте вы запускаете dnstt-client и получаете локальный TCP-порт, который работает как вход в удалённый SOCKS5-прокси.
Везде, где указано
example.com, подставьте свой домен.
- Требования и проверки перед стартом
- Подготовка окружения
- Системные настройки и сервисы
- Запуск и проверка
- Подключение клиента
- Автообновление контейнеров
- Практические замечания
- VPS с белым IPv4 и доступом по SSH.
- Домен, у которого вы можете создавать
A, иNSзаписи. - Возможность опубликовать
53/udpименно на публичном IP VPS. - На VPS установлены:
podmanверсии>= 4.4systemdверсии>= 244
-
Убедитесь, что
53/udpсейчас не опубликован на публичном IP VPS:ss -ulpn | grep '<public_ipv4>:53\b'
-
Проверьте версии:
podman --version systemctl --version
- Создайте записи:
Atns.example.com->IPv4_вашего_VPSNSt.example.com->tns.example.com
Метки
tnsиtможно заменить на свои, ноtлучше держать короткой, аtnsне должен быть поддоменомt. Например,tns.example.comиt.example.comподходят, аns.t.example.comуже плохой вариант.
mkdir -p /etc/containers/systemd# /etc/containers/systemd/main.pod
[Unit]
After=network-online.target
[Pod]
PublishPort=<public_ipv4>:53:53/udp
[Install]
WantedBy=default.targetНе используйте
0.0.0.0:53:53/udpв этом сценарии. Порт DNS лучше публиковать только на внешнем адресе VPS, чтобы не раздавать его на всех интерфейсах хоста.
# /etc/containers/systemd/dnstt.container
[Unit]
PartOf=main-pod.service
[Container]
Environment=DNS_ZONE=t.example.com
Image=ghcr.io/ergolyam/dnstt-docker:latest
AutoUpdate=registry
Pod=main.pod
Volume=dnstt:/data
[Service]
Restart=always
SuccessExitStatus=2# /etc/containers/systemd/socks.container
[Unit]
PartOf=main-pod.service
[Container]
Environment=LISTEN_ADDRESS=127.0.0.1
Image=ghcr.io/ergolyam/hev-socks5-server-docker:latest
AutoUpdate=registry
Pod=main.pod
[Service]
Restart=alwaysЕсли нужен логин и пароль на SOCKS5, смотрите раздел Практические замечания.
systemctl daemon-reload
systemctl start main-pod.service
systemctl status dnstt.service --no-pager
systemctl status socks.service --no-pager- Проверьте, что порт
53/udpопубликован именно на внешнем IP:ss -ulpn | grep '<public_ipv4>:53\b'
- Этот ключ понадобится на клиенте.
podman exec -it systemd-dnstt cat /data/server.pub
ARCH=$(uname -m); ARCH=${ARCH/x86_64/amd64}; ARCH=${ARCH/aarch64/arm64}
wget -O ${PREFIX:-$HOME/.local}/bin/dnstt-client "https://dnstt.network/dnstt-client-linux-${ARCH}"
chmod +x ${PREFIX:-$HOME/.local}/bin/dnstt-client-
DoH:
dnstt-client -doh https://1.1.1.1/dns-query -pubkey <PUBLIC_KEY_HEX> -utls random t.example.com 127.0.0.1:2080
-
DoT:
dnstt-client -dot 1.1.1.1:853 -pubkey <PUBLIC_KEY_HEX> -utls random t.example.com 127.0.0.1:2080
-
UDP DNS:
dnstt-client -udp 1.1.1.1:53 -pubkey <PUBLIC_KEY_HEX> -utls random t.example.com 127.0.0.1:2080
Plain UDP DNS легче детектируется и фильтруется, но именно он чаще остаётся доступным в ограниченных сетях. Для постоянного использования лучше оставаться на
DoHилиDoT.
- После запуска клиента проверьте, что локальный SOCKS5 действительно работает:
curl --socks5-hostname 127.0.0.1:2080 --connect-timeout 10 https://ifconfig.me
Если всё собрано правильно, команда вернёт внешний IP вашего VPS.
- В quadlet уже задано:
[Container] AutoUpdate=registry
Это позволяет
dnsttиsocksавтоматически подтягивать новые образы и перезапускаться черезpodman-auto-update.
systemctl enable --now podman-auto-update.timersystemctl status podman-auto-update.timer --no-pager
systemctl list-timers | grep podman-auto-updatednsttаутентифицирует сервер, но не аутентифицирует клиента. Если кто-то знает ваш публичный ключ и имя зоны, он теоретически сможет пользоваться туннелем.- В этом сценарии
53/udpлучше публиковать адресно, например<public_ipv4>:53:53/udp, а не на0.0.0.0. Это снижает риск случайно открыть DNS-сервис на лишних интерфейсах. - Если хотите закрыть SOCKS5 логином и паролем, добавьте в сервис
socksпеременные окружения:[Container] Environment=AUTH_ENABLED=true Environment=PROXY_USER=myuser Environment=PROXY_PASSWORD=mypassword
- Тогда проверка на клиенте будет выглядеть так:
curl --socks5-hostname 127.0.0.1:2080 --proxy-user myuser:mypassword https://ifconfig.me
- Чем короче зона туннеля, тем больше полезной нагрузки помещается в DNS-запрос. Поэтому
t.example.comлучше, чем что-то длинное вродеtunnel-dns.example.com.