دادن CAP_NET_ADMIN به OpenVPN بدون دادن root
واحدی که با کاربر بدون دسترسی ممتاز آغاز میشود هنوز به مجموعه توانایی درست نیاز دارد. واحد، فرایند زنده و مرز exec را به همین ترتیب بررسی کنید.
سرویس آغاز میشود، گزارش مینالد که نمیتواند دستگاه tun را باز کند، و مسیرها هرگز پدیدار نمیشوند. دستور capsh --print را در شل خود اجرا کنید و cap_net_admin همانجاست، که شکست را غیرممکن جلوه میدهد. آنچه میان شل شما و واحد تفاوت دارد گذار امتیازهاست، نه آمادگی هسته برای اعطای توانایی. چهار بررسی زیر را به ترتیب انجام دهید و در نخستین بررسیای که شکاف را توضیح میدهد بایستید.
توانایی غایب را از دستگاه پنهان جدا کنید
دو شکست از روی خط گزارش یکسان به نظر میرسند. فرایندی بدون CAP_NET_ADMIN نمیتواند رابط تونل را بسازد یا تنظیم کند، و فرایندی که جعبهشنیاش /dev/net/tun را پنهان میکند از آغاز نمیتواند آن را باز کند. افزودن تواناییها مورد دوم را درست نمیکند.
پیش از تغییر هر چیزی بررسی کنید آیا دستگاه درون فضای نام سرویس وجود دارد. PrivateDevices=yes خط سختیسازی رایجی است که گره tun را بهکلی حذف میکند، و ProtectSystem محدودکننده میتواند مسیر پیکربندی را چنان فقطخواندنی کند که مانند خطای دسترسی خوانده شود. هر دو خطوط گزارشی میسازند که تونل را ذکر میکنند، و از همین رو تواناییها سرزنش میشوند. نخست تأیید کنید که گره هست و باز میشود، سپس پیش بروید.
بدانید به کدام مجموعه توانایی نگاه میکنید
لینوکس مجموعههای مجاز، مؤثر، قابلارثبری، کرانمند و محیطی را نگه میدارد، و مجموعه محیطی همان است که از exec کاربر غیر root جان به در میبرد. تواناییهای فایل روی باینری میتوانند هنگام exec حقوق مجاز و مؤثر را واگذار کنند، اما تنها تا زمانی که چیزی در زنجیره آن واگذاری را مسدود نکند.
اینجاست که sudo مردم را گمراه میکند. فرمانی که از طریق sudo -u اجرا میشود گذار تازهای از امتیازها را آغاز میکند و مجموعه محیطی از میان میرود، پس همان بررسیای که بهعنوان root موفق میشود آنجا شکست میخورد. مدیر سرویس هم گذار دیگری است، و چیزی محیطی اعطا نمیکند مگر آنکه واحد چنین بگوید.
توانایی را در واحد بدهید، نه در پوشش
بخش خدمت کمینه برای تونلی که باید دستگاهی بسازد و مسیرهایی نصب کند چنین است.
[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 حق را پیش از آغاز فرایند در مجموعه محیطی میگذارد، و CapabilityBoundingSet نمیگذارد فرایند چیزی بیرون از آن فهرست نگه دارد. NoNewPrivileges=yes کسب امتیاز از راه setuid یا تواناییهای فایل را مسدود میکند، در حالی که تواناییای که واحد آشکارا میدهد هنوز اعمال میشود. CAP_NET_BIND_SERVICE را تنها زمانی بیفزایید که سرویس باید درگاهی پایین را ببندد، و هرگز CAP_SYS_ADMIN را فقط به این دلیل که رشتهای در انجمن چنین کرده است نیفزایید.
اگر واحد باینری را در sudo میپیچد، پوشش را بردارید. systemd از پیش User= را اعمال میکند، و آن لایه اضافی محتملترین دلیل خالی بودن مجموعه محیطی است.
در برابر فرایند زنده بررسی کنید، نه پرونده واحد
بخوانید مدیر در واقع چه اعمال کرده است، سپس فرایندی را که پدید آورده بخوانید.
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")/statusاگر واحد توانایی را فهرست میکند و CapEff هنوز آن را ندارد، یک drop-in تنظیم را زیر پا میگذارد یا گام ExecStartPre محیط را تغییر میدهد. پیش از آنکه پرونده اصلی را مرجع بدانید، نام واحد را در شاخههای drop-in جستوجو کنید، زیرا پروندهای که دیرتر میآید بیصدا پیروز میشود. اگر هم واحد و هم فرایند توانایی را نشان میدهند و تونل هنوز شکست میخورد، به بررسیهای دستگاه و مسیر بازگردید نه به گستردن مجموعه کرانمند. گستردن آن علت واقعی را پنهان میکند و سرویس را ممتازتر از پیش رها میکند.
کاهش امتیازها پس از راهاندازی را ترجیح دهید
OpenVPN میتواند با امتیاز آغاز کند و سپس از راه گزینههای user و group خود به حسابی بدون امتیاز فرود آید، و persist-key و persist-tun تونل را پس از آن قابل استفاده نگه میدارند. این چیدمان پنجرهای را که فرایند در آن حقوق دارد تنگ میکند، و غالباً از آغاز کردن تمام دیمن بدون امتیاز با تواناییهای دائمی مناسبتر است.
هر الگویی که برگزینید، واحد را دوباره راهاندازی کنید و بررسیها را پس از ریاستارت تکرار کنید، زیرا سرویسی که از شل root تعاملی کار میکند و هنگام بوت شکست میخورد معمولاً تفاوتی در توانایی، دستگاه یا دسترسی فایل است. تنظیمات واحد را کنار خروجی توانایی فرایند ثبت کنید تا بازبین بعدی ببیند آیا بهروزرسانی بسته یا drop-in مرز را جابهجا کرده است.