update
This commit is contained in:
parent
e19a09f2df
commit
33f60b93c4
4 changed files with 4 additions and 230 deletions
22
flake.lock
generated
22
flake.lock
generated
|
@ -1,26 +1,6 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"root": {}
|
||||||
"locked": {
|
|
||||||
"lastModified": 1738574474,
|
|
||||||
"narHash": "sha256-rvyfF49e/k6vkrRTV4ILrWd92W+nmBDfRYZgctOyolQ=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "fecfeb86328381268e29e998ddd3ebc70bbd7f7c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-24.11",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
"version": 7
|
"version": 7
|
||||||
|
|
30
flake.nix
30
flake.nix
|
@ -1,35 +1,11 @@
|
||||||
{
|
{
|
||||||
description = "Opinionated Nixvim config as a flake";
|
description = "Opinionated Nixvim config as a flake";
|
||||||
|
|
||||||
inputs = {
|
outputs = { ... }:
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = { self, nixpkgs, ... } @ inputs:
|
|
||||||
# let
|
|
||||||
# system = "x86_64-linux";
|
|
||||||
# in
|
|
||||||
{
|
{
|
||||||
packages.x86_64-linux = let
|
|
||||||
pkgs = import "${nixpkgs}" {
|
|
||||||
# system = "x86_64-linux";
|
|
||||||
};
|
|
||||||
|
|
||||||
in with pkgs; {
|
|
||||||
nixvim-config = callPackage ./default.nix {
|
|
||||||
inherit builtins;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
nixosModules = rec {
|
nixosModules = rec {
|
||||||
homefree = import ./default.nix {
|
nixvim-config = import ./default.nix {};
|
||||||
# inherit system;
|
default = nixvim-config;
|
||||||
};
|
|
||||||
imports = [ ];
|
|
||||||
default = homefree;
|
|
||||||
lan-client = import ./lan-client.nix {
|
|
||||||
# inherit system;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import getopt
|
|
||||||
import inspect
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import psutil
|
|
||||||
import signal
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
import urllib
|
|
||||||
|
|
||||||
from selenium import webdriver
|
|
||||||
from selenium.webdriver.chrome.service import Service
|
|
||||||
from selenium.webdriver.support.ui import WebDriverWait
|
|
||||||
from xdg_base_dirs import xdg_config_home
|
|
||||||
|
|
||||||
script_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
|
||||||
|
|
||||||
class OpenconnectPulseLauncher:
|
|
||||||
|
|
||||||
def signal_handler(self, _sig, _frame):
|
|
||||||
subprocess.run(['sudo', 'route', 'del', 'default', 'gw', self.vpn_gateway_ip])
|
|
||||||
while 'openconnect' in (i.name() for i in psutil.process_iter()):
|
|
||||||
subprocess.run(['sudo', 'pkill', '-SIGINT', 'openconnect'])
|
|
||||||
ps = subprocess.Popen(
|
|
||||||
['getent', 'hosts', self.hostname],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
)
|
|
||||||
output = subprocess.check_output(
|
|
||||||
['awk', '{print $1}'],
|
|
||||||
stdin=ps.stdout
|
|
||||||
)
|
|
||||||
ps.wait()
|
|
||||||
vpn_ip = output.decode().rstrip()
|
|
||||||
# This is normally deleted when the VPN is killed, but sometimes is left behind as there are two entries
|
|
||||||
subprocess.run(['sudo', 'route', 'del', vpn_ip])
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.is_root = os.geteuid() == 0
|
|
||||||
self.chrome_profile_dir = os.path.join(xdg_config_home(), 'chromedriver', 'pulsevpn')
|
|
||||||
if not os.path.exists(self.chrome_profile_dir):
|
|
||||||
os.makedirs(self.chrome_profile_dir)
|
|
||||||
|
|
||||||
self.vpn_gateway_ip = None
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, self.signal_handler)
|
|
||||||
|
|
||||||
def is_dsid_valid(self, dsid):
|
|
||||||
# Expiry is set to Session
|
|
||||||
return dsid is not None and 'value' in dsid
|
|
||||||
|
|
||||||
def connect(self, vpn_url, chromedriver_path, chromium_path, debug=False, script=None):
|
|
||||||
self.hostname = urllib.parse.urlparse(vpn_url).hostname
|
|
||||||
|
|
||||||
dsid = None
|
|
||||||
returncode = 0
|
|
||||||
while True:
|
|
||||||
if self.is_dsid_valid(dsid) and returncode != 2:
|
|
||||||
logging.info('Launching openconnect.')
|
|
||||||
|
|
||||||
## Run in background
|
|
||||||
|
|
||||||
## openconnect is built to already point to a pre-packaged vpnc-script, so no need to specify
|
|
||||||
# p = subprocess.run(['sudo', 'openconnect', '-b', '-C', dsid['value'], '--protocol=pulse', vpn_url, '-s', '${pkgs.unstable.vpnc-scripts}/bin/vpnc-script'])
|
|
||||||
|
|
||||||
## --no-dtls addresses VPN dying with "ESP detected dead peer", and also "ESP receive error: Message too long" error
|
|
||||||
## See: https://gitlab.com/openconnect/openconnect/-/issues/647
|
|
||||||
## Downside: lots of console spam
|
|
||||||
## Also, seems to die often with this error:
|
|
||||||
## Short packet received (2 bytes)
|
|
||||||
## Unrecoverable I/O error; exiting.
|
|
||||||
# p = subprocess.run(['sudo', 'openconnect', '--no-dtls', '-b', '-C', dsid['value'], '--protocol=pulse', vpn_url])
|
|
||||||
command_line = ['sudo', 'openconnect']
|
|
||||||
if debug:
|
|
||||||
command_line.extend(['-vvvv'])
|
|
||||||
if script is not None:
|
|
||||||
command_line.extend(['-s', script])
|
|
||||||
command_line.extend(['-b', '-C', dsid['value'], '--protocol=pulse', vpn_url])
|
|
||||||
if debug:
|
|
||||||
print('Command line:')
|
|
||||||
print(' {}'.format(' '.join(command_line)))
|
|
||||||
print('')
|
|
||||||
p = subprocess.run(command_line)
|
|
||||||
|
|
||||||
returncode = p.returncode
|
|
||||||
|
|
||||||
## Get tun0 IP and set as default GW (vpnc-script doesn't do this for some reason)
|
|
||||||
## Probably due to something like this:
|
|
||||||
## https://github.com/dlenski/openconnect/issues/125#issuecomment-426032102
|
|
||||||
## There is an error on the command line when openconnect is run:
|
|
||||||
## Error: argument "via" is wrong: use nexthop syntax to specify multiple via
|
|
||||||
|
|
||||||
## sleep to make sure tun0 is available
|
|
||||||
time.sleep(3)
|
|
||||||
ps = subprocess.Popen(
|
|
||||||
['ifconfig', 'tun0'],
|
|
||||||
stdout=subprocess.PIPE
|
|
||||||
)
|
|
||||||
output = subprocess.check_output(
|
|
||||||
['awk', '-F', ' *|:', '/inet /{print $3}'],
|
|
||||||
stdin=ps.stdout
|
|
||||||
)
|
|
||||||
ps.wait()
|
|
||||||
self.vpn_gateway_ip = output.decode().rstrip()
|
|
||||||
print('VPN IP: '+self.vpn_gateway_ip)
|
|
||||||
p = subprocess.run(['sudo', 'route', 'add', 'default', 'gw', self.vpn_gateway_ip])
|
|
||||||
|
|
||||||
# Wait for ctrl-c
|
|
||||||
signal.pause()
|
|
||||||
else:
|
|
||||||
returncode = 0
|
|
||||||
service = Service(executable_path=chromedriver_path)
|
|
||||||
options = webdriver.ChromeOptions()
|
|
||||||
options.binary_location = chromium_path
|
|
||||||
options.add_argument('--window-size=800,900')
|
|
||||||
# options.add_argument('--remote-debugging-pipe')
|
|
||||||
# options.add_argument('--remote-debugging-port=9222')
|
|
||||||
options.add_argument('user-data-dir=' + self.chrome_profile_dir)
|
|
||||||
|
|
||||||
logging.info('Starting browser.')
|
|
||||||
driver = webdriver.Chrome(service=service, options=options)
|
|
||||||
|
|
||||||
driver.get(vpn_url)
|
|
||||||
dsid = WebDriverWait(driver, float('inf')).until(lambda driver: driver.get_cookie('DSID'))
|
|
||||||
driver.quit()
|
|
||||||
logging.info('DSID cookie: %s', dsid)
|
|
||||||
|
|
||||||
def main(argv):
|
|
||||||
script_name = os.path.basename(__file__)
|
|
||||||
chromedriver_path = shutil.which('chromedriver')
|
|
||||||
chromium_path = shutil.which('chromium') or shutil.which('google-chrome')
|
|
||||||
help_message = '{} <vpn_url>'.format(script_name)
|
|
||||||
|
|
||||||
try:
|
|
||||||
opts, args = getopt.getopt(argv, 'hds:c:', ['help', 'debug', 'script=', 'chromedriver-path'])
|
|
||||||
except getopt.GetoptError:
|
|
||||||
print(help_message)
|
|
||||||
sys.exit(2)
|
|
||||||
if len(args) != 1:
|
|
||||||
print(help_message)
|
|
||||||
sys.exit(2)
|
|
||||||
debug = False
|
|
||||||
script = None
|
|
||||||
for o, a in opts:
|
|
||||||
if o in ('-h', '--help'):
|
|
||||||
print(help_message)
|
|
||||||
sys.exit()
|
|
||||||
elif o in ('-d', '--debug'):
|
|
||||||
debug = True
|
|
||||||
elif o in ('-s', '--script'):
|
|
||||||
if len(a):
|
|
||||||
script = a
|
|
||||||
elif o in ('-c', '--chromedriver-path'):
|
|
||||||
if len(a):
|
|
||||||
chromedriver_path = a
|
|
||||||
vpn_url = args[0]
|
|
||||||
|
|
||||||
launcher = OpenconnectPulseLauncher()
|
|
||||||
launcher.connect(vpn_url, chromedriver_path=chromedriver_path, chromium_path=chromium_path, debug=debug, script=script)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main(sys.argv[1:])
|
|
|
@ -1,16 +0,0 @@
|
||||||
attrs==23.2.0
|
|
||||||
certifi==2024.2.2
|
|
||||||
h11==0.14.0
|
|
||||||
idna==3.6
|
|
||||||
outcome==1.3.0.post0
|
|
||||||
psutil==5.9.8
|
|
||||||
PySocks==1.7.1
|
|
||||||
selenium==4.19.0
|
|
||||||
sniffio==1.3.1
|
|
||||||
sortedcontainers==2.4.0
|
|
||||||
trio==0.25.0
|
|
||||||
trio-websocket==0.11.1
|
|
||||||
typing_extensions==4.11.0
|
|
||||||
urllib3==2.2.1
|
|
||||||
wsproto==1.2.0
|
|
||||||
xdg-base-dirs==6.0.1
|
|
Loading…
Add table
Reference in a new issue