Systemd servisi çıkmadan çalışıyor


30

Jekyll için kendi servisimi yarattım ve servisi başlattığımda arka plan işlemi gibi görünmüyor, çünkü bunun dışında ctrl+ 'dan cçıkmak zorunda kalıyorum . Sadece --watch nedeniyle ön planda kalır. Etrafında dolaşıp, arka planda çalışacak şekilde yapmayı nasıl bilmiyorum. Düşüncesi olan var mı?

# /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

systemd, işleminize başlar ve kullanıyorsanız başka bir işlem yapmasını bekler Type=forking. Dahası, execStartkabuk genişlemesi olarak çalışmayacak , böylece &sonunda asla bir arka plan bayrağı olarak anlaşılmayacaktır.
grochmal

benim hatam & ben test ediyordum. Öyleyse yazı basit mi olmalı?
madmanali93

2
Yanılmıyorsam jekyll bir ray tipi bir şey, yani yakut içinde küçük bir weby server. Yani evet, Type=simpleuygun olur. Ayrıca, bu, en azından internete bakan bir makinede (sizin durumunuzda olmayabilir) kök olarak çalıştığım bir uygulama değil.
grochmal

Teşekkürler evet basit işe yaradı. Ayrıca bu komut Apache için statik HTML oluşturur, böylece jekyll sunucuda kullanılmaz. Bence root olarak çalışıyorsa iyi olmalı. Emin değilim ama tartışıyordu.
madmanali93

Oh tamam, bu ne --incrementalyapar :). Evet, dosyaları kök olarak yeniden oluştururken hiçbir güvenlik sorunu görmüyorum. Tabii ki, bu dosyaların kullanıcı tarafından temin edilmediği düşünülürse.
grochmal

Yanıtlar:


54

Systemd, özellikle aşağıdakilerden biri olan çeşitli servis tiplerini idare edebilir.

  • simple - Kendini arka planlamasın ve kabuğa bağlı kalan uzun süren bir işlem.
  • forking - Kendisini çalıştıran süreçten ayırmasını, etkili bir şekilde arka plana çıkmasını zorlayan tipik bir servistir.
  • oneshot - Çıkması beklenen kısa ömürlü bir süreç.
  • dbus - Basit gibi, ancak işlemlerin başlangıç ​​bitirme bildirimi dbus üzerinden gönderilir.
  • notify - Basit gibi, ancak işlemlerin başlangıç ​​bitirme bildirimi inotify üzerinden gönderilir.
  • idle - Basit gibi, ancak ikili iş gönderildikten sonra başlatılır.

Sizin durumunuzda Type=forkingseçtiniz ki bu, systemd'in sürecin kendisini çatallamasını ve ana sürecin bitmesini beklediğini, bu sürecin başarıyla başladığının bir göstergesi olarak alıyor demektir. Ancak, işleminiz bunu yapmıyor - ön planda kalıyor ve bu nedenle systemctl startsüresiz olarak veya işlemler çökene kadar askıda kalıyor .

Bunun yerine, istediğiniz Type=simplevarsayılanı seçin, böylece aynı efekti elde etmek için çizgiyi tamamen kaldırabilirsiniz. Bu modda sistemd işlemlerin başlamasını beklemiyor (ne zaman gerçekleştiğini bilmediği için) ve böylece hizmetleri derhal yürütmeye ve bağımlı kılmaya devam ediyor. Senin durumunda hiç yok bu yüzden önemli değil.

Güvenlik hakkında küçük bir not:

Hizmeti kök olarak çalıştırıyorsunuz, bu ayrıcalıklı olmayan bir kullanıcı olarak çalıştırılmasından daha az güvenli olduğu için önerilmez. Bunun nedeni , jekyll'de bir şekilde komutların yürütülmesine izin veren bir güvenlik açığı varsa (muhtemelen ayrıştırma koduyla), saldırganın sisteminize tamamen sahip olmak için başka hiçbir şey yapmaması gerektiğidir. Öte yandan, ayrıcalıklı olmayan bir kullanıcı olarak çalıştırılırsa, saldırgan yalnızca bu kullanıcı kadar zarar verebilir ve şimdi sisteminize tamamen sahip olmak için kök ayrıcalıkları kazanmaya çalışmalıdır. Basit bir şekilde saldırganların saldırması gereken ekstra bir katman olduğunu da ekliyor.

Basitçe web sunucunuzu çalıştıran aynı kullanıcı olarak çalıştırabilirsiniz, ancak bu sizi başka bir potansiyel saldırıya açık bırakır. Web sunucunuzda, kullanıcının sisteminizdeki dosyaları yönetmesine izin veren bir güvenlik açığı varsa, oluşturulan html dosyalarını değiştirebilir veya kaynak dosyaları en kötü durumda bırakabilir ve sunucunuzun istediği her şeyi yapmasına neden olabilir. Ancak, oluşturulan dosyalar ve kaynak dosyalar yalnızca web sunucusu tarafından okunabiliyorsa ve yazılabilir başka bir ayrıcalıklı kullanıcı değilse, web sunucusuna saldırarak bunları kolayca değiştiremezler.

Ancak, bu sunucudan yalnızca statik dosyalar sunuyorsanız ve sunucuyu güncel tutuyorsanız, bu saldırılar çok düşük bir ihtimaldir - ancak yine de mümkündür. Sisteminizin ne kadar kritik olduğuna bağlı olarak kurmanın genel masraflarına karşı riskleri tartmak sizin sorumluluğunuzdadır, ancak bu ipuçlarının her ikisi de kurulumu çok kolaydır ve bakım masrafları yoktur.


0

@ Michael Daffin'in çözümüne ek forkingolarak, aşağıdaki örnekte gösterildiği gibi kullanımını sağlamak için daemonize aracını da kullanabilirsiniz .

Servis etmek istediğim ve systemd üzerinde kontrol etmek istediğim küçük bir kabuk betiği verildiğinde şunu kaydettim /home/pi/testscript.sh:

#!/bin/bash

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

Henüz sahip değilseniz, bu şekilde daemonize yükleyin:

sudo apt install daemonize

Şimdi dosya servis tanımı dosyasını oluşturun:

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

Yeni oluşturulan servis sisteme bildirilmelidir:

systemctl daemon-reload

Şimdi servisi ve scriptleri başlatabilirsiniz. Beklendiği gibi servis başlangıcı derhal kabuğa geri döner. Sonuç açıktır:

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


Sistemi başlatmak yerine daemonize+ Type=forkingkullanmanın Type=simpleve sistemin hizmete bakmasına izin vermenin avantajı nedir ? Type=forkingÇatala yazılmış eski programları desteklemek için sistemde bir tür uyumluluk ayarıdır.
Johan Myréen

Bunun eşdeğer bir çözüm olduğunu düşünüyorum; OP'ye alternatif bir çözüm sunmak ve /etc/init.d zamanlarında zaten kullandığım bu araçtan haberdar olmasını istedim, çünkü soru aynı zamanda bir sürecin nasıl yönetileceği hakkında da biraz.
Michael
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.