Публикуване на клиентски порт за VPN зад CGNAT: контролен списък
Само правило за NAT на местоназначението дава наполовина отворени връзки. Фиксирайте адреса на тунела, превеждайте в двете посоки и потвърдете пътя на отговора преди тестване.
Поставете услуга на лаптоп зад NAT на операторско ниво, насочете този лаптоп към VPS през VPN и никой отвън не може да го достигне. Добавяте правило за NAT на местоназначението на VPS и получавате нещо по-лошо от мълчание: връзките се отварят, после забиват. Отговорът не липсва, той излиза по собствения маршрут по подразбиране на клиента, което означава, че сървърът никога не го вижда. Мине тези пет проверки по ред и спри на първата, която не се издържи.
Потвърдете, че сървърът изобщо ще препраща
Отметнете това квадратче, преди да напишете дори един превод. Правило за DNAT за пакет, който ядрото отказва да препрати, се приема от анализатора на правила и след това се изхвърля от пътя за препращане, което дава изчакване, изглеждащо като проблем с защитна стена.
sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1
Задаването в работещо ядро не е същото като задаването през рестарт. Запишете net.ipv4.ip_forward=1 във файл под /etc/sysctl.d/, изпълнете sysctl --system, после прочетете стойността обратно, вместо да вярвате, че файлът е прихванат. Контейнер, който управлява свое собствено пространство от имена за мрежата, се нуждае от същата стойност вътре в това пространство, не само на хоста.
Ако прочитането все още е нула, спрете тук. Нищо надолу няма да работи.
Фиксирайте адреса на тунела, преди някое правило да го спомене
Пулът раздава адреси в реда на свързване, така че правило, написано за днешния наем, може тихо да сочи към различен клиент следващата седмица. Обвържете адреса с идентичността на сертификата, а не с реда на пристигане.
client-config-dir /etc/openvpn/ccd
ifconfig-push 10.77.0.14 10.77.0.13
Тази двойка е клиентският край и крайният възел на тунел точка-точка, като сървърът е ключен към общото име на сертификата. При топология на подмрежа втората стойност се чете като мрежова маска вместо това, така че напишете формата, който отговаря на използваната топология. После свържете клиента наново и прочетете адреса на самия клиент, защото виждането на сървъра за пула не е доказателство за това какво е конфигурирал клиентът.
Ако адресът се промени след повторно свързване, спрете. Правило за NAT, което следва движеща се цел, ще се проваля на пресекулки и няма да ви научи на нищо.
Превеждайте в двете посоки
Преводът на местоназначението изпраща входящия пакет към клиента. Преводът на източника е това, което кара клиента да отговори на сървъра, а не на първоначалния подател, и именно това правило хората пропускат.
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 29443 -j DNAT --to-destination 10.77.0.14:29443
iptables -t nat -A POSTROUTING -d 10.77.0.14 -p tcp --dport 29443 -j SNAT --to-source 10.77.0.13
Без второто правило клиентът отговаря през своята ISP връзка нагоре, така че отдалеченият възел вижда адрес на източник, с който никога не е говорил, докато сървърът не държи запис за проследяване на отговора. Външният наблюдател вижда ръкостискане, което се довършва наполовина, и това е точно симптомът, който кара хората да търсят грешка в защитната стена, каквато няма.
Прочетете двете правила обратно с iptables -t nat -S и потвърдете, че името на интерфейса е това, което носи публичния адрес. На хост, който вече филтрира с nftables, напишете превода в NAT верига на nftables от съответното семейство адреси, вместо да смесвате инструменти.
Пуснете таблицата за филтриране
Таблиците на NAT пренаписват заглавките; те не дават разрешение. При политика DROP по подразбиране препращаният поток се нуждае от собствено приемане, плюс обратната посока, която повечето политики вече покриват с правило established,related.
iptables -A FORWARD -i eth0 -o tun0 -p tcp --dport 29443 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Проверете политиката на веригата FORWARD, преди да добавите нещо, защото редът на ранен DROP решава дали правилото ви изобщо ще бъде потърсено. На хост, чието филтриране живее в nftables, добавете еквивалентното правило към куката forward на таблицата inet и потвърдете, че базовата верига наистина вижда препращан трафик, а не само локален вход. Ако броячът на пакети на новото правило остава на нула, докато броячите на NAT растат, пакетът се изхвърля преди вашето правило. Това е сигнал да прочетете реда на веригите, а не да добавите второ копие на същото правило.
Докажете го от външна мрежа
Тествайте от несвързана мрежа. Проверка от друга машина в същата локална мрежа може да мине през поддръжката на hairpin NAT и никога да не упражни пътя, който използва отдалечен клиент, така че зеленият резултат там доказва грешното нещо.
tcpdump -ni any port 29443
conntrack -L | grep 29443
Пуснете заснемането на сървъра и на клиента едновременно. Заснемането на сървъра показва дали преведеният пакет излиза към тунела; заснемането на клиента показва дали заявката пристига и накъде е адресиран отговорът. Запис за превод в conntrack -L доказва, че правилото е съвпаднало, а липсата му доказва, че пакетът никога не е достигнал NAT веригата.
Скенерите на портове са слабо доказателство. Те отчитат порта като затворен, докато приложението не се обвърже и не слуша, така че използвайте истинска връзка към истинската услуга. Когато най-накрая работи, задръжте излагането на този един порт: препращането на SSH или административен панел, защото първото правило се стори неудобно, е много по-голямо решение от публикуването на услуга.