创建持久反向 SSH 隧道时,autossh 在运行 systemd 的系统上有用吗?通常,autossh 由选项 -M 设置为零的服务运行,这将禁用对链接的监视。这意味着 ssh 必须先退出,然后 autossh 才能重新启动它。从手册页:
将监控端口设置为0会关闭监控功能,autossh只会在ssh退出时重新启动ssh。例如,如果您使用的是最新版本的 OpenSSH,您可能希望尝试使用 ServerAliveInterval 和 ServerAliveCountMax 选项让 SSH 客户端在发现自己不再连接到服务器时退出。从很多方面来说,这可能是比监控端口更好的解决方案。
systemd 服务本身似乎能够通过包含以下选项的服务文件来执行此操作:
Type=simple
Restart=always
RestartSec=10
那么 autossh 当由 systemd 服务运行时是多余的吗?或者它是否在做其他事情来帮助保持 SSH 连接?
谢谢。
答案1
谢谢你提出了一个很好的问题。我有一个使用 autossh -M 0 运行的 systemd 服务。并且刚刚意识到将 autossh 与 systemd 一起使用是多余的。
这是我的新服务,没有 autossh。即使我自己杀死 ssh 进程,它也运行良好并重新启动。
[Unit]
Description=autossh
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=
ExecStart=/usr/bin/ssh -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o ExitOnForwardFailure=yes -R8023:localhost:22 sshtunnel@[address of my server] -N -p 22 -i /root/.ssh/id_rsa_insecure
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
如何开始服务:
- 在服务器上创建sshtunnel用户(不要赋予root权限)
- 将未加密的 RSA 密钥“id_rsa_insecure”放在这里 /root/.ssh/。您应该将公共部分放在服务器上的 /home/sshtunnel/.ssh/authorized_keys 中
- 使用上面的代码创建一个文件“autossh.service”并将其放在 /etc/systemd/system 中
- 运行以下命令
sudo systemctl daemon-reload
sudo systemctl start autossh
sudo systemctl enable autossh
一些解释性说明:
ExitOnForwardFailure
这是我第一次错过的。如果没有此选项,如果端口转发由于某种原因失败(相信我,这种情况确实发生了),SSH 隧道将存在,但毫无用处。所以需要将其杀死并重新启动。
/root/.ssh/id_rsa_insecure
从名称中可以看出,该密钥未加密,因此它必须是一个特殊的密钥,并且您必须限制使用该密钥的用户在服务器端执行任何操作,但创建反向通道。最简单的方法是限制服务器端的authorized_keys 文件中的行为。
# /home/sshtunnel/.ssh/authorized_keys
command="/bin/true" ssh-rsa [the public key]
这可以防止“sshtunnel”用户启动 shell 并执行任何命令。
额外的安全保障:
我尝试过但不起作用:1)在服务器端:将“sshtunnel”用户的 /etc/passwd 中的 shell 更改为 /bin/false 2)在服务器端:在authorized_keys 文件中添加 Permitopen=host:port sshtunnel id_rsa_insecure 密钥
我没有尝试,但我认为它应该有效:您可以通过配置 SELinux 用户配置文件进一步限制“sshtunnel”用户(仅允许特定端口转发) - 但我没有方便的代码。如果有人有代码,请告诉我。
我很想听听我当前的解决方案中存在的任何安全错误。谢谢
答案2
由于尝试这两种方法相对容易,因此请测试这两种方法的可靠性并亲自确认。
我想你会发现它autossh
更适合这份工作。autossh
设计用于运行在前景,而systemd
主要设计用于背景不附加到特定的服务电传打字机。
此外,autossh
至少具有一项特定于该任务的功能:
autossh 会定期(默认情况下每 10 分钟一次)尝试在监视器转发端口上传递流量。如果失败,autossh 将终止 ssh 子进程(如果它仍在运行)并启动一个新进程;
因此,autossh
不仅仅是保持进程运行,而是确认连接ssh
确实正常工作。