Bir Linux uygulamasını UID kurallarıyla VPN'e sabitlemek
Bir UID kuralı yalnızca yerel soketleri görür ve olağan loopback istisnası tüneli öldürür. Önce hesabı yönlendirin, sonra her adımı süzün ve doğrulayın.
Tek bir programı Linux'ta VPN'e sabitlemek çoğunlukla bir yönlendirme sorunudur, ve güvenlik duvarı kuralı yalnızca rota seçildikten sonra ne olacağına karar verir. Tünel varsayılan rotaya sahip olmadan önce programın UID'sini OUTPUT içinde eşlerseniz, kural tam olarak korumak istediğiniz trafiği düşürür. Aynı kural, programın DNS sorgularını yanıtlayan çözümleyici sürecini de görmez. Sırayı doğru kurun ve ayrıcalıksız tek bir hesap güvenilir bir bölünmüş tünel seçici olur.
Karardan önce hesaba bir rota verin
Sahip eşleşmesi tek bir soruyu yanıtlar: paketi bu UID'ye ait yerel bir soket mi oluşturdu? Bir arayüz seçmez ve ana tablonun hâlihazırda fiziksel NIC üzerinden gönderdiği trafiği taşıyamaz. Bu yüzden eşleşen rotası olmayan bir UID kuralı programı yeniden yönlendirmek yerine engeller.
Hesabı önce kendi tablosundan geçirin, sonra güvenlik duvarının sonucu doğrulamasına izin verin. Bu, iproute2'si uidrange'i anlayan bir ana makinede çalışır; bunu ip rule help tek satırda bildirir. Tablo 100 tünel üzerinden bir varsayılan rota tutar ve kural yalnızca UID 1000'i o tabloya gönderir. Diğer her şey ana tabloda kalır ve fiziksel bağlantıyı kullanmaya devam eder.
ip rule add uidrange 1000-1000 table 100 ip route add default dev tun0 table 100
Başka bir tünele gereksinim duyan ikinci hesap, tablo 101'i ve kendi kuralını alır, çünkü iki profil aynı tabloda varsayılan rotaya birlikte sahip olamaz. NetworkManager profilleri sistem genelindedir, bu yüzden bu bölüm elle kalır ve yeniden başlatmada kurallar kaybolur, bir şey onları geri getirmezse. Tabloları tünel tanımının yanındaki açılış betiğine yazın, böylece yeniden bağlanma bir hesabı yanlış yolda bırakmasın.
Loopback istisnası tüneli neden öldürür
Kuralın kopyalanan sürümlerinin çoğu loopback üzerinden çıkmayan her paketi düşürür. Tünel loopback değildir, bu yüzden bu biçim tünel trafiğini de düşürür ve sonuç güvenlik duvarı hatası değil ölü bir VPN gibi görünür.
OUTPUT çalıştığında çekirdek çıkış arayüzünü çoktan seçmiştir, bu yüzden -o paket başlığıyla değil rotanın yanıtıyla karşılaştırılır. Sahip eşleşmesi yalnızca OUTPUT ve POSTROUTING içinde sorgulanır ve iletilen paketler onun okuyabileceği bir soket taşımaz. Bu bileşim, istisnanın loopback'i reddetmek yerine tünel arayüzünü adlandırması ve o eşleşmeyi reddetmesi gerektiği anlamına gelir.
Loopback hâlâ DROP'un üstünde kendi ACCEPT'ini hak eder, çünkü programın ilk DNS paketi lo üzerinden yerel stub'a gider. İki kuralı bu sıraya koyun ve hesap stub'a, sonra tünele ulaşır, başka hiçbir yere değil.
iptables -I OUTPUT 1 -o lo -m owner --uid-owner vpnapp -j ACCEPT iptables -A OUTPUT -m owner --uid-owner vpnapp ! -o tun0 -j DROP
IPv6 ayrı bir kural kümesidir ve yalnızca v4 için olan çift ip6tables dokunulmadan bırakır. AAAA kayıtlarını tercih eden bir program o zaman DROP'a hiç ulaşmadan fiziksel bağlantıdan çıkardı. Her iki kuralı ip6tables içinde yansıtın veya tünel v6 adresi taşımadığında ana makinede IPv6'yı kapatın. Elle eklenen kurallar da yeniden başlatmada kaybolur, bu yüzden onları netfilter-persistent save ile kaydedin veya aynı mantığı açılış biriminin yüklediği nftables tablosu olarak yeniden kurun.
DNS yanıtları başka bir süreçten gelir
Programın 127.0.0.53 adresine sorgusu loopback ACCEPT'ini geçer ve UID eşleşmesi tam orada durur. Stub çözümleyici kendi hizmet hesabından yukarı iletir, bu yüzden vpnapp adresine bağlı bir kural ikinci sorguyu asla görmez. Çözümleyici bağlantı için bir LAN sunucusu seçerse yanıtlar fiziksel NIC üzerinden geri döner, programın kendi paketleri ise tünelde kalır. Görünen sonuç, adları bozuk çalışan bir tünel ya da seçmediğiniz bir sunucunun yanıtladığı adlardır.
Ad çözümlemesini uygulamada değil tünel bağlantısında düzeltin. Tünel profiline bir DNS sunucusu ve yönlendirme alanı verin, sonra resolvectl query ve resolvectl status tun0 ile çözümleyicinin önemli adlar için bunu kullandığını doğrulayın. Bir ağ ad alanının içinde sorun kaybolur, çünkü ad alanının çözümleyicisi yalnızca tüneli bilir.
Kuralı hesabın kendisinden denetleyin
Çekirdeğe bir UID'nin hangi rotayı aldığını sorun, sonra o hesap olarak bir istek yapın ve çıkış adresini kendi hesabınızınkiyle karşılaştırın. İkisi de aynı adresi bildiriyorsa kural, test ettiğiniz trafikten başka bir şeyle eşleşiyor. Aşağıdaki ilk komut paket göndermeden rota aramasını gösterir; bu, bir yönlendirme hatasını güvenlik duvarı hatasından ayırır.
ip route get 1.1.1.1 uid 1000 sudo -u vpnapp curl -s https://ifconfig.co
Sayaçlar bir kuralın hiç tetiklenip tetiklenmediğini gösterir. iptables -vnL OUTPUT komutunu çalıştırın, her kuralın yanındaki paket sayısını okuyun ve gerçek trafikten sonra DROP'un yanındaki sıfırı eşleşme hatası sayın.
İletilen trafik bu tasarımın dışındadır. Bir köprünün arkasındaki kapsayıcı veya VM'in vpnapp sahip olduğu yerel soketi yoktur, bu yüzden sahip eşleşmesi hiç tetiklenmez ve o paketler bunun yerine FORWARD ilkesini izler. O iş yükü kapsanacaksa ayrı test edin ve köprüye ya da kapsayıcı adresine bağlı bir ilke yazın. Tasarım, tablo, arayüz istisnası, çözümleyici ve v6 kuralları aynı yönü gösterdiğinde ayakta kalır; herhangi birini dışarıda bırakın, hesap ya sızar ya bağlantıyı kaybeder.