나는 jekyll에 대한 자체 서비스를 만들었고 서비스를 시작할 때 강제로 종료해야 하기 때문에 백그라운드 프로세스로 실행되지 않는 것 ctrl같습니다 c. --watch 때문에 포그라운드에 머물게 됩니다. 그것을 우회하고 백그라운드에서 실행시키는 방법을 모르겠습니다. 어떤 아이디어가 있나요?
# /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
답변1
Systemd는 다양한 서비스 유형, 특히 다음 중 하나를 처리할 수 있습니다.
simple
- 자신을 백그라운드에 두지 않고 셸에 연결된 상태로 유지하는 장기 실행 프로세스입니다.forking
- 자신을 포크하여 실행 중인 프로세스에서 분리하여 효과적으로 백그라운드에 배치하는 일반적인 데몬 프로세스입니다.oneshot
- 종료될 것으로 예상되는 단기 프로세스입니다.dbus
- 단순하지만 프로세스 시작 완료 알림이 dbus를 통해 전송됩니다.notify
- 단순하지만 프로세스 시작 완료 알림이 inotify를 통해 전송됩니다.idle
- 단순함과 동일하지만 작업이 전달된 후 바이너리가 시작됩니다.
귀하가 선택한 경우 Type=forking
이는 systemd가 프로세스가 자체적으로 분기되고 상위 프로세스가 종료되기를 기다리고 있음을 의미합니다. 이는 프로세스가 성공적으로 시작되었음을 나타냅니다. 그러나 프로세스는 이를 수행하지 않습니다. 프로세스는 포그라운드에 남아 있으므로 systemctl start
무기한으로 정지되거나 프로세스가 충돌할 때까지 정지됩니다.
대신 Type=simple
이것이 기본값이므로 라인을 완전히 제거하여 동일한 효과를 얻을 수 있습니다. 이 모드에서 systemd는 프로세스 시작이 완료될 때까지 기다리지 않으므로(언제 이런 일이 발생하는지 알 수 없기 때문에) 실행 및 종속 서비스를 즉시 계속합니다. 귀하의 경우에는 없으므로 중요하지 않습니다.
보안에 대한 작은 참고 사항:
서비스를 루트로 실행하는데, 권한이 없는 사용자로 실행하는 것보다 덜 안전하기 때문에 사용하지 않는 것이 좋습니다. 그 이유는만약에어떻게든 명령 실행을 허용하는 jekyll의 취약점(아마도 구문 분석 중인 코드를 통해)은 공격자가 다른 조치를 취하지 않고도 시스템을 완전히 제어할 수 있게 해줍니다. 반면, 권한 없는 사용자로 실행 중인 경우 공격자는 해당 사용자만큼만 피해를 입힐 수 있으며 이제 시스템을 완전히 제어하려면 루트 권한을 얻으려고 해야 합니다. 이는 공격자가 통과해야 하는 추가 계층을 추가할 뿐입니다.
웹 서버를 실행하는 사용자와 동일한 사용자로 간단히 실행할 수 있지만 그렇게 하면 또 다른 잠재적인 공격에 노출될 수 있습니다. 사용자가 시스템의 파일을 조작할 수 있도록 허용하는 웹 서버에 취약점이 있는 경우 생성된 HTML 파일이나 최악의 경우 소스 파일을 수정하여 서버가 원하는 대로 서비스를 제공할 수 있습니다. 그러나 결과 파일과 소스 파일을 웹 서버에서만 읽을 수 있고 권한이 없는 다른 사용자가 쓸 수 있는 경우에는 웹 서버를 공격하여 쉽게 수정할 수 없습니다.
그러나 해당 서버에서 정적 파일을 제공하고 서버를 최신 상태로 유지한다면 이러한 공격은 거의 발생하지 않지만 여전히 가능합니다. 시스템의 중요성에 따라 설정 비용과 위험을 비교하는 것은 사용자의 책임입니다. 그러나 두 팁 모두 설정이 매우 간단하고 유지 관리 비용이 거의 또는 전혀 필요하지 않습니다.
답변2
또한 @마이클 더핀솔루션을 사용할 수도 있습니다.악마forking
다음 예와 같이 사용법을 달성하기 위한 도구입니다.
systemd를 데몬화하고 제어하려는 작은 쉘 스크립트를 다음과 같이 저장합니다 /home/pi/testscript.sh
.
#!/bin/bash
while true;
do
sleep 1
echo -n "."
done
아직 데몬을 설치하지 않았다면 다음과 같이 설치하세요.
sudo apt install daemonize
이제 파일 서비스 정의 파일을 만듭니다.
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
새로 생성된 서비스는 systemd에 선언되어야 합니다.
systemctl daemon-reload
이제 서비스를 시작할 수 있으며 스크립트가 분기됩니다. 예상대로 서비스는 즉시 셸로 돌아가기 시작합니다. 결과는 분명합니다.
$ tail -f testscript.log
.....................