CGNAT portları bloklayanda VPS vasitəsilə ev serverini yayımlamaq
Brauzerdən ev maşınına gedən yol: xəttin CGNAT arxasında olduğunu sübut et, DNS-i VPS-ə yönləndir, bir portda DNAT et, qayıdış yolunu düzəlt və kənardan yoxla.
Bayırdan başladım, bir istifadəçinin edəcəyi kimi: adı mobil datadakı telefon brauzerinə yazdım və bağlantının vaxt bitənə qədər asılı qalmasını izlədim. Ad həll olunurdu, yəni DNS qaydasında idi. Ev marşrutlaşdırıcısının port yönləndirmə səhifəsi də çıxılmaz idi, çünki onun WAN ünvanı 100.64.31.42 göstərirdi və bu, provayderin məni internetdən yönləndirəcəyi ünvan deyil. Bu rəqəm bütün nasazlığı izah edir: xətt carrier-grade NAT arxasındadır, yəni tunelin mənim tərəfimdəki ictimai ünvanı provayderə aiddir. Bundan sonra həmin ilişib qalmış tabdan cavab verən xidmətə qədər getdiyim yol gəlir.
Müştəridən başla və içəri doğru get
Hər hansı qaydanı dəyişməzdən əvvəl zəncirin harada dayandığını sübut et. Noutbukda dig +short files.example.net əmrini işə saldım və VPS ünvanını geri aldım, bu da maşınımdakı köhnə DNS-i istisna etdi. Sonra curl -v --connect-timeout 5 files.example.net:5022 rədd edilmək əvəzinə vaxt bitməsinə düşdü. Bu fərq vacibdir: vaxt bitməsi adətən paketlərin yolda atıldığını bildirir, rədd isə nəyinsə cavab verib yox dediyini bildirir.
İçəri doğru növbəti addım VPS-in özü idi. ss -ltnp 5022-də dinləyən heç nə göstərmədi, bu da DNAT qaydası yaranmadan əvvəl gözlənilən idi. Həmin maşında wg show (və ya OpenVPN üçün ip -br a show tun0) ev peer-inin işlədiyini və təzə handshake olduğunu təsdiqlədi. Peer işləmirsə, heç bir NAT qaydası kömək etməz və ev marşrutlaşdırıcısının VPN səhifəsindəki yaşıl işıq heç nə demək deyil.
Ev xəttinin həqiqətən CGNAT arxasında olduğunu təsdiqlə
Marşrutlaşdırıcının WAN interfeysində bildirdiyi ünvanı kənardakı xidmətin gördüyü ilə müqayisə et. 100.64.0.0/10 daxilində olan hər şey, yəni 100.64.x.x-dən 100.127.x.x-ə qədər, RFC 6598-dəki paylaşılan ünvan aralığıdır və internetdən əlçatan deyil. Marşrutlaşdırıcı adi özəl ünvan iddia edib ictimai sorğu əlaqəsiz bir şey qaytardıqda da eyni nəticəyə gəlirsən. CGNAT xətti yalnız növbəti lease-ə qədər qüvvədə olan ictimai ünvanla da gələ bilər, buna görə port yönləndirmə bir saat işləyir kimi görünür və sonra səssizcə ölür.
Bəzi provayderlər həqiqətən real ictimai ünvan verir, lakin yaşayış hesablarında daxil olan 80 və 443 portlarını bloklayır. Xidmətin yalnız vebdirsə və WAN ünvanı həqiqətən ictimaidirsə, relay qurmazdan əvvəl dəstəkdən soruş. Deyilsə, aşağıdakı dizayn hər port üçün eyni dərəcədə keçərlidir və təcrübəni marşrutlaşdırıcı tərəfində dayandırmağa dəyər: provayderin şəbəkəsindəki tərcüməçi bağlantını sənin WAN interfeysinə çatmadan sonlandırır.
Adı VPS ünvanına yönləndir
DNS trafiki ötürmür, buna görə xidmətin A qeydi VPS-in ictimai ünvanını saxlamalıdır. 192.168.1.20-yə yönələn A qeydi yalnız VPN-in içində olan müştərilər üçün faydalı həll olunur; internetdən heç kimin yönləndirə bilmədiyi ünvana həll olunur. VPS-in öz inzibati girişi üçün ayrı ad saxlayıram ki, qeydin hansı hosta aid olduğunu heç vaxt qarışdırmayım.
Həm VPS, həm də ev maşını HTTP xidməti verirsə, hər birinə öz adını ver və kimin cavab verəcəyinə VPS qərar versin. Onları bir ada birləşdirib proxy-nin düzgün backend seçəcəyinə ümid etmək, məhz yanlış hostda bir günorta səhv axtarmağa səbəb olur.
Bir port DNAT, SSH 22-də qalsın
Birbaşa seçim VPS-də təyinat NAT-dır. İşləyən nüvə üçün yönləndirməni aktiv et və qaydada ev serverinin tunel ünvanını saxla, LAN ünvanını yox:
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
VPS-in özünə SSH-ı 22-də saxla və başqa bir portu, məsələn 5022-ni ev maşınına yönləndir. 22-ni söndürülmüş maşına yönləndirsən, onu düzəldə biləcək yeganə yolu itirərsən. Eyni məntiq proxy üçün də keçərlidir: VPS-in idarəetmə portunu relay qaydalarından kənarda saxla.
Qaydaları işləməyə başlayanda daimi et. Debian və ya Ubuntu-da apt install iptables-persistent və sonra netfilter-persistent save onları /etc/iptables/rules.v4 faylına yazır. firewalld olan hostda ekvivalent zonada daimi port yönləndirməsidir və tətbiq olunmadan əvvəl firewall-cmd --reload tələb edir. Yalnız yaddaşda yaşayan qaydalar provayderin ilk texniki xidmət yenidən başlatmasında yox olur, adətən pis saatda.
Qayıdış yolunu düzəlt və ya ona ehtiyacdan qaç
DNAT yalnız təyinatı yenidən yazır. Ev serveri bağlantını ilkin müştəri ünvanından görür və əgər standart marşrutu ev marşrutlaşdırıcısına gedirsə, cavab ev WAN-ından çıxır və orada provayderin tərcüməçisi onu atır. Bu asimmetriya, DNAT qaydası tamamilə düzgün göründükdən sonra rastlaşdığım ikinci nasazlıq idi.
İki düzəliş işləyir. Ev maşınına siyasət marşrutu ver ki, tuneldən gələn trafik tuneldən geri qayıtsın:
ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100
Ya da VPS mənbəyi yenidən yazsın ki, cavabın çata biləcəyi bir ünvanı olsun və conntrack onu çıxışda geri çevirsin:
iptables -t nat -A POSTROUTING -d 10.8.0.2 -p tcp --dport 5022 -j SNAT --to-source 10.8.0.1
SNAT versiyası həqiqi müştəri ünvanını ev serverindən gizlədir, buna görə tətbiq jurnalları peer kimi 10.8.0.1 göstərir. İlkin ünvanı tətbiq səviyyəsində ötür və ya müştəri üzrə jurnal itkisini qəbul et, amma bunu insident zamanı kəşf etmək əvəzinə şüurlu şəkildə qərarlaşdır.
Bütün yolu kənardan yoxla
Nə VPS, nə də ev olmayan şəbəkədən yoxla: mobil datadakı telefon və ya başqa yerdə ucuz shell. nc -vz files.example.net 5022 uğurlu bağlantı bildirməli və openssl s_client -connect files.example.net:443 -servername files.example.net ictimai ad üçün sertifikatı göstərməlidir. Sonra provayderin təhlükəsizlik qrupunu və ya bulud firewallunu yoxla. Heç vaxt paket görməyən DNAT qaydası adətən hostdan bir qat yuxarıda bloklanır.
Nəhayət, tunel düşdükdə nə olacağına qərar ver. DNAT qaydası bağlantıları qəbul etməyə davam edir və onları səssizcə ölü tunelə ötürür, bu da tamamilə xarab olmuş xidmət kimi görünür. VPS-də peer işləmədikcə portu rədd edən sağlamlıq yoxlaması bir neçə sətirə başa gəlir və bir saatlıq təxmini qənaət edir. Bundan sonra qaydaları redaktə etməyi dayandır və ona güvənməzdən əvvəl bir gün izlə.