Files

16 KiB
Raw Permalink Blame History

ru1 — 85.198.109.86 (RU entry node)

VPN entry-нода в РФ. Точка входа в топологии RU↔DE: умный роутинг (RU-трафик → напрямую, зарубежный → туннель AWG до de1). Полный runbook — ~/README.md на сервере. Секреты (WEB-proxy secret в /etc/tproxy-server/profiles.json и /etc/mtproxy/mtproxy.env, token.key, ключи WG) — только на сервере, не здесь.

Провайдер: VDSina · РФ ОС: Ubuntu 24.04.3 LTS · kernel 6.8.0-78 Ресурсы: 1 vCPU / 1.9 GB RAM / 50 GB (swap 2 GB) — маленькая нода hostname: v2911854.hosted-by-vdsina.ru

Доступ

  • ssh mik@85.198.109.86 (пользователь mik, вход по ключу), passwordless sudo.
  • Ключи в ~mik/.ssh/authorized_keys (по комментарию, сверено 2026-09-23): mikpokrovskij@gmail.com, iluha_proxy, iluha_rabobot@ruzzy.dev, openclaw@ruzzy, claude-bot@ruzzy.dev (добавлен 2026-09-23, SHA256:mNK/9jiwypqVHj8oOnKUcr1mqt39z4cVrWWsxxbKP+o; бэкап прежнего файла — authorized_keys.bak-20260923). ⚠️ У mik passwordless sudo, поэтому любой из этих ключей даёт root. Отдельного пользователя под ботов нет.

Интерфейсы

  • ens3 — публичный 85.198.109.86/24 (RU интернет, default route via 85.198.109.1)
  • tun0 — OpenVPN #1 (умный роутинг) 192.168.255.1/24
  • tun1 — OpenVPN #2 (RU-выход) 192.168.254.1/24
  • wg0 — AmneziaWG туннель 10.8.1.4/32 → с 2026-06-21 endpoint переключён на fr1 (161.97.93.252:36360) (был de1). Ключи/PSK те же, менялся только Endpoint в /etc/amnezia/amneziawg/wg0.conf. Откат: вернуть IP на 213.136.74.247.
  • wg1 — WireGuard для клиентов 10.8.2.1/24

Сервисы и порты

Сервис Порт Описание
OpenVPN #1 1194/udp (tun0) умный роутинг: RU→ens3, зарубеж→wg0→de1. Cfg /etc/openvpn/server/openvpn.conf
OpenVPN #2 1195/udp (tun1) RU-выход (весь трафик через ens3, DNS Yandex). Cfg /etc/openvpn/server/ruopenvpn.conf
AmneziaWG wg0 (awg, 45451/udp) туннель до de1 (exit). awg-quick@wg0, cfg /etc/amnezia/amneziawg/wg0.conf, Table=off
WireGuard wg1 51820/udp VPN для клиентов (Docker linuxserver/wireguard), подсеть 10.8.2.0/24, ~/wireguard/
WEB-прокси Telegram 443 (через nginx) tproxy-server (relay, systemd, 127.0.0.1:8090, admin :8091) → официальный MTProxy (systemd, 2398, stats 8888, оба закрыты nftables для не-lo). Подробно — раздел ниже
nginx 80, 443 фронт ru.ruzzy.dev: весь 443 → relay. Docker nginx:alpine, ~/gost/
certbot — certbot renew раз в 12 ч, webroot ~/gost/certbot/www

Контейнеры: nginx, certbot (~/gost), wireguard (~/wireguard), агент мониторинга (~/monitoring-agent). Compose, nginx.conf и скрипт установки — копия в репо stacks/tproxy/.

WEB-прокси Telegram (с 2026-10-09)

Новый тип прокси в клиентах Telegram (Desktop ≥ 7.1.0; мобильные — по сообщениям с 13.0, официально не подтверждено). Клиент держит скрытый WebView к https://ru.ruzzy.dev/ и гонит по HTTPS/WSS мультиплексированные MTProxy-потоки. Сервер — официальный telegramdesktop/tproxy-server, коммит c8adb8b (2026-09-29).

  • Клиенту: server ru.ruzzy.dev, secret — 32 hex из profiles.json. Ссылка: https://t.me/webproxy?server=ru.ruzzy.dev&secret=<secret>; получить на сервере — последней строкой вывода setup-ru1.sh.
  • Цепочка: клиент → nginx :443 (TLS, ru.ruzzy.dev) → relay 127.0.0.1:8090 → MTProxy 127.0.0.1:2398 → middle-end Telegram через wg0 → fr1.
  • Mode A, без base path: relay — единственный шлюз хоста и сам отдаёт публичный сайт из /srv/tproxy-site (копия маскировочного ~/gost/nginx/html/index.html; перечитывается только при рестарте relay). Запросы без валидной capability (?bridge= = HMAC от секрета и имени хоста) получают обычный сайт. Base path не включали: по документации его понимает только Desktop.
  • ⚠️ NAT для MTProxy задан вручную: MTPROXY_NAT_ARGS=--nat-info 10.8.1.4:161.97.93.252 в /etc/mtproxy/mtproxy.env. Официальный MTProxy выводит AES-ключи middle-end сессии из своего адреса; трафик к Telegram с ru1 уходит в wg0 и выходит с IP fr1. Автоопределение апстримного install.sh спросило бы ifconfig-сервис через ens3, получило 85.198.109.86 — и MTProxy принимал бы клиентов, никому не отвечая, без ошибок нигде. Сменится exit-IP fr1 или адрес wg0 — править здесь. Симптом: journalctl -u mtproxy | grep 'Disconnected from RPC Middle-End'.
  • Юниты: tproxy-firewall (nft-таблица inet tproxy_backend: 2398/8888 только с lo), mtproxy, tproxy-server, refresh-mtproxy-config.timer (ежедневно тянет proxy-multi.conf, рестарт MTProxy только при изменении). Бинарник relay /usr/local/bin/tproxy-server собран локально (CGO_ENABLED=0 GOOS=linux GOARCH=amd64), MTProxy — /opt/MTProxy, собран deploy/install-mtproxy.sh (закреплённый коммит + sha256).
  • Carrier: websocket (с 2026-10-09, было https по умолчанию) — поле carrier_mode профиля в profiles.json: один WSS-канал /api/v1/ws на все потоки клиента вместо POST + long poll. Клиенту менять нечего, режим выбирает сервер. Relay пингует WSS раз в 25 с простоя (long_poll), поэтому proxy_read_timeout 90s в nginx канал не рвёт. Смена режима — systemctl restart tproxy-server, живые сессии переподключаются. websocket-lanes не взят: отдельный WSS на поток, на macOS WebKit сериализует рукопожатия и подключение может не уложиться в таймаут клиента. Бэкап профиля до правки — profiles.json.bak-20261009.
  • ⚠️ Порты relay 8090/8091, а не дефолтные 8080/8081: *:8080 занят cadvisor из ~/monitoring-agent.
  • ⚠️ Логи nginx выключены (access_log off): в URI bridge-страницы — capability, в Sec-WebSocket-Protocol — токен сессии. Не включать.
  • Проверено 2026-10-09: readyz 200; 10 ME-соединений с 10.8.1.4, Disconnected — 0; obfuscated2 + req_pq_multi на 127.0.0.1:2398 → resPQ за ~60 мс (3/3); capability через публичный фронт → bridge-страница (200, свой CSP). Живой клиент не проверялся.
  • Диагностика: curl -s 127.0.0.1:8091/readyz, curl -s 127.0.0.1:8091/metrics | grep tproxy_sessions, journalctl -u tproxy-server -u mtproxy.
  • Маршрут: весь Telegram (91.108.4/22, 91.108.8/22, 91.108.56/22, 95.161.64/20, 149.154.160/20) — в main-таблице dev wg0. Упал wg0 — прокси не работает.
  • Сертификат ru.ruzzy.dev (LE, webroot, только это имя; перевыпущен 2026-10-09, до 2027-01-07). Продление: certbot в контейнере каждые 12 ч; nginx сам делает reload раз в 6 ч (цикл в command compose). ⚠️ До 2026-10-09 контейнера certbot не было вовсе, хотя он был описан в compose: сертификат истёк 2026-07-01 и три месяца отдавался просроченным.
  • ⚠️ nginx.conf смонтирован в контейнер одним файлом: замена через mv/редактор с новым inode контейнер не видит, nginx -s reload перечитает старый. После такой замены — docker compose restart nginx (2026-10-09 так получили минуту простоя 443).
  • Открытый прокси для всех, кто знает secret; лимиты — дефолтные апстрима (128 сессий, 4096 потоков).

История 2026-10-09

  1. Под «web-proxy для Telegram» сначала понят Telegram Web в браузере: nginx-прокси на web.telegram.org с переписыванием адресов DC (zws*.ru.ruzzy.dev) — убран в тот же день, не то.
  2. telemt (MTProxy, FakeTLS под ru.ruzzy.dev, был на 443, API 9091 торчал наружу) снят, возвращён, затем удалён окончательно по решению владельца: контейнер, образ, ~/gost/telemt-config (со старым секретом), telemt-data, том gost_mtproxy-config.
  3. Поднят WEB-прокси (выше). Бэкапы compose/nginx.conf до изменений — ~/gost/*.bak-20261009*.

Умный роутинг (tun0 и wg1)

  • ipset ru_ips (~11400 подсетей, источник ipdeny.com). До routing decision (mangle PREROUTING):
    • dst ∈ ru_ips → RETURN (без метки) → main table → ens3 (RU напрямую)
    • иначе → MARK 0x64 → ip rule fwmark 0x64 → table vpn (100) → default dev wg0 → de1
  • ⚠️ Правило fwmark 0x64 → vpn ставит PostUp в wg0.conf, и его снимает рестарт systemd-networkd. По умолчанию networkd при старте удаляет «чужие» ip rule (ManageForeignRoutingPolicyRules=yes). 2026-10-09 в 16:36 apt-get install из установки WEB-прокси обновил библиотеки → needrestart перезапустил networkd → правило пропало, и ~45 мин (до 17:21) зарубежный трафик клиентов OpenVPN #1 шёл через ens3 (RU IP) вместо туннеля; жаловались пользователи VPN. Вернули вручную (ip rule add fwmark 100 lookup vpn priority 10000). Защита с 2026-10-09: /etc/systemd/networkd.conf.d/10-keep-foreign-routing.conf — ManageForeignRoutingPolicyRules=no, ManageForeignRoutes=no (действует со следующего старта networkd; networkd ради этого не перезапускали). Та же мина раньше висела на unattended-upgrades. Быстрая проверка: ip rule | grep 0x64.
  • Обновление списка: ~/smart-routing/update-ru-ips.sh, cron вс 03:00. Восстановление при ребуте: ipset-restore.service (до awg-quick@wg0).
  • tun1 — без умного роутинга (всегда RU/ens3).

AWG Watchdog

  • ~/awg-watchdog.sh в root-cron каждые 3 мин: если handshake wg0 старше 5 мин → рестарт awg-quick@wg0 + чистка дублей iptables. Лог ~/awg-watchdog.log. (WEB-прокси зависит от wg0: адреса Telegram с хоста идут через туннель.)

Клиенты

  • OpenVPN: ~/gen_client.sh --profile de|ru|both <имя>, PKI ~/easy-rsa/pki, профили ~/clients/. CRL отключён.
  • WireGuard: ~/wireguard/gen_client.sh <имя> → ~/wireguard/clients/<имя>.conf (горячее добавление).

Мониторинг

  • Агент ~/monitoring-agent (node-exporter + cadvisor, host-network → видит ens3/wg0/wg1/tun0/tun1) → Prometheus fr1, instance ru1.
  • openvpn-exporter (kumina, host-net :9176) — per-client метрики обоих OpenVPN (status-файлы /run/openvpn-server/status-openvpn.log + /var/log/openvpn-ru-status.log). Дашборд Grafana «OpenVPN — клиенты».
  • Порты 9100/8080/9176 закрыты iptables INPUT DROP ! -s 161.97.93.252 (только fr1, сохранено netfilter-persistent). Скрейп по публичному IP.

Прочее в ~

  • badvpn, gost, smart-routing, tun2socks.log, net-backup, works, telemt-build, cloudflared.deb.

Живой статус (2026-06-21)

Все юниты active (awg-quick@wg0, оба openvpn-server@, ipset-restore), 3 контейнера up, wg0 handshake свежий, ipset ru_ips = 11394.

⚠️ Грабли (из README)

  • wg1.conf обязан иметь Table = off — иначе wg-quick при рестарте сносит default route и сервер теряет SSH (восстановление: ip route add default via 85.198.109.1 dev ens3).
  • Таблица маршрутизации — vpn (100), не awg.

Бэкап (с 2026-10-11)

  • Домашняя rpi каждую ночь забирает зашифрованную (age, открытый ключ) выгрузку — stacks/server-backup/. Ключ server-backup@rpi в ~mik/.ssh/authorized_keys с restrict,command="sudo -n /usr/local/sbin/backup-export" (бэкап — authorized_keys.bak-20261011).
  • /usr/local/sbin/backup-export (root 750) пакует /etc, /opt, /srv, /usr/local, ~mik (без сборок badvpn/telemt-build, логов, .claude), /root, crontab; /usr/local/bin/age — статический v1.3.2. Архив ~17 МБ.
  • Главное в нём — ~mik/easy-rsa (CA OpenVPN): без него пришлось бы перевыпускать все 43 клиентских конфига.

Открытые хвосты

  • Умный роутинг для wg1 не настроен (2026-10-09): mangle-правила есть только для -i tun0, для wg1 / 10.8.2.0/24 — ни одного, хотя раздел «Умный роутинг» заявляет tun0 и wg1. В wg1 один пир, рукопожатий не было ни разу — сервисом, похоже, никто не пользуется. Не правили.
  • Drop-in 10-keep-foreign-routing.conf фактически не проверен рестартом networkd (рестарт ens3 по SSH на этой ноде — риск). Проверить при следующей плановой перезагрузке: после неё ip rule | grep 0x64 должен показать правило.
  • Живой клиент через WEB-прокси не проверен (2026-10-09): серверная цепочка проверена по частям (см. раздел WEB-прокси). Поддержка в мобильных клиентах подтверждена только новостью про Telegram 13.0.
  • DNS *.ru.ruzzy.dev (CNAME → ru.ruzzy.dev, Namecheap) остался от веб-прокси Telegram Web — больше не нужен, удалить. Имена zws*.ru.ruzzy.dev уже попали в CT-логи через сертификат от 2026-10-09 (Let's Encrypt) — это не отменить.
  • /tmp/tproxy-server на сервере — исходники и setup-ru1.sh, нужны для deploy/update-relay.sh; /tmp чистится при ребуте — при обновлении заливать заново.
  • ~/gost/manage.sh — от прежнего gost/SOCKS5, не используется.
  • Замечено при снапшоте 2026-10-09, не разбиралось: iperf3 --server (порт 5201 наружу, пользователь iperf3, PPID 1), cadvisor unhealthy. Остальное описание (OpenVPN, AWG, клиенты) сверялось до переключения на fr1 — см. строку в AGENTS.md.