Дві схеми, одна HTTPS-програма, і пакет у кожній іде іншим шляхом. Проброс порту змінює, куди доставляється пакет, і решту не чіпає. VPN спершу несе цей пакет усередині іншого пакета, тому слухач програми бачить інше джерело й менше максимальне корисне навантаження. Шифрування, про яке сперечаються, присутнє в обох випадках, бо програма й далі HTTPS; різниця в тому, хто може відкрити з'єднання і що може спостерігати мережа між ними. Ця різниця вирішує більшість практичних питань.

Правило DNAT переписує призначення і на цьому зупиняється

На шлюзі Linux опублікувати сервіс означає правило в ланцюжку PREROUTING таблиці nat або еквівалент у nftables. Правило збігається з публічною адресою та портом, потім переписує призначення на приватну адресу програми. Адреса джерела, порт джерела й корисне навантаження лишаються недоторканими, а conntrack записує зіставлення, щоб відповіді переписувалися під час виходу. Поведінка — це традиційна модель трансляції адрес, описана в RFC 3022.

sudo iptables -t nat -A PREROUTING -d 203.0.113.10 -p tcp --dport 443 \
  -j DNAT --to-destination 10.20.30.40:443
sudo iptables -t nat -L PREROUTING -n -v
sudo conntrack -L -p tcp --dport 443

Слухач програми ніколи не дізнається, що з'єднання прийшло через трансляцію. Він бачить справжню адресу джерела клієнта, що корисно для журналів доступу й обмежень швидкості, і відповідає на приватну адресу, бо conntrack обертає зіставлення. Ніщо на цьому шляху не розшифровує й не перешифровує: TLS і далі працює між клієнтом і власним сертифікатом програми.

Правило також визначає режими відмови, з якими ви зіткнетеся пізніше. Якщо шлюз пересилає, але хост програми не має зворотного маршруту до клієнта, відповіді виходять із неправильним джерелом і рукостискання застрягає. Якщо друге правило збігається першим, порядок вирішує результат, і iptables -t nat -L -n -v показує лічильники, що доводять, яке правило взяло пакет.

Тунель пакує пакет до того, як слухач його побачить

VPN узагалі не публікує програму. Клієнт будує зовнішній пакет, адресований публічній адресі шлюзу, шифрує внутрішній пакет усередині, а шлюз розшифровує й спрямовує внутрішній пакет до приватного призначення. У WireGuard зовнішній транспорт — UDP, зазвичай на високому порту; у OpenVPN поверх TCP 443 зовнішній пакет виглядає як TLS для всього, що спостерігає за шляхом.

Усередині тунелю внутрішній пакет зберігає приватні адреси: адресу тунелю клієнта, скажімо 10.8.0.6, і програму на 10.20.30.40. Тому слухач бачить джерело з пулу тунелю, і кожен клієнт ділить цей шлюз як наступний крок. Журнали доступу за VPN часто показують шлюз, а не користувача, саме з цієї причини, якщо шлюз не зберігає початкове джерело.

Пакування коштує місця в заголовку, і це єдина різниця на рівні механізму з вимірюваним наслідком. Зовнішній IP-заголовок плюс UDP плюс власний заголовок WireGuard з'їдають MTU шляху, тому великі пакети треба фрагментувати або внутрішньому стеку TCP треба обмежити свій MSS. Передача, що працює на проброшеному шляху, може застрягти на тунелі, коли проміжний пристрій відкидає ICMP, який повідомив би про менший MTU.

ip route get 10.20.30.40
ping -M do -s 1400 10.20.30.40
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
  -j TCPMSS --clamp-mss-to-pmtu

Експозиція вирішується на вході, а не шифром

Обидві схеми закінчуються на тому самому TLS-слухачі, тому обидві успадковують той самий сертифікат, ті самі версії протоколу й той самий вхід у програму. Змінюється те, кому дозволено почати рукостискання. При публічному пробросі будь-який хост, що досягає 203.0.113.10:443, отримує TCP-рукостискання й TLS ClientHello ще до того, як авторизацію вашої програми взагалі буде перевірено. При доступі лише через тунель слухач доступний тільки з адрес, які шлюз спрямовує в тунель, а SYN чужого вмирає на політиці шлюзу.

Ця різниця стосується доступності, а не конфіденційності. Проброшений сервіс HTTPS не є відкритим текстом, і VPN не скасовує потреби в автентифікації програми: допуск у тунель відповідає, чи може пристрій надсилати пакети в цю мережу, а файлова програма відповідає, чи може користувач читати документ. Змішувати ці два поняття — шлях до VPN, який віддає всю локальну мережу, і до програми з одним спільним паролем.

Перевіряйте слухач і політику окремо, бо кожен із них може бути ширшим, ніж ви припускаєте:

sudo ss -ltnp 'sport = :443'
sudo nft list ruleset
openssl s_client -connect 203.0.113.10:443 -servername files.example.com </dev/null

Якщо ss показує, що слухач прив'язаний до 0.0.0.0, програма доступна звідки завгодно, куди пускають маршрутизація й політика брандмауера, а проброс — лише один зі шляхів усередину. Прив'язка до приватної адреси або обмеження діапазону джерел у брандмауері — окреме рішення від вибору VPN, і саме воно справді звужує експозицію.

Вимірюйте шлях, а не ярлик

Коли хтось стверджує, що проброс швидший, чесне порівняння тримає все інше сталим: той самий клієнт, та сама мережа доступу, той самий файл, та сама конфігурація TLS, той самий хост програми. Запустіть передачу двічі на кожному шляху й запишіть загальний час, кількість збоїв і чутливість, а не вивід стороннього тесту швидкості.

curl -sS -o /dev/null -w '%{time_connect} %{time_appconnect} %{time_total}\n' \
  https://files.example.com/report.pdf
mtr -rwc 20 203.0.113.10
mtr -rwc 20 10.20.30.40

Ці числа відокремлюють встановлення з'єднання від часу передачі, що важливо, бо два шляхи зазвичай різняться затримкою туди й назад і MTU, а не вартістю шифру. Робота TLS відбувається на кінцях в обох схемах, а тунель додає інкапсуляцію, інший маршрут і, можливо, завантаженіший шлюз. Якщо шлях тунелю довший або його шлюз завантажений, різниця належить шляху, а не слову шифрування.

Виберіть політику входу, яка справді потрібна сервісу, потім вирішіть, чи виправдовує виміряна різниця її зміну. Публічний проброс пасує сервісу, призначеному для відкритого інтернету, з обмеженнями джерел, оновленим TLS і моніторингом перед ним. Доступ лише через тунель пасує внутрішньому інструменту, користувачі якого вже зареєстровані, за умови, що маршрутизація шлюзу й дозволи програми обидва вужчі за всю локальну мережу.

Перш ніж оголосити схему завершеною, підтвердьте чотири речі: до якої адреси прив'язаний слухач, яке правило або маршрут пускає пакет усередину, чи працює зворотний шлях зі справжньої адреси клієнта і чи переживають великі навантаження MTU. Для кожного з них вище є команда, і на жодне не відповідає слово безпечно або графік пропускної здатності.

Схожі статті