OpenVPN को root दिए बिना CAP_NET_ADMIN देना
बिना विशेषाधिकार वाले उपयोगकर्ता के रूप में शुरू होने वाली यूनिट को अब भी सही क्षमता-समूह की जरूरत होती है। यूनिट, जीवित प्रक्रिया और exec सीमा को इसी क्रम में जाँचें।
सेवा शुरू होती है, लॉग शिकायत करता है कि वह tun डिवाइस नहीं खोल सकता, और रूट कभी दिखाई नहीं देते। अपने शेल में capsh --print चलाएँ और cap_net_admin ठीक वहीं मिलेगा, जिससे विफलता असंभव लगती है। आपके शेल और यूनिट के बीच जो अंतर है वह विशेषाधिकार संक्रमण है, कर्नेल की क्षमता देने की इच्छा नहीं। नीचे दी चार जाँचें क्रम से करें और जो पहली खाई समझाए वहीं रुकें।
गुम क्षमता को छिपे डिवाइस से अलग करें
लॉग पंक्ति से दो विफलताएँ एक जैसी दिखती हैं। CAP_NET_ADMIN के बिना प्रक्रिया टनल इंटरफ़ेस न बना सकती है न कॉन्फ़िगर कर सकती है, और जिस प्रक्रिया का सैंडबॉक्स /dev/net/tun छिपाता है वह उसे शुरू से ही खोल नहीं सकती। क्षमताएँ जोड़ने से दूसरा मामला ठीक नहीं होगा।
कुछ भी संपादित करने से पहले जाँचें कि डिवाइस सेवा के नेमस्पेस के भीतर मौजूद है या नहीं। PrivateDevices=yes एक आम हार्डनिंग पंक्ति है जो tun नोड को पूरी तरह हटा देती है, और प्रतिबंधक ProtectSystem कॉन्फ़िगरेशन पथ को ऐसे केवल-पठनीय बना सकता है जो अनुमति त्रुटि जैसा पढ़ा जाए। दोनों ऐसी लॉग पंक्तियाँ बनाते हैं जो टनल का ज़िक्र करती हैं, इसलिए दोष क्षमताओं पर डाला जाता है। पहले पुष्टि करें कि नोड मौजूद है और खुल सकता है, फिर आगे बढ़ें।
जानें कि आप कौन-सा क्षमता-समूह देख रहे हैं
Linux अनुमत, प्रभावी, उत्तराधिकार-योग्य, सीमित और परिवेशी समूह रखता है, और परिवेशी समूह ही वह है जो गैर-root उपयोगकर्ता के exec के बाद बचता है। बाइनरी पर फ़ाइल-क्षमताएँ 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 ने सीमा खिसकाई है या नहीं।