Saya sedang menulis file unit systemd untuk OSSEC HIDS. Masalahnya adalah bahwa ketika systemd memulai layanan segera menghentikan mereka.
Ketika saya menggunakan petunjuk ExecStart itu semua berfungsi dengan baik.
ExecStart=/var/ossec/bin/ossec-control start
Tetapi ketika saya melakukan perbaikan kecil saya baik-baik saja di log OSSEC, bahwa ia menerima SIG 15 setelah memulai.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'
Jika saya membuat layanan perubahan kecil lainnya akan menerima SIG 15 setelah 20 detik.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'
Jadi, saya kira, systemd itu membunuh proses / bin / sh setelah layanan dimulai, dan bin / sh kemudian membunuh OSSEC.
Bagaimana saya bisa menyelesaikan masalah ini?
Jawaban:
protokol kesiapan tidak cocok
Seperti yang ditunjukkan Wieland,
Type
layanan ini penting. Pengaturan itu menunjukkan apa protokol sistem kesiapan dan mengharapkan layanan untuk berbicara. Suatusimple
layanan diasumsikan segera siap. Sebuahforking
layanan diambil untuk siap setelah proses awal garpu anak dan kemudian keluar. Sebuahdbus
layanan diambil untuk siap ketika server muncul di Desktop Bus. Dan seterusnya.Jika Anda tidak mendapatkan protokol kesiapan yang dinyatakan dalam unit layanan untuk cocok dengan apa yang dilakukan layanan, maka semuanya akan serba salah. Ketidakcocokan protokol kesiapan menyebabkan layanan tidak dimulai dengan benar, atau (lebih sering) didiagnosis oleh sistemd sebagai gagal. Ketika suatu layanan dianggap gagal untuk memulai systemd memastikan bahwa setiap proses tambahan yatim piatu dari layanan yang mungkin dibiarkan berjalan sebagai bagian dari kegagalan (dari sudut pandangnya) terbunuh untuk membawa layanan dengan benar kembali ke yang tidak aktif. negara.
Anda melakukan ini dengan tepat.
Pertama-tama, hal-hal sederhana:
sh -c
tidak cocokType=simple
atauType=forking
.Dalam
simple
protokol, proses awal diambil sebagai proses layanan. Tetapi pada kenyataannyash -c
pembungkus menjalankan program layanan yang sebenarnya sebagai proses anak . JadiMAINPID
salah danExecReload
berhenti bekerja, untuk pemula. Saat menggunakanType=simple
, seseorang harus menggunakansh -c 'exec …'
atau tidak menggunakansh -c
di tempat pertama. Yang terakhir lebih sering merupakan jalan yang benar daripada yang dipikirkan beberapa orang.sh -c
juga tidak cocokType=forking
. Protokol kesiapan untuk suatuforking
layanan cukup spesifik. Proses awal harus memotong seorang anak, dan kemudian keluar. systemd menerapkan batas waktu untuk protokol ini. Jika proses awal tidak bercabang dalam waktu yang ditentukan, itu gagal untuk siap. Jika proses awal tidak keluar dalam waktu yang ditentukan, itu juga merupakan kegagalan.horor yang tidak perlu itu
ossec-control
Yang membawa kita ke hal-hal kompleks:
ossec-control
naskah itu.Ternyata itu adalah
rc
skrip System 5 yang memotong antara 4 dan 10 proses, yang pada gilirannya mereka garpu dan keluar juga. Ini adalah salah saturc
skrip System 5 yang berupaya mengelola seluruh rangkaian proses server dalam satu skrip tunggal, denganfor
loop, kondisi balapan, arbitrarysleep
untuk mencoba menghindarinya, mode kegagalan yang dapat mencekik sistem dalam keadaan setengah-mulai, dan semua kengerian lain yang membuat orang menemukan hal-hal seperti AIX System Resource Controller dan daemontools dua dekade lalu. Dan jangan lupa skrip shell tersembunyi dalam direktori biner yang ditulis ulang dengan cepat, untuk mengimplementasikan idiosyncraticenable
dandisable
kata kerja.Jadi ketika Anda
/bin/sh -c '/var/ossec/bin/ossec-control start'
yang terjadi adalah:ossec-control
.ossec-control
keluar.forking
maupun parasimple
protokol kesiapan, systemd menganggap layanan secara keseluruhan telah gagal dan menutup ke mundur.Tak satu pun dari kengerian ini benar-benar diperlukan di bawah systemd sama sekali. Tidak satu pun.
unit layanan template systemd
Sebagai gantinya, seseorang menulis unit template yang sangat sederhana :
Simpan ini sebagai
/etc/systemd/system/[email protected]
.Berbagai layanan aktual adalah contoh dari template ini, dinamai:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Kemudian aktifkan dan nonaktifkan fungsi datang langsung dari sistem manajemen layanan (dengan RedHat bug 752774 diperbaiki), tanpa perlu skrip shell tersembunyi.
Selain itu, systemd mengetahui, dan melacak, setiap layanan aktual secara langsung. Itu dapat menyaring log mereka dengan
journalctl -u
. Ia dapat mengetahui kapan suatu layanan individual gagal. Ia tahu layanan apa yang seharusnya diaktifkan dan dijalankan.Omong-omong:
Type=simple
dan-f
pilihannya ada di sini seperti halnya dalam banyak kasus lainnya. Sangat sedikit layanan di alam yang benar - benar memberi sinyal kesiapan mereka karenaexit
, dan ini di sini juga tidak seperti itu. Tapi itulah yang dimaksud denganforking
tipenya. Layanan di alam liar hanya bercabang-cabang dan keluar karena beberapa anggapan yang salah diterima bahwa itulah yang seharusnya dilakukan para demon. Sebenarnya tidak. Belum sejak tahun 1990-an. Sudah waktunya untuk mengejar ketinggalan.Bacaan lebih lanjut
sumber
Requires=
merupakan semua instance yang diperlukan, dan kemudian aturPartOf=ossec.target
di ossec @ .service. Ini akan memungkinkan untuk memulai dan menghentikan ossec dengan memulai dan menghentikan ossec.target.Simpan Type = forking dan berikan lokasi file pid jika layanan awal / aplikasi mempertahankan pid apa pun.
[Unit]
Deskripsi = "Jalankan aplikasi saat boot"
Setelah = network.target syslog.target auditd.service
[Layanan]
Jenis = forking
PIDFile = / var / run / apache2 / apache2.pid
ExecStart = / etc / init.d / apache2 start
ExecStop = / etc / init.d / apache2 berhenti
StandardOutput = syslog
StandardError = syslog
Restart = on-failure
SyslogIdentifier = webappslog
[Instal]
WantedBy = multi-user.target
Alias = webapps
sumber
Agak terkait, saya memiliki layanan systemd yang tampaknya systemd akan "membunuhnya" setelah 30-an.
systemctl status service-name
akan ditampilkanmain process exited, code=exited, status=1/FAILURE
setelah 30-an telah berlalu.Ini akan berjalan dengan baik "dalam isolasi" (seperti secara manual di terminal dengan lingkungan yang sama ).
Ternyata itu tadi
di
my_script_to_spawn_process.sh
dalamnya sedang melakukan/bin/something > /dev/null 2>&1 &
yang berfungsi tetapi membuang informasi log keluaran (biasanya ia pergi ke file, atau, jika tidak, mungkin
journalctl
).Mengubahnya untuk masuk ke tempat lain seperti
/bin/something > /tmp/my_file
kemudian membuntuti
/tmp/my_file
mengungkapkan penyebab sebenarnya. Yang mana (secara tangensial) bahwa Anda tidak dapat menggunakan sintaksisEnvironment=ABC="true"
seperti yang Anda dapat dalam bash, itu harus ada tanda kutip atau nilai kunci semua dalam tanda kutip sepertiEnvironment="ABC=true"
yang menyebabkan proses saya untuk keluar "dalam tahap setup" setelah sekitar 30-an.sumber
Perhatikan bahwa model daemon systemd sederhana dan tidak kompatibel dengan banyak daemon yang ada yang melakukan banyak forking, exec'ing dan setuid'ing. Paling umum adalah daemon yang dimulai sebagai root untuk mengatur segalanya dan kemudian beralih ke UID yang kurang istimewa untuk operasi rutin. misalnya inisialisasi file Pid adalah satu hal yang gagal di bawah systemd karena masalah hak istimewa. Ada beberapa solusi (bukan perbaikan) tetapi didokumentasikan dengan buruk.
Penjelasan JdeBP disambut baik tetapi tidak lengkap dan klaimnya bahwa semua kesalahan kontrol ossec sama sekali tidak benar. Bahkan hal-hal sepele cukup bermasalah misalnya mendapatkan baris log yang tidak terputus untuk debug masalah atau pesan kesalahan yang bermakna dari systemd sendiri ketika itu membunuh proses.
sumber