Systemd 서비스를 다시 시작하라는 명령

Systemd 서비스를 다시 시작하라는 명령

운영 체제: Debian 11 Bullseye

문맥:

  • 이것제로틸애플리케이션은 zerotier-one.service시스템 서비스를 추가하고 가상 네트워크 인터페이스를 생성합니다(작동하는 경우).
  • 서버는 sshd기본적으로 모든 주소를 수신합니다.0.0.0.0

그때까지만 해도 난 괜찮았어

이제 사용자 정의 구성을 도입하고 내 서버가 Zerotier 인터페이스 주소의 호출만 허용한다고 /etc/ssh/sshd_config.d/my-sshd.conf추가했습니다 .ListenAddress 192.168.10.10sshd

이제 컴퓨터를 다시 시작한 후 다음과 같은 이유로 sshd.service이전에 시작된 것으로 의심됩니다 .zerotier-one.service

$ sudo systemctl status sshd.service
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Thu 2023-09-14 17:21:27 CEST; 28s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 524 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
    Process: 551 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=255/EXCEPTION)
   Main PID: 551 (code=exited, status=255/EXCEPTION)
        CPU: 21ms

systemd[1]: Starting OpenBSD Secure Shell server...
sshd[551]: error: Bind to port 22 on 192.168.10.10 failed: Cannot assign requested address.
sshd[551]: fatal: Cannot bind any address.
systemd[1]: ssh.service: Main process exited, code=exited, status=255/EXCEPTION
systemd[1]: ssh.service: Failed with result 'exit-code'.
systemd[1]: Failed to start OpenBSD Secure Shell server

After=그래서 다음을 사용하여 변경하는 옵션을 추가했습니다 ./etc/systemd/system/ssh.service.d/override.confsudo systemctl edit sshd.service

[Unit]
After=network.target auditd.service

도착하다:

[Unit]
After=network.target auditd.service network-online.target zerotier-one.service

이제 다음과 같이 보입니다.

$ sudo systemctl cat sshd.service
# /lib/systemd/system/ssh.service
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service

# /etc/systemd/system/ssh.service.d/override.conf
[Unit]
After=network.target auditd.service network-online.target zerotier-one.service

그런데 컴퓨터를 다시 시작해도 계속 오류가 발생합니다.

지금 그렇게 하면 다음과 같은 결과를 sudo systemctl restart sshd.service얻습니다.

$ sudo systemctl status sshd.service
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/ssh.service.d
             └─override.conf
     Active: active (running) since Thu 2023-09-14 17:40:43 CEST; 2s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 3065 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
   Main PID: 3066 (sshd)
      Tasks: 1 (limit: 9423)
     Memory: 1.0M
        CPU: 21ms
     CGroup: /system.slice/ssh.service
             └─3066 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups

systemd[1]: Starting OpenBSD Secure Shell server...
sshd[3066]: Server listening on 192.168.10.10 port 22.
systemd[1]: Started OpenBSD Secure Shell server.

내 인상은 sshd.service아직 전부터 시작되고 있었던 것 같아zerotier-one.service

뭔가 빠졌나요? 아니면 다르게 확인할 수 있나요?

추가하는 것 외에 더 해야 할 일이 있나요 zerotier-one.service?After=

편집(다른 사용자의 정보):

@telkoM이 제안한 솔루션(감사합니다) 외에도 또 다른 방법으로 내 문제를 해결했습니다.

or ExecStartPost=sleep 10에 지시문을 추가하기만 하면 됩니다 .zerotier-one.serviceExecStartPre=sleep 10sshd.service

답변1

귀하의 구성에 따르면 sshd.service확실히 시작됩니다zerotier-one.service 시작. 그러나 이것만으로는 충분하지 않습니다. sshd.service실제로 Zerotier까지 기다려야 함연결 성공, 이는 상당히 늦게 발생할 수 있습니다(적어도 컴퓨터 시간 규모에서는). 그리고현재의zerotier-one.service해당 정보를 다음으로 가져오려고 시도하지도 않습니다 systemd.

[Unit]
Description=ZeroTier One
After=network-online.target network.target
Wants=network-online.target

[Service]
ExecStart=/usr/sbin/zerotier-one
Restart=always
KillMode=process

[Install]
WantedBy=multi-user.target

예를 들어 또는 IP 주소 192.168.10.10을 찾는 루프가 포함된 스크립트를 실행하는 Type=oneshot서비스(라고 부르겠습니다 )를 만들어야 할 수도 있습니다 . 사용할 수 없는 경우 스크립트는 몇 초 동안 절전 모드로 전환된 후 다시 시도됩니다.zerotier-wait-online.servicezerotier-cli listnetworksip addr show

스크립트가 주소가 나타나는 것을 확인하면 스크립트가 종료됩니다. 이는 systemd실행하도록 구성된 모든 서비스 After=zerotier-wait-online.service에 이제 계속할 수 있음을 알려줍니다. (기본 서비스 Type=simple및 기타 여러 서비스 유형과 달리 서비스는 기본 프로세스가 시작된 Type=oneshot후에만 "시작"된 것으로 간주됩니다.ExecStart성공적으로 종료되었습니다- 이것이 바로 당신에게 필요한 것입니다.

서비스가 작동하게 되면 sshd.service재정의를 다음으로 변경할 수 After=zerotier-wait-online.service있으며 원하는 방식으로 작동해야 합니다.

자체적으로 실행되므로 단순히 zerotier-wait-online.service실행을 요청할 수는 없습니다 . 그러한 요구 사항을 설정하려고 시도하면 불가능한 상황이 발생할 수 있습니다.Before=network-online.targetzerotier-one.serviceAfter=network-online.target


문제의 근본 원인은 이를 사용하면 ListenAddress시작 시 지정된 주소가 이미 존재해야 한다는 요구 사항이 발생한다는 것입니다 sshd.

sshdZerotier IP 주소를 수신 해야 하는 경우오직, 그러나 이를 구현하기 위해 특별히 사용할 필요는 없으며 ListenAddress다른 방법을 사용하여 제한을 구현할 수 있습니다.

에서는 다음과 같은 블록을 /etc/ssh/sshd_config추가하여 Zerotier를 제외한 모든 로컬 IP 주소에 대한 액세스를 거부할 수 있습니다 .Match

Match LocalAddress *,!192.168.10.10
    DenyUsers *

iptables또는 대상 주소가 192.168.10.10이 아닌 경우 다음을 사용하여 들어오는 연결을 끊거나 거부할 수 있습니다.

iptables -I INPUT 1 -p tcp --dport 22 \! -d 192.168.10.10/32 -j DROP

DROP차단된 연결 시도가 시간 초과될 때까지 중단됩니다. 차단된 연결이 빨리 실패하도록 하려면 대신 다음과 같은 규칙을 사용하세요.

iptables -I INPUT 1 -p tcp --dport 22 \! -d 192.168.10.10/32 -j REJECT --reject-with tcp-reset

다른 방화벽 관리 시스템을 사용하는 경우 ufw이에 상응하는 규칙을 구성하는 방법이 있을 수 있습니다.

답변2

문제를 해결하는 데 잘못된 레이어가 있기 때문에 해결 방법을 사용하면 계속해서 문제가 발생합니다. systemd 또는 zerotier에 없습니다. 설정이 허용되어야 하는 sshd입니다. IP_free 바인딩소켓 옵션을 사용하면 "아직" 또는 "한번도" 구성된 주소를 수신할 수 있습니다. }

이를 수행하는 패치는 다음과 같습니다.https://bugzilla.mindrot.org/attachment.cgi?id=2763, 맞는 말이지만 불행하게도 openSSH 개발자들은 이를 받아들이지 않았습니다.

관련 정보