डेल हागलगुंड पर हाजिर है। इसलिए मैं केवल एक ही बात कहने जा रहा हूं, लेकिन कुछ अलग तरीके से और कुछ उदाहरणों के साथ। ☺
यूनिक्स और लिनक्स दुनिया में करने के लिए सही चीज़ है:
- एक छोटा, सरल, आसानी से सुनने योग्य कार्यक्रम, जो सुपरसुसर के रूप में चलता है और सुनने वाले सॉकेट को बांधता है;
- एक और छोटा, सरल, आसानी से सुनने योग्य कार्यक्रम, जो विशेषाधिकारों को गिराता है, पहला कार्यक्रम
- सेवा का मांस, एक अलग तीसरे कार्यक्रम में, एक गैर-सुपरसुअर खाते के तहत चलाया जाता है और दूसरे कार्यक्रम द्वारा लोड की गई श्रृंखला, सॉकेट के लिए बस एक खुली फाइल डिस्क्रिप्टर विरासत में मिलने की उम्मीद है।
आपके पास गलत विचार है कि उच्च जोखिम कहां है। उच्च जोखिम नेटवर्क से पढ़ने और एक सॉकेट खोलने, इसे एक बंदरगाह से बांधने, और कॉल करने के सरल कार्यों में नहीं पढ़ा जाने पर अभिनय करना हैlisten()
। यह एक ऐसी सेवा का हिस्सा है जो वास्तविक संचार करता है जो उच्च जोखिम है। खुलने वाले हिस्से bind()
, और listen()
, और यहां तक कि (एक हद तक) वह हिस्सा accepts()
, जो उच्च जोखिम नहीं है और सुपरसुसर के तत्वावधान में चलाया जा सकता है। वे accept()
नेटवर्क पर अविश्वसनीय अजनबियों के नियंत्रण में हैं डेटा पर ( मामले में स्रोत आईपी पते के अपवाद के साथ) उपयोग और कार्य नहीं करते हैं।
ऐसा करने के कई तरीके हैं।
inetd
जैसा कि डेल हाग्लगंड कहते हैं, पुराना "नेटवर्क सुपरसर्वर" inetd
ऐसा करता है। वह खाता जिसके तहत सेवा प्रक्रिया चलाई जाती है, वह कॉलम में से एक है inetd.conf
। यह सुनने के भाग और छोड़ने वाले विशेषाधिकारों को दो अलग-अलग कार्यक्रमों में अलग नहीं करता है, छोटे और आसानी से सुनने योग्य, लेकिन यह मुख्य सेवा कोड को एक अलग कार्यक्रम में अलग करता है, exec()
एक सेवा प्रक्रिया में एड जो एक खुली फ़ाइल विवरणक के साथ घूमता है सॉकेट के लिए।
ऑडिटिंग की कठिनाई इतनी अधिक समस्या नहीं है, क्योंकि किसी को केवल एक प्रोग्राम का ऑडिट करना होता है। inetd
अधिक बड़ी समस्या ऑडिटिंग नहीं है, बल्कि यह है कि यह हाल के औजारों की तुलना में सिंपल फाइन ग्रेनड रनटाइम सर्विस कंट्रोल प्रदान नहीं करता है।
UCSPI-TCP और daemontools
डैनियल जे। बर्नस्टीन के UCSPI-TCP और daemontools संकुल को संयोजन के रूप में ऐसा करने के लिए डिज़ाइन किया गया था। वैकल्पिक रूप से ब्रूस Guenter के बड़े पैमाने पर समकक्ष डेमोनटूल-एनकोर टूलसेट का उपयोग कर सकते हैं ।
सॉकेट फ़ाइल डिस्क्रिप्टर को खोलने और विशेषाधिकार प्राप्त स्थानीय पोर्ट से बाइंड करने का कार्यक्रम tcpserver
UCSPI-TCP से है। यह करता है listen()
और दोनों accept()
।
tcpserver
इसके बाद या तो एक सेवा कार्यक्रम शुरू होता है जो रूट विशेषाधिकारों को छोड़ देता है (क्योंकि परोसा जा रहा प्रोटोकॉल में सुपरसिर के रूप में शुरू करना शामिल है और फिर "लॉगिंग", जैसा कि मामला है, उदाहरण के लिए, एक एफ़टीपी या एक एसएसएच डेमॉन) या setuidgid
जो है स्वयं निहित छोटे और आसानी से श्रव्य कार्यक्रम जो विशेष रूप से विशेषाधिकारों को छोड़ देता है और फिर श्रृंखला को सेवा कार्यक्रम में लोड करता है उचित (जिसका कोई हिस्सा कभी भी सुपरसुसर विशेषाधिकारों के साथ नहीं चलता, जैसा कि मामला है, कहते हैं qmail-smtpd
)।
run
इस प्रकार एक सेवा स्क्रिप्ट उदाहरण के लिए होगी (यह शून्य आईडी सेवा प्रदान करने के लिए डमीटिड के लिए एक है ):
#!/bin/sh -e
exec 2>&1
exec \
tcpserver 0 113 \
setuidgid nobody \
dummyidentd.pl
nosh
मेरा nosh पैकेज ऐसा करने के लिए डिज़ाइन किया गया है। इसकी एक छोटी सी setuidgid
उपयोगिता है, दूसरों की तरह। एक मामूली अंतर यह है कि यह systemd
"LISTEN_FDS" सेवाओं के साथ-साथ UCSPI-TCP सेवाओं के साथ प्रयोग करने योग्य है , इसलिए पारंपरिक tcpserver
कार्यक्रम को दो अलग-अलग कार्यक्रमों द्वारा प्रतिस्थापित किया जाता है: tcp-socket-listen
और tcp-socket-accept
।
फिर से, एकल-उद्देश्य उपयोगिताओं स्पॉन और चेन एक दूसरे को लोड करते हैं। डिजाइन की एक दिलचस्प विचित्रता यह है कि सुपरसुसर विशेषाधिकारों को छोड़ सकते हैं, listen()
लेकिन इससे पहले भी accept()
। यहाँ एक run
स्क्रिप्ट है qmail-smtpd
जो वास्तव में ठीक वैसा ही करती है:
#!/bin/nosh
fdmove -c 2 1
clearenv --keep-path --keep-locale
envdir env/
softlimit -m 70000000
tcp-socket-listen --combine4and6 --backlog 2 ::0 smtp
setuidgid qmaild
sh -c 'exec \
tcp-socket-accept -v -l "${LOCAL:-0}" -c "${MAXSMTPD:-1}" \
ucspi-socket-rules-check \
qmail-smtpd \
'
प्रोग्राम हैं जो सुपर उपयोगकर्ता के तत्वावधान में चलाए जा छोटे सेवा-अज्ञेयवाद श्रृंखला लोडिंग उपकरण हैं fdmove
, clearenv
, envdir
, softlimit
, tcp-socket-listen
, और setuidgid
। sh
प्रारंभ होने वाले बिंदु तक , सॉकेट smtp
बंदरगाह के लिए खुला और बाध्य है , और इस प्रक्रिया में अब सुपरसुसर विशेषाधिकार नहीं हैं।
s6, s6- नेटवर्किंग, और निष्पादित करें
लॉरेंट Bercot के S6 और S6-नेटवर्किंग संकुल संयोजन के रूप में यह करने के लिए डिजाइन किए गए थे। आदेश संरचनात्मक रूप से daemontools
और UCSPI-TCP के समान हैं।
run
स्क्रिप्ट ज्यादा एक ही हो सकता है, के प्रतिस्थापन के अलावा s6-tcpserver
के लिए tcpserver
और s6-setuidgid
के लिए setuidgid
। हालाँकि, एक ही समय में एम। बरकोट के एक्सेललाइन टूलसेट का उपयोग करने का भी चयन किया जा सकता है ।
यहां एफ़टीपी सेवा का एक उदाहरण दिया गया है , जिसे वेन मार्शल के मूल से हल्के ढंग से संशोधित किया गया है , जो पब्लिकलाइन से एफ़लाइन, एस 6, एस 6-नेटवर्किंग और एफ़टीपी सर्वर प्रोग्राम का उपयोग करता है :
#!/command/execlineb -PW
multisubstitute {
define CONLIMIT 41
define FTP_ARCHIVE "/var/public/ftp"
}
fdmove -c 2 1
s6-envuidgid pubftp
s6-softlimit -o25 -d250000
s6-tcpserver -vDRH -l0 -b50 -c ${CONLIMIT} -B '220 Features: a p .' 0 21
ftpd ${FTP_ARCHIVE}
ipsvd
गेरिट पपी का ipsvd एक और टूलसेट है जो ucspi-tcp और s6-नेटवर्किंग के समान लाइनों के साथ चलता है। उपकरण हैं chpst
और tcpsvd
इस बार, लेकिन वे एक ही काम करते हैं, और उच्च जोखिम कोड जो कि अविश्वसनीय ग्राहकों द्वारा नेटवर्क पर भेजे गए चीजों के पढ़ने, प्रसंस्करण और लेखन को करता है, अभी भी एक अलग कार्यक्रम में है।
यहां एम। पपी काfnord
एक run
स्क्रिप्ट में चलने का उदाहरण है :
#!/bin/sh
exec 2>&1
cd /public/10.0.5.4
exec \
chpst -m300000 -Uwwwuser \
tcpsvd -v 10.0.5.4 443 sslio -v -unobody -//etc/fnord/jail -C./cert.pem \
fnord
systemd
systemd
नई सेवा पर्यवेक्षण और init प्रणाली जो कुछ लिनक्स वितरणों में पाई जा सकती है, का उद्देश्य है कि inetd
वह क्या कर सकता है । हालांकि, यह छोटे स्व-निहित कार्यक्रमों के एक सूट का उपयोग नहीं करता है। systemd
दुर्भाग्य से, इसकी संपूर्णता का लेखा- जोखा करना होगा।
systemd
एक के साथ एक गर्तिका को परिभाषित करने के लिए विन्यास फाइल बनाता है systemd
, और एक सेवा जो systemd
शुरू होती है। सेवा "यूनिट" फ़ाइल में सेटिंग्स हैं जो सेवा प्रक्रिया पर नियंत्रण का एक बड़ा सौदा करने की अनुमति देती हैं, जिसमें वह किस उपयोगकर्ता के रूप में चलती है।
उस उपयोगकर्ता के साथ एक गैर-सुपरयुसर होने के लिए, systemd
सॉकेट खोलने, उसे एक बंदरगाह पर बांधने, और कॉलिंग listen()
(और, यदि आवश्यक हो, accept()
) प्रक्रिया # 1 में सुपरयुसर के रूप में, और सेवा प्रक्रिया के सभी कार्य करता है spawns सुपरसुसर विशेषाधिकारों के बिना चलता है।