Bagaimana cara melepaskan hak root di skrip shell?

13

Opsi "--up" di OpenVPN biasanya digunakan untuk perutean dll. Jadi itu diproses sebelum OpenVPN menjatuhkan hak akses root untuk dijalankan sebagai bukan siapa-siapa. Namun, saya menggunakan skrip shell yang harus dijalankan sebagai pengguna yang tidak memiliki hak.

Bagaimana aku melakukan itu? Saya telah mempelajari Drop Process Privileges , terutama jawaban polinomial dan tylerl, tetapi saya tidak mengerti bagaimana cara mengimplementasikannya. Saya bekerja di Centos 6.5, dan suid diblokir, baik sebagai "chmod u + s" dan sebagai "setuid ()".

Ada plugin OpenVPN ("openvpn-down-root.so") yang memungkinkan skrip yang dipanggil oleh opsi "--down" untuk dijalankan sebagai root. Mungkin ada yang setara, seperti "openvpn-up-user.so", tapi saya belum menemukannya.

Sunting0

Per jawaban Nikola Kotur, saya telah menginstal runit-rpm Ian Meyer . Meskipun perintah chpst bekerja di terminal, dalam skrip up gagal dengan "perintah tidak ditemukan". Yang berfungsi adalah "sudo chpst" plus pengaturan tampilan dan bahasa yang tepat. Silakan lihat Mengapa terminal saya tidak mengeluarkan karakter unicode dengan benar? Mengingat itu, skrip up membutuhkan empat baris ini:

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &

Sunting1

Per komentar 0xC0000022L, saya menemukan bahwa "sudo -u pengguna" berfungsi juga "sudo chpst -u pengguna -U pengguna":

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &

Saya akan mempelajari man sudoers dan memperbarui jika / ketika saya mendapatkan sudo sendiri untuk bekerja.

mirimir
sumber
komentar yang ditinggalkan oleh @ user66229: "Bolehkah saya menyarankan Anda berselancar ke sourceforge.net/p/openvpn/mailman dan berlangganan daftar yang menurut Anda paling sesuai."
slm
@ user66229 Terima kasih. Tetapi saya tidak percaya bahwa ini adalah pertanyaan khusus OpenVPN. Mengapa Anda percaya itu?
mirimir

Jawaban:

7

Saya menggunakan runit 's chpstalat untuk tugas-tugas seperti ini. Misalnya, dari skrip atas panggil skrip tidak terprivat Anda:

chpst -u nobody /path/to/script
Nikola Kotur
sumber
Keren :) Terima kasih. Apakah github.com/imeyer/runit-rpm cara terbaik untuk mendapatkan runit ke Centos 6.5? Bahkan dengan repo Red Hat, saya tidak menemukan paket.
mirimir
@mirimir, ya, saya menggunakan repo itu ketika saya perlu membangun paket runit untuk CentOS.
Nikola Kotur
10

Meliputi hanya runit dan sudo sangat dirindukan. Sebenarnya ada seluruh keluarga toolet seperti runit, dan berbagai pilihan alat untuk melakukan hal ini, tugas yang mereka rancang untuk:

  • Daemontools Daniel J. Bernstein, memiliki setuidgid:

    setuidgid user /home/user/unprivileged.sh
  • Freedt Adam Sampson memiliki setuidgid:

    setuidgid user /home/user/unprivileged.sh
  • Daemontools-encore Bruce Guenter memiliki setuidgid:

    setuidgid user /home/user/unprivileged.sh
  • Runit Gerrit Pape memiliki chpst:

    chpst -u pengguna /home/user/unprivileged.sh
  • Pelatih Wayne Marshall memiliki runuid:

    runuid user /home/user/unprivileged.sh
  • Laurent Bercot's s6 memiliki s6-setuidgid:

    s6-setuidgid pengguna /home/user/unprivileged.sh
  • nosh saya memiliki setuidgid:

    setuidgid user /home/user/unprivileged.sh

Mereka tidak berbaur dalam tugas yang berbeda untuk menambahkan hak istimewa, dan tidak pernah jatuh ke mode interaktif.

Omong- omong masalah Anda sedikit lebih dari lupa Anda untuk memiliki sbinserta bindi Anda PATH, omong-omong.

Bacaan lebih lanjut

JdeBP
sumber
3

skrip yang menghapus hak istimewa dan menjalankan skrip lain (tapi di sini saya membuatnya agar berjalan sendiri):

#!/bin/sh

id=`id -u`
safeuser="nobody"

if [ $id = "0" ]
then
         # we're root. dangerous!
        sudo -u $safeuser $0
else
    echo "I'm not root"
    id
fi

Contoh:

root@n3:/tmp/x# id
uid=0(root) gid=0(root) группы=0(root)
root@n3:/tmp/x# ./drop.sh
I'm not root
uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)
yaroslaff
sumber
Saat menggunakan "sudo -u pengguna" berfungsi untuk beberapa perintah, itu tidak menyediakan lingkungan pengguna yang cukup untuk tujuan saya. Dan sementara "pengguna su" bekerja dengan baik di terminal, ia tidak melakukan apa pun dalam skrip. Saya kira itu fitur keamanan. Jadi sepertinya saya pergi dengan menginstal runit.
mirimir
1
@mirimir: mengapa? /etc/sudoersmemungkinkan untuk menjadi sangat spesifik variabel lingkungan apa yang dapat disampaikan ke program yang dijalankan oleh sudodan sebagainya. man sudoers. Jujur saja, siapa pun yang menggunakan sudohanya untuk sudo su -atau beralih konteks pengguna tidak memiliki petunjuk tentang apa yang ada di balik program yang luar biasa ini dan seberapa banyak Anda dapat mengunci hal-hal untuk program individu, pengguna, host dll ...
0xC0000022L
@ 0xC0000022L Terima kasih. Aku memandangi sudo lagi. Dan ya, "sudo -u user" plus tampilan dan bahasa juga berfungsi.
mirimir
1
Berbicara tentang berbahaya - Anda tidak bisa percaya $0; penelepon dapat mengatur skrip $0untuk apa pun yang mereka inginkan. Dan gunakan lebih banyak kutipan.
Charles Duffy
2
... jika skrip Anda $0adalah /directory/name with spaces/script(dan ingat, pengguna dapat membuat symlink sewenang-wenang di lokasi mereka sendiri, bahkan jika mereka tidak menggunakan exec -a somename yourscriptuntuk memanggil yourscriptdengan $0dari somename), maka Anda akan mendapatkan sudo -u nobody /directory/name with spaces, dengan withdan spaceslulus sebagai argumen terpisah untuk perintah Anda .
Charles Duffy
1

Bagaimana dengan:

sudo -Eu <user> <command>

Anda mengeluh tentang lingkungan di komentar sebelumnya, jadi Anda mungkin juga membandingkan perbedaan antara output:

sudo -u <user> printenv
sudo -Eu <user> printenv
thiagowfx
sumber
1

Di Linux Anda dapat menggunakan runuseratau setprivjika sesi PAM tidak diperlukan (keduanya dari util-linux):

runuser -u USER [--] COMMAND [ARGUMENTS...]

setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...]  # Like su/runuser/sudo
setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...]  # Like daemontools setuid(8)

Dari suhalaman manual:

su sebagian besar dirancang untuk pengguna yang tidak berhak, solusi yang disarankan untuk pengguna yang memiliki hak istimewa (misalnya skrip yang dieksekusi oleh root) adalah dengan menggunakan runuser perintah non-set-pengguna-ID (1) yang tidak memerlukan otentikasi dan menyediakan konfigurasi PAM yang terpisah. Jika sesi PAM tidak diperlukan sama sekali maka solusi yang disarankan adalah dengan menggunakan perintah setpriv (1) .

as
sumber