Systemd, başlattıktan hemen sonra servisi öldürüyor


15

OSSEC HIDS için systemd birim dosyası yazıyorum. Sorun, systemd hizmete başladığında hemen durdurmasıdır.

Bu ExecStart yönergesini kullandığımda hepsi iyi çalışıyor.

ExecStart=/var/ossec/bin/ossec-control start

Ancak küçük bir iyileşme yaptığımda, OSSEC günlüklerinde iyiyim, başlangıçtan sonra SIG 15 alıyor.

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'

Başka bir küçük değişiklik yaparsam servis 20 saniye sonra SIG 15 alacaktır.

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'

Yani, sanırım bu systemd hizmet başladıktan sonra / bin / sh işlemini öldürür ve bin / sh daha sonra OSSEC'yi öldürür.

Bu sorunu nasıl çözebilirim?


1
Hizmetin türü nedir?
Wieland

@Wieland, basit ve çatallı çalışıyordum, ama sonuç hala aynı.
Daniil Svetlov

Yanıtlar:


37

hazır olma protokolü uyumsuzluğu

Wieland'ın ima ettiği Typegibi, hizmet önemlidir. Bu ayar, sisteme hazır olma protokol sisteminin konuşmayı beklediğini gösterir . Bir simplehizmetin hemen hazır olduğu varsayılır. Bir forkinghizmet, ilk süreci bir çocuğu çatalladıktan ve sonra çıktıktan sonra hazır olarak alınır. Bir dbushizmet sunucu Masaüstü Bus göründüğünde hazır olması alınır. Ve böylece.

Hizmet biriminde, hizmetin ne yaptığına uygun olarak bildirilmek üzere hazır olma protokolünü almazsanız, işler ters gider. Hazırlık protokolü uyumsuzlukları, hizmetlerin doğru şekilde başlamamasına veya (daha genel olarak) sistemd tarafından başarısız olarak (yanlış) tanılanmasına neden olur. Bir hizmetin systemd başlatılamaması olarak görüldüğünde , hizmetin etkin olmayan bir şekilde geri etkin hale getirilmesi için, arızanın bir parçası olarak çalışmasına izin verilebilecek her yetim ek hizmet işleminin (kendi bakış açısından) öldürülmesini sağlar. durum.

Tam olarak bunu yapıyorsun.

Her şeyden önce, basit şeyler: sh -cuyuşmuyor Type=simpleveya Type=forking.

Olarak simpleprotokol, başlangıç işlem için alınır olmak hizmet işlemi. Ancak aslında bir sh -csarıcı, gerçek hizmet programını bir alt süreç olarak çalıştırır . Yani MAINPIDyanlış gidiyor ve ExecReloadyeni başlayanlar için çalışmayı bırakıyor. Kullanırken Type=simple, ilk etapta ya kullanmalı sh -c 'exec …'ya da kullanmamalı sh -c . İkincisi, bazı insanların düşündüğünden daha doğru bir seyirdir.

sh -ceşleşmiyor Type=forking. Bir forkinghizmet için hazır olma protokolü oldukça spesifiktir. İlk işlem bir çocuğu çatallamak ve sonra çıkmak zorundadır. systemd bu protokole bir zaman aşımı uygular. İlk işlem ayrılan süre içinde çatallanmazsa, hazır olmak başarısız olur. İlk işlem ayrılan süre içinde çıkmazsa, bu da bir başarısızlıktır.

gereksiz korku ossec-control

Bu da bizi karmaşık şeylere getiriyor: o ossec-controlsenaryo.

Görünüşe görerc , kendi dönüş çatallarında ve çıkışlarında da 4 ila 10 süreç arasında çatal yapan bir Sistem 5 betiği. Bir rcdizi sunucu işlemini tek bir komut dosyasında, fordöngüler, yarış koşulları, sleepbunlardan kaçınmaya çalışmak için keyfi s, sistemi yarı başlangıç ​​durumunda boğabilecek arıza modları ile yönetmeye çalışan Sistem 5 komut dosyalarından biridir. ve insanları yirmi yıl önce AIX Sistem Kaynağı Kontrolörü ve daemontools gibi şeyleri icat eden diğer tüm dehşet. Ve bir ikili dizindeki gizli kabuk komut dosyasını, kendine özgü enableve disablefiilleri uygulamak için anında yeniden yazdığını unutmayalım .

Öyleyse ne /bin/sh -c '/var/ossec/bin/ossec-control start'olduğu şu:

  1. systemd, hizmet süreci olmasını beklediğini çatallar.
  2. Çatal olan kabuk budur ossec-control.
  3. Bu da 4 ila 10 torun arasında çatal.
  4. Torunların hepsi çatal ve sırayla çıkıyor.
  5. Büyük torunların hepsi çatal ve paralel olarak çıkarlar.
  6. ossec-control çıkışlar.
  7. İlk kabuk çıkar.
  8. Hizmet süreçleri vardı büyük büyük torun, ancak çalışma maçların bu şekilde çünkü ne forking desimple hazırlık protokolü, systemd bir bütün olarak hizmet gördüğü bu geri adım başarısız oldu ve kapanır olması.

Bu dehşetten hiçbiri aslında sistemd altında gerekli değildir. Hiçbiri.

bir sistem şablonu şablonu hizmet birimi

Bunun yerine, çok basit bir şablon birimi yazar :

[Birim]
Açıklama = OSSEC HIDS% i sunucusu
= Network.target sonra 

[Hizmet]
Tür = basit
ExecStartPre = / usr / bin / env / var / ossec / bin /% p-% i -t
ExecStart = / usr / bin / env / var / ossec / bin /% p-% i -f

[Yüklemek]
WantedBy = multi-user.target

Bunu olarak kaydedin /etc/systemd/system/ossec@.service.

Çeşitli gerçek hizmetlerdir örneklemi adlı bu şablonun ait:

  • ossec@dbd.service
  • ossec@agentlessd.service
  • ossec@csyslogd.service
  • ossec@execd.service
  • ossec@agentd.service
  • ossec@logcollector.service
  • ossec@syscheckd.service
  • ossec@maild.service
  • ossec@analysisd.service
  • ossec@remoted.service
  • ossec@monitord.service

Ardından etkinleştirme ve devre dışı bırakma işlevi , gizli kabuk komut dosyalarına gerek kalmadan doğrudan hizmet yönetim sisteminden ( RedHat bug 752774 sabit) gelir.

 systemctl etkinleştir ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analydes ossec @ logcollector ossec @ remoted ossec @ syscheckd ossec @ monitord

Dahası, systemd her bir gerçek servisi doğrudan tanır ve takip eder. Günlüklerini filtreleyebilir journalctl -u. Bireysel bir hizmetin ne zaman başarısız olduğunu bilebilir. Hangi hizmetlerin etkinleştirilmesi ve çalıştırılması gerektiğini bilir.

Bu arada: Type=simpleve -fseçenek burada diğer birçok durumda olduğu gibi. Vahşi Çok az servisler aslında hazır olduklarını işaret kuvvetiyle tarafından exitve burada bu ya böyle vakalar değildir. Ama forkingtipin anlamı budur. Vahşi hizmet sadece çatal ve çıkış bazı yanlış alınan bilgelik kavramı nedeniyle dæmons yapması gerekiyordu. Aslında öyle değil. 1990'lardan beri olmadı. Yakalama zamanı.

daha fazla okuma


2
Çok detaylı cevap! Ayrıca Requires=, gerekli tüm örneklerin oluşturduğu ossec.target adlı bir "gruplama" hedefi oluşturmayı ve sonra PartOf=ossec.targetossec @ .service içinde ayarlamayı öneririm. Bu, ossec.target öğesini başlatarak ve durdurarak ossec'in başlatılmasını ve durdurulmasını sağlar.
intelfx

@JdeBP, vay! Bu tür ayrıntılı cevaplar için çok teşekkürler. Umarım bu birimi yapacağım ve sonuçları hakkında yazacağım. Yine de daha kolay olacağım. Ama haklısın, Ossec-kontrol bir başlangıç ​​cehennemidir.
Daniil Svetlov

1
/ Usr / bin / env'yi sarmalayıcı olarak kullanmanın nedeni nedir?
Marius Gedminas

1

Start hizmet / uygulama herhangi bir pid koruyorsa, Type = forking yazın ve bir pid dosyası konumu verin.

[Birim]
Description = "Uygulamayı önyüklemede çalıştır"
Sonra = network.target syslog.target auditd.service

[Hizmet]
Tür = çatallama
PIDFile = / var / run / apache2 / apache2.pid
ExecStart = / etc / init.d / apache2 başlat
ExecStop = / etc / init.d / apache2 stop
StandardOutput = syslog
StandardError = syslog
Yeniden başlat = hata durumunda
SyslogIdentifier = webappslog

[Yükle]
WantedBy = multi-user.target
Takma ad = webapps


0

Biraz alakalı, ben 30d sonra systemd onu "öldürecek" görünüyordu bir systemd hizmet vardı.

systemctl status service-namemain process exited, code=exited, status=1/FAILURE30'lar geçtikten sonra gösterecekti .

"İzole" olarak iyi çalışır ( aynı ortama sahip terminalde elle olduğu gibi ).

Olduğu ortaya çıktı

Type=forking
...
Environment=ABC="TRUE"
ExecStart=/path/to/my_script_to_spawn_process.sh

içinde my_script_to_spawn_process.shyapıyordu

/bin/something > /dev/null 2>&1 &

hangi çalışır ancak çıktı günlüğü bilgileri atıyordu (normalde bir dosyaya gider, ya da değilse, muhtemelen journalctl).

Gibi başka bir yerde oturum açmak için değiştirme /bin/something > /tmp/my_file

sonra /tmp/my_fileortaya gerçek nedeni kuyruklama . Hangi (teğetsel) sözdizimini bash'de kullanabildiğiniz Environment=ABC="true"gibi kullanmıyordu, tırnak işaretleri veya anahtar değerler içinde Environment="ABC=true", işlemimin yaklaşık 30 saniyeden sonra "kurulum aşamasında" çıkmasına neden olan anahtar değer olmamalıdır .


-4

Systemd'in daemon modelinin basit olduğunu ve çoklu çatallama, yürütme ve setuid yapma gibi birçok mevcut cinle uyumsuz olduğunu unutmayın. En yaygın olan şey, şeyleri ayarlamak için kök olarak başlayan ve daha sonra rutin işlem için daha az ayrıcalıklı bir UID'ye geçiş yapan cinlerdir. Pid dosyası başlatma, ayrıcalık sorunları nedeniyle systemd altında başarısız olan bir şeydir. Geçici çözümler var (düzeltmeler değil), ancak kötü belgelenmiş.

JdeBP'nin açıklaması açıktır, ancak eksiktir ve hepsinin ossec kontrolünün hatası olduğu iddiası doğru değildir. Oldukça önemsiz şeyler bile sorunludur, örneğin süreçleri öldürdüğünde problemleri veya sistemd'den önemli hata mesajlarını ayıklamak için kesilmemiş günlük satırları almak.


1
Zaten PID dosyaları ne işe yarar? Belirli bir hizmet için bir kişi varsa, bu PID'de gerçek bir işlem olabilir veya olmayabilir ve doğru PID'ye sahip bir işlem olduğunda, gerçekte beklenen hizmet olabilir veya olmayabilir.
JoostM
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.