VPN कनेक्शननंतरची कृती डेमन म्हणून नाही, वापरकर्ता म्हणून चालवा
USER=alice असे सांगणारा पर्यावरण चल बदलत नाही की hook कोणत्या खात्याने चालतो. घटना, ट्रिगर आणि कृती वेगळे करा, मग UID सिद्ध करा.
VPN डेमनवरील कनेक्शन hook डेमन म्हणून चालतात, आणि सामान्यतः याचा अर्थ ते root म्हणून चालतात। त्या hook पैकी एक जेव्हा कोणाच्या होम डिरेक्टरीत लिहितो किंवा डेस्कटॉप सहाय्यक पुन्हा सुरू करतो, त्याच क्षणी तुम्ही नेटवर्क घटनेला कोणत्याही स्थानिक वापरकर्त्याप्रमाणे कार्य करण्याची क्षमता दिली आहे। नेहमीचा छोटा मार्ग, म्हणजे पर्यावरण चलातून वापरकर्तानाव वाचून ते पुढे पाठवणे, हे सुधारत नाही। तो फक्त कृतीला पुन्हा लेबल लावतो, पण कोणते खाते ती पार पाडते हे बदलत नाही। जे चालते ते तीन भागांचे हस्तांतरण आहे, ज्यात विशेषाधिकारित पायरी सांगते की काय घडले आणि एक वेगळी युनिट योग्य ओळखीखाली कृती करते।
पर्यावरणातील वापरकर्तानाव ही ओळख स्विच नाही
युनिक्स प्रक्रियेला कशाला स्पर्श करता येईल हे तिच्या प्रभावी वापरकर्ता ID वरून ठरवते, तिच्या पर्यावरणातील स्ट्रिंगवरून नाही। USER=alice सेट करणे किंवा LOGNAME निर्यात करणे हे बदलते की निष्काळजी सॉफ्टवेअर आपल्या आउटपुटमध्ये काय छापते; फाइल मालकी तपासण्यांमध्ये ते काहीही बदलत नाही। ते चल सेट असलेल्या स्थितीत root म्हणून चालणारा hook तरीही root म्हणूनच Alice च्या फाइल उघडतो।
नावेही एकच नाव नाहीत। दूरस्थ प्रवेश लॉगिन, स्थानिक युनिक्स खाते आणि प्रमाणपत्राचे सामान्य नाव हे तीन ओळखकर्ते आहेत जे बऱ्याचदा जुळतात आणि कधीकधी जुळत नाहीत। a.smith म्हणून प्रमाणीकरण करणाऱ्या वापरकर्त्याकडे स्थानिक खाते अजिबात नसू शकते, किंवा डिरेक्टरी सेवेद्वारे ते asmith वर मॅप होऊ शकते। एक स्ट्रिंग तीनही भूमिका पार पाडते असे गृहीत धरणारी कोणतीही रचना पहिल्या कंत्राटदाराकडे तुटेल।
त्यामुळे पहिला प्रश्न «कोणता वापरकर्ता जोडलेला आहे» हा नाही, तर «कोणत्या स्थानिक खात्याला ही कृती करण्याची परवानगी आहे» हा आहे। त्याचे उत्तर तुमच्या स्वतःच्या खाते डेटाबेसमधून द्या, क्लायंटने पाठवलेल्यातून नाही:
id -u alice
getent passwd alice | cut -d: -f1,3,6
stat -c '%U:%G %a %n' /home/alice/.local/state/vpn-status.json
तिसरा आदेश हा आहे जो लोक वगळतात। लक्ष्य फाइल root च्या मालकीची असेल कारण मागील hook ने ती तयार केली, तर योग्यरित्या संरचित वापरकर्ता कृती systemd समस्येसारखी दिसणाऱ्या, पण नसलेल्या परवानगी त्रुटीने अयशस्वी होईल।
डेमन जिथे आहे तिथेच राहतो
VPN सेवेचे स्वतःचे User= Alice वर बदलणे हा चुकीचा तोल आहे। ते बदलते की डेमन इंटरफेस कसे बांधतो, किल्ल्या कशा वाचतो, आपली स्थिती फाइल कशी लिहितो आणि मार्ग कसे सांभाळतो, आणि ते सर्व धोका चालत असलेल्या युनिटमध्ये हलवते। डेमनला त्याचे विशेषाधिकार हवे आहेत; पुढील कृतीला नको।
युनिटला स्पर्श करण्यापूर्वी ते प्रत्यक्षात काय करत आहे ते पहा। दोन आदेश तुम्हाला अंमलबजावणीची ओळख आणि लागू असलेल्या अचूक आदेश ओळी सांगतात, ओव्हरराइडने जोडलेले सर्व काही धरून:
systemctl show -p User -p Group -p ExecStart openvpn-server@server
systemctl cat openvpn-server@server
डीफॉल्ट पॅकेज इन्स्टॉलमध्ये डेमन root असतो आणि --up स्क्रिप्ट ते वारशाने घेते। गृहीत धरण्याऐवजी त्याची पुष्टी करा, कारण कडक केलेल्या वितरणाने ते समर्पित खात्यावर हलवले असेल, आणि हाताने लिहिलेला drop-in hook वेगळ्या नियमांच्या रॅपरमधून चालवत असेल।
तीन नामांकित भाग, एक अरुंद ट्रिगर
देखभालीत टिकणाऱ्या मांडणीत घटना, ट्रिगर आणि कृती असतात। डेमन सांगतो की नामांकित सत्र वर आले। ट्रिगर ती लहान गोष्ट स्वीकारतो आणि एक निश्चित कृती मागतो। कृती स्पर्श केलेल्या फाइलींची मालक असलेल्या स्थानिक खात्याखाली चालते। साखळीत काहीही अनियंत्रित आदेश मार्ग स्वीकारत नाही।
कृती स्वतः एक सामान्य सेवा युनिट आहे, आणि ओळख म्हणजे त्यातील एक निर्देश:
[Service]
Type=oneshot
User=alice
Group=alice
ExecStart=/usr/local/bin/refresh-vpn-status --slot %i
लक्षात घ्या की User=alice संपूर्ण युनिटला लागू होते, आणि systemd एक अपवाद नोंदवते जो जाणून घेण्यासारखा आहे: + उपसर्ग असलेला आदेश याकडे दुर्लक्ष करून पूर्ण विशेषाधिकारांनी चालतो। तो उपसर्ग एकाच विशेषाधिकारित पायरीसाठी कायदेशीर साधन आहे आणि नुकतेच बांधलेले विभाजन रद्द करण्याचा सोयीचा मार्ग आहे, त्यामुळे त्या युनिटमधील कोणत्याही + ला पुनरावलोकनात न्याय्य ठरवावे लागणारी गोष्ट माना।
ट्रिगरचे इनपुट किमान आणि गुप्त नसलेले ठेवा। सत्र ओळखकर्ता, मॅप केलेले खाते आणि वेळेची नोंद हे सामान्यतः आवश्यक असलेले सर्व आहे। सीमेपलीकडे कधीही शेल तुकडा, कार्यान्वित होणाऱ्या फाइलचा मार्ग किंवा क्लायंटने दिलेला पर्यावरण ब्लॉक पाठवू नका, कारण प्राप्त करणाऱ्या बाजूकडे कायदेशीर मूल्य आणि इंजेक्ट केलेले मूल्य वेगळे करण्याचा मार्ग नाही।
प्रत्यक्षात चाललेली ओळख पडताळा
संरचना पुनरावलोकन हा पुरावा नाही। मंजूर चाचणी कनेक्शननंतर, फाइलला स्पर्श केलेला UID आणि डेमन अजूनही वापरत असलेला UID यांची पुष्टी करा:
stat -c '%U %G %y %n' /home/alice/.local/state/vpn-status.json
ps -o user=,pid=,cmd= -p "$(pgrep -o -f 'openvpn --daemon')"
systemd-run --uid=alice --pipe /usr/local/bin/refresh-vpn-status --dry-run
पहिल्या ओळीत Alice आणि तुमच्या चाचणी कालावधीतील वेळेची नोंद दिसायला हवी। दुसऱ्यात अजूनही root किंवा पॅकेजचे सेवा खाते दिसायला हवे, जे सिद्ध करते की डेमन हलले नाही। तिसरी म्हणजे प्रत्यक्ष पुनर्जोडणीची वाट न पाहता कृतीच्या परवानग्या तपासण्याचा सर्वात स्वस्त मार्ग।
जर फाइलचा मालक Alice असेल पण तिचा गट किंवा मोड चालवण्यांमध्ये बदलला असेल, तर तर्कदोष नाही, UMask= किंवा डिरेक्टरी परवानगीतील फरक शोधा। जर वेळेची नोंद अजिबात हलली नाही, तर ट्रिगर कधीही सक्रिय झाला नाही, आणि उपयुक्त पुढील पायरी दुसरे क्लायंट पुनर्जोडणी नाही, तर कृती युनिटसाठी journalctl -u आहे।
कनेक्शन घटना अजूनही काय सिद्ध करत नाही
स्थापित बोगदा ही एक गोष्ट आहे। याचा अर्थ डेस्कटॉप सत्र उघडे आहे, सत्र बस पोहोचण्यायोग्य आहे, किंवा कृतीला हवे असलेले खाजगी संसाधन आता उपलब्ध आहे असा नाही। Alice च्या UID खालील oneshot युनिटकडे तिची ओळख आहे आणि तिच्या सत्रातील काहीही नाही, त्यामुळे ग्राफिकल बस आवश्यक असलेल्या प्रत्येक गोष्टीला समर्थित वापरकर्ता-सत्र यंत्रणेतून जावे लागेल आणि ती लॉग आउट असताना काय होते हे परिभाषित करावे लागेल।
पुनर्जोडणीही पुनरावृत्त होतात। ट्रेनमध्ये झोपलेला लॅपटॉप एका तासात डझनभर कनेक्शन घटना निर्माण करू शकतो, आणि प्रत्येक वेळी एक ओळ जोडणारा hook स्थिती फाइलचे असे लॉग करतो जे कोणीही वाचू शकत नाही। कृतीला इडेम्पोटेंट बनवा, किंवा सत्र-किल्ली असलेली एकच नोंद बदलू द्या।
शेवटी, युनिटमध्येच हानीची त्रिज्या मर्यादित करा: स्थिती डिरेक्टरीबाहेर फक्त-वाचनीय फाइलसिस्टम दृश्य, नवीन विशेषाधिकार नाहीत, आणि स्पष्ट कालमर्यादा। डेमन आणि वापरकर्ता कृती यांतील विभाजन स्वतःच मोलाचे आहे, पण कृती तुम्ही मंजूर केलेल्या एका गोष्टीशिवाय दुसरे काहीही करू शकत नसेल तेव्हा ते कितीतरी जास्त मोलाचे आहे।