एक अलग उपयोगकर्ता के रूप में लिनक्स सेवा चलाने के लिए सबसे अच्छा अभ्यास


141

rootमेरे आरएचईएल बॉक्स पर बूट समय के रूप में शुरू करने के लिए डिफ़ॉल्ट सेवाएं । यदि मैं सही ढंग से याद करता हूं, तो अन्य लिनक्स डिस्ट्रोस के लिए भी यही सही है जो इनिट स्क्रिप्ट का उपयोग करते हैं /etc/init.d

आपको क्या लगता है कि मेरे चयन की प्रक्रिया (स्थिर) उपयोगकर्ता के रूप में चलने के बजाय सबसे अच्छा तरीका है?

एकमात्र तरीका जो मैं आया था, वह था:

 su my_user -c 'daemon my_cmd &>/dev/null &'

लेकिन यह थोड़ा अस्वाभाविक लगता है ...

क्या कुछ ऐसा जादू है जो स्वचालित रूप से अन्य, गैर-रूट उपयोगकर्ताओं के रूप में सेवाएं शुरू करने के लिए एक आसान तंत्र प्रदान करता है?

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


क्या पायथन सिस्टम कॉल के सेटिड () परिवार तक पहुंच प्रदान नहीं करता है? यह पर्ल की तुलना में एक गंभीर दोष की तरह लगता है।
जोनाथन लेफ्लर 15

12
वाह, हाँ यह करता है: os.setuid (uid)। हर दिन एक स्कूल का दिन!
जेम्स ब्रैडी

जवाबों:


67

डेबियन पर हम start-stop-daemonउपयोगिता का उपयोग करते हैं , जो पिड-फाइल्स को संभालता है, उपयोगकर्ता को बदलता है, डेमॉन को पृष्ठभूमि में डालता है और बहुत कुछ।

मैं RedHat से परिचित नहीं हूँ, लेकिन daemonउपयोगिता जो आप पहले से ही उपयोग कर रहे हैं (जो कि /etc/init.d/functions, btw में परिभाषित है ) हर जगह पर समान के रूप में उल्लिखित है start-stop-daemon, इसलिए या तो यह आपके प्रोग्राम के यूआईडी को बदल सकता है, या जिस तरह से आप कर सकते हैं। यह पहले से ही सही है।

यदि आप नेट के चारों ओर देखते हैं, तो कई तैयार किए गए रैपर हैं जो आप उपयोग कर सकते हैं। कुछ को पहले से ही RedHat में पैक किया जा सकता है। daemonizeउदाहरण के लिए, पर एक नज़र है ।


एक्स-रे दिलचस्प है। मेरा अपना स्वयं का कार्यक्रम है, बहुत समान है; पिडफाइल या लॉकफाइल नहीं करता, umask सेट करता है। मेरे पास यूआईडी, जीआईडी, ईयूआईडी, ईजीआईडी, और ऑक्स समूह (जिसे आरोहोट कहा जाता है) स्थापित करने के लिए एक अलग SUID रूट प्रोग्राम है। मैं 'आरोही [opts] का उपयोग करता हूं - env ​​-i [env] डेमनाइज [opts] - कमांड [opts]'
जोनाथन लेफलर 15

(जारी): POSIX मानक env प्रोग्राम पर्यावरण सेटिंग और निष्पादित कमांड के बीच '-' को स्वीकार नहीं करता (irksome, लेकिन ऐसा है)।
जोनाथन लेफ़लर

4
Upstart स्क्रिप्ट में /etc/init.d/functions से डेमन फ़ंक्शन कैसे किया जा सकता है? क्या आप एक उदाहरण दिखा सकते हैं, कृपया।
मेग्गियो जूल

10
डेबियन पर देखें /etc/init.d/skeleton। यूआईडी, जीआईडी ​​वैरिएबल और do_start()प्रयोग में जोड़ें :start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid $UID:$GID -- $DAEMON_ARGS
जोनाथन बेन-अवराम

मुझे लगता daemon()है कि मेरे /etc/rc.d/init.d/functionदोनों आरएचईएल और सेंटोस बॉक्स पर परिभाषित किया गया है।
क्विकशिफ्टिन

53

यहां सभी सुझावों को देखने के बाद, मैंने कुछ चीजें खोजी हैं, जो मुझे उम्मीद है कि मेरी स्थिति में दूसरों के लिए उपयोगी होगी:

  1. हॉप मुझे वापस इंगित करने के लिए सही है /etc/init.d/functions: daemonफ़ंक्शन पहले से ही आपको एक वैकल्पिक उपयोगकर्ता सेट करने की अनुमति देता है:

    daemon --user=my_user my_cmd &>/dev/null &
    

    इस प्रक्रिया के आह्वान को लागू करने के साथ इसे लागू किया जाता है runuser- बाद में इस पर और अधिक।

  2. जोनाथन लेफ़लर सही है: पाइथन में सेतु है:

    import os
    os.setuid(501) # UID of my_user is 501
    

    मुझे अभी भी नहीं लगता कि आप एक जेवीएम के अंदर से सेतुबंध कर सकते हैं, हालाँकि।

  3. न तो suऔर न ही runuser इनायत से उस मामले को संभालें जहां आप एक कमांड को चलाने के लिए पूछते हैं जो आप पहले से ही उपयोगकर्ता हैं। उदाहरण के लिए:

    [my_user@my_host]$ id
    uid=500(my_user) gid=500(my_user) groups=500(my_user)
    [my_user@my_host]$ su my_user -c "id"
    Password: # don't want to be prompted!
    uid=500(my_user) gid=500(my_user) groups=500(my_user)
    

की है कि व्यवहार वैकल्पिक हल के लिए suऔर runuser, मैं की तरह कुछ करने के लिए अपने init स्क्रिप्ट बदल दिया है:

if [[ "$USER" == "my_user" ]]
then
    daemon my_cmd &>/dev/null &
else
    daemon --user=my_user my_cmd &>/dev/null &
fi

आपकी सहायताके लिए शुक्रिया!


5
  • कुछ डेमॉन (उदा। अपाचे) खुद को सेतुद () कहकर ऐसा करते हैं
  • आप एक अलग उपयोगकर्ता के रूप में प्रक्रिया को चलाने के लिए सेतु-फ़ाइल ध्वज का उपयोग कर सकते हैं ।
  • बेशक, आपके द्वारा बताए गए समाधान भी काम करता है।

यदि आप अपना स्वयं का डेमॉन लिखने का इरादा रखते हैं, तो मैं सेतुद () बुलाने की सलाह देता हूं। इस तरह, आपकी प्रक्रिया हो सकती है

  1. इसकी मूल विशेषाधिकारों का उपयोग करें (उदाहरण के लिए लॉग फाइलें खोलें, पीआईडी ​​फाइलें बनाएं)।
  2. स्टार्टअप के दौरान एक निश्चित बिंदु पर इसकी जड़ विशेषाधिकार छोड़ें।

3

बस कुछ अन्य चीजों को जोड़ने के लिए बाहर देखने के लिए:

  • एक init.d स्क्रिप्ट में सूडो अच्छा नहीं है क्योंकि इसमें ट्टी की जरूरत होती है ("sudo: क्षमा करें, आपके पास sudo चलाने के लिए एक tty होना चाहिए")
  • यदि आप एक जावा एप्लिकेशन को डिमोनेटाइज कर रहे हैं, तो आप जावा सर्विस रैपर पर विचार कर सकते हैं (जो उपयोगकर्ता किनारों को सेट करने के लिए एक तंत्र प्रदान करता है)
  • एक और विकल्प su --session- कमांड = [cmd] [उपयोगकर्ता] हो सकता है

3

svn सर्वर के लिए एक CENTOS (Red Hat) वर्चुअल मशीन पर: /etc/init.d/svnserver पिड को उस चीज में बदलने के लिए संपादित किया गया, जिसे svn लिख सकता है:

pidfile=${PIDFILE-/home/svn/run/svnserve.pid}

और जोड़ा विकल्प --user=svn:

daemon --pidfile=${pidfile} --user=svn $exec $args

मूल पिडफाइल था /var/run/svnserve.pid। डेमन ने शुरू नहीं किया था क्योंकि केवल जड़ ही वहां लिख सकता था।

 These all work:
/etc/init.d/svnserve start
/etc/init.d/svnserve stop
/etc/init.d/svnserve restart

3
यह एक विशेषाधिकार वृद्धि भेद्यता बनाता है। Svn उपयोगकर्ता अब /home/svn/run/svnserve.pid फ़ाइल में मनमाने ढंग से PIDs लगा सकता है जो svn सेवा के बजाय मारा जाएगा जब भी svn सेवा बंद या फिर से शुरू की जाएगी।
जु।

2

कुछ चीजें देखने के लिए:

  • जैसा कि आपने उल्लेख किया है, यदि आप पहले से ही लक्षित उपयोगकर्ता हैं, तो su एक पासवर्ड के लिए संकेत देगा
  • यदि आप पहले से ही लक्षित उपयोगकर्ता हैं (कुछ OS पर) तो इसी तरह, setuid (2) विफल हो जाएगा
  • setuid (2) /etc/limits.conf (Linux) या / etc / user_attr (Solaris) में परिभाषित विशेषाधिकार या संसाधन नियंत्रण स्थापित नहीं करता है
  • यदि आप सेटगिड (2) / सेतुइड (2) मार्ग पर जाते हैं, तो initgroups (3) को कॉल करना न भूलें - इस पर यहाँ और अधिक

मैं आमतौर पर डेमन शुरू करने से पहले उपयुक्त उपयोगकर्ता पर स्विच करने के लिए / sbin / su का उपयोग करता हूं।


2

क्यों init स्क्रिप्ट में निम्न प्रयास नहीं करें:

setuid $USER application_name

इसने मेरे लिए काम किया।


3
यह सभी डिस्ट्रोस पर उपलब्ध नहीं है। मैंने setuid: command not found
आरएचईएल

0

मुझे एक सेवा के रूप में एक स्प्रिंग .jar आवेदन चलाने की आवश्यकता थी, और एक विशिष्ट उपयोगकर्ता के रूप में इसे चलाने का एक सरल तरीका मिला:

मैंने अपने जार फ़ाइल के स्वामी और समूह को उस उपयोगकर्ता में बदल दिया जिसे मैं चलाना चाहता था। फिर init.d में इस जार को सिमिलिंक किया और सेवा शुरू की।

इसलिए:

#chown myuser:myuser /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar

#ln -s /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar /etc/init.d/springApp

#service springApp start

#ps aux | grep java
myuser    9970  5.0  9.9 4071348 386132 ?      Sl   09:38   0:21 /bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -jar /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.