Почему сайт открывается через VPN, но не грузится у пользователей в РФ: диагностика за 2 минуты
Фраза «через VPN открывается, без VPN нет» звучит в поддержке каждый день. Она полезна ровно как бинарный симптом: путь из-за пределов фильтруемой сети живой, путь абонента в РФ нет. Она не говорит, сломан ли сервер, лжёт ли DNS, режется ли SNI или домен уже лежит в реестре. Ниже порядок, который укладывается в две минуты и оставляет в тикете факты, а не ощущения.
Минута 0. Зафиксировать, что именно не открывается
Запишите три строки, как их прислал пользователь: URL с путём, город или оператора, точное поведение. «Крутится» , «соединение сброшено», «сертификат», «DNS_PROBE_FINISHED_NXDOMAIN» и «обрыв на половине» - это разные поломки. Попросите IP сайта, который человек видит в ошибке, если браузер его показывает. Сверьте со своим:
dig +short example.com A @1.1.1.1 dig +short example.com A @8.8.8.8 dig +short example.com A @77.88.8.8
77.88.8.8 - публичный резолвер Яндекса, то есть взгляд из российской DNS-инфраструктуры. Если Cloudflare, Google и Яндекс отдают один адрес, подмена DNS маловероятна, и VPN «чинит» не резолвер, а дальнейший маршрут. Если Яндекс отдаёт другой адрес или пусто, пользователю без VPN нечего чинить на сервере: он ходит не к вам. Это сразу закрывает ложный тикет «упал backend».
Минута 1. Отделить живой origin от фильтра
С машины вне жалобы (зарубежный VPS, офисный канал, где сайт открывается) снимите код и размер. Затем посмотрите TLS по имени.
curl -s -o /dev/null \
-w "http=%{http_code} size=%{size_download} remote=%{remote_ip} time=%{time_total}\n" \
--http1.1 --max-time 15 https://example.com/
echo | openssl s_client -connect example.com:443 \
-servername example.com -brief
HTTP 200 и размер хотя бы в десятки килобайт плюс состоявшееся рукопожатие означают: процесс, сертификат и контент на месте. VPN у пользователя приводит его примерно в эту же точку маршрута, поэтому «через VPN работает» совпадает с вашим curl. Значит, падения сервера нет. Дальше сравнивайте российский путь.
Самый быстрый российский путь без своего прокси - проверка на rkn-test.ru. Введите домен на главной. Сервис отдельно показывает реестр Роскомнадзора, DPI через российский канал и статус IP. Прочитайте слои, а не только зелёную или красную плашку:
| Реестр | DPI | IP | Как это стыкуется с VPN |
|---|---|---|---|
| есть | есть | любой | Ограничение официальное, VPN обходит маршрут провайдера. Лечится содержанием, URL или сменой адреса, а не «починкой SSL» |
| нет | есть | нет | Внереестровая фильтрация, чаще SNI. Сервер жив. См. разбор ТСПУ |
| нет | нет | есть | Режется адрес целиком, соседи по хостингу страдают так же. Новый домен на старом IP не спасёт |
| нет | нет | нет | Из канала проверки сайт доступен. Ищите частный случай: антивирус, корпоративный прокси, IPv6, гео-блок самого приложения |
Минута 2. Закрыть частные случаи, пока не ушли переносить сайт
IPv6. Браузер пользователя может предпочесть AAAA, а ваш curl сходил по A. Если AAAA ведёт в мёртвый или фильтруемый адрес, симптом «у меня открылось» зависит от того, есть ли у клиента IPv6.
dig +short example.com AAAA curl -6 -sI --max-time 10 https://example.com/ || echo "ipv6 fail" curl -4 -sI --max-time 10 https://example.com/
Сертификат и имя. Ошибка «не защищено» при рабочем VPN иногда значит, что без VPN человек попадает на заглушку провайдера с чужим сертификатом. Сравните издателя:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \ | openssl x509 -noout -issuer -subject -dates
Издатель заглушки не совпадёт с Let's Encrypt или вашим CA. Это снова сеть провайдера, а не забытый certbot на сервере. Если даты сертификата просрочены и снаружи, VPN тут ни при чём: чините выпуск сертификата.
Гео-блок приложения и Cloudflare challenge выглядят так же, как «РКН», если смотреть только глазами. Приложение может отдавать 403 только российским ASN, а CF - проверку браузера. Чекер помечает такие ответы отдельно от DPI. Не снимайте домен с делегирования, пока не увидите, какой слой красный.
Что написать пользователю и что автоматизировать
Короткий ответ в поддержку: «Сервер отвечает, DNS совпадает у 1.1.1.1 и 77.88.8.8, из РФ режется слой DPI / реестра / IP (нужное по результату проверки). VPN меняет сеть, поэтому у вас он открывается.» Приложите ссылку на результат или повторите проверку при человеке на главной.
Чтобы следующий такой тикет не занимал две минуты вручную, поставьте домен на мониторинг: уведомление приходит, когда статус реестра или DPI меняется, а не когда первый пользователь уже пишет в чат. Для своей статус-страницы хватает виджета. Для скрипта дежурного - одна строка из документации API:
curl -s "https://rkn-test.ru/api/check?domain=example.com"
Если слой реестра подтвердился и вы готовите новое имя, не публикуйте его вслепую. Сначала прочитайте, как устроены основания блокировки: проверка домена и IP в реестре. И не путайте этот симптом с пропажей делегирования по закону 569-ФЗ: там сайт не откроется и через VPN, потому что NS перестанут отвечать.
Вопросы и ответы
Если VPN помогает, блокировки РКН точно нет?
Наоборот: VPN обходит сеть провайдера и часто подтверждает, что origin жив. Реестр и DPI при этом могут быть красными. Проверьте домен на главной, а не только через туннель.
Зачем сравнивать dig через 1.1.1.1 и 77.88.8.8?
77.88.8.8 - публичный резолвер с российской стороны. Другой адрес или пустой ответ при честном 1.1.1.1 означает DNS-фильтрацию, а не упавший backend.
Чекер зелёный, а один пользователь всё равно не открывает сайт. Что проверить?
AAAA и curl -4/-6, корпоративный прокси, антивирус и издателя сертификата. Заглушка провайдера показывает чужой сертификат при живом сервере.
Проверить свой домен на блокировку РКН и DPI прямо сейчас
Реестр Роскомнадзора, фильтрация по российскому каналу и статус IP в одной проверке. Для постоянного контроля подключите мониторинг, API или виджет.