यदि मेरा आवेदन शुरू से ही निचले स्तर पर चल सकता है, तो मैं सुरक्षा के लिए सैंडबॉक्सिंग के लिए चुरोट क्यों करूंगा?


14

मैं सी में एक HTTP सर्वर डेमन लिख रहा हूं (इसके कारण हैं), इसे सिस्टमड यूनिट फ़ाइल के साथ प्रबंधित करना।

मैं 20 साल पहले, 1995 के आसपास डिज़ाइन किए गए एक आवेदन को फिर से लिख रहा हूं। और जो सिस्टम वे उपयोग करते हैं, वह यह है कि वे चुरोट और फिर सेट्युड, और मानक प्रक्रिया।

अब मेरे पिछले काम में, सामान्य नीति यह थी कि आप कभी भी किसी प्रक्रिया को मूल नहीं मानते हैं। आप इसके लिए एक उपयोगकर्ता / समूह बनाएं और वहां से चलाएं। बेशक, सिस्टम ने कुछ चीजों को रूट के रूप में चलाया, लेकिन हम रूट किए बिना सभी बिजनेस लॉजिक प्रोसेसिंग को प्राप्त कर सकते थे।

अब HTTP डेमॉन के लिए, मैं इसे रूट के बिना चला सकता हूं, अगर मैं एप्लिकेशन के अंदर चेरोट नहीं करता हूं। तो क्या यह एप्लिकेशन को कभी भी रूट के रूप में चलाने के लिए अधिक सुरक्षित नहीं है?

क्या इसे शुरू से ही mydaemon-user के रूप में चलाना अधिक सुरक्षित नहीं है? इसे रूट, चेरोटिंग से शुरू करने के बजाय, फिर mydaemon-user पर सेट करें?


3
आपको पोर्ट 80 या 443 का उपयोग करने के लिए रूट के रूप में चलाने की आवश्यकता है। अन्यथा, आप ऐसा कर सकते हैं कि टॉमकैट, और अन्य वेबैप / वेब-सर्वर सॉफ़्टवेयर क्या करता है और एक उच्च पोर्ट पर चलता है (जैसे, 8080, 9090, आदि) और फिर या तो उपयोग करें अपाचे / nginx आपके वेब सर्वर सॉफ़्टवेयर से कनेक्शन को प्रॉक्सी करने के लिए, या नेट 80 के लिए सिस्टम के फ़ायरवॉल का उपयोग करें / पोर्ट 80 से अपने वेबसर्वर पर ट्रैफ़िक को अग्रेषित करें। यदि आपको पोर्ट 80 या 443 की आवश्यकता नहीं है, या कनेक्शन को प्रॉक्सी या फॉरवर्ड कर सकते हैं, फिर आपको रूट के रूप में, चुरोट में या अन्यथा चलने की कोई आवश्यकता नहीं है।
स्नेकडोक

3
@SnakeDoc लिनक्स पर अब सच नहीं है। के लिए धन्यवाद capabilities(7)
0xC0000022L

@SnakeDoc आप ऑर्बिट के साथ
अब्दुल अहद

जवाबों:


27

ऐसा लगता है कि दूसरों ने आपकी बात को याद किया है, जो कारण नहीं थे कि परिवर्तित जड़ों का उपयोग करने के लिए, जो निश्चित रूप से आप पहले से ही स्पष्ट रूप से जानते हैं, और न ही आप डॉमन पर सीमाएं लगाने के लिए क्या कर सकते हैं, जब आप स्पष्ट रूप से दूसरों के तत्वावधान में चलने के बारे में जानते हैं। बिना खाता वाले उपयोगकर्ता खाते; लेकिन आवेदन के अंदर यह सामान क्यों करना है । क्यों के बिंदु उदाहरण पर वास्तव में एक काफी है।

httpdडैनियल जे। बर्नस्टीन के पब्लिकफाइल पैकेज में डॉमन कार्यक्रम के डिजाइन पर विचार करें । पहली बात यह है कि रूट रूट को रूट डाइरेक्टरी में बदल दिया गया है जिसे यह एक कमांड तर्क के साथ उपयोग करने के लिए कहा गया था, फिर विशेषाधिकार प्राप्त उपयोगकर्ता आईडी और समूह आईडी के लिए विशेषाधिकार छोड़ दें जो दो पर्यावरण चर में पारित किए जाते हैं।

Dæmon प्रबंधन टूलसेट में रूट डायरेक्टरी को बदलने और अनप्लग किए गए उपयोगकर्ता और समूह आईडी को छोड़ने जैसी चीजों के लिए समर्पित उपकरण हैं। गेरिट पपी की रनरेट है chpst। मेरा नोश टूलसेट है chrootऔर setuidgid-fromenv। लॉरेंट Bercot s6 है s6-chrootऔर s6-setuidgid। वेन मार्शल के पेर runtoolऔर है runuid। इत्यादि। दरअसल, उन सभी के पास एम। बर्नस्टीन का अपना डेमोंटोल्स टूलसेट है setuidgid, जो एक एंटीकेडेंट के रूप में है।

किसी को लगता है कि कोई httpdइस तरह के समर्पित टूल से कार्यक्षमता को निकाल सकता है और उपयोग कर सकता है । फिर, जैसा कि आप कल्पना करते हैं, सर्वर प्रोग्राम का कोई भी हिस्सा सुपरसुअर विशेषाधिकारों के साथ कभी नहीं चलता है।

समस्या यह है कि प्रत्यक्ष परिणाम के रूप में एक को बदले हुए रूट को स्थापित करने के लिए अधिक काम करना पड़ता है, और यह नई समस्याओं को उजागर करता है।

बर्नस्टीन के साथ httpdजैसा कि यह खड़ा है, केवल फाइलें और निर्देशिका जो रूट डायरेक्टरी ट्री में हैं वे दुनिया में प्रकाशित होने वाली हैं। नहीं है और कुछ नहीं सब पर पेड़ में। इसके अलावा, किसी भी निष्पादन योग्य प्रोग्राम छवि फ़ाइल के उस पेड़ में मौजूद होने का कोई कारण नहीं है ।

लेकिन एक श्रृंखला लोडिंग कार्यक्रम (या systemd) में रूट निर्देशिका परिवर्तन बाहर ले जाते हैं, और के लिए अचानक कार्यक्रम छवि फ़ाइल httpd, किसी भी साझा पुस्तकालयों यह है कि लोड होता है और किसी भी विशेष फ़ाइलों /etc, /runऔर /devकार्यक्रम लोडर या सी पुस्तकालय पहुँच रनटाइम कि प्रोग्राम इनिशियलाइज़ेशन के दौरान (जो आपको काफी आश्चर्यजनक लग सकता है यदि आप truss/ straceC या C ++ प्रोग्राम), भी परिवर्तित रूट में मौजूद होना चाहिए। अन्यथा httpdइसे जंजीर में नहीं डाला जा सकता और न ही इसे लोड / चलाया जा सकेगा।

याद रखें कि यह एक HTTP (S) सामग्री सर्वर है। यह संभावित रूप से परिवर्तित रूट में किसी भी (विश्व-पठनीय) फ़ाइल की सेवा कर सकता है। इसमें अब आपके साझा लाइब्रेरी, आपके प्रोग्राम लोडर, और आपके ऑपरेटिंग सिस्टम के लिए विभिन्न लोडर / CRTL कॉन्फ़िगरेशन फ़ाइलों की प्रतियां शामिल हैं। और अगर कुछ (आकस्मिक) से मतलब है कि सामग्री सर्वर में सामान लिखने की पहुंच है , तो एक समझौता किया हुआ सर्वर संभवतः httpdअपने लिए प्रोग्राम छवि तक पहुंच प्राप्त कर सकता है, या यहां तक ​​कि आपके सिस्टम का प्रोग्राम लोडर भी लिख सकता है । (याद रखें कि आप अब की दो समानांतर सेट है कि /usr, /lib, /etc, /run, और /devनिर्देशिका सुरक्षित रखने के लिए।)

इनमें से कोई भी ऐसा मामला नहीं है जो httpdरूट को बदलता है और विशेषाधिकारों को छोड़ देता है।

तो आपने विशेषाधिकार प्राप्त कोड की एक छोटी राशि का कारोबार किया है, जो ऑडिट करने में काफी आसान है और जो httpdप्रोग्रामर के विशेषाधिकारों के साथ चलकर कार्यक्रम की शुरुआत में सही चलता है ; परिवर्तित रूट के भीतर फ़ाइलों और निर्देशिकाओं की एक बहुत विस्तारित हमले की सतह होने के लिए।

यही कारण है कि सेवा कार्यक्रम के लिए बाहरी रूप से सब कुछ करना उतना सरल नहीं है।

ध्यान दें कि यह फिर भी httpdअपने भीतर एक न्यूनतम कार्यक्षमता है। सभी कोड जो ऐसी चीजें करते हैं जैसे कि उपयोगकर्ता आईडी और समूह आईडी के लिए ऑपरेटिंग सिस्टम के खाते के डेटाबेस में उन पर्यावरण चर को पहली जगह में देखने के लिए httpdप्रोग्राम के लिए बाहरी है , सरल स्टैंडअलोन ऑडिटेबल कमांड जैसे envuidgid। (और निश्चित रूप से यह एक UCSPI उपकरण है तो यह कोड में से कोई भी प्रासंगिक TCP पोर्ट (एस) या कनेक्शन स्वीकार करने पर सुनने के लिए होता है, इस तरह के रूप आदेशों की डोमेन जा रहा है उन tcpserver, tcp-socket-listen, tcp-socket-accept, s6-tcpserver4-socketbinder, s6-tcpserver4d, और इतने पर।)

आगे की पढाई


+1, आरोप के अनुसार दोषी। मैंने शीर्षक और अंतिम पैराग्राफ अस्पष्ट पाया, और यदि आप सही हैं तो मैं इस बिंदु को याद कर रहा हूं। यह उत्तर बहुत व्यावहारिक व्याख्या देता है। व्यक्तिगत रूप से मैं स्पष्ट रूप से ध्यान देना चाहूंगा कि चिरोट वातावरण का निर्माण इस तरह का एक अतिरिक्त प्रयास है, जिससे अधिकांश लोग बचना चाहेंगे। लेकिन यहां के 2 सुरक्षा बिंदु पहले से ही अच्छे हैं।
sourcejedi

याद रखने की एक और बात यह है कि यदि सर्वर किसी नेटवर्क ट्रैफ़िक को संसाधित करने से पहले विशेषाधिकार छोड़ देता है, तो विशेषाधिकार कोड किसी भी दूरस्थ कारनामे के संपर्क में नहीं आता है।
कैस्परल्ड

5

मुझे लगता है कि आपके प्रश्न के कई विवरण समान रूप से लागू हो सकते हैं avahi-daemon, जिन्हें मैंने हाल ही में देखा था। (मैं एक और विस्तार याद कर सकते हैं कि हालांकि अलग है)। एवोही-डेमॉन को चेरोट में चलाने के कई फायदे हैं, अगर एवाही-डेमन से समझौता किया जाता है। इसमें शामिल है:

  1. यह किसी भी उपयोगकर्ता के घर निर्देशिका को नहीं पढ़ सकता है और निजी जानकारी को बाहर निकाल सकता है।
  2. यह / tmp लिखकर अन्य कार्यक्रमों में बग का दोहन नहीं कर सकता है। इस तरह के कीड़े की कम से कम एक पूरी श्रेणी है। जैसे https://www.google.co.uk/search?q=tmp+race+security+bug
  3. यह किसी भी यूनिक्स सॉकेट फ़ाइल को नहीं खोल सकता है, जो चेरोट के बाहर है, जिस पर अन्य डेमॉन संदेश सुन और पढ़ सकते हैं।

बिंदु 3 विशेष रूप से अच्छा हो सकता है जब आप डब या समान का उपयोग नहीं कर रहे हैं ... मुझे लगता है कि अवही-डेमन डब का उपयोग करता है, इसलिए यह सुनिश्चित करता है कि सिस्टम डब का उपयोग चुरोट के अंदर से भी किया जाए। यदि आपको सिस्टम डब पर संदेश भेजने की क्षमता की आवश्यकता नहीं है, तो इस बात से इनकार करते हुए कि क्षमता काफी अच्छी सुरक्षा सुविधा हो सकती है।

सिस्टमड यूनिट फ़ाइल के साथ इसे प्रबंधित करना

ध्यान दें कि अगर अवही-डेमॉन को फिर से लिखा गया था, तो यह संभवतः सुरक्षा के लिए सिस्टमड पर भरोसा करने और उदाहरण के लिए उपयोग करने के लिए चुन सकता है ProtectHome। मैंने इन सुरक्षा को अतिरिक्त परत के रूप में जोड़ने के लिए अवही-डेमॉन में बदलाव का प्रस्ताव रखा, साथ ही कुछ अतिरिक्त सुरक्षा प्रदान की जो चेरोट द्वारा गारंटीकृत नहीं हैं। आप मेरे द्वारा प्रस्तावित विकल्पों की पूरी सूची देख सकते हैं:

https://github.com/lathiat/avahi/pull/181/commits/67a7b10049c58d6afeebdc64ffd2023c5a93d49a

ऐसा लगता है कि अधिक प्रतिबंध हैं जो मैं इस्तेमाल कर सकता था अगर अवही-डेमन खुद चेरोट का उपयोग नहीं करते थे, जिनमें से कुछ का उल्लेख प्रतिबद्ध संदेश में किया गया है। मुझे यकीन नहीं है कि यह कितना लागू होता है।

ध्यान दें, मेरे द्वारा उपयोग किए जाने वाले प्रोटेक्शन ने डेमॉन को यूनिक्स सॉकेट फाइल (प्वाइंट 3 ऊपर) खोलने से सीमित नहीं किया होगा।

एक अन्य दृष्टिकोण SELinux का उपयोग करना होगा। हालाँकि आप अपने एप्लिकेशन को लिनक्स वितरण के उस उप-सेट से बांधना चाहेंगे। यहाँ मैंने SELinux के बारे में सकारात्मक रूप से सोचा, इसका कारण यह है कि SELinux उस पहुँच को प्रतिबंधित करता है, जो प्रक्रियाओं को ठीक-ठाक तरीके से dbus में रखती है। उदाहरण के लिए, मुझे लगता है कि आप अक्सर उम्मीद कर सकते हैं कि systemdबस नाम की सूची में नहीं होगा जो आपको संदेश भेजने के लिए सक्षम होना चाहिए :-)।

"मैं सोच रहा था, अगर सिस्टमड सैंडबॉक्सिंग का उपयोग चेरोट / सेतुइड / उमस्क / ... से अधिक सुरक्षित हो ..."

सारांश: दोनों क्यों नहीं? चलो ऊपर थोड़ा सा डिकोड करें।

यदि आप बिंदु 3 के बारे में सोचते हैं, तो चेरोट का उपयोग करना अधिक कारावास प्रदान करता है। प्रोटेक्टहोम = और उसके दोस्त भी चेरोट के रूप में प्रतिबंधक बनने की कोशिश नहीं करते हैं। (उदाहरण के लिए, कोई भी नामित सिस्टमडाल विकल्प ब्लैकलिस्ट नहीं करता है /run, जहां हम यूनिक्स सॉकेट फाइलें डालते हैं)।

चेरोट से पता चलता है कि फाइलसिस्टम एक्सेस को प्रतिबंधित करना एक बहुत शक्तिशाली हो सकता है, लेकिन लिनक्स पर सब कुछ फ़ाइल :-) नहीं है। सिस्टमड विकल्प हैं जो अन्य चीजों को प्रतिबंधित कर सकते हैं, जो फाइलें नहीं हैं। यह उपयोगी है यदि प्रोग्राम से छेड़छाड़ की जाती है, तो आप इसके लिए उपलब्ध कर्नेल सुविधाओं को कम कर सकते हैं, जो इसमें भेद्यता का फायदा उठाने की कोशिश कर सकता है। उदाहरण के लिए अवही-डेमन को ब्लूटूथ सॉकेट की आवश्यकता नहीं है और मुझे लगता है कि आपका वेब सर्वर या तो नहीं है। :-)। इसलिए इसे AF_BLUETOOTH पता परिवार तक पहुँच न दें। RestrictAddressFamilies=विकल्प का उपयोग करते हुए बस श्वेतसूची AF_INET, AF_INET6, और शायद AF_UNIX ।

आपके द्वारा उपयोग किए जाने वाले प्रत्येक विकल्प के लिए डॉक्स पढ़ें। कुछ विकल्प दूसरों के साथ संयोजन में अधिक प्रभावी हैं, और कुछ सभी सीपीयू आर्किटेक्चर पर उपलब्ध नहीं हैं। (इसलिए नहीं कि सीपीयू खराब है, बल्कि इसलिए कि उस सीपीयू के लिए लिनक्स पोर्ट अच्छी तरह से डिज़ाइन नहीं किया गया था। मुझे लगता है)।

(यहां एक सामान्य सिद्धांत है। यह अधिक सुरक्षित है यदि आप उन चीज़ों की सूची लिख सकते हैं जिन्हें आप अनुमति देना चाहते हैं, न कि आप जिसे अस्वीकार करना चाहते हैं। जैसे कि एक कैरोट को परिभाषित करने से आपको उन फ़ाइलों की एक सूची मिलती है जिन्हें आप एक्सेस करने की अनुमति देते हैं, और यह अधिक मजबूत है। यह कहने से कि आप ब्लॉक करना चाहते हैं /home)।

सिद्धांत रूप में, आप setuid () से पहले खुद पर सभी समान प्रतिबंध लागू कर सकते हैं। यह सब सिर्फ कोड है जिसे आप सिस्टमड से कॉपी कर सकते हैं। हालांकि, सिस्टमड यूनिट विकल्पों को लिखने में काफी आसान होना चाहिए, और चूंकि वे एक मानक प्रारूप में हैं, इसलिए उन्हें पढ़ना और समीक्षा करना आसान होना चाहिए।

इसलिए मैं man systemd.execआपके लक्ष्य प्लेटफ़ॉर्म पर सैंडबॉक्सिंग अनुभाग के माध्यम से पढ़ने की अत्यधिक अनुशंसा कर सकता हूं । लेकिन अगर आप सबसे सुरक्षित डिजाइन चाहते हैं, तो मैं आपके कार्यक्रम में भीchroot (और फिर rootविशेषाधिकार छोड़ ) कोशिश करने से नहीं डरूंगा । यहाँ एक व्यापार है। अपने समग्र डिजाइन पर कुछ बाधाओं का उपयोग करना । यदि आपके पास पहले से ही एक डिज़ाइन है जो चेरोट का उपयोग करता है, और ऐसा लगता है कि आपको क्या चाहिए, तो यह बहुत अच्छा लगता है।chroot


+1 सिस्टमडे सुझावों के लिए विशेष रूप से।
13

मैंने उर उत्तर से काफी कुछ सीखा है, अगर स्टैक ओवर फ्लो की अनुमति देता है तो कई उत्तर मुझे उर भी स्वीकार होंगे। मैं सोच रहा था, अगर chroot / setuid / umask / की तुलना में systemd sandboxing का उपयोग अधिक सुरक्षित है ...
mur

@ मूर आपको यह पसंद आया :)। मेरे जवाब के लिए यह बहुत स्वाभाविक प्रतिक्रिया है। इसलिए मैंने इसे फिर से अपडेट किया है, आपके प्रश्न का उत्तर देने के लिए।
sourcejedi

1

यदि आप सिस्टमड पर भरोसा कर सकते हैं, तो यह वास्तव में सुरक्षित है (और सरल!) सैंडबॉक्सिंग को सिस्टमड पर छोड़ दें। (बेशक, एप्लिकेशन यह भी पता लगा सकता है कि यह सिस्टमबॉक्स द्वारा सैंडबॉक्स लॉन्च किया गया है या नहीं, और सैंडबॉक्स ही यदि अभी भी रूट है।) आपके द्वारा वर्णित सेवा के बराबर होगा:

[Service]
ExecStart=/usr/local/bin/mydaemon
User=mydaemon-user
RootDirectory=...

लेकिन हमें वहाँ रुकना नहीं है। systemd आपके लिए बहुत सारे अन्य सैंडबॉक्सिंग भी कर सकता है - यहाँ कुछ उदाहरण दिए गए हैं:

[Service]
# allocate separate /tmp and /var/tmp for the service
PrivateTmp=yes
# mount / (except for some subdirectories) read-only
ProtectSystem=strict
# empty /home, /root
ProtectHome=yes
# disable setuid and other privilege escalation mechanisms
NoNewPrivileges=yes
# separate network namespace with only loopback device
PrivateNetwork=yes
# only unix domain sockets (no inet, inet6, netlink, …)
RestrictAddressFamilies=AF_UNIX

man 5 systemd.execबहुत अधिक निर्देशों और अधिक विस्तृत विवरणों के लिए देखें । यदि आप अपना डेमॉन सॉकेट-एक्टिवेबल ( man 5 systemd.socket) बनाते हैं , तो आप नेटवर्क से संबंधित विकल्पों का भी उपयोग कर सकते हैं: सेवा का केवल बाहरी दुनिया के लिए लिंक ही वह नेटवर्क सॉकेट होगा जो इसे सिस्टमड से प्राप्त होता है, यह किसी और चीज से कनेक्ट नहीं हो पाएगा। यदि यह एक साधारण सर्वर है जो केवल कुछ बंदरगाहों पर सुनता है और अन्य सर्वर से कनेक्ट करने की आवश्यकता नहीं है, तो यह उपयोगी हो सकता है। (फाइल सिस्टम से संबंधित विकल्प भी RootDirectoryअप्रचलित कर सकते हैं , मेरी राय में, इसलिए शायद अब आपको सभी आवश्यक बायनेरीज़ और लाइब्रेरीज़ के साथ एक नई रूट निर्देशिका स्थापित करने की आवश्यकता नहीं है।)

नए सिस्टमड संस्करण (v232 के बाद से) भी समर्थन करते हैं DynamicUser=yes, जहां सिस्टमड स्वचालित रूप से आपके लिए केवल सेवा के रनटाइम के लिए सेवा उपयोगकर्ता आवंटित करेगा। इसका मतलब है आप सेवा के लिए एक स्थायी उपयोगकर्ता रजिस्टर करने के लिए नहीं है, और लंबे समय से सेवा के रूप में के रूप में ठीक काम करता है किसी भी फाइल सिस्टम इसके अतिरिक्त किसी अन्य स्थान पर लिख नहीं करता है StateDirectory, LogsDirectoryऔर CacheDirectory(जो आप भी इकाई फ़ाइल में घोषणा कर सकते हैं - देखें man 5 systemd.exec, फिर - और कौन सी प्रणाली का प्रबंधन करेगा, देखभाल करने के लिए गतिशील उपयोगकर्ता को सही ढंग से असाइन करने के लिए)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.