dlenski / vpn-slice

vpnc-script replacement for easy and secure split-tunnel VPN setup
GNU General Public License v3.0
721 stars 86 forks source link

Split DNS not working when using `--background` flag #145

Closed amimof closed 9 months ago

amimof commented 9 months ago

I haven notived that split DNS is not working whenever I use the --background flag to openconnect. This is what I run:

sudo OPENSSL_CONF=/usr/share/openconnect/openssl.conf openconnect vpn.mycompany.com --background --user amimo --csd-wrapper /usr/share/openconnect/csd-post.sh --pid-file /run/openconnect.pid -s '/usr/local/bin/vpn-slice --verbose --dump somehost.domain.com 10.x.x.x/24'

Nothing is added to /etc/hosts however my route table is altered with the addition of the subnet provided to vpn-sclice. And this is the output of the openconnect command above:

POST https://vpn.mycompany.com
Connected to X.X.X.X:443
SSL negotiation with vpn.mycompany.com
Connected to HTTPS on vpn.mycompany.com with ciphersuite (TLS1.2)-(ECDHE-SECP256R1)-(RSA-SHA512)-(AES-256-GCM)
XML POST enabled
Trying to run CSD Trojan script '/usr/share/openconnect/csd-post.sh'.
************************************************************************
WARNING: xmlstarlet not found in path; CSD token extraction may not work
************************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<hostscan><status>TOKEN_SUCCESS</status></hostscan>
CSD script '/usr/share/openconnect/csd-post.sh' completed successfully.
GET https://vpn.mycompany.com/+CSCOE+/sdesktop/wait.html
Got HTTP response: HTTP/1.1 302 Moved Temporarily
POST https://vpn.mycompany.com/
SSL negotiation with vpn.mycompany.com
Connected to HTTPS on vpn.mycompany.com with ciphersuite (TLS1.2)-(ECDHE-SECP256R1)-(RSA-SHA512)-(AES-256-GCM)
Please enter your username and password.
Password:
POST https://vpn.mycompany.com/
Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 30, Keepalive 20
Established DTLS connection (using GnuTLS). Ciphersuite (DTLS1.2)-(ECDHE-RSA)-(AES-256-GCM).
Configured as X.X.X.X, with SSL connected and DTLS connected
Session authentication will expire at Thu Dec 21 14:06:23 2023

Continuing in background; pid 11331

If I run the same command without --backround hosts are added to /etc/hosts and output is the following

POST https://vpn.mycompany.com
Connected to X.X.X.X:443
SSL negotiation with vpn.mycompany.com
Connected to HTTPS on vpn.mycompany.com with ciphersuite (TLS1.2)-(ECDHE-SECP256R1)-(RSA-SHA512)-(AES-256-GCM)
XML POST enabled
Trying to run CSD Trojan script '/usr/share/openconnect/csd-post.sh'.
************************************************************************
WARNING: xmlstarlet not found in path; CSD token extraction may not work
************************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<hostscan><status>TOKEN_SUCCESS</status></hostscan>
CSD script '/usr/share/openconnect/csd-post.sh' completed successfully.
GET https://vpn.mycompany.com/+CSCOE+/sdesktop/wait.html
Got HTTP response: HTTP/1.1 302 Moved Temporarily
POST https://vpn.mycompany.com/
SSL negotiation with vpn.mycompany.com
Connected to HTTPS on vpn.mycompany.com with ciphersuite (TLS1.2)-(ECDHE-SECP256R1)-(RSA-SHA512)-(AES-256-GCM)
Please enter your username and password.
Password:
POST https://vpn.mycompany.com/
Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 30, Keepalive 20
Established DTLS connection (using GnuTLS). Ciphersuite (DTLS1.2)-(ECDHE-RSA)-(AES-256-GCM).
Configured as X.X.X.X, with SSL connected and DTLS connected
Session authentication will expire at Thu Dec 21 14:09:54 2023

Called by /usr/sbin/openconnect (PID 13133) with environment variables for vpnc-script:
  reason                  => reason=<reasons.pre_init: 1>
  VPNGATEWAY              => gateway=IPv4Address('X.X.X.X')
  CISCO_DEF_DOMAIN        => domain=['domain.com']
  INTERNAL_IP4_ADDRESS    => myaddr=IPv4Address('X.X.X.X')
  INTERNAL_IP4_MTU        => mtu=1300
  INTERNAL_IP4_NETMASK    => netmask=IPv4Address('255.255.255.0')
  INTERNAL_IP4_NETMASKLEN => netmasklen=24
  INTERNAL_IP4_NETADDR    => network=IPv4Network('X.X.X.0/24')
  INTERNAL_IP4_DNS        => dns=[IPv4Address('X.X.X.X'), IPv4Address('X.X.X.X')]
  IDLE_TIMEOUT            => idle_timeout=1800
  VPNPID                  => vpnpid=13133
Complete set of subnets to include in VPN routes:
  10.X.X.X/24
Complete set of host names to include in VPN routes after DNS lookup (and add /etc/hosts entries for):
  somehost.domain.com
Called by /usr/sbin/openconnect (PID 13133) with environment variables for vpnc-script:
  reason                  => reason=<reasons.connect: 2>
  VPNGATEWAY              => gateway=IPv4Address('X.X.X.X')
  TUNDEV                  => tundev='tun1'
  CISCO_DEF_DOMAIN        => domain=['domain.com']
  INTERNAL_IP4_ADDRESS    => myaddr=IPv4Address('X.X.X.X')
  INTERNAL_IP4_MTU        => mtu=1300
  INTERNAL_IP4_NETMASK    => netmask=IPv4Address('255.255.255.0')
  INTERNAL_IP4_NETMASKLEN => netmasklen=24
  INTERNAL_IP4_NETADDR    => network=IPv4Network('X.X.X.0/24')
  INTERNAL_IP4_DNS        => dns=[IPv4Address('X.X.X.X'), IPv4Address('X.X.X.X')]
  IDLE_TIMEOUT            => idle_timeout=1800
  VPNPID                  => vpnpid=13133
Complete set of subnets to include in VPN routes:
  10.X.X.X/24
Complete set of host names to include in VPN routes after DNS lookup (and add /etc/hosts entries for):
  somehost.domain.com
Blocked incoming traffic from VPN interface with iptables.
Added routes for 2 nameservers, 1 subnets, 0 aliases.
Restored routes for 0 excluded subnets.
Adding /etc/hosts entries for 2 nameservers...
  X.X.X.X = dns0.tun1
  X.X.X.X = dns1.tun1
Looking up 1 hosts using VPN DNS servers...
Got results: [<DNS IN A rdata: X.X.X.X>]
  somehost.domain.com = X.X.X.X
Added hostnames and aliases for 3 addresses to /etc/hosts.
Added 1 routes for named hosts.
Connection setup done, child process 13192 exiting.

OpenConnect

OpenConnect version v9.01-3
Using GnuTLS 3.7.9. Features present: TPMv2, PKCS#11, RSA software token, HOTP software token, TOTP software token, Yubikey OATH, System keys, DTLS, ESP
Supported protocols: anyconnect (default), nc, gp, pulse, f5, fortinet, array
Default vpnc-script (override with --script): /usr/share/vpnc-scripts/vpnc-script

vpn-slice

vpn-slice 0.16.1

System

Linux DESKTOP-2KSKAB8 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 GNU/Linux
dlenski commented 9 months ago

UPDATE: Although I still don't trust Microsoft to implement Linux/POSIX APIs correctly, it's clear that this suspicion :point_down: is incorrect in this case. Same issue occurs on Ubuntu (see https://github.com/dlenski/vpn-slice/issues/145#issuecomment-1866888309 and https://github.com/dlenski/vpn-slice/issues/146).


The --background functionality requires a working os.fork, and os.fork does not normally work on Windows.

Linux DESKTOP-2KSKAB8 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 GNU/Linux

Although fork(2)/os.fork is supposed to work on WSL, I have no idea about whether it actually works on WSL… your log suggests it isn't working.

Microsoft/Windows has a nasty track record of claiming to add support for various POSIX system calls, completely messing it up, and then never :cursing_face: fixing it, never acknowledging the mistake, and massively wasting the time of FLOSS developers who are attempting to support Windows (Exhibit A).

amimof commented 9 months ago

Thank you for the quick response. It was working before I upgraded my Debian dist in WSL. So it has at least worked at some point :) Thanks for your time. Closing this for now. Cheers

dlenski commented 9 months ago

It was working before I upgraded my Debian dist in WSL.

Hrmm, interesting. Nothing else changed?

Feel free to reopen if you discover why it stopped working, or if anyone else encounters a similar issue.

dlenski commented 9 months ago

@amimof, any chance that redirecting OpenConnect's stderr makes any difference here? (See https://github.com/dlenski/vpn-slice/issues/146#issuecomment-1866581829)

amimof commented 9 months ago

I just tried it and it's working with stderr is sent to a file. Thanks for letting me know, this was very useful!

dlenski commented 9 months ago

I just tried it and it's working with stderr is sent to a file.

:open_mouth: Okay, so this issue is in fact the same as #146.