أفضل الممارسات لتشغيل خدمة Linux كمستخدم مختلف

StackOverflow https://stackoverflow.com/questions/394984

  •  23-08-2019
  •  | 
  •  

سؤال

الخدمات الافتراضية لبدء root في وقت التمهيد على صندوق rhel الخاص بي. إذا كنت أتذكر بشكل صحيح، فإن الشيء نفسه صحيح بالنسبة لوزارة Linux الأخرى التي تستخدم البرامج النصية INIT /etc/init.d.

ما رأيك هو أفضل طريقة لتشغيل العمليات بدلا من ذلك كمستخدم (ثابت) من اختياري؟

الطريقة الوحيدة التي وصلت إليها هي استخدام شيء مثل:

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

ولكن هذا يبدو غير مرتب قليلا ...

هل هناك بعض الشيء من السحر مدسوس يوفر آلية سهلة لبدء الخدمات تلقائيا كمستخدمين آخرين غير جذرين؟

تعديل: كان يجب أن أقول إن العمليات التي بدأت في هذه الحالة إما إما برامج نصية بيثون أو برامج Java. أفضل عدم كتابة غلاف أصلي من حولهم، لذلك لسوء الحظ أنا غير قادر على الاتصال Setuid () كما أسود وتقترح.

هل كانت مفيدة؟

المحلول

على دبيان نستخدم start-stop-daemon الأداة المساعدة التي تعالج ملفات PID وتغيير المستخدم ووضع الخفي في الخلفية وأكثر من ذلك بكثير.

أنا لست على دراية بإعادة، لكن daemon الأداة المساعدة التي تستخدمها بالفعل (والتي تم تعريفها /etc/init.d/functions, ، راجع للشغل.) مذكورة في كل مكان ما يعادل start-stop-daemon, ، لذلك إما أنه يمكن أيضا تغيير UID من برنامجك، أو الطريقة التي تقوم بها الأمر بالفعل الصحيح.

إذا نظرت حول الشبكة، فهناك العديد من الأغلفة الجاهزة التي يمكنك استخدامها. قد يتم تعبئتها بعضها بالفعل في redhat. القي نظرة على daemonize, ، علي سبيل المثال.

نصائح أخرى

بعد النظر إلى جميع الاقتراحات هنا، اكتشفت بعض الأشياء التي آمل أن تكون مفيدة للآخرين في وضعي:

  1. قفزة هو الصحيح في الإشارة لي مرة أخرى في /etc/init.d/functions: الdaemon الدالة تتيح لك بالفعل تعيين مستخدم بديل:

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

    يتم تنفيذ ذلك عن طريق التفاف استدعاء العملية runuser - المزيد في هذا لاحقا.

  2. جوناثان ليفر هو الصحيح: هناك Setuid في بيثون:

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

    ما زلت لا أعتقد أنك تستطيع التوصل من داخل JVM، ولكن

  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 Script إلى شيء مثل:

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

شكرا كلا لمساعدتكم!

  • بعض الشياطين (مثل Apache) قم بذلك بنفسها عن طريق الاتصال Setuid ()
  • يمكنك استخدام العلم Setuid-file لتشغيل العملية كمستخدم مختلف.
  • بالطبع، الحل الذي ذكرته يعمل كذلك.

إذا كنت تنوي كتابة الخفي الخاص، فأنا أوصي بالاتصال SetUID (). بهذه الطريقة، يمكن لعمليتك

  1. الاستفادة من امتيازات الجذر (مثل ملفات السجل المفتوح، إنشاء ملفات PID).
  2. إسقاط امتيازات الجذر في نقطة معينة أثناء بدء التشغيل.

فقط لإضافة بعض الأشياء الأخرى التي تراقبها من أجل:

  • Sudo في البرنامج النصي Init.d ليس جيدا لأنه يحتاج إلى TTY ("Sudo: عذرا، يجب أن يكون لديك TTY لتشغيل Sudo")
  • إذا كنت مخلفا من تطبيق Java، فقد ترغب في التفكير في مجمع خدمة Java (يوفر آلية لإعداد معرف المستخدم)
  • بديل آخر يمكن أن يكون SU -Session- أمر = [CMD] [مستخدم

في آلة CentoS (Red Hat) الافتراضي لخادم SVN: تم تحريره /etc/init.d/svnserverلتغيير PID إلى شيء يمكن أن يكتب SVN:

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

وأضاف الخيار --user=svn:

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

وكان pidfile الأصلي /var/run/svnserve.pid. وبعد لم يبدأ الخفي في Becaseu فقط الجذر يمكن أن يكتب هناك.

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

بعض الأشياء التي يجب مراقبتها من أجل:

  • كما ذكرت، سوف يدفع سو كلمة مرور إذا كنت بالفعل المستخدم المستهدف
  • وبالمثل، ستفشل SetUID (2) إذا كنت بالفعل المستخدم المستهدف (على بعض OSS)
  • SetuID (2) لا يقوم بتثبيت امتيازات أو عناصر تحكم الموارد المحددة في /etc/limits.conf (Linux) أو / etc / user_attr (solaris)
  • إذا ذهبت إلى SetGID (2) / SetUID (2)، فلا تنس أن تستدعي intergroups (3) - أكثر على هذا هنا

أنا عموما استخدام / SBIN / SU للتبديل إلى المستخدم المناسب قبل بدء الشياطين.

لماذا لا تحاول ما يلي في البرنامج النصي INIT:

setuid $USER application_name

عملت معي.

كنت بحاجة إلى تشغيل تطبيق Spring .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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top