OpenVPN на 443 всё ещё блокируется? Проверьте, что инспектирует сеть
Порт 443 меняет номер, а не форму протокола. Если путь инспектирует или завершает TLS, следующий тест — обёртка и правильный маршрут к хосту.
Туннель подключается с домашней линии и застревает в гостиничной или офисной сети, а перенос сервера на порт 443 ничего не изменил. Этот результат достаточно частый, чтобы иметь форму: порт был простой частью, а остаток решения принадлежит всему, что стоит между клиентом и сервером. Два вопроса решают большинство случаев, и ни один из них не о шифрах. Принимает ли сеть рукопожатие TLS на этот адрес, и сохраняет ли клиент маршрут к собственной обёртке, пока туннель поднят?
Рукопожатие выдаёт больше, чем номер
Родной слушатель VPN на TCP 443 говорит своим протоколом с первого пакета. У ClientHello есть поле версии, случайное значение и список расширений, и устройство, прочитавшее несколько сотен байт, видит разницу, ничего не расшифровывая. Номера портов дёшево удовлетворить, а форма протокола — это то, что фильтр действительно проверяет. Правила обычно пишут и по протоколам, поэтому политика, инспектирующая TLS, ничего не говорит об UDP.
Прозрачный прокси, требующий действительного сеанса TLS, сбрасывает соединение при настройке, часто после завершения рукопожатия TCP. Эта деталь важна позже, потому что означает: журнал клиента обрывается после установки сокета.
Оборачивание потока создаёт две точки отказа
Обёртка TLS вроде stunnel восстанавливает ожидаемую форму: клиент подключается к локальному слушателю, обёртка открывает настоящий сеанс TLS к серверу на 443, а вторая обёртка на сервере передаёт расшифрованные байты демону VPN. Внешний сеанс теперь выглядит как любое другое соединение HTTPS. Демон VPN на сервере должен слушать только на loopback, потому что ничему вне обёртки не нужно до него добираться.
Для этой схемы должны совпасть три отдельные вещи. Профиль клиента указывает на локальный слушатель, сертификат сервера совпадает с именем, которое проверяет клиент, а переадресация на стороне сервера нацелена на порт, который демон действительно использует. Ошибётесь в любой из них — и соединение умирает, не дойдя до уровня VPN. Тогда несовпадение сертификата проявляется как ошибка обёртки, а не как ошибка VPN, и поэтому оба журнала стоит читать рядом.
Маршрут к обёртке — это ловушка
Как только туннель поднимается, маршрут по умолчанию указывает в него, и внешнему сеансу TLS нужен путь, который не входит в туннель, который он несёт. Обычный клиент VPN защищает адрес, на который звонит; обёрнутый клиент звонит на свой собственный loopback, поэтому адрес назначения обёртки невидим для этой защиты.
sudo ip route add 198.51.100.20 via 192.168.0.1
sudo openvpn --config client.ovpn
sudo ip route del 198.51.100.20
Точные адреса вписываете вы, и маршрут должен существовать всю жизнь соединения, а не только при запуске. Небольшой скрипт-обёртка, который добавляет маршрут до клиента и удаляет после, надёжнее запомненной команды.
В Android эквивалент этого исключения — настройка для каждого приложения: исключите приложение-обёртку из туннеля, чтобы его собственный трафик выходил через мобильное соединение. Без исключения обёртка направляется в тот туннель, который пытается построить, и цикл переподключения выглядит как проблема сервера.
Прочитайте тайминги, прежде чем что-то менять
Сеанс, который умирает через один и тот же интервал каждый раз, — это подпись политики, а не криптографический сбой, и долгие лимиты потока дают именно такой узор. Соединение, сбрасываемое сразу после рукопожатия, указывает на прокси, которому не понравилась цепочка сертификатов.
Сравните издателя сертификата обычного сайта HTTPS из обеих сетей. Если в ограниченной сети издатель другой, что-то завершает TLS посередине, и никакая обёртка не переживёт этот перехват без изменений. То же сравнение подскажет, нацелена ли блокировка на имя вашего сервера или на каждый сеанс TLS по этому адресу.
Запишите наблюдавшееся поведение: сколько длился сеанс, открылся ли сокет, зафиксировала ли обёртка рукопожатие. Каждый из этих пунктов сужает следующий тест.
Проверяйте по одной переменной за раз
Сначала проверьте UDP, потому что некоторые сети полностью его отбрасывают, а сбой UDP ничего не говорит о 443. Затем попробуйте TCP 443 без обёртки, потом обёртку на 443. Читайте журнал клиента на каждом шаге и остановитесь, как только поведение изменится.
Меняйте по одному элементу за попытку. Новый порт, новая обёртка и новый шифр в одном прогоне не оставят вам возможности сказать, что из трёх имело значение.