VPN konteynerinde NET_ADMIN: neyi ve nerede değiştirebilir
Bu yetenek, tek bir ağ ad alanı içinde arayüz, rota ve güvenlik duvarı değişikliklerine izin verir. Ana bilgisayar ağıyla bu ad alanı ana bilgisayarın kendi yığınıdır.
NET_ADMIN, bir sürecin ağ yönetimi yapmasına izin veren Linux yeteneğidir ve bir konteynerde tam olarak bunu sürecin çalıştığı ağ ad alanı içinde yapar. Bu bir soket açma lisansı değildir ve bir aygıtın veya rotanın yerine geçmez. İlginç soru hiçbir zaman yeteneğin verilip verilmediği değil, değişikliği hangi ad alanının aldığıdır.
Yetenek neleri kapsar
Kendi ad alanı içinde NET_ADMIN taşıyan bir süreç arayüzleri kaldırıp indirebilir, adres atayabilir, rota ekleyip kaldırabilir ve güvenlik duvarı kuralları yazabilir; bu, capabilities(7) belgesinin bu yetenek altında topladığı işlem grubudur. Çekirdeğin trafiği nasıl kuyruğa aldığını ve filtrelediğini denetleyen arayüz düzeyindeki ayarları da düzenleyebilir. Bir VPN istemcisi başlangıçta bunlardan birkaçına ihtiyaç duyar ve sonrasında başka hiçbir şeye ihtiyaç duymaz. Bu yüzden çoğu imaj kullandığından daha geniş bir kapsam ister.
O ad alanının dışındaki işlemler kapsanmaz ve komşu ayrıcalıklar ayrıdır. Ham paketleri okumak ve yazmak NET_RAW kapsamındadır ve bir tun aygıtı oluşturmak hem yeteneği hem de aygıt düğümüne erişimi gerektirir. Aygıtı olmayan bir süreç, ağ sorunu gibi görünen ama olmayan bir izin hatası alır.
Ad alanı hasar yarıçapını belirler
Kendi köprü ağındaki bir konteyner kendi loopback'ine, kendi arayüzlerine ve kendi yönlendirme tablosuna erişir. Orada NET_ADMIN verilmesi VPN istemcisinin ana bilgisayarın yönlendirme kararlarına dokunmadan bir tünel kurmasını sağlar; çoğu konteyner imajının varsaydığı düzen budur.
O konteyneri ana bilgisayar ağına geçirin ve aynı izin artık ana bilgisayarın rotalarını ve güvenlik duvarını düzenler, çünkü ayrı bir ad alanı kalmamıştır. Tek bir tüneli yönetmesi gereken istemci o zaman tüm makinenin trafiğini yönlendirebilir ve sökme betiğindeki bir hata ana bilgisayarda kimsenin yazmadığı kurallar bırakır. Yeteneğin kendisinde hiçbir şey değişmedi; bağlam değişti. Aynı compose dosyasının iki ana bilgisayarda farklı davranmasının nedeni budur.
Tekte birleşen üç ön koşul
VPN konteynerlerindeki başlatma hataları genellikle üç ayrı şeyden biriyle ilgilidir: yetenek, tünel aygıtı ve protokol için çekirdek desteği. Üçünü birden vermek işe yarar ve bir sonraki hatayı da atfedilemez kılar. Asgari bir compose parçası yeteneği verir ve aygıt düğümünü açıkça iletir:
services:
vpn:
image: example/vpn-client:latest
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
sysctls:
- net.ipv4.conf.all.src_valid_mark=1Hangi sysctl'lere ihtiyaç duyduğunu imajın kendi belgelerinden okuyun, çünkü konteyner içindeki bir sysctl ek bir ayrıcalık veya ana bilgisayar düzeyinde bir ayar gerektirebilir. İmajın yalnızca kullanıcı alanı kipini desteklediği yerlerde aygıta hiç gerek yoktur ve yetenek listesi buna göre küçülür.
Kipi değil, dar işlemi verin
Ayrıcalıklı kip her yeteneği devreder ve aynı zamanda aygıt erişimini genişletir, bu yüzden üç ön koşuldan hangisinin eksik olduğunu gizler. Konteynerin arıza biçimlerini ana bilgisayar değişikliklerinden ayırt edilemez de kılar. Yazması daha uzun olsa bile açık bir listeyi tercih edin.
Rootsuz ve kullanıcı ad alanı dağıtımları, yeteneğin pratikte ne anlama geldiğini değiştirir, çünkü süreç onu yalnızca eşlenmiş bir ad alanı içinde tutabilir. Bir yetenek listesini rootlu bir örnekten rootsuz bir çalışma ortamına kopyalayıp aynı erişimi beklemek öğleden sonrayı kaybetmenin yaygın bir yoludur.
Sırlar ayrı bir karara aittir. NET_ADMIN taşımak, istemcinin hangi eş kimliğini sunduğu, hangi kimlik bilgilerini yüklediği veya bunların nasıl döndürüldüğü hakkında hiçbir şey söylemez. Ağ yönetimi güven sağlamaz.
Değişikliği doğrulayın ve iznin neden var olduğunu kaydedin
Tünelde hata ayıklamadan önce konteynerin gerçekte ne aldığını doğrulayın. Aşağıdaki inceleme eklenen yetenekleri ve ağ kipini bildirir, ardından arayüz listesinin içeriden nasıl göründüğünü gösterir:
docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip routeYetenek varsa ve arayüz listesi hâlâ boşsa, istemci bir şey oluşturamadan önce başarısız olmuştur ve bakılacak sonraki yer konteyner günlükleridir. Tünel varsa ama trafik akmıyorsa, konteynerin içindeki yönlendirme tablosu bir sonraki soruyu yanıtlar.
Sökme yolunu da test edin, çünkü güvenlik duvarı kuralları yazan bir istemci bunları geride bırakabilir. Konteyneri durdurun ve ana bilgisayar ağı kullanılıyorsa ana bilgisayarın kural kümesini yeniden kontrol edin. Yalnızca başlangıçta iki saniye gereken bir izin, bunu açıklayan bir not olmadan compose dosyasında kalıcı bir gereksinim olarak tanımlanmamalıdır.
Her yeteneğin yanına nedeni yazın: hangi işlem ona ihtiyaç duydu ve o olmadan ne başarısız oluyor. Bu not imaj güncellemelerinden sonra da kalır ve gözden geçirilmiş bir ayrıcalık listesiyle kopyalayıp yapıştırarak büyüyen bir liste arasındaki fark budur.