“把它放到后台运行”这句话里藏着两个问题。第一,这个用户究竟能不能启动一个带特权的进程;第二,会话能否在无人对着终端输入的情况下继续。shell 的与号对两者都不作回答,而把 sudo 密码存进变量的脚本,对第一个问题回答得很糟,对第二个问题则毫无触及。把这两件事分开,各选项就很容易比较。

比较这三个候选方案时,要看归属,而不是看方便。

离开终端的三种方式,三个不同的归属者

在命令后加与号,是请 shell 把它作为后台作业运行,而作业仍属于那个 shell。sudo 可能在程序启动前就发问,而OpenVPN之后还可能索要密钥口令或登录信息。把需要输入的命令放到后台,只会得到一个在无人观察的终端前等待的进程。终端被释放了,交互并没有。

那是最便宜的做法,也是最容易以令人困惑的方式失败的做法:提示出现在操作员早已离开的地方。

sudo -b 并不是凭据处理器

sudo -b 从 sudo 自己的视角把命令放到后台运行,听起来像是那个缺失的功能,其实并不是。按 sudo 手册的说法,交互式命令在该模式下通常表现失常,而 shell 的作业控制也无法管理它创建的进程。它只是移动了进程,却没有给出回答问题的途径。它本身并不提供私钥口令,也不提供网关登录。

如果连接需要交互,解决办法是受支持的非交互式认证安排,而不是换一种方式去启动同一个提示。

--daemon 改变的是程序,而不是登录

--daemon 请 OpenVPN 自己在初始化之后脱离终端。2.6 版手册指出,syslog 重定向在解析该选项时就会发生,尽管真正的脱离更晚,因此消息可能比预期更早地从终端消失。此后安静并不能证明隧道可用。请显式加上--log 或 --log-append,让输出落到你能读到的地方。

守护模式还会永久去掉控制台。受保护的私钥在该模式下需要askpass,而控制台输入的凭据若与缓存选项叠加,可能让之后的重新认证无处询问。在假定后台启动能撑过第一次密钥轮换之前,请对照已安装版本检查认证模型。

sudo 校验买到什么,又买不到什么

sudo -v 校验或刷新缓存的本地凭据,策略要求时会进行认证。它不启动 OpenVPN,不向网关认证,也不保证脚本中后续的命令会被允许。sudo -n 含义相反:不要发问,直接失败。这让本地授权失败变得明确,这点有用,但它对 OpenVPN 之后会索要什么只字不提。

两个选项都不构成理由,去给所有人授予免密命令,或把管理员密码灌进脚本。

优先选择可被观察的归属者

对于归机器所有的隧道,请使用发行版支持的服务实例。这样的归属者提供启动、停止、状态和日志,并且能在你的会话结束后继续存在。把 shell 后台运行、守护化和重启循环彼此套在一起,会让一条隧道有三个归属者,也没有明确答案说谁在运行。

无论选择哪一种,都要验证隧道所服务的资源。启动请求成功只是一个进程事件,并不是连接可用的证据。

相关文章