使用 pexpect 和 openconnect 建立 VPN 连接

问题描述 投票:0回答:2

我正在尝试创建一个启动 VPN 连接的脚本。我根据这个 question 建模了我的脚本,它可以很好地满足我的目的,但我发现一旦我关闭脚本,VPN 连接就会中断。 当使用“-b”选项时,我在 child.read() 末尾得到以下内容:

已建立 DTLS 连接(使用 GnuTLS)。密码套件 (DTLS0.9)-(RSA)-(AES-256-CBC)-(SHA1)。 SSL 操作已取消 用户从会话中分离(SIGHUP);退出。 '

这是我的代码:

import os, sys, subprocess, time, re, pexpect
import signal

def signal_handler(sig, frame):
        print("sigHUUUUUP")
        sys.exit

child = pexpect.spawn('sudo openconnect -b --script /etc/vpnc/vpnc-script remote.host')

child.expect('.*')
child.sendline('yes')

child.expect('.*')
child.sendline('ipsec')

child.expect('.*')
child.sendline('username')

child.expect('.*')
child.sendline('password')
signal.signal(signal.SIGHUP, signal_handler)
time.sleep(15)

我强烈倾向于保留 python,但我对运行 openconnect 并为其提供预期密码的其他方式持开放态度。主要是寻找一种无需连续运行脚本即可设置 VPN 的方法。

我尝试过使用ignore_sighup=True,但这不起作用。

python linux python-3.x pexpect
2个回答
1
投票

我找到了一种方法来实现我想要的:

import os, sys, subprocess, time, re, pexpect
import signal

def signal_handler(sig, frame):
        print("sigHUUUUUP")
        sys.exit

child = pexpect.spawn('sudo screen openconnect remote.host')

child.expect('.*')
child.sendline('yes')

child.expect('.*')
child.sendline('ipsec')

child.expect('.*')
child.sendline('username')

child.expect('.*')
child.sendline('password')
child.sendline('\01d')

我将屏幕添加到我的生成线并添加了“child.sendline('d')” 我希望这不是实现这一目标的唯一方法。


0
投票

可以使用

disown -h

如果给出

-h
选项,则作业不会从表中删除,但会被标记,以便在 shell 收到 SIGHUP 时不会向作业发送 SIGHUP。

工作结果:

import subprocess
import time
import pexpect
import signal

child = None

def connect_to_vpn():
  global child
  # Send the password and tunnel information to the process
  password = "YOUR_PASSWORD_HERE"
  tunnel = "YOUR_TUNNEL_HERE"
  print("Attempting to connect to vpn!")
  
  child = pexpect.spawn('bash')
  openconnect_command = 'sudo openconnect --user=YOUR_USERNAME_HERE YOUR_VPN_URL_HERE --background'
  child.sendline(openconnect_command)  # Replace with your tunnel info
  
  # TUNNEL
  child.expect('TUNNEL_STRING_HERE', timeout=90)  # Replace with actual prompt text if needed
  print(child.before.decode())  # Prints all data up to the EOF
  child.sendline(tunnel)  # Replace with your tunnel info
  
  # PASSWORD
  child.expect('Password:', timeout=90)
  print(child.before.decode())  # Prints all data up to the EOF
  child.sendline(password)  # Replace with your password
  
  child.expect("Connected as ", timeout=30)  # Wait until the process finishes
  print(child.before.decode())  # Prints all data up to the EOF
  print("Successfully connected!")  # Print the captured output
  child.sendline("disown -h")  # Replace with your tunnel info
  child.expect(pexpect.EOF)  # Wait for the end of the output
  print(child.before.decode())  # Prints all data up to the EOF
© www.soinside.com 2019 - 2024. All rights reserved.