Yalnızca VPN portuna izin veren bir güvenlik duvarı tek bir kural değildir. Aynı port numarasına denk gelen üç ayrı karardır: giriş zinciri yerel bir sürece neyin ulaşabileceğine, yönlendirme zinciri tünel istemcileri adına ana makineden neyin geçebileceğine karar verir, NAT tablosu ise çıkışta kaynak adresini yeniden yazar. Birini yanlış yaparsanız sonuç nadiren temiz bir kesinti olur. İstemcileri kabul eden ama hiçbir şey yüklemeyen bir ana makine ya da biri zincirlerin sırasını okuyana kadar kapalı görünen bir ana makine elde edersiniz.

Kapatılamayan tek port

VPN dinleyicisi öngöremeyeceğiniz adreslerden bağlantı kabul etmek zorundadır, bu yüzden tanımı gereği genel bir hizmettir. Tasarımın üzerine kurulduğu tek istisna budur: OpenVPN için bir UDP portu, WireGuard için bir UDP portu, bir SSL VPN için bir TCP portu. Geri kalan her şey tünelin arkasına aittir, yani uygulama hizmetleri tüm arayüzlere değil tünel adresine ya da loopback'e bağlanmalıdır.

Ancak bağlamak uygulamak değildir. 0.0.0.0 adresine bağlı bir süreç yalnızca bir kural izin verirse erişilebilir olur ve varsayılan politika hiçbir kuralla eşleşmeyen trafik için yedektir, portu yöneten kural değildir. Drop'unuzun üstüne konan bir accept yine accept'tir ve bir hizmeti genel adresten taşımak zincirin yerine geçmeyen bağımsız bir iyileştirmedir.

Giriş, yönlendirme ve NAT farklı soruları yanıtlar

Giriş trafiği ana makinenin kendisine yöneliktir, bu yüzden VPN dinleyicisi ve yönetim yolu orada yaşar. Yönlendirme trafiği ana makineden geçer ve tünel istemcileri buna net.ipv4.ip_forward=1 ile birlikte ihtiyaç duyar. Klasik yarım bozuk yapılandırma giden akışa izin verir ve dönüş yönünü unutur, böylece istemci el sıkışmayı tamamlar ve ardından hiçbir şey yüklenmez; kurulmuş ve ilişkili trafik için bir conntrack kuralı o yönü kapsar.

NAT üçüncü sorudur. Postrouting'de yeniden yazma olmadan, yönlendirilen paketler tünelin özel kaynağıyla çıkar ve yukarıda düşürülür, çünkü ana makinenin ötesindeki hiçbir ağ havuzu geri yönlendirmeyi bilmez. O kuraldaki kaynak öneki VPN havuzuyla eşleşmelidir, ana makinenin kendi adresiyle değil, ve istemci alt ağını adlandıran yönlendirme kuralı için de aynısı geçerlidir.

IPv6 ikinci bir politikedir, sonradan akla gelen bir düşünce değil. Katı IPv4 zinciri ve ip6tables üzerinde açık politikası olan bir ana makine hiçbir şeyi kapatmamıştır; hizmetlere diğer aile üzerinden hâlâ erişilebilir. Ya kural kümesini ip6tables ile yansıtın ya da genel arayüzde IPv6'yı bilerek kapatın ve hangisini seçtiğinizi yazın.

Tek geçişte okunabilen bir temel

Reddetmeyle başlayın, sonra yalnızca ana makinenin ihtiyaç duyduğunu ekleyin. Önce loopback ve yanıtlar, sonra yönetim yolu, sonra tünel dinleyicisi, sonra istemciler için yönlendirme politikası:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -m conntrack --ctstate NEW -j ACCEPT
sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Arayüz adları, port ve havuz yer tutucudur; kopyalamak yerine sunucudan okuyun. Sonucu kaydetmek yazmak kadar önemlidir, çünkü yalnızca bellekte yaşayan bir kural kümesi sonraki yeniden başlatmada kaybolur ve ana makineyi sessizce yeniden açar. Dağıtımın mekanizmasıyla kalıcı hale getirin ve makinenin açılmayacağı gün için makine dışında bir kopya tutun.

Ana makineyi kaybetmeden son portu kapatmak

Tasarımda bir tuzak var. SSH yalnızca tünel üzerinden varsa, başarısız bir VPN hizmeti SSH'yi de yanında götürür ve geri dönüşün tek yolu hiç açmadığınız bir konsol olabilir. Son genel portu kapatmadan önce o konsolun var olduğunu ve gerçekten kullanabildiğinizi doğrulayın ya da tünele bağlı olmayan dar bir yönetim yolu bırakın: sabit adresten SSH, yalnızca anahtarlar, parola kimlik doğrulaması kapalı.

Değişikliği zaten kurulmuş bir oturumdan uygulayın, filtrelemek üzere olduğunuz bağlantı üzerinden değil. Bir hatanın kalıcı olmak yerine süresinin dolması için geri alma planlayın, örneğin önceki kural kümesini geri yükleyen bir systemd-run --on-active=10min işi, ve ilkini test ederken ikinci SSH oturumunu açık tutun. Ardından geri alma işinin gerçekten tetiklendiğini doğrulayın, çünkü test edilmemiş kurtarma hiç kurtarma olmamasıyla aynıdır.

Betiği değil, yolu doğrulayın

Yüklenen kuralları okuyun, onları yüklemesi gereken dosyayı değil. Yetkili bir dış ana makineden yalnızca amaçlanan portların yanıt verdiğini doğrulayın; tünelin içinden yayımlamak istediğiniz hizmetlere erişilebildiğini doğrulayın. Tünel trafiğini de engelleyen varsayılan reddetme politikası, biri kullanmayı deneyene kadar çalışan bir kilitle tamamen aynı görünür.

iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr show

İzin verilen portu, istemci havuzunu, tünel arayüzünü, yönetim kaynağını ve konsol prosedürünü yapılandırmanın yanına not edin. Havuzdaki veya arayüz adındaki sonraki değişiklik hem filtrede hem NAT kuralında eşleşmelidir, aksi halde ana makine kimse fark etmeden yarı açık bir duruma döner.

Bir alışkanlık kural kümesinden daha değerlidir: her değişiklikten sonra yönlendirme yolunu bir istemci isteğiyle, kurtarma yolunu ikinci bir oturumla kanıtlayın. Kullanmadığınız bir kilit yalnızca bir varsayımdır.

İlgili makaleler