Layanan Systemd berjalan tanpa keluar

30

Saya membuat layanan saya sendiri untuk jekyll dan ketika saya memulai layanan sepertinya tidak berjalan sebagai proses latar belakang karena saya terpaksa ctrl+ ckeluar dari itu. Itu hanya tetap di latar depan karena --watch. Saya tidak yakin bagaimana cara memutarnya dan membuatnya agar berjalan di latar belakang. Adakah pikiran?

# /etc/systemd/system/jekyll-blog.service

[Unit]
Description=Start blog jekyll

[Service]
Type=forking
WorkingDirectory=/home/blog
ExecStart=/usr/local/bin/jekyll build --watch --incremental -s /home/blog -d /var/www/html/blog &
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
User=root
Group=root

[Install]
WantedBy=multi-user.target
madmanali93
sumber
systemd akan memulai proses Anda dan berharap untuk melakukan proses lain jika Anda menggunakan Type=forking. Selain itu, itu tidak akan berjalan execStartsebagai ekspansi shell, sehingga &pada akhirnya tidak akan pernah dipahami sebagai bendera latar belakang.
grochmal
salah saya & adalah saya mengujinya. Jadi haruskah tipe sederhana?
madmanali93
2
Jika saya tidak salah jekyll adalah jenis raily thingy, yaitu server weby kecil di ruby. Jadi ya, Type=simpleakan lebih tepat. Juga, ini bukan jenis aplikasi yang akan saya jalankan sebagai root, setidaknya tidak pada mesin internet (yang mungkin bukan kasus Anda).
grochmal
Terima kasih ya sederhana berhasil. Juga perintah ini menghasilkan html statis untuk Apache sehingga jekyll tidak berfungsi di server. Saya pikir itu akan baik-baik saja jika berjalan sebagai root. Tidak yakin meskipun sedang memperdebatkannya.
madmanali93
Oh OK, jadi --incrementalmemang begitu :). Ya, saya tidak melihat masalah keamanan dalam meregenerasi file sebagai root. Tentu saja, mengingat bahwa file-file itu tidak disediakan pengguna.
grochmal

Jawaban:

54

Systemd mampu menangani berbagai jenis layanan yang berbeda khususnya salah satu dari yang berikut ini

  • simple - Proses jangka panjang yang tidak melatarbelakangi dirinya sendiri dan tetap melekat pada shell.
  • forking - Sebuah dasmon khas yang bercabang sendiri melepaskannya dari proses yang menjalankannya, secara efektif melatar belakangi dirinya sendiri.
  • oneshot - Proses berumur pendek yang diharapkan untuk keluar.
  • dbus - Seperti sederhana, tetapi pemberitahuan proses penyelesaian startup dikirim melalui dbus.
  • notify - Seperti sederhana, tetapi pemberitahuan proses penyelesaian startup dikirim tidak sah.
  • idle - Seperti sederhana, tetapi biner dimulai setelah pekerjaan telah dikirim.

Dalam kasus Anda, Anda telah memilih Type=forkingyang berarti systemd sedang menunggu proses untuk memotong sendiri dan untuk proses induk berakhir, yang diperlukan sebagai indikasi bahwa proses telah mulai berhasil. Namun, proses Anda tidak melakukan ini - ia tetap berada di latar depan dan systemctl startakan menggantung tanpa batas waktu atau hingga proses macet.

Alih-alih, Anda menginginkannya Type=simple, yang merupakan default sehingga Anda dapat menghapus garis seluruhnya untuk mendapatkan efek yang sama. Dalam mode ini systemd tidak menunggu proses untuk menyelesaikan memulai (karena tidak memiliki cara untuk mengetahui kapan ini terjadi) dan dengan demikian terus menjalankan dan bergantung layanan langsung. Dalam kasus Anda tidak ada jadi ini tidak masalah.

Catatan kecil tentang keamanan:

Anda menjalankan layanan sebagai root, ini tidak disarankan karena kurang aman daripada menjalankannya sebagai pengguna yang tidak memiliki hak. Alasan untuk ini adalah bahwa jika ada kerentanan dalam jekyll yang entah bagaimana memungkinkan eksekusi perintah (mungkin melalui kode itu parsing) maka penyerang perlu melakukan apa-apa lagi untuk sepenuhnya memiliki sistem Anda. Sebaliknya, jika dijalankan sebagai pengguna yang tidak memiliki hak istimewa, penyerang hanya dapat melakukan kerusakan sebanyak pengguna itu dan sekarang harus berusaha untuk mendapatkan hak akses root untuk sepenuhnya memiliki sistem Anda. Ini hanya menambahkan penyerang lapisan tambahan harus pergi sekalipun.

Anda cukup menjalankannya sebagai pengguna yang sama yang menjalankan server web Anda, tetapi ini membuat Anda terbuka untuk kemungkinan serangan lain. Jika ada kerentanan di server web Anda yang memungkinkan pengguna untuk memanipulasi file di sistem Anda, mereka dapat memodifikasi file html yang dihasilkan, atau terburuk file sumber dan menyebabkan server Anda melayani apa pun yang mereka inginkan. Namun, jika file yang dihasilkan dan file sumber hanya dapat dibaca oleh server web dan dapat ditulis menjadi pengguna yang tidak memiliki hak istimewa, mereka tidak akan dapat, dengan mudah, memodifikasinya dengan menyerang server web.

Namun, jika Anda hanya menyajikan file statis dari server ini dan menjaga server tetap up to date, serangan ini sangat kecil kemungkinannya - tetapi masih memungkinkan. Adalah tanggung jawab Anda untuk menimbang risiko vs overhead pengaturannya berdasarkan seberapa penting sistem Anda, tetapi kedua tips ini sangat sederhana untuk diatur dan hampir tidak ada overhead pemeliharaan.

Michael Daffin
sumber
0

Selain @ Michael Daffin solusi , Anda juga dapat menggunakan alat daemonize untuk mencapai penggunaan forkingseperti yang ditunjukkan pada contoh berikut.

Diberikan skrip shell kecil yang ingin saya daemonize dan yang ingin saya kontrol atas systemd, saya menyimpannya sebagai /home/pi/testscript.sh :

#!/bin/bash

while true;
do
    sleep 1
    echo -n "."
done

Jika Anda belum memilikinya, instal daemonize, seperti ini:

sudo apt install daemonize

Sekarang buat file definisi layanan file:

sudo vi /etc/systemd/system/testomat.service
# It is not recommended to modify this file in-place, because it will
# be overwritten during package upgrades. If you want to add further
# options or overwrite existing ones then use
# $ systemctl edit testomat.service
# See "man systemd.service" for details.

# copied from https://github.com/bitcoin/bitcoin/blob/master/contrib/init/bitcoind.service and modified by Michael 

[Unit]
Description=Test service
After=network.target

[Service]
ExecStart=daemonize -p /run/testomat/testomat.pid -o /home/pi/testscript.log /home/pi/testscript.sh
TimeoutSec=1200

# Make sure the config directory is readable by the service user
PermissionsStartOnly=true

# Process management
####################
Type=forking
PIDFile=/run/testomat/testomat.pid
Restart=on-failure
GuessMainPID = true

# Directory creation and permissions
####################################

# Run as pi:pi
User=pi
Group=pi

# /run/testomat
RuntimeDirectory=testomat
RuntimeDirectoryMode=0710

# /var/lib/testomat
StateDirectory=testomat
StateDirectoryMode=0710

# Hardening measures
####################

# Provide a private /tmp and /var/tmp.
PrivateTmp=true

# Mount /usr, /boot/ and /etc read-only for the process.
ProtectSystem=full

# Allow access to /home, /root and /run/user
# Chosing "false" is actually no hardening, this is just to demonstrate the usage of a service. Well, I could have omitted it. True. :)
ProtectHome=false

# Disallow the process and all of its children to gain
# new privileges through execve().
NoNewPrivileges=true

# Use a new /dev namespace only populated with API pseudo devices
# such as /dev/null, /dev/zero and /dev/random.
PrivateDevices=true

# Deny the creation of writable and executable memory mappings.
MemoryDenyWriteExecute=true

[Install]
WantedBy=multi-user.target

Layanan yang baru dibuat harus diumumkan ke systemd:

systemctl daemon-reload

Sekarang Anda dapat memulai layanan dan garpu skrip. Seperti yang diharapkan, layanan mulai segera kembali ke shell. Hasilnya jelas:

$ tail -f testscript.log 
.....................

Michael
sumber
Apa keuntungan menggunakan daemonize+ Type=forkingalih-alih Type=simpledan membiarkan systemd mengurus memulai layanan? Type=forkingadalah semacam pengaturan kompatibilitas dalam systemd untuk mendukung program lawas yang ditulis untuk fork.
Johan Myréen
Saya pikir ini solusi yang setara; Saya hanya ingin memberikan OP solusi alternatif dan membuatnya sadar akan alat ini yang telah saya gunakan di /etc/init.d kali karena pertanyaannya juga sedikit tentang bagaimana cara mengubah proses.
Michael