如何在 systemctl 中在两个服务器之间创建持久 SSH 连接

如何在 systemctl 中在两个服务器之间创建持久 SSH 连接

这是我的/etc/systemd/system/proxy.service文件:

[Unit]
Description=proxy
After=system.slice multi-user.target

[Service]
Type=forking
User=root

StandardOutput=stdout
StandardError=stderr
SyslogIdentifier=root

ExecStart=/usr/bin/bash /root/proxy/proxy.sh
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

当我运行时systemctl status proxy,我发现它没有运行,并且我在我的网站中看到此错误:

An error occurred: Failed to connect to api.domain.com port 9999: Connection refused

/root/proxy/proxy.sh但是如果我在终端中手动运行,连接api.domain.com:9999将持续并且工作正常。这是systemctl status proxy

● proxy.service - proxy
   Loaded: loaded (/etc/systemd/system/proxy.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Sat 2022-01-22 17:02:40 +0330; 5min ago
  Process: 1830 ExecStart=/usr/bin/bash /root/proxy/proxy.sh (code=exited, status=0/SUCCESS)

Jan 22 17:02:40 server.domain.com root[1830]: IPv4 address for veth-srv-proxy:  192.0.2.2
Jan 22 17:02:40 server.domain.com root[1830]: IPv4 address for wg0:             10.7.0.1
Jan 22 17:02:40 server.domain.com root[1830]: * Super-optimized for small spaces - read how we shrank the memory
Jan 22 17:02:40 server.domain.com root[1830]: footprint of MicroK8s to make it the smallest full K8s around.
Jan 22 17:02:40 server.domain.com root[1830]: https://ubuntu.com/blog/microk8s-memory-optimisation
Jan 22 17:02:40 server.domain.com root[1830]: 5 updates can be applied immediately.
Jan 22 17:02:40 server.domain.com root[1830]: 5 of these updates are standard security updates.
Jan 22 17:02:40 server.domain.com root[1830]: To see these additional updates run: apt list --upgradable
Jan 22 17:02:40 server.domain.com root[1830]: *** System restart required ***
Jan 22 17:02:40 server.domain.com systemd[1]: Started proxy.

我看到它成功退出(在服务器登录时),但按照人的逻辑它不起作用。

我应该怎么做才能保持持久连接?

我应该说一下我尝试过链接和在我的命令中,但它无法保持其持久性。

更新 1

内容/root/proxy/proxy.sh

ssh -L 127.0.0.1:9999:api.domain.com:443 remote-server

答案1

首先,basicssh默认会启动一个交互式 shell 会话。一旦该 shell 到达“文件末尾”(当无法从 stdin 读取更多输入时),它就会退出。由于服务输入可用时,交互式 shell 将立即退出。

对于服务来说,该ssh -N选项更为合适:它不会尝试启动任何 shell 会话,也不会尝试启动批处理命令,而是创建一个纯粹用于隧道的连接。

其次,Type=forking期望相关程序将“守护进程化”或“进入后台”。如果它不这样做 - 例如,您从终端运行它并且它继续占用该终端 - 那么它不是 Type=forking,它只是 Type=simple/Type=exec。

(Systemd 并不关心服务是否将使用 fork();Type= 专门用于初始进程是否会 fork然后退出即在启动期间“守护进程”。)

使用 ssh 时,该ssh -f选项(即,ssh -fN在本例中)将使其 Type=forking。如果没有,则-f在您的情况下将是 Type=simple/exec(尽管在给出短时间运行的命令的情况下,它也可能是 Type=oneshot)。

(虽然中间bash过程可能会使事情变得有点混乱。如果您想要的只是运行 1 个命令,那么这是不必要的 - 只需将该命令直接放入 systemd 服务中即可。)

把所有东西放在一起:

  • 我更喜欢使用“forking”模式,因为它允许 systemd 清楚地区分仍在“启动”的服务与已完全“启动”的服务。

    [服务]
    类型=分叉
    ExecStart=/usr/bin/ssh-f -N-L 127.0.0.1:9999:api.domain.com:443 远程服务器
    
  • 但在某些情况下,“简单”就足够了:

    [服务]
    类型=简单的
    ExecStart=/usr/bin/ssh-N-L 127.0.0.1:9999:api.domain.com:443 远程服务器
    

相关内容