Dışarıdan başladım, bir kullanıcının yapacağı gibi: adı mobil verideki bir telefon tarayıcısına yazdım ve bağlantının zaman aşımına uğrayana kadar asılı kalmasını izledim. Ad çözülüyordu, yani DNS yolundaydı. Ev yönlendiricisinin port yönlendirme sayfası da çıkmaz sokaktı, çünkü WAN adresi 100.64.31.42 gösteriyordu ve bu, bir sağlayıcının beni internetten yönlendireceği bir adres değil. Bu sayı tüm arızayı açıklıyor: hat carrier-grade NAT arkasında, yani tünelin benim tarafımdaki genel adres sağlayıcıya ait. Aşağıdakiler, o takılı sekmeden yanıt veren bir servise kadar yürüdüğüm yoldur.

İstemciden başla ve içeri doğru ilerle

Herhangi bir kuralı değiştirmeden önce zincirin nerede durduğunu kanıtla. Dizüstünde dig +short files.example.net komutunu çalıştırdım ve VPS adresini geri aldım, bu da makinemdeki eski DNS'i eledi. Ardından curl -v --connect-timeout 5 files.example.net:5022 reddedilmek yerine zaman aşımına uğradı. Bu fark önemli: zaman aşımı genellikle paketlerin yolda düşürüldüğü anlamına gelir, reddetme ise bir şeyin yanıt verip hayır dediği anlamına gelir.

İçeri doğru bir sonraki adım VPS'in kendisiydi. ss -ltnp 5022'de dinleyen hiçbir şey göstermedi, bu da DNAT kuralı yokken beklenen durumdu. Aynı makinede wg show (veya OpenVPN için ip -br a show tun0) ev peer'ının çalıştığını ve taze bir handshake'e sahip olduğunu doğruladı. Peer kapalıysa hiçbir NAT kuralı yardımcı olmaz ve ev yönlendiricisinin VPN sayfasındaki yeşil ışık hiçbir şey ifade etmez.

Ev hattının gerçekten CGNAT arkasında olduğunu doğrula

Yönlendiricinin WAN arayüzünde bildirdiği adresi, dışarıdaki bir servisin gördüğüyle karşılaştır. 100.64.0.0/10 içindeki her şey, yani 100.64.x.x ile 100.127.x.x arası, RFC 6598'deki paylaşılan adres aralığıdır ve internetten erişilemez. Yönlendirici sıradan bir özel adres iddia edip genel bir sorgu alakasız bir şey döndürdüğünde de aynı sonuca varırsın. CGNAT hattı yalnızca bir sonraki lease'e kadar geçerli bir genel adresle de gelebilir, bu yüzden port yönlendirme bir saat çalışıyor gibi görünür ve sonra sessizce ölür.

Bazı sağlayıcılar gerçekten gerçek bir genel adres verir ama konut hesaplarında gelen 80 ve 443 portlarını engeller. Hizmetin yalnızca web ise ve WAN adresi gerçekten genelse, relay kurmadan önce desteğe sor. Değilse, aşağıdaki tasarım her port için aynı şekilde geçerlidir ve deneyi yönlendirici tarafında durdurmaya değer: sağlayıcının ağındaki çevirici, bağlantı senin WAN arayüzüne ulaşmadan önce onu sonlandırır.

Adı VPS adresine yönlendir

DNS trafiği iletmez, bu yüzden hizmetin A kaydı VPS'in genel adresini içermelidir. 192.168.1.20'ye işaret eden bir A kaydı yalnızca VPN'in içindeki istemciler için anlamlı çözülür; internetten kimsenin yönlendiremeyeceği bir adrese çözülür. VPS'in kendi yönetim erişimi için ayrı bir ad tutuyorum, böylece bir kaydın hangi ana makineye ait olduğunu asla karıştırmam.

Hem VPS hem de ev makinesi HTTP sunuyorsa her birine kendi adını ver ve hangisinin yanıt vereceğine VPS karar versin. İkisini tek bir ada katlayıp proxy'nin doğru backend'i seçeceğini ummak, tam olarak yanlış ana makinede bir öğleden sonra hata ayıklamana yol açar.

Tek port DNAT, SSH 22'de kalsın

Doğrudan seçenek VPS üzerinde hedef NAT'tır. Çalışan çekirdek için yönlendirmeyi etkinleştir ve kuralda ev sunucusunun tünel adresini tut, LAN adresini değil:

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 kendisine SSH'ı 22'de bırak ve başka bir portu, örneğin 5022'yi, ev makinesine yönlendir. 22'yi kapalı bir makineye yönlendirirsen onu düzeltebilecek tek yolu kaybedersin. Aynı mantık proxy için de geçerli: VPS'in yönetim portunu relay kurallarının dışında tut.

Kuralları çalışmaya başlayınca kalıcı yap. Debian veya Ubuntu'da apt install iptables-persistent ve ardından netfilter-persistent save bunları /etc/iptables/rules.v4 dosyasına yazar. firewalld olan bir ana makinede eşdeğeri bölgede kalıcı bir port yönlendirmesidir ve uygulanmadan önce firewall-cmd --reload gerekir. Yalnızca bellekte yaşayan kurallar sağlayıcının ilk bakım yeniden başlatmasında kaybolur, genellikle kötü bir saatte.

Dönüş yolunu düzelt ya da ona ihtiyaç duymaktan kaçın

DNAT yalnızca hedefi yeniden yazar. Ev sunucusu bağlantıyı özgün istemci adresinden görür ve varsayılan rotası ev yönlendiricisine gidiyorsa yanıt, sağlayıcının çeviricisinin onu düşürdüğü ev WAN'ından çıkar. Bu asimetri, DNAT kuralı tamamen doğru göründükten sonra karşılaştığım ikinci arızaydı.

İki düzeltme işe yarıyor. Ev makinesine bir politika rotası ver, böylece tünelden gelen trafik tünelden geri dönsün:

ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100

Ya da VPS'in kaynağı yeniden yazmasına izin ver, böylece yanıtın ulaşabileceği bir adresi olsun ve conntrack onu çıkışta 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 sürümü gerçek istemci adresini ev sunucusundan gizler, bu yüzden uygulama günlükleri peer olarak 10.8.0.1 gösterir. Özgün adresi uygulama katmanında ilet ya da istemci başına günlük kaybını kabul et, ama bunu bir olay sırasında keşfetmek yerine bilinçli olarak kararlaştır.

Tüm yolu dışarıdan kontrol et

Ne VPS ne de ev olan bir ağdan doğrula: mobil verideki bir telefon veya başka bir yerde ucuz bir shell. nc -vz files.example.net 5022 başarılı bir bağlantı bildirmeli ve openssl s_client -connect files.example.net:443 -servername files.example.net genel ad için sertifikayı göstermelidir. Ardından sağlayıcının güvenlik grubunu veya bulut güvenlik duvarını kontrol et. Hiç paket görmeyen bir DNAT kuralı genellikle ana makinenin bir katman üstünde engellenir.

Son olarak tünel düştüğünde ne olacağına karar ver. Bir DNAT kuralı bağlantıları kabul etmeye devam eder ve onları sessizce ölü bir tünele besler; bu da tam olarak bozuk bir hizmet gibi görünür. VPS üzerinde peer kapalıyken portu reddeden bir sağlık kontrolü birkaç satıra mal olur ve bir saatlik tahmini kurtarır. Bundan sonra kuralları düzenlemeyi bırak ve güvenmeden önce bir gün izle.

İlgili makaleler