Restart layanan systemd hanya sebagai pengguna tertentu?

9

Saya membuat beberapa layanan systemd yang pada dasarnya berfungsi:

lokasi:

/etc/systemd/system/multi-user.target.wants/publicapi.service

kandungan:

[Unit]
Description=public api startup script

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=-/etc/environment
WorkingDirectory=/home/techops
ExecStart=/home/techops/publicapi start
ExecStop=/home/techops/publicapi stop

[Install]
WantedBy=multi-user.target

Ketika saya mencoba me-restart layanan sebagai pengguna techops di baris perintah, saya mendapatkan output berikut:

==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'publicapi.service'.
Multiple identities can be used for authentication:
 1.  Myself,,, (defaultuser)
 2.  ,,, (techops)
Choose identity to authenticate as (1-2):

Saya ingin hanya Techops yang dapat me-restart layanan dan saya ingin prompt ini tidak muncul ketika sedang login sebagai Techops. Bagaimana saya bisa melakukan itu?

Saya membaca bahwa ada pendekatan berbeda dengan polkit-1 atau sudoers, tapi saya tidak yakin.

[UPDATE] 2019-01-27 4:40 pm
Terima kasih atas jawaban komprehensif ini untuk Thomas dan Perlduck. Ini membantu saya meningkatkan pengetahuan saya tentang systemd.

Menurut pendekatan untuk memulai layanan tanpa kata sandi, dan saya ingin meminta maaf bahwa saya tidak cukup menekankan masalah sebenarnya:

Sebenarnya, yang paling penting bagi saya adalah bahwa tidak ada pengguna selain techops yang harus menghentikan atau memulai layanan. Tetapi setidaknya dengan dua pendekatan pertama saya masih bisa menjalankan service publicapi stopdan saya mendapatkan prompt ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===lagi. Ketika saya memilih pengguna default dan mengetahui kata sandi, saya bisa menghentikan semua layanan. Saya ingin menolak pengguna ini melakukan hal itu, meskipun ia memiliki kata sandi . Info latar belakang penting untuk lebih memahami mengapa ini adalah bagian yang lebih penting bagi saya:
Pengguna default adalah satu-satunya pengguna yang terkena ssh tetapi pengguna ini tidak dapat melakukan hal lain (kecuali mengubah ke pengguna lain jika Anda memiliki kata sandi dari pengguna lain ini) . Tetapi saat ini, ia dapat memulai atau menghentikan layanan, tetapi pengguna ini tidak boleh melakukan ini.
Jika seseorang mendapatkan kata sandi pengguna default dan masuk melalui ssh, maka dia bisa menghentikan semua layanan saat ini. Inilah yang saya maksudkan dengan "Saya ingin hanya techops yang dapat memulai kembali layanan". Maaf, saya tidak tepat pada pertanyaan awal saya. Saya pikir sudoing pengguna techops mungkin akan memotong masalah ini, tetapi tidak. Masalahnya bukan menjalankan perintah tanpa kata sandi. (Saya bisa dengan mudah melakukan itu sebagai pengguna Techops ketika saya baru saja menjalankan /home/techops/publicapi start). Masalahnya sendiri adalah untuk mengunci pengguna default dari memulai layanan ini.

Dan saya berharap ada solusi yang bisa melakukannya.

Saya mulai dengan pendekatan Thomas. Pendekatan dengan sudo berfungsi ketika saya tidak ingin dimintai kata sandi untuk pengguna techops ketika saya menjalankan perintah seperti yang dijelaskan, misalnya

sudo systemctl start publicapi.service
sudo systemctl stop publicapi.service

Pendekatan kedua belum bekerja untuk saya. Saya tidak dapat memulai layanan tanpa prompt kata sandi ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===dan saya berhenti dapat login sebagai pengguna default ketika saya memiliki kata sandi pengguna ini.

Dengan pendekatan ketiga, layanan ini bahkan tidak mulai saat proses boot lagi jadi saya tidak yakin apakah pendekatan ini yang tepat untuk saya. Saya bahkan tidak bisa melakukannya dengan systemctl enable publicapi.serviceyang membawa saya ke kesalahan berikut:

Failed to enable unit: Unit file mycuisine-publicapi.service does not exist.

Kesalahan tidak terjadi ketika saya memindahkan semua layanan kembali ke / etc / systemd / system / dan jalankan systemctl enable publicapi.service. Kemudian layanan mulai lagi saat boot.

Semua pendekatan ini akan sedikit banyak membantu untuk mem-bypass prompt kata sandi untuk pengguna techops tetapi ketika saya menjalankan service publicapi stopatau systemctl stop publicapi dengan pengguna default, saya dapat menghentikan layanan jika saya memiliki kata sandi. Tetapi target saya adalah untuk mengunci pengguna default dari memulai atau menghentikan layanan sama sekali.

Bevor
sumber
1
Untuk pendekatan ketiga Anda harus menjalankan systemctl --user ...sebagai pengguna techopsbukan sebagai root. Baik saran saya maupun salah satu dari @PerlDuck memberikan setiap sudohak Anda defaultuser tetapi hanya untuk techops pengguna.
Thomas
1
Apakah pengguna default dikonfigurasi sebagai sudo? Dalam hal ini Anda harus menghapus pengguna dari grup sekunder dan memeriksa /etc/sudoersfile Anda jika ada referensi untuk pengguna itu.
Thomas
@ Thomas Ah, itu dia. Ini berfungsi seperti yang diharapkan sekarang. Terima kasih.
Bevor

Jawaban:

17

Untuk mencapai itu pengguna techopsdapat mengontrol layanan publicapi.servicetanpa memberikan kata sandi, Anda memiliki berbagai kemungkinan. Yang mana yang cocok untuk Anda tidak dapat dijawab karena Anda harus memilih sendiri.


sudoPendekatan klasik mungkin yang paling banyak digunakan, karena sudah ada sejak lama. Anda harus membuat mis. File sebagai berikut.
Perhatikan bahwa direktori drop-in /etc/sudoers.dhanya aktif ketika #includedir /etc/sudoers.ddiatur /etc/sudoers. Tapi itu harusnya terjadi jika Anda menggunakan distribusi Ubuntu modern. Seperti rootmengeksekusi:

cat > /etc/sudoers.d/techops << SUDO
techops ALL= NOPASSWD: /bin/systemctl restart publicapi.service
techops ALL= NOPASSWD: /bin/systemctl stop publicapi.service
techops ALL= NOPASSWD: /bin/systemctl start publicapi.service
SUDO

Sekarang Anda harus dapat menjalankan systemctlperintah sebagai pengguna techopstanpa memberikan kata sandi dengan menambahkan terlebih dahulu sudoke perintah.

sudo systemctl start publicapi.service
sudo systemctl stop publicapi.service
sudo systemctl restart publicapi.service

Metode kedua adalah menggunakan PolKit (diganti namanya dari PolicyKit ) untuk memungkinkan pengguna techopsmengontrol systemdlayanan. Bergantung pada versi polit, Anda dapat memberi pengguna normal kontrol atas unit sistemd.
Untuk memeriksa versi polkit , jalankan pkaction --version.

  • dengan polkit versi 0.106 dan lebih tinggi , Anda dapat memungkinkan pengguna untuk mengontrol unit systemd tertentu.
    Untuk melakukannya, Anda bisa membuat aturan sebagai root:

    cat > /etc/polkit-1/rules.d/10-techops.rules << POLKIT
    polkit.addRule(function(action, subject) {
        if (action.id == "org.freedesktop.systemd1.manage-units" &&
            action.lookup("unit") == "publicapi.service" &&
            subject.user == "techops") {
            return polkit.Result.YES;
        }
    });
    POLKIT
    
  • dengan polkit versi 0.105 dan lebih rendah : Anda dapat memungkinkan pengguna untuk mengontrol unit systemd. Sayangnya ini mencakup semua unit systemd dan Anda mungkin tidak ingin melakukan ini. Tidak yakin apakah ada cara untuk membatasi akses ke unit systemd tertentu dengan versi 0.105 atau lebih rendah, tapi mungkin orang lain bisa mengklarifikasi.
    Untuk mengaktifkan ini, Anda dapat membuat file sebagai root:

    cat > /etc/polkit-1/localauthority/50-local.d/org.freedesktop.systemd1.pkla << POLKIT
    [Allow user techops to run systemctl commands]
    Identity=unix-user:techops
    Action=org.freedesktop.systemd1.manage-units
    ResultInactive=no
    ResultActive=no
    ResultAny=yes
    POLKIT
    

Dalam kedua kasus, Anda dapat menjalankan systemctl [start|stop|restart] publicapi.servicesebagai pengguna techopstanpa memberikan kata sandi. Dalam kasus terakhir (polkit <= 0,105) pengguna techopsdapat mengontrol unit systemd apa pun.


Opsi ketiga adalah menjadikan layanan tersebut layanan pengguna, yang tidak perlu sudoatau polkitkonfigurasi. Ini menempatkan semuanya di bawah kendali pengguna dan hanya berfungsi jika layanan Anda yang sebenarnya yang dimulai dengan /home/techops/publicapi startdapat berjalan tanpa roothak istimewa.

Pertama, Anda harus mengaktifkan berlama-lama untuk pengguna techops. Ini diperlukan untuk memulai layanan pengguna saat boot. Seperti rootmengeksekusi:

loginctl enable-linger techops

Selanjutnya Anda harus memindahkan systemdfile unit ke techopsdirektori pengguna. Sebagai pengguna techopsjalankan perintah sebagai berikut.

mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/publicapi.service << UNIT
[Unit]
Description=public api startup script

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=-/etc/environment
WorkingDirectory=/home/techops
ExecStart=/home/techops/publicapi start
ExecStop=/home/techops/publicapi stop

[Install]
WantedBy=default.target
UNIT

Perhatikan bahwa WantedByharus default.targetkarena tidak ada multi-user.targetdalam konteks pengguna.

Sekarang muat ulang konfigurasi dan aktifkan layanan. Sekali lagi saat pengguna techopsmenjalankan perintah.

systemctl --user daemon-reload
systemctl --user enable publicapi.service
systemctl --user start publicapi.service

Secara umum Anda harus menempatkan unit systemd Anda di /etc/systemd/system/tidak langsung dalam /etc/systemd/system/multi-user.target.wants. Ketika Anda mengeksekusi systemctl enable publicapi.servicetautan simbolik akan dibuat etc/systemd/system/multi-user.target.wantsatau target apa pun yang ditentukan untuk unit itu.

Seperti yang telah disebutkan, jika layanan / proses itu sendiri dapat dijalankan tanpa hak root, Anda harus mempertimbangkan User=techopsuntuk menambahkan ke file unit Anda untuk menjalankan proses dengan akun pengguna yang tidak diistimewakan.

Thomas
sumber
Baik sekali. Anda bahkan memikirkan target WantedBy yang berbeda untuk unit pengguna. Jelas, ini bukan file unit pertama yang Anda tulis :-)
PerlDuck
Tanks @PerlDuck. = 0)
Thomas
Terima kasih untuk balasan Anda. Ini sebagian menjawab pertanyaan saya, tetapi saya masih memiliki masalah awal saya. (Saya memperbarui pertanyaan)
Bevor
Maaf, untuk yang .pklatidak berfungsi. Ini perlu [section]entri. Jawaban yang diperbarui.
Thomas
5

Pertama-tama, Anda tidak meletakkan file unit dalam direktori /etc/systemd/system/multi-user.target.wants. Direktori ini dikelola oleh systemddan systemctlperintah. Masukkan file unit /etc/systemd/systemsebagai gantinya dan kemudian aktifkan dengan

sudo systemctl enable publicapi.service

Ini akan membuat symlink di bawah ini multi-user.target.wants(atau di mana pun, systemctllebih tahu) untuk menghormati garis

[Install]
WantedBy=multi-user.target

di unit.

Selanjutnya, buat sudoersfile di bawah ini /etc/sudoers.d:

sudo visudo -f /etc/sudoers.d/techops

dengan konten berikut:

Cmnd_Alias HANDLE_PUBLICAPI = \
    /bin/systemctl start   publicapi.service \
    /bin/systemctl stop    publicapi.service \
    /bin/systemctl restart publicapi.service

techops ALL = (root) NOPASSWD: HANDLE_PUBLICAPI

Jangan gunakan editor reguler (mis. sudo vim /etc/sudoers.d/techops) Untuk mengedit file itu karena jika Anda memasukkan kesalahan sintaksis di dalamnya, Anda tidak akan dapat menjalankannya sudolagi. visudodi sisi lain memeriksa sintaksis dari file sebelum meninggalkan editor.

Sekarang pengguna techopsdapat berlari

sudo systemctl start publicapi.service

dan dua lainnya tanpa memberikan kata sandi. Perhatikan bahwa Anda harus mengetik perintah dan parameter persis seperti yang diberikan dalam sudoersfile (kecuali untuk /bin/systemctlbagian yang dapat disingkat menjadi adil systemctl).

Misalnya, sudo /bin/systemctl start publicapi(tanpa .service) akan meminta kata sandi.

PerlDuck
sumber