OpenVPN qarmağını hansı systemd sandbox-unun rədd etdiyini necə tapmalı
Qarmaq root kimi işləyir, systemd altında isə uğursuz olur, çünki unit daha az imkan, daha kiçik /dev və yalnız oxuna bilən yollar saxlayır.
Qarmaq onu əl ilə root kimi işlətdikdə işləyir və Operation not permitted qaytarır, xidmət onu işə salan anda. Fayl bu iki işə salma arasında dəyişməyib; mühit dəyişib. systemd prosesə daha kiçik bir dünya verir: daha az imkan, fərqli /dev, yalnız oxuna bilən fayl sistemi yolları və tapşırıq tavanı. Uğursuzluğu bir konkret əməliyyatı rədd edən sərhəd kimi oxuyun, pozulmuş skript kimi yox.
Rədd edilən əməliyyatdan başlayın
Unitin uğursuz olduğunu deyən log sətri demək olar ki, heç nə demir. Faydalı sətir rədd edilən çağırışı adlandırır: açıla bilməyən cihaz qovşağı, yazıla bilməyən qovluq, yaradıla bilməyən ad sahəsi. Hər hansı direktivə toxunmazdan əvvəl həmin çağırışı tapın, çünki hər biri fərqli məhdudiyyətə uyğun gəlir. Sonra paketin göndərdiyi faylı deyil, həqiqətən işləyən uniti, drop-in-lər daxil olmaqla oxuyun.
Aşağıdakı sorğu fraqment yolunu, drop-in qovluqlarını və cihaz ya fayl sistemi rəddi üçün vacib olan xassələri çap edir. Hansı sərhədin aktual olduğuna qərar verməzdən əvvəl hamısını oxuyun:
systemctl show "[email protected]" -p FragmentPath -p DropInPaths -p PrivateDevices -p DevicePolicy -p DeviceAllow -p ProtectHome -p ProtectSystem -p TasksMax
journalctl -u "[email protected]" -b --no-pager | grep -iE 'operation not permitted|permission denied|cannot open|failed'Bu blokda heç nə yazmır. Rədd edilən çağırış jurnalda yoxdursa, direktivləri təxmin etmək əvəzinə bir işə salma üçün müştərinin detallılıq səviyyəsini artırın. İşləyən proses unitin başladığını sübut edir, qarmağın lazımi imtiyazlarla işlədiyini yox.
Ad sahəsi TUN cihazının heç vaxt istifadə etmədiyi mount hüquqlarını tələb edir
Bir qarmaq daxilində eyni görünən iki əməliyyatın icazə profilləri fərqlidir. /dev/net/tun açmaq və interfeysi yaratmaq şəbəkə administrasiyası və həmin qovşağa giriş tələb edir. Adlandırılmış şəbəkə ad sahəsi yaratmaq da mount ilə əlaqəli iş tələb edir, çünki ad sahəsi aləti təzə /sys görünüşü mount edir və bir vəziyyət qovluğunu yerinə bağlayır. yuxarı axın müştəri uniti mount administrasiyasını qəsdən öz bounding set-indən kənarda saxlayır, buna görə ad sahəsi addımı rədd edilir, halbuki tunelin özü işləyərdi.
Buna görə cihaz qovşağının verilməsi skripti xilas etmir. Bir cihaz icazəsi tək bir suala cavab verir: bu proses bu qovşağı aça bilərmi? Ad sahəsi sualı isə başqa sualdır. Bir şeyi genişləndirməzdən əvvəl uğursuz çağırışı öz imkanı ilə uyğunlaşdırın.
Qabığınızdakı test məhdudiyyətsiz root-un malik olduğu hər imkanı miras alır, unit isə öz bounding set-inin saxladığını miras alır. İki işə salma fərqli təcrübələrdir binar fayl eyni olsa belə.
Cihazlar, qorunan yollar və tapşırıq tavanları
Rədd edilən əməliyyat bilindikdən sonra üç direktiv qrupu uğursuzluqların çoxunu izah edir. Cihaz girişinə PrivateDevicesnəzarət edir, hansı ki /dev minimal psevdo-cihaz dəsti ilə əvəz edir, və DevicePolicy ilə DeviceAllowbirlikdə cgroup-un nəyə icazə verdiyini müəyyən edir. /dev/net/tun həmin minimal dəstin hissəsi deyil, ona görə PrivateDevices=yes olan unit cihaz siyasəti nə deyirsə də onu aça bilməz.
Fayl sistemi qoruması ikinci suala cavab verir. ProtectHome=yes /home, /root və /run/user qovluqlarını əlçatmaz edir, və ProtectSystem=full /usr, /boot və /etc qovluqlarını yalnız oxuna bilən edir. Buna görə öz konfiqurasiya faylının yanında yazan qarmaq sizin qabığınızda işləyir və unit altında uğursuz olur, itkin imkanla eyni icazə forması ilə. Yazıla bilən girişi siyasətin icazə verdiyi yola köçürün və ya dar bir ReadWritePaths= girişi əlavə edin.
Resurs məhdudiyyətləri üçüncü qrupdur və ən az aydın olanıdır. TasksMax= unitin nə qədər tapşırıq yarada biləcəyini məhdudlaşdırır, fayl deskriptoru tavanı isə soketlər və tutacaqlar üçün eyni cür davranır. Tavandan böyüyən yerləşdirmə icazə xətası əvəzinə resurs xətası ilə uğursuz olur, buna görə dəqiq mesaj hələ də vacibdir.
Ad sahəsi addımını qarmaqdan çıxarın
Müştərinin malik olmamalı olduğu imtiyazı tələb edən hazırlıq öz unitində yer almalıdır. Müştəridən əvvəl işləyən, nəticəsini saxlayan və bağlantıdan əvvəl sıralanan bir oneshot ad sahəsi addımına lazım olanı verir, həmin hüquqları tunel prosesinə vermədən. Sonra müştəri skripti öz up qarmağından çağırmaq əvəzinə həmin unitə istinad edir.
Aşağıdakı şablon başlanğıc formasıdır, oxumadan tətbiq ediləcək bir şey deyil. Hazırlığı imtiyazın yaşadığı yerdə saxlayır və tunel unitinə toxunmur:
# /etc/systemd/system/[email protected]
[Unit]
Description=Namespace preparation for %i
Before=openvpn-client@%i.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/netns-up.sh %i
CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.targetSıralamanı paketlənmiş uniti redaktə etmək əvəzinə drop-in ilə əlavə edin, belə ki yeniləmə dəyişikliyinizi səssizcə ata bilməsin. Qovluğun açarı instansiya adıdır, ona görə ikinci profil öz faylını tələb edir:
sudo mkdir -p /etc/systemd/system/[email protected]
sudo tee /etc/systemd/system/[email protected]/10-namespace.conf >/dev/null <<'CONF'
[Unit]
[email protected]
[email protected]
CONF
sudo systemctl daemon-reloadDəyişiklikdən sonra eyni çağırışı təkrarlayın
Təmir yalnız eyni çağırış fərqli nəticə verdikdə təsdiqlənir. Hər iki uniti yenidən başladın, uğursuz olan əməliyyatı icra edin və nəticəsini dəyişiklikdən əvvəl saxladığınız jurnal sətri ilə müqayisə edin. Qarmaq bir daha işləmədiyi halda başlayan unit təmir deyil.
Aşağıdakı ardıcıllıq müqayisəni dürüst saxlayır, çünki unitin rəngini deyil, rədd edilən çağırışı yoxlayır. Çıxışını dəyişiklikdən əvvəl tutduğunuz jurnal sətrinin yanında saxlayın:
sudo systemctl restart "[email protected]" "[email protected]"
systemctl status "[email protected]" --no-pager
journalctl -u "[email protected]" -b --no-pager | grep -c 'Operation not permitted'
ip -brief addr show tun0Son sətri oxumaq əvəzinə rəddləri sayın, çünki qarmaq uğursuz ola, yenidən cəhd edə və uğurlu ola bilər, sərhədin tərpənib-tərpənmədiyini yalnız say göstərir. Drop-in-də boşaltdığınız direktivin adını və səbəbini qeyd edin, çünki növbəti yeniləmə konfiqurasiyanızı paketlənmiş defoltla müqayisə edir. Yalnız bütün qorumalar söndürüldükdən sonra başlayan unit düzəldilməyib.