VPN сервер не работает¶
Клиенты не могут подключиться к одному или нескольким VPN-серверам.
Симптомы¶
- Пользователи сообщают, что конкретная страна/сервер не работает
- В Grafana сервер в статусе DOWN или DEGRADED
- VPN Config Service worker выдаёт
SSH: Connection refusedна конкретный IP - health_check воркера пишет
unhealthy, restarting xrayбез результата
Диагностика¶
1. Проверить статус сервера в Grafana¶
Открыть дашборд «VPN Servers» → найти сервер по IP/имени → посмотреть метрики xray_status и online_sessions.
2. Проверить сетевую доступность¶
# Пинг сервера (с внутренней сети через jump)
./scripts/ssh-internal.sh 10.99.87.249 "ping -c 3 SERVER_IP"
# TCP-проверка VPN-порта (обычно 443 или 8443)
./scripts/ssh-internal.sh 10.99.87.249 "timeout 5 nc -zv SERVER_IP VPN_PORT && echo OK || echo FAIL"
3. SSH на сервер¶
Если SSH недоступен — сервер offline или firewall заблокировал порт 22.
4. Проверить docker-контейнер xray¶
# Зайдя на сервер через ssh:
docker ps | grep xray
docker inspect xray --format='{{.State.Status}}'
ss -tlnp | grep xray
Ожидаемый результат: контейнер running, xray слушает на нужных портах.
5. Посмотреть логи xray¶
Смотреть на ошибки: failed, timeout, panic, TLS-ошибки.
6. Проверить, есть ли inbound-записи (через XUI API)¶
# Список inbounds через XUI панель (порт 1443 через nginx, логин: shadmin)
curl -sk -X POST "https://SERVER_IP:1443/login" \
-d "username=shadmin&password=$(см. Vaultwarden → VPN Servers → xui-password)"
# После получения cookie:
curl -sk "https://SERVER_IP:1443/panel/api/inbounds/list" \
--cookie "3x-ui=SESSION_COOKIE" | python3 -m json.tool | head -60
7. Проверить UFW / iptables¶
VPN-порт должен быть открыт. Если UFW включён и порт закрыт — добавить правило.
8. Проверить статус через VPN Config Service health endpoint¶
Причины и решения¶
| Симптом | Причина | Решение |
|---|---|---|
docker inspect → exited |
Контейнер xray упал | docker restart xray |
| Контейнер running, порт не слушает | xray crash loop | docker logs xray --tail 100 → анализ ошибки |
| SSH недоступен, ping идёт | Firewall заблокировал 22 | Обратиться к хостеру или console |
| SSH и ping недоступны | Сервер offline | Хостер VPS panel → power on / console |
| xray запущен, клиент не коннектится | Reality SNI заблокирован провайдером | Проверить SNI, сменить если нужно |
| xray запущен, inbounds пустые | База x-ui сброшена после rollback | Восстановить inbounds из VCS PostgreSQL |
| Сертификат истёк | TLS cert expired | ls -la /usr/local/etc/xray/*.crt → обновить |
Исправление¶
Перезапуск xray¶
xray в crash loop — проверить конфиг¶
./scripts/ssh-internal.sh SERVER_IP "docker exec xray xray -test -config /usr/local/etc/xray/config.json"
Восстановить inbounds из VCS PostgreSQL¶
# Найти Reality private key в PostgreSQL VCS (10.99.87.249:5434, db: vpnconfig)
./scripts/ssh-internal.sh 10.99.87.249 \
"docker exec vpn-config-postgres psql -U vpnconfig vpnconfig -c \
\"SELECT s.ip, i.stream_settings->'realitySettings'->>'privateKey' \
FROM inbounds i JOIN servers s ON i.server_id = s.id \
WHERE s.ip = 'SERVER_IP';\""
UFW — открыть порт¶
Проверить статус после исправления¶
# Принудительный sync через VCS API
./scripts/ssh-internal.sh 10.99.87.249 \
"curl -sX POST http://localhost:8000/api/v1/sync/full \
-H 'X-API-Key: VazVBGPEBLTG7qNVOQQu4xR21DWTBi4_fodUjuEojnE'"
Эскалация¶
- P1 (массовые жалобы): немедленно уведомить Max (PO) и Nikita (Ops)
- Если сервер физически недоступен — открыть тикет у хостера (MonoVM, DataPacket, Hetzner)
- Список серверов:
ansible/shiva-ansible/inventory/servers.ini→ имя хоста содержит провайдера
См. также: Деплой VPN-сервера · Runbooks · DevOps скрипты · Инвентарь серверов