OpenVPN'e root vermeden CAP_NET_ADMIN vermek
Ayrıcalıksız kullanıcı olarak başlayan bir unit yine de doğru yetenek kümesine ihtiyaç duyar. Unit'i, canlı süreci ve exec sınırını bu sırayla kontrol edin.
Servis başlıyor, günlük tun aygıtını açamadığından şikâyet ediyor ve rotalar hiç görünmüyor. Kendi kabuğunuzda capsh --print çalıştırın ve cap_net_admin hemen orada, bu da hatayı imkânsız gibi gösteriyor. Kabuğunuzla unit arasındaki fark, çekirdeğin yeteneği vermeye istekli olması değil, ayrıcalık geçişidir. Aşağıdaki dört kontrolü sırayla yapın ve boşluğu açıklayan ilkinde durun.
Eksik yeteneği gizli bir aygıttan ayırın
Günlük satırından iki hata aynı görünüyor. CAP_NET_ADMIN olmayan bir süreç tünel arayüzünü oluşturamaz veya yapılandıramaz, sandbox'ı /dev/net/tun gizleyen bir süreç ise onu baştan açamaz. Yetenek eklemek ikinci durumu düzeltmez.
Herhangi bir şeyi düzenlemeden önce aygıtın servisin ad alanı içinde olup olmadığını kontrol edin. PrivateDevices=yes tun düğümünü tamamen kaldıran yaygın bir sertleştirme satırıdır ve kısıtlayıcı ProtectSystem yapılandırma yolunu izin hatası gibi okunan bir biçimde salt okunur yapabilir. İkisi de tünelden söz eden günlük satırları üretir, bu yüzden yetenekler suçlanır. Önce düğümün var olduğunu ve açılabildiğini doğrulayın, sonra devam edin.
Hangi yetenek kümesine baktığınızı bilin
Linux izin verilen, etkin, devralınabilir, sınırlayan ve ortam kümelerini tutar ve exec'i root olmayan bir kullanıcıdan sonra atlatan ortam kümesidir. İkilinin üzerindeki dosya yetenekleri exec sırasında izin verilen ve etkin hakları devredebilir, ama yalnızca zincirde hiçbir şey bu aktarımı engellemediği sürece.
sudo burada insanları yanıltıyor. sudo -u üzerinden çalıştırılan bir komut yeni bir ayrıcalık geçişi başlatır ve ortam kümesi kaybolur, bu yüzden root olarak başarılı olan aynı kontrol orada başarısız olur. Servis yöneticisi yine başka bir geçiştir ve unit söylemedikçe ortamla ilgili hiçbir şey vermez.
Yeteneği sarmalayıcıda değil, unit içinde verin
Aygıt oluşturması ve rota kurması gereken bir tünel için asgari servis bölümü şöyle görünür.
[Unit]
Description=OpenVPN client, office profile
After=network-online.target
[Service]
Type=notify
User=openvpn
Group=openvpn
NoNewPrivileges=yes
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/office.confAmbientCapabilities hakkı süreç başlamadan önce ortam kümesine koyar ve CapabilityBoundingSet sürecin o listenin dışında bir şey tutmasını engeller. NoNewPrivileges=yes setuid veya dosya yetenekleri üzerinden ayrıcalık kazanmayı engeller, unitin açıkça verdiği yetenek ise geçerli olmaya devam eder. CAP_NET_BIND_SERVICE yalnızca servis düşük bir bağlantı noktası bağlamak zorunda olduğunda ekleyin ve bir forum başlığı yaptı diye CAP_SYS_ADMIN asla eklemeyin.
Unit ikiliyi sudo içine sarıyorsa sarmalayıcıyı kaldırın. systemd zaten User= uygular ve bu ek katman ortam kümesinin boş olmasının en olası nedenidir.
Unit dosyasına değil, canlı sürece karşı doğrulayın
Yöneticinin gerçekte ne uyguladığını okuyun, sonra oluşturduğu süreci okuyun.
unit=openvpn-client@office
systemctl show -p User -p AmbientCapabilities "$unit"
systemctl show -p MainPID --value "$unit" | xargs -r getpcaps
grep -E '^Cap(Eff|Amb)' /proc/$(systemctl show -p MainPID --value "$unit")/statusUnit yeteneği listeliyor ama CapEff hâlâ onu içermiyorsa, bir drop-in ayarı geçersiz kılıyor ya da bir ExecStartPre adımı ortamı değiştiriyor. Ana dosyanın yetkili olduğunu varsaymadan önce drop-in dizinlerinde unit adını arayın, çünkü sonraki dosya sessizce kazanır. Hem unit hem de süreç yeteneği gösteriyor ve tünel hâlâ başarısız oluyorsa, sınırlayan kümeyi genişletmek yerine aygıt ve yol kontrollerine dönün. Onu genişletmek gerçek nedeni saklar ve servisi eskisinden daha ayrıcalıklı bırakır.
Başlangıçtan sonra ayrıcalıkları bırakmayı tercih edin
OpenVPN ayrıcalıklı başlayıp sonra kendi user ve group seçenekleriyle ayrıcalıksız bir hesaba inebilir, persist-key ve persist-tun tüneli sonrasında kullanılabilir tutar. Bu düzen, sürecin haklara sahip olduğu pencereyi daraltır ve genellikle tüm daemonu kalıcı yeteneklerle ayrıcalıksız başlatmaktan daha uygundur.
Hangi modeli seçerseniz seçin, unit'i yeniden başlatın ve yeniden başlatmadan sonra kontrolleri yineleyin, çünkü etkileşimli bir root kabuğundan çalışıp açılışta başarısız olan bir servis genellikle yetenek, aygıt veya dosya izni farkıdır. Unit ayarlarını sürecin yetenek çıktısının yanına not edin, böylece bir sonraki gözden geçiren paket güncellemesinin veya bir drop-in'in sınırı kaydırıp kaydırmadığını görsün.