我想在启动时自动启动电子邮件隧道和袜子代理。我有一个/etc/init.d/email-tunnels
脚本调用我的主目录下的另一个脚本。它在启动时不起作用,如果我执行它就不起作用sudo service email-tunnels start
,但如果我只是运行它它就起作用sudo /etc/init.d/email-tunnels start
。顺便说一句,我在另一台机器(Debian 8)上有一个相同的设置,它在那台机器上工作起来就像一个魅力。
这些是详细信息(Ubuntu 18 设置,不起作用的设置):
[···]$ ls -lh /etc/init.d/email-tunnels
-rwxr-xr-x 1 root root 602 Aug 28 10:21 /etc/init.d/email-tunnels
[···]$
内容为(包括一些调试echo
):
[···]$ cat /etc/init.d/email-tunnels
#! /bin/sh
### BEGIN INIT INFO
# Provides: email_tunnels
# Required-Start: $all
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3
# Default-Stop: 0 1 6
# Short-Description: E-mail and HTTP tunnels over SSH
### END INIT INFO
echo "email-tunnels invoked at `date`" >> /tmp/email-tunnels.log
touch /var/lock/email-tunnels
case "$1" in
start)
echo "email-tunnels executing 'start' at `date`" >> /tmp/email-tunnels.log
su -c "/home/cal/bin/email.sh &" cal
;;
stop)
;;
*)
echo "Usage: /etc/init/email-tunnels {start|stop}"
exit 1
;;
esac
exit 0
然后,我的主目录中的脚本:
[···]$ ls -lh /home/cal/bin/email.sh
-rwxr-xr-x 1 cal cal 410 Aug 28 10:09 /home/cal/bin/email.sh
[···]$
及其内容:
[···]$ cat /home/cal/bin/email.sh
#!/bin/bash
echo "email.sh executed at `date`" >> /tmp/email.log
sleep 30
while [ "1" == "1" ]
do
echo "email.sh about to execute ssh at `date`" >> /tmp/email.log
ssh -N -D5080 -Llocalhost:10110:xx.xx.xx.xx:110 -Llocalhost:10025:xx.xx.xx.xx:25 [email protected]
sleep 120
done
我的目标(服务器)计算机上的隧道用户确实正确配置了 PK 身份验证,以便我可以在没有任何用户交互的情况下进行 ssh 连接(无需提供密码)。
有什么想法为什么它不起作用吗?从调试输出中,我看到 init.d 脚本(email-tunnels)被执行(我在 /tmp/email-tunnels.log 处看到输出),但没有执行 /home/cal/bin/email.sh - -- 当我手动运行时/etc/init.d/email-tunnels start
,我确实看到了 /tmp/email.log 调试输出,就这一点而言,隧道在我运行它之后就可以工作了。
答案1
您使用的是 Ubuntu Linux,该操作系统自 2016 年以来一直是 systemd 操作系统,并且自 2006 年以来一直是 Upstart 操作系统。van Smoorenburgrc
脚本不是这样的,尤其是对于新东西。
尤其是在这种情况下。这几乎是候选人恐怖之屋。在您的系统上,生成的服务单元正在运行一个进程来解释脚本,该进程分叉一个进程来运行su
(滥用该进程来删除特权),该进程分叉一个进程来运行 shell,该进程分叉一个进程来解释另一个脚本,该脚本运行一个无限循环的穷人守护进程主管,反复分叉ssh
。
而这一切只是为了做服务经理能做的事反正:以特定用户身份运行特定程序,并在每次退出时重新启动它。
学习journalctl -b
阅读日志,并在此相当简单的基础上进行构建:
# /etc/systemd/system/email_tunnels.service [单元] 描述=通过 SSH 的电子邮件和 HTTP 隧道 文档=https://unix.stackexchange.com/a/465353/5132 [服务] 用户=cal 类型=简单 ExecStart=/usr/bin/ssh -N -D5080 -Llocalhost:10110:xx.xx.xx.xx:110 -Llocalhost:10025:xx.xx.xx.xx:25[电子邮件受保护] 重启秒=120 [安装] WantedBy=多用户.target
然后,您只需确保在包含 SSH 身份文件的主目录可用后运行此服务即可。当然,对于某些设置来说,这只是情况登录后你的主目录已经被自动挂载、解密等等。在这种情况下你还不如不设置系统级服务根本不而是将其作为用户服务在每个用户的 systemd 实例下运行,该实例在您第一次登录时启动:
# /home/cal/.config/systemd/user/email_tunnels.service [单元] 描述=通过 SSH 的电子邮件和 HTTP 隧道 文档=https://unix.stackexchange.com/a/465353/5132 [服务] 类型=简单 ExecStart=/usr/bin/ssh -N -D5080 -Llocalhost:10110:xx.xx.xx.xx:110 -Llocalhost:10025:xx.xx.xx.xx:25[电子邮件受保护] 重启秒=120 [安装] WantedBy=default.target
当然,使用--user
选项来systemctl
控制此类每用户服务。
进一步阅读
- https://unix.stackexchange.com/a/200281/5132
- 乔纳森·德博因·波拉德 (2015)。 systemd 恐怖屋。经常给出的答案。
- https://unix.stackexchange.com/a/408848/5132
- 乔纳森·德博因·波拉德 (2014)。不要滥用 su 来删除用户权限。常见答案。
- https://unix.stackexchange.com/a/233581/5132
- 为什么systemd服务无法访问用户的主目录,但服务重启后可以工作?