Saya sedang menulis systemd
file unit untuk OSSEC HIDS. Masalahnya adalah ketika systemd
memulai layanan itu segera menghentikannya.
Ketika saya menggunakan ExecStart
berikut direktif semuanya bekerja dengan baik.
ExecStart=/var/ossec/bin/ossec-control start
Tetapi ketika saya melakukan perbaikan kecil berikut, saya menemukan di log OSSEC bahwa ia menerima SIG 15
setelah dimulai.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'
Jika saya melakukan perubahan kecil lagi, layanan akan menerima SIG 15
setelah 20 detik.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'
Jadi, saya rasa, systemd
. itu membunuh /bin/sh
proses setelah layanan dimulai, dan /bin/sh
lalu bunuh OSSEC
.
Bagaimana cara mengatasi masalah ini?
Jawaban yang Diterima:
ketidakcocokan protokol kesiapan
Seperti yang disiratkan Wieland, Type
dari layanan itu penting. Pengaturan itu menunjukkan apa protokol kesiapan systemd mengharapkan layanan untuk berbicara. Sebuah simple
layanan diasumsikan segera siap. Sebuah forking
layanan diambil untuk siap setelah proses awalnya memotong anak dan kemudian keluar. Sebuah dbus
layanan diambil untuk siap ketika server muncul di Bus Desktop. Dan seterusnya.
Jika Anda tidak mendapatkan protokol kesiapan yang dinyatakan di unit layanan agar sesuai dengan apa yang dilakukan layanan, maka semuanya menjadi serba salah. Ketidakcocokan protokol kesiapan menyebabkan layanan tidak dimulai dengan benar, atau (biasanya lebih) didiagnosis (salah) oleh systemd sebagai gagal. Ketika layanan dianggap gagal memulai systemd memastikan bahwa setiap proses tambahan yatim piatu dari layanan yang mungkin dibiarkan berjalan sebagai bagian dari kegagalan (dari sudut pandangnya) dimatikan untuk mengembalikan layanan dengan benar ke status tidak aktif.
Anda melakukan hal ini.
Pertama-tama, hal-hal sederhana:sh -c
tidak cocok dengan Type=simple
atau Type=forking
.
Dalam simple
protokol, proses awal diambil untuk menjadi proses pelayanan. Tapi sebenarnya sh -c
wrapper menjalankan program layanan sebenarnya sebagai proses anak . Jadi MAINPID
salah dan ExecReload
berhenti bekerja, sebagai permulaan. Saat menggunakan Type=simple
, seseorang harus menggunakan sh -c 'exec …'
atau tidak menggunakan sh -c
di tempat pertama. Yang terakhir lebih sering jalan yang benar daripada yang dipikirkan beberapa orang.
sh -c
tidak cocok dengan Type=forking
antara. Protokol kesiapan untuk forking
layanan cukup spesifik. Proses awal harus fork anak, dan kemudian keluar. systemd menerapkan batas waktu untuk protokol ini. Jika proses awal tidak bercabang dalam waktu yang ditentukan, itu adalah kegagalan untuk menjadi siap. Jika proses awal tidak keluar dalam waktu yang ditentukan, itu juga merupakan kegagalan.
kengerian yang tidak perlu yaitu ossec-control
Yang membawa kita ke hal yang rumit:ossec-control
naskah.
Ternyata itu adalah rc
Sistem 5 skrip yang memotong antara 4 dan 10 proses, yang pada gilirannya juga bercabang dan keluar. Itu salah satu dari rc
Sistem 5 itu skrip yang mencoba mengelola seluruh rangkaian proses server dalam satu skrip tunggal, dengan for
loop, kondisi balapan, sleep
sewenang-wenang s 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 di direktori biner yang ditulis ulang dengan cepat, untuk mengimplementasikan enable
yang istimewa dan disable
kata kerja.
Jadi ketika Anda /bin/sh -c '/var/ossec/bin/ossec-control start'
yang terjadi adalah:
- systemd memotong apa yang diharapkan sebagai proses layanan.
- Itu cangkangnya, yang memotong
ossec-control
. - Itu pada gilirannya membagi antara 4 dan 10 cucu.
- Cucu-cucu bercabang dan keluar secara bergantian.
- Cucu buyut semuanya bercabang dan keluar secara paralel.
ossec-control
keluar.- Cangkang pertama keluar.
- Proses layanan adalah hebat-hebat- cucu, tetapi karena cara kerja ini tidak keduanya
forking
atausimple
protokol kesiapan, systemd menganggap layanan secara keseluruhan telah gagal dan mematikannya kembali.
Tak satu pun dari kengerian ini sebenarnya diperlukan di bawah systemd sama sekali. Tidak ada.
unit layanan template systemd
Sebagai gantinya, seseorang menulis unit template yang sangat sederhana :
[Unit] Description=The OSSEC HIDS %i server After=network.target [Service] Type=simple ExecStartPre=/usr/bin/env /var/ossec/bin/%p-%i -t ExecStart=/usr/bin/env /var/ossec/bin/%p-%i -f [Install] WantedBy=multi-user.target
Simpan ini sebagai /etc/systemd/system/[email protected]
.
Berbagai layanan sebenarnya adalah instansiasi dari template ini, bernama:
[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 langsung dari sistem manajemen layanan (dengan bug RedHat 752774 diperbaiki), tanpa perlu skrip shell tersembunyi.
systemctl enable [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]
Selain itu, systemd mengetahui, dan melacak, setiap layanan aktual secara langsung. Itu dapat memfilter log mereka dengan journalctl -u
. Itu bisa tahu kapan layanan individu gagal. Ia mengetahui layanan apa yang seharusnya diaktifkan dan dijalankan.
Omong-omong:Type=simple
dan -f
pilihan ada di sini seperti halnya dalam banyak kasus lainnya. Sangat sedikit layanan di alam liar yang benar-benar menandakan kesiapan mereka melalui exit
, dan ini juga bukan kasus seperti itu. Tapi itulah yang forking
jenis berarti. Layanan di alam liar di jalan utama hanya bercabang dan keluar karena beberapa gagasan kebijaksanaan yang diterima secara keliru bahwa itulah yang seharusnya dilakukan oleh iblis. Sebenarnya tidak. Belum lagi sejak tahun 1990-an. Saatnya mengejar ketinggalan.
Bacaan lebih lanjut
- Jonathan de Boyne Pollard (2015). Masalah protokol kesiapan dengan Unix dmons . Jawaban yang Sering Diberikan.