Објавување домашен сервер преку 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-от е долу чини неколку реда и штеди еден час нагаѓање. Потоа престани да уредуваш правила и гледај го еден ден пред да му веруваш.