如何在脚本中以 root 身份在后台运行 OpenVPN?

nul*_*ull 34 command-line bash scripts job-control openvpn

我想编写一个脚本,openvpn首先调用,然后调用ssh. 输入命令时

sudo openvpn ~/my_connection.ovpn
Run Code Online (Sandbox Code Playgroud)

在命令提示符下,我得到以下输出:

...
Wed Jan  4 21:04:35 2017 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Wed Jan  4 21:04:35 2017 /sbin/ip link set dev tun0 up mtu 1500
Wed Jan  4 21:04:35 2017 /sbin/ip addr add dev tun0 local IP_FOO peer IP_FOO
Wed Jan  4 21:04:35 2017 Initialization Sequence Completed
Run Code Online (Sandbox Code Playgroud)

此命令被阻塞,shell 未释放。为了之后启动 ssh 连接,我需要通过键入Ctrl+Z后跟 a将 openvpn 进程推入后台bg

但是,我想通过仅调用我的 bash 文件来自动调用 openvpn 连接步骤和 ssh。我如何设法模拟此文件中的Ctrl+Zbg步骤?

我试图将 a 附加&openvpn命令并放在nohup它的前面。两者都不起作用。

Eli*_*gan 57

TL;DR:使用sudo -b或更好地使用.openvpn [...] --daemon

由于您正在运行openvpn(更具体地说,因为您希望在后台以 root身份运行程序),关于如何在后台运行命令的最常见分配信息并不能解决您的情况。你说:

我试图将 & 附加到 cpenvpn 命令并将 nohop 放在它前面。两者都不起作用。

你的命令是:

sudo openvpn ~/my_connection.ovpn
Run Code Online (Sandbox Code Playgroud)

sudo的默认配置下,如果您最近没有sudo在同一终端中输入密码(或已注销并重新登录该终端),那么它会询问您的密码。但是,如果您通过追加在后台运行命令,&那么您将不会看到该行或有机会输入它。[sudo] password for user:

所以在这种情况下,运行命令,输入密码,然后将其发送到后台是一种合理的方法,用于交互使用

但这不是唯一的方法,正如您所说,您不会希望在脚本中这样做。

方式 1:确保sudo有一个新的时间戳。

您可以确保sudo在用于运行命令时具有当前时间戳,首先运行:

sudo -v
Run Code Online (Sandbox Code Playgroud)

然后,在那之后,您可以运行:

sudo openvpn ~/my_connection.ovpn &
Run Code Online (Sandbox Code Playgroud)

但是,当您想在后台运行命令时,最好完全避免&(和nohupsudo。脚本编写尤其如此。

方式二:使用sudo -b. 一般来说,这通常是您想要的。

相反,您可以sudo在前台运行自己,但传递-b标志以便sudo在后台运行命令。

sudo -b openvpn ~/my_connection.ovpn
Run Code Online (Sandbox Code Playgroud)

这通常是一种更好的方法,尤其是当您将命令放入脚本时。随着sudo -b你没有得到作业控制,但在shell脚本作业控制默认情况下禁用,你不应该经常使用它

正如man sudo解释:

     -b, --background
                 Run the given command in the background.  Note that it is not
                 possible to use shell job control to manipulate background
                 processes started by sudo.  Most interactive commands will
                 fail to work properly in background mode.
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为sudo 收到您的密码(如有必要)并确定您被允许运行该命令之前,后台不会运行任何内容。

方式 3:但是对于openvpn,您可能应该使用--daemon.

openvpn如果您使用以下--daemon选项运行它,它将在后台自动运行:

sudo openvpn ~/my_connection.ovpn --daemon
Run Code Online (Sandbox Code Playgroud)

--daemon在您的.opvn文件名之后而不是之前传递;后面的参数--daemon(如果有)被解释为守护openvpn进程应该使用的名称。(难道也追加&。)

这是否合适取决于在openvpn运行之后但在守护进程之前是否必须发生任何交互。而部分取决于,上有什么设置~/my_connection.ovpn。但是如果openvpn不能立即守护进程,那么所有其他在后台立即运行它的方式也会中断

因此,在你知道你想要的任何情况openvpn,以开始在后台运行,并且你知道你不会希望把它放回前景,你应该认真考虑与调用它的方法--daemon选择。这是特定于openvpn--most 程序不支持--daemon选项的,尽管许多服务器程序确实有一些这样的选项。(但是,名称和语法各不相同。)

要决定是否要使用这个选项(以及要如何使用它),我建议你阅读openvpn手册页,特别是在上一节--daemon。它有很多有用的信息,我在这里只引用第一段:

       --daemon [progname]
              Become  a  daemon  after  all   initialization   functions   are
              completed.   This option will cause all message and error output
              to be sent to  the  syslog  file  (such  as  /var/log/messages),
              except  for  the  output of scripts and ifconfig commands, which
              will go to /dev/null unless otherwise  redirected.   The  syslog
              redirection  occurs  immediately  at  the point that --daemon is
              parsed on the command line even though the  daemonization  point
              occurs  later.   If one of the --log options is present, it will
              supercede syslog redirection.

              The optional progname parameter [...]
Run Code Online (Sandbox Code Playgroud)

方式 4:有时以 root 身份运行整个脚本是合理的。

如果您有一个以 root 用户身份执行多个操作的脚本,它没有任何重要的活动可以合理地以 root 用户身份运行,并且以非 root 用户身份运行脚本永远不会有任何用处,那么脚本的用户可能应该以 root 身份运行它。

如果是这种情况,那么您应该sudo从脚本中的命令中删除。当脚本以 root 身份运行时,不需要sudo. (虽然root用户可以在默认情况下,运行任何命令,任何用户,包括本身sudo,如果你并不需要密码才能这样做。所以的休假情况sudo在脚本那么它仍然可能会工作。)

如果您sudo在脚本中有任何实际用于以 root 以外的其他用户身份运行命令的实例(使用),那么您仍应保留这些实例。-u user

如果整个脚本以 root 身份运行,那么大多数使命令在后台运行的典型方法都适用,包括附加&和在需要时使用nohup(您已经知道)。但是,为此,您仍然应该强烈考虑使用openvpn--daemon选项。

  • 须藤 openvpn --config ~/my_connection.ovpn --daemon (3认同)
  • 一个非常全面和深思熟虑的答案。做得好。 (2认同)

Raj*_*rma 9

TL;DR在守护进程模式下运行它:openvpn --config Windscribe-Japan.ovpn --daemon

openvpn仅当未指定其他选项时,将配置 (.ovpn) 文件名传递给命令才有效。如果我指定--daemon选项,则 openvpn 尝试将文件名解析为选项参数并抛出选项错误:我正在尝试将“Windscribe.ovpn”解析为 --option 参数,但我没有看到前导 '--'

回答:

为避免这种情况,必须使用--config选项指定文件名。例如,openvpn --config Windscribe.ovpn --daemon。然后用tail -f /var/log/syslog,尾随 syslog 以进行进一步检查。

您还可以检查此 curl 命令的前后输出curl ifconfig.co以确保 VPN 已连接。

注意:即使您从 SSH 会话注销,这也将使守护程序继续运行。