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.serviceAfter=

編集(他のユーザーの情報):

@telkoMが提案したソリューション(ありがとう)に加えて、別の方法で私の問題を解決しました。

orExecStartPost=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開発者はこれを受け入れませんでした。

関連情報