Објављивање кућног сервера преко VPS-а када CGNAT блокира портове
Пут од прегледача до кућног строја: докажи да је линија иза CGNAT-а, усмери DNS на VPS, уради DNAT једног порта, поправи повратну руту и провери споља.
Почео сам споља, како би то учинио корисник: уписао сам име у прегледач телефона на мобилним подацима и гледао како веза виси док није истекла. Име се разрешавало, па је DNS био у реду. Ни страница за прослеђивање портова кућног рутера није била решење, јер је њена WAN адреса показивала 100.64.31.42, а то није адреса на коју ме провајдер усмерава са интернета. Тај број објашњава цео квар: линија је иза carrier-grade NAT, па јавна адреса на мојој страни тунела припада провајдеру. Оно што следи је пут који сам прешао од тог заглављеног таба до услуге која одговара.
Почни код клијента и иди према унутра
Пре него што промениш било које правило, докажи где се ланац зауставља. На преносном рачунару сам покренуо dig +short files.example.net и добио адресу VPS-а назад, што је искључило застарео DNS на мом рачунару. Затим је curl -v --connect-timeout 5 files.example.net:5022 истекао уместо да буде одбијен. Та разлика је важна: истек обично значи да се пакети на путу одбацују, док одбијање значи да је нешто одговорило и рекло не.
Следећи скок према унутра био је сам VPS. ss -ltnp није показао ништа што слуша на 5022, што се очекивало пре него што је правило DNAT постојало. На истом строју wg show (или ip -br a show tun0 за OpenVPN) потврдио је да је кућни peer активан са свежим handshake-ом. Ако је peer доле, ниједно NAT правило не помаже, а зелено светло на VPN страници кућног рутера не значи ништа.
Потврди да је кућна линија заиста иза CGNAT-а
Упореди адресу коју рутер пријављује на свом WAN интерфејсу са оним што види спољна услуга. Све у 100.64.0.0/10, дакле од 100.64.x.x до 100.127.x.x, је опсег дељених адреса из RFC 6598 и није доступно са интернета. До истог закључка долазиш када рутер тврди да има обичну приватну адресу, а јавна претрага врати нешто неповезано. Линија CGNAT може имати и јавну адресу која важи само до следећег lease-а, па прослеђивање порта изгледа да ради сат времена и онда тихо умре.
Неки провајдери заиста дају праву јавну адресу, али блокирају долазне портове 80 и 443 на стамбеним рачунима. Ако је твоја услуга само веб и WAN адреса је заиста јавна, питај подршку пре него што изградиш relay. Ако није, доњи дизајн важи једнако за сваки порт, и вреди зауставити експеримент на страни рутера: преводилац у мрежи провајдера прекида везу пре него што икада стигне до твог WAN интерфејса.
Усмери име на адресу VPS-а
DNS не преноси саобраћај, па запис A услуге мора да садржи јавну адресу VPS-а. Запис A на 192.168.1.20 корисно се разрешава само за клијенте који су већ у VPN-у; са интернета се разрешава на адресу коју нико не може да усмери. За административни приступ самом VPS-у држим засебно име, да никада не побркам на који се рачунар запис односи.
Ако и VPS и кућни строј служе HTTP, дај свакоме сопствено име и пусти VPS да одлучи ко одговара. Спојити их у једно име и надати се да ће proxy одабрати прави backend тачно је како проведеш цело поподне отклањајући грешке на погрешном рачунару.
Један порт кроз DNAT, SSH остаје на 22
Директна опција је одредишни NAT на VPS-у. Укључи forwarding за језгро које ради и држи адресу тунела кућног сервера у правилу, не његову LAN адресу:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -d 198.51.100.10 --dport 5022 -j DNAT --to-destination 10.8.0.2
Пусти SSH према самом VPS-у на 22 и проследи други порт, на пример 5022, на кућни строј. Ако проследиш 22 на угашен строј, губиш једини пут који га је могао поправити. Иста логика важи за proxy: држи управљачки порт VPS-а изван правила relay-а.
Учини правила трајним када прораде. На Debian-у или Ubuntu-у apt install iptables-persistent и затим netfilter-persistent save их уписују у /etc/iptables/rules.v4. На рачунару са firewalld еквивалент је трајно прослеђивање порта у зони, које пре примене треба firewall-cmd --reload. Правила која живе само у меморији нестају при првом сервисном рестарту провајдера, обично у лоше доба.
Поправи повратну руту или избегни потребу за њом
DNAT преписује само одредиште. Кућни сервер види везу са изворне адресе клијента, а ако његова подразумевана рута показује на кућни рутер, одговор излази кроз кућни WAN где га преводилац провајдера одбацује. Та асиметрија је била други квар на који сам наишао, пошто је правило DNAT изгледало потпуно исправно.
Две поправке делују. Дај кућном строју политику руте да саобраћај из тунела иде назад кроз тунел:
ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100
Или пусти VPS да препише извор како би одговор имао адресу коју може да достигне, и пусти conntrack да га на излазу окрене:
iptables -t nat -A POSTROUTING -d 10.8.0.2 -p tcp --dport 5022 -j SNAT --to-source 10.8.0.1
Верзија SNAT скрива праву адресу клијента од кућног сервера, па записи апликације показују 10.8.0.1 као peer. Проследи изворну адресу на нивоу апликације или прихвати губитак бележења по клијенту, али одлучи то свесно уместо да откријеш током инцидента.
Провери цео пут споља
Провери из мреже која није ни VPS ни кућа: телефон на мобилним подацима или јефтин shell негде другде. nc -vz files.example.net 5022 би требало да пријави успешну везу, а openssl s_client -connect files.example.net:443 -servername files.example.net би требало да покаже сертификат за јавно име. Затим провери сигурносну групу или cloud заштитни зид провајдера. Правило DNAT које никада не види пакет обично је блокирано један слој изнад рачунара.
На крају одлучи шта се дешава када тунел падне. Правило DNAT наставља да прихвата везе и тихо их шаље у мртав тунел, што изгледа тачно као покварена услуга. Провера здравља на VPS-у која одбија порт док је peer доле кошта неколико редова и штеди сат нагађања. После тога престани да уређујеш правила и посматрај то један дан пре него што му поверујеш.