OpenVPN за stunnel: пересылайте обёртку, а не порт 1194
Два слушателя, три порта. Проверьте, куда попадает переадресация, где привязывается обёртка, куда она подключается, что пропустил локальный тест и обе идентичности.
Поставьте TLS-обёртку перед OpenVPN, и развёртывание получит второй слушатель, из которых только один должен когда-либо смотреть в интернет. Когда туннель работает с той же машины и не работает снаружи, переадресация обычно направлена на неправильный из двух. Совпадать должна цепочка: публичное правило доходит до обёртки, а собственное backend-соединение обёртки доходит до настоящего VPN-сокета. Четыре прыжка несут эту цепочку, и любой из них может закончить расследование досрочно.
Два сокета, два владельца, один из них публичный
Обёртка завершает TLS для внешнего соединения и передаёт расшифрованный поток байтов обычному слушателю OpenVPN TCP. Это отдельные сокеты с отдельными файлами конфигурации, поэтому правка одного оставляет другой нетронутым и по-прежнему внешне здоровым. Это также значит, что два могут разойтись, когда один меняют без другого.
Работа с самой машины поэтому доказывает очень мало о публичном пути. Прямое соединение с родным портом пропускает обёртку, соединение с обёрткой на её адресе LAN пропускает трансляцию, и только полная схема на стороне клиента упражняет то, что делает внешний пользователь. Имена тоже нужно читать внимательно, потому что localhost означает хост, на котором работает именно этот компонент, а не хост, на котором вы случайно печатаете. Держите это различие в своих заметках, потому что тест, записанный без прыжка, который он покрывал, приглашает к сравнению двух разных вещей.
Куда на самом деле попадает переадресация
Цепочку легче держать как четыре прыжка, чем как три номера портов, потому что одно и то же число на каждом конце может означать разное. Читайте таблицу строка за строкой: каждая строка — это один сокет, который должен принять соединение, а затем открыть следующее. Когда строка нацелена на неверного партнёра, симптом в последнем столбце — это то, о чём сообщает пользователь.
| Hop | Listens on | Must reach | Symptom when it points elsewhere |
|---|---|---|---|
| Client machine | A local plaintext port | The wrapper's public TLS address | Plain text offered to a TLS endpoint |
| Router forward | Public TCP 443 | The wrapper host on its translated port | Wrapper records no connection at all |
| Wrapper, server mode | Its accepted port, 8443 here | The native VPN socket on loopback | Handshake completes, then silence |
| Native VPN listener | Loopback TCP port | Its peer, over TCP only | A UDP socket behind a byte-stream relay |
Правило, нацеленное на родной порт VPN вместо обёртки, полностью пропускает завершение TLS, и это самая распространённая форма этой ошибки: клиент открывает рукопожатие со слушателем, который ожидает кадрирование OpenVPN, поэтому соединение может открыться и затем зависнуть. Сверяйте переведённый порт с файлом конфигурации обёртки, а не с памятью, потому что следующий человек, который будет править этот файл, мог выбрать другой номер. Две команды ниже показывают обе стороны этого вопроса сразу.
grep -nE '^[[:space:]]*(accept|connect)' /etc/stunnel/stunnel.conf
ss -lntp | grep -E ':443|:8443|:1194'
Адрес привязки, который вас отклоняет
Строка accept, привязанная к 127.0.0.1, отвечает только самому хосту, поэтому переадресация, приходящая на адрес LAN, не может подключиться, и клиент видит отказ, который звучит как проблема пакетного фильтра. Посмотрите на сокет, прежде чем трогать межсетевой экран, потому что сокет — более дешёвый ответ. Либо привяжите обёртку к интерфейсу, на который нацелена переадресация, либо оставьте её на loopback и добейтесь, чтобы переадресация достигала loopback через что-то действительно работающее. Это два проекта, и каждому нужно своё правило.
Их смешение — это то, из-за чего рабочая обёртка становится недоступной снаружи, пока каждый файл выглядит правильным. Проверка ниже — одна команда, и она отвечает на вопрос, на который обзор правил межсетевого экрана ответить не может. Если вывод показывает адрес loopback, а переадресация нацелена на адрес LAN, исправление относится к строке accept, а не к пакетному фильтру.
ss -lntp '( sport = :8443 )'
Что на самом деле доказал локальный тест
Успех, записанный без прыжка, который он покрывал, не является доказательством о других прыжках. Отметьте, какой адрес использовал тест и какой процесс ответил. Затем повторите снаружи сети, а не с телефона в той же сети Wi-Fi, потому что поведение шпильки различается между маршрутизаторами, и соединение, никогда не покидавшее LAN, может удовлетворить клиента без всякого участия переадресации. Только эта вторая попытка тренирует путь, которым идёт посторонний.
Когда попытка не удаётся, проследите одно соединение по обоим журналам: принятые и подключённые строки обёртки, затем собственный журнал сеанса демона VPN. Первая граница, которая ничего не записывает, — это место следующего изменения. Как только OpenVPN начинает сравнивать параметры партнёра, судите об этих сообщениях по правилам той реализации. Предупреждение о несоответствии link-mtu не является автоматически фатальным, закрепление link-mtu на 1500 не доказывает, что фрагментация прекратилась, а согласование шифра относится к внутренней конфигурации OpenVPN, а не к переадресации маршрутизатора.
nc -vz 127.0.0.1 1194
journalctl -u stunnel -n 50 --no-pager
Эти пробы охватывают backend-сокет и журнал обёртки, что отделяет отклонённый backend от отклонённого рукопожатия. Запускайте их, пока идёт одна попытка, а не после. Именно метки времени одной попытки делают сравнение надёжным.
Две идентичности, два порядка отказа
Внешний сертификат принадлежит обёртке, а внутренняя идентичность — OpenVPN, и они могут происходить от разных органов. Отключение любой из двух проверок, чтобы путь выглядел здоровым, меняет реальную защиту на косметический результат. Сохраняйте обе проверки и отлаживайте их по порядку, потому что последовательность сообщений называет уровень: проблема сертификата обёртки появляется до согласования любой опции VPN, тогда как сбой внутренней идентичности появляется только после установления потока.
руководство stunnel точно определяет accept, connect и режим клиента, и эти разделы отвечают на вопрос о сокете быстрее, чем догадки. Когда вы всё ещё не можете сказать, какой уровень ответил, прочитайте сертификат, который представляет публичный порт, командой ниже. Сертификат обёртки в выводе означает, что переадресация дошла до обёртки, а тишина или ошибка протокола означает, что не дошла. Это единственное различие экономит больше времени, чем любая другая проверка здесь.
openssl s_client -connect vpn.example:443 -servername vpn.example </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer