Диагностика и устранение неисправностей VPN: пошаговое руководство | AdminWiki

Диагностика и устранение неисправностей VPN: пошаговое руководство

29 июля 2026 11 мин. чтения

VPN-туннель не поднимается, клиенты не могут подключиться, трафик уходит в чёрную дыру. Каждая минута простоя - это потерянные данные или недоступность критичных сервисов. Это руководство даёт системный подход к поиску и устранению неисправностей. Вы получите готовые команды для проверки аутентификации, DNS, брандмауэра и маршрутизации, а не общие рассуждения.

Материал построен по принципу «от простого к сложному». Сначала - три обязательные проверки, которые локализуют проблему за пару минут. Затем - глубокий разбор каждого узла: сертификаты, файрвол, таблицы маршрутизации. Если вы уже сталкивались с асимметричной маршрутизацией или обрывами туннелей после миграции, обратите внимание на руководство по диагностике проблем маршрутизации в VPN, где эти кейсы разобраны детально.

Быстрый старт: первичная диагностика VPN-соединения

Когда VPN не работает, хаотичная проверка всего подряд крадёт время. Выполните три шага строго последовательно. Они покрывают 80% типовых отказов.

Шаг 1: базовая связность. Отправьте ICMP-запрос на IP-адрес VPN-сервера с клиентской машины. Отсутствие ответа означает, что проблема на сетевом уровне - порт недоступен, маршрут отсутствует или сервер физически выключен.

ping -c 4 203.0.113.10

Если пинг не проходит, проверьте доступность порта утилитой netcat. Для OpenVPN это обычно UDP 1194, для WireGuard - UDP 51820.

nc -vz -u 203.0.113.10 1194

Отказ на этом этапе - сигнал проверить правила брандмауэра на всём пути: клиент, промежуточные шлюзы, сервер. На сервере под управлением Linux выполните:

iptables -L -v -n | grep -E "1194|51820"

Шаг 2: состояние службы VPN. На сервере демон мог упасть после обновления пакетов или исчерпания памяти. Проверьте статус:

systemctl status openvpn@server
systemctl status wg-quick@wg0

Обратите внимание на строку Active:. Состояние inactive (dead) - служба остановлена. failed (Result: exit-code) - демон запустился, но завершился с ошибкой. В последнем случае немедленно смотрите логи.

Шаг 3: анализ логов в реальном времени. Откройте второй терминал и запустите потоковый вывод журнала. Попробуйте установить соединение с клиента и наблюдайте за сообщениями.

tail -f /var/log/openvpn.log
journalctl -u openvpn@server -f

Ключевые маркеры для быстрого поиска: AUTH_FAILED - проблема с учётными данными или сертификатами, TLS Error - ошибка рукопожатия, Connection refused - порт не слушается, MULTI: bad source address - пакет пришёл с неожиданного IP. Зафиксируйте конкретную ошибку и переходите к соответствующему разделу.

Для сложных сценариев, где трафик теряется на промежуточных узлах, используйте практическое руководство по диагностике сетевой маршрутизации. Там разобрана методика поиска обрывов с traceroute и mtr.

Ошибки аутентификации: проверка учетных данных и сертификатов

Ошибка аутентификации - самая частая причина отказа VPN после сетевых проблем. Сервер отклоняет подключение, клиент получает AUTH_FAILED или TLS handshake failed. Причина не всегда в неверном пароле. Разберём три типовых сценария.

Несовпадение учётных данных. Проверьте логин и пароль на клиенте. Сравните хеш пароля в базе сервера. Для OpenVPN с аутентификацией через auth-user-pass файл на сервере обычно лежит в /etc/openvpn/server/auth.txt. Убедитесь, что клиент использует правильный алгоритм хеширования, если пароль передаётся не в открытом виде.

Права доступа к файлам ключей. Если закрытый ключ клиента доступен для чтения другим пользователям, OpenVPN откажется его использовать. Проверьте маску:

ls -la /etc/openvpn/client/client.key
chmod 600 /etc/openvpn/client/client.key

Несовпадение алгоритмов шифрования. Клиент и сервер должны договориться о шифре. Если на сервере задан жёсткий список data-ciphers AES-256-GCM, а клиент пытается использовать устаревший BF-CBC, рукопожатие провалится. Сверьте конфигурации:

grep -E "^data-ciphers|^cipher" /etc/openvpn/server/server.conf
grep -E "^data-ciphers|^cipher" /etc/openvpn/client/client.ovpn

Проблемы с сертификатами: срок действия и цепочка доверия

Ошибки TLS маскируются под общие сбои аутентификации. Сертификат клиента или сервера просрочен, отозван, или отсутствует корневой CA в доверенных. Проверьте срок действия сертификата сервера:

openssl x509 -in /etc/openvpn/server/server.crt -text -noout | grep -A2 "Validity"

Убедитесь, что поле Not After содержит дату в будущем. Просроченный сертификат нужно перевыпустить и распространить на клиентов. Проверьте цепочку доверия: клиент должен иметь корневой сертификат CA, которым подписан сертификат сервера. Команда для проверки с клиентской машины:

openssl s_client -connect 203.0.113.10:1194 -showcerts

Вывод покажет всю цепочку. Ошибка verify error:num=19:self signed certificate in certificate chain означает, что клиент не доверяет сертификату сервера. Добавьте корневой CA в конфигурацию клиента директивой ca ca.crt.

Проверка списка отзыва (CRL) обязательна, если вы отзывали скомпрометированные сертификаты. На сервере OpenVPN директива crl-verify crl.pem заставляет сверять каждый клиентский сертификат с CRL. Убедитесь, что файл CRL актуален:

openssl crl -in /etc/openvpn/server/crl.pem -text -noout | grep -A2 "Last Update\|Next Update"

Рассинхронизация времени как скрытая причина отказа

Разница в системном времени между клиентом и сервером более 5 минут ломает проверку сертификатов. Сертификат может считаться ещё не действительным или уже просроченным. Это проявляется как ошибка TLS, хотя все ключи корректны. Проверьте время на обеих машинах:

date
timedatectl status

Если время сбито, настройте синхронизацию по NTP. Для systemd-based систем:

timedatectl set-ntp true
systemctl restart systemd-timesyncd

Проверьте, что синхронизация прошла успешно:

timedatectl show -p NTPSynchronized

Значение yes подтверждает корректную работу. На старых системах без systemd-timesyncd используйте ntpd или chrony. После синхронизации перезапустите VPN-службу и повторите попытку подключения.

Проблемы с DNS: когда VPN подключен, но сайты не открываются

Туннель поднят, пинг до внутренних IP проходит, но браузер показывает «DNS_PROBE_FINISHED_NXDOMAIN». Трафик идёт через VPN, а DNS-запросы утекают к провайдеру или не разрешаются вовсе. Это классический симптом неправильной настройки DNS.

Сначала определите, какие DNS-серверы использует система после подключения VPN. На Linux:

resolvectl status
nslookup example.com

Вывод покажет, какой DNS-сервер фактически обрабатывает запросы. Если там адрес провайдера, а не VPN-сервера, конфигурация не применилась. Проверьте утечки DNS - запросы, которые идут в обход туннеля. Быстрый тест через CLI:

dig +short myip.opendns.com @resolver1.opendns.com

Сравните возвращённый IP с ожидаемым IP VPN-сервера. Несовпадение - признак утечки.

Принудительная настройка DNS на клиенте и сервере

Самый надёжный метод - явно задать DNS-серверы в конфигурации клиента. Для OpenVPN добавьте в client.ovpn:

dhcp-option DNS 8.8.8.8
dhcp-option DNS 1.1.1.1
redirect-gateway def1

Директива redirect-gateway def1 заставляет весь трафик идти через туннель, включая DNS. Без неё система может использовать локальный резолвер. На сервере OpenVPN можно принудительно пушить DNS клиентам:

push "dhcp-option DNS 10.8.0.1"

Для WireGuard укажите DNS в секции [Interface] клиентского конфига:

[Interface]
PrivateKey = ...
Address = 10.0.0.2/24
DNS = 8.8.8.8, 1.1.1.1

После изменения конфигурации сбросьте кеш DNS. Для systemd-resolved:

resolvectl flush-caches

Для старых систем с nscd или dnsmasq - перезапустите соответствующую службу. Если вы настраиваете раздельный туннелинг, где только часть трафика идёт в VPN, обратитесь к руководству по настройке split tunneling. Там детально разобрана защита от утечек DNS в этом режиме.

Брандмауэр и блокировка портов: как найти и обойти

Файрвол блокирует VPN-трафик на одном из трёх уровней: клиент, сервер или промежуточный сетевой экран провайдера. Симптомы: таймаут при подключении, пакеты не доходят до сервера, соединение сбрасывается после рукопожатия.

Проверьте доступность порта снаружи. С внешней машины выполните:

nc -vz -u 203.0.113.10 1194
telnet 203.0.113.10 1194

Для TCP-режима OpenVPN telnet покажет, слушает ли сервер порт. Для UDP netcat с флагом -u отправит дейтаграмму. Отсутствие ответа при работающей службе VPN - вина файрвола.

Для диагностики временно отключите брандмауэр на сервере. Предварительно убедитесь, что это безопасно в вашем окружении:

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F

Если соединение установилось, проблема в правилах. Восстановите файрвол и правьте правила точечно.

Анализ правил iptables и работа с NAT

Просмотрите текущие правила с числовыми значениями портов и адресов. Флаг -v добавляет счётчики пакетов - это показывает, срабатывает ли правило:

iptables -L -v -n
iptables -t nat -L -v -n

Для OpenVPN критичны две вещи: разрешение входящего трафика на порт 1194 и наличие правила MASQUERADE для доступа клиентов в локальную сеть сервера. Добавьте правила, если их нет:

iptables -A INPUT -p udp --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Для WireGuard правила аналогичны, меняется интерфейс и порт:

iptables -A INPUT -p udp --dport 51820 -j ACCEPT
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

Для IPsec-туннелей (IKEv2, L2TP) дополнительно проверьте, не блокируются ли протоколы ESP (IP-протокол 50) и AH (51), а также UDP-порты 500 и 4500. Некоторые облачные провайдеры фильтруют их на уровне гипервизора. Если вы работаете с Linux-шлюзом и строите сложные схемы маршрутизации, изучите руководство по VPN-маршрутизации на Linux с iptables и nftables.

Ошибки маршрутизации: трафик идет не в туннель

VPN-клиент подключён, но трафик до целевых ресурсов идёт в обход туннеля или не доходит вовсе. Причина - в таблице маршрутизации. Проверьте её сразу после установки соединения:

ip route show
route -n

Ищите маршрут к удалённой подсети через VPN-интерфейс (tun0, wg0). Если его нет, сервер не передал маршруты клиенту. В OpenVPN за это отвечает директива push "route 192.168.100.0 255.255.255.0" в конфигурации сервера. В WireGuard маршрут определяется полем AllowedIPs на стороне клиента.

Диагностируйте путь пакета утилитами traceroute и mtr. Они покажут, на каком узле трафик сворачивает не туда:

traceroute -n 192.168.100.50
mtr -r -c 10 192.168.100.50

Если первый хоп - шлюз по умолчанию локальной сети, а не VPN-сервер, маршрут не применился. Принудительно направьте весь трафик в туннель. Для OpenVPN:

redirect-gateway def1

Для WireGuard укажите AllowedIPs = 0.0.0.0/0 в пире. Это перекроет таблицу маршрутизации и пустит все пакеты через VPN.

Конфликт IP-адресов и подсетей

Клиент находится в локальной сети 192.168.1.0/24. Сервер VPN раздаёт адреса из той же подсети 192.168.1.0/24. Операционная система не понимает, куда слать пакеты - в локальный интерфейс или в туннель. Симптом: часть трафика идёт правильно, часть теряется, соединения рвутся случайным образом.

Обнаружить конфликт просто: сравните вывод ip addr show на клиенте с подсетью VPN-сервера. Если они пересекаются, у вас два пути. Первый - сменить подсеть на стороне сервера. В конфигурации OpenVPN измените директиву server 10.8.0.0 255.255.255.0 на уникальный диапазон, например 10.77.0.0 255.255.255.0. Второй - использовать client-to-client с NAT, но это усложнит доступ к клиентам изнутри VPN-сети.

Для WireGuard конфликт решается изменением Address в секции [Interface] сервера и соответствующих AllowedIPs на клиентах. После смены подсети перезапустите службу и переподключите всех клиентов.

Практический инструментарий: команды для диагностики VPN

Соберите этот набор команд в отдельный файл или шпаргалку. Он покрывает все этапы: от проверки связности до анализа трафика на уровне пакетов.

ЗадачаКомандаЧто проверяет
Базовая связностьping -c 4 IP_сервераДоступность хоста
Доступность портаnc -vz -u IP_сервера 1194UDP-порт слушается
Состояние службыsystemctl status openvpn@serverДемон запущен
Логи в реальном времениjournalctl -u openvpn@server -fОшибки аутентификации, TLS
Маршрутыip route showТаблица маршрутизации
Трассировкаtraceroute -n IP_целиПуть пакета
Открытые портыss -tunlpСлушающие сервисы
Правила файрволаiptables -L -v -nФильтрация трафика
DNS-резолвингdig example.comИспользуемый DNS-сервер
Сертификатыopenssl x509 -in server.crt -text -nooutСрок действия, CN

Захват и анализ трафика для выявления скрытых проблем

Когда логи молчат, а туннель нестабилен, переходите на уровень пакетов. tcpdump покажет, что происходит на проводе. Захватите трафик на VPN-порту сервера:

tcpdump -i eth0 -n port 1194 -v

Для WireGuard:

tcpdump -i eth0 -n port 51820

Анализируйте рукопожатие TLS. Если клиент шлёт Client Hello, а сервер не отвечает Server Hello, проблема на стороне сервера - скорее всего, файрвол режет пакеты или демон не слушает порт. Если рукопожатие проходит, но затем идут RST-пакеты, причина в несовпадении параметров шифрования или сертификатах.

Для IPsec-туннелей захватывайте трафик протокола ESP:

tcpdump -i eth0 proto esp

Отсутствие ESP-пакетов при активном IKE-рукопожатии указывает на блокировку IP-протокола 50. Провайдер или облачная платформа могут фильтровать его. Решение - переключить IPsec в режим NAT-T, который инкапсулирует ESP в UDP-пакеты на порт 4500.

Ищите сброшенные пакеты с флагом RST. Они сигнализируют, что одна из сторон принудительно разрывает соединение. Причиной может быть превышение MTU. Пакет не влезает в туннель, фрагментация запрещена, соединение рвётся. Проверьте MTU на интерфейсе туннеля:

ip link show tun0 | grep mtu

Для туннелей поверх интернета рекомендуется MTU 1400 или ниже, чтобы учесть накладные расходы на шифрование и инкапсуляцию.

Восстановление стабильности: keepalive и автоматическое переподключение

Туннель падает ночью, клиенты отваливаются при смене Wi-Fi, соединение висит, но трафик не идёт. Эти проблемы решаются настройкой keepalive и механизмов реконнекта.

Для OpenVPN ключевые директивы в конфигурации сервера:

keepalive 10 60
persist-key
persist-tun

keepalive 10 60 отправляет пинг-пакеты каждые 10 секунд. Если ответа нет 60 секунд, сервер считает клиента отключённым и освобождает ресурсы. persist-key и persist-tun запрещают перечитывать ключи и пересоздавать интерфейс при перезапуске - это ускоряет восстановление.

На клиенте добавьте бесконечные попытки переподключения:

resolv-retry infinite
connect-retry 5 300

Это заставляет клиента пытаться переподключиться каждые 5 секунд в течение 300 секунд, а затем бесконечно повторять цикл. Для WireGuard keepalive настраивается в секции пира:

[Peer]
PersistentKeepalive = 25

Значение 25 секунд подходит для большинства NAT-устройств. Оно предотвращает закрытие UDP-сессии на промежуточных маршрутизаторах из-за неактивности.

Типовые причины обрывов: агрессивные таймауты NAT на домашних роутерах (30-60 секунд), смена IP-адреса клиентом, нестабильный мобильный интернет. Keepalive решает проблему с NAT. Для смены IP нужен скрипт мониторинга, который перезапускает туннель при обнаружении обрыва. Простейший вариант - cron-задача, пингующая удалённый конец туннеля раз в минуту и дёргающая systemctl restart при неудаче.

Если вы разворачиваете VPN-инфраструктуру на облачных серверах, обратите внимание на облачные серверы Timeweb Cloud. Они позволяют быстро поднять узел с готовыми образами и гибко масштабировать ресурсы при росте числа клиентов.

Поделиться:
Сохранить гайд? В закладки браузера