如何以交互方式打开 VPN 通道并在后台保持 VPN 会话

如何以交互方式打开 VPN 通道并在后台保持 VPN 会话

[Archlinux 4.18.9]

我已经建立了一个简单的别名来通过 vpn 连接到集群:

alias clusvpn='sudo /usr/bin/openvpn --config client.ovpn'

这包括一个特定的/etc/sudoers条目,因此在发出 cmd 时不需要向授权用户请求 sudo 密码。

这会导致 2 个输入请求:一个用于远程 vpn 服务器上的注册用户姓名,一个用于用户密码。手动从 cli 执行操作,一切正常。没有问题。

然而一旦通道打开,即用户输入了他们的姓名和密码后,我想自动将我的 vpn 会话置于后台。理想情况下,我想在使用别名发出 cmd 的同时表明这一事实。但发出命令sudo /usr/bin/openvpn --config client.ovpn &并不允许用户输入用户名和密码。

有没有办法做到这一点,而不必借助包含密码和用户名的文件?

答案1

我了解,您谈论的凭证可以通过 传递--auth-user-pass,但不能通过 传递--askpass,因此--daemon没有用。

我认为你可以使用expect. 可能的解决方案的草图:

  1. spawn sudo /usr/bin/openvpn --config client.ovpn运行该程序。
  2. expect "Username: "或类似(取决于openvpn打印的内容,我现在无法检查)等待提示。
  3. 使用如下代码:

    send_user "Username: "
    expect_user -re "(.*)\n"
    

    从用户处获取用户名。

  4. send "$expect_out(1,string)\n"将其传递给程序。

  5. 重复密码,stty -echo可能会有用。
  6. 最后使用fork并将disconnect程序置于后台。

手册中有一些示例可能会对您有所帮助。我认为您甚至可以实现一些逻辑来涵盖诸如“密码无效,请重试”等响应。


这是我的尚未完全测试代码片段:

#!/usr/bin/expect

log_user 0
set timeout -1

spawn sudo /usr/bin/openvpn --config client.ovpn

expect "*sername*"
send_user "Username: "
expect_user -re "(.*)\n"
send "$expect_out(1,string)\n"

expect "*assword*"
stty -echo
send_user "Password: "
expect_user -re "(.*)\n"
send "$expect_out(1,string)\n"
stty echo

send_user "\n"

if {[fork]!=0} exit
disconnect
expect eof

唯一的测试是在 Debian 上进行的,spawn nc …它连接到另一个nc在单独的控制台中监听的控制台。我成功发送了提示和答案,然后原来的控制台expect终止了。我处于 shell 提示符下,但两个nc-s 仍然连接着,生成的那个在后台运行。应该也会发生同样的情况openvpn,但我从未用它测试过openvpn

请从这里开始(提示:注释掉该行log_user 0对于测试很有用)。

相关内容