Git Product home page Git Product logo

vpn-slice's Introduction

vpn-slice

License: GPL v3 Build Status PyPI Homebrew

Table of Contents

Introduction

This is a replacement for the vpnc-script used by OpenConnect or VPNC.

Instead of trying to copy the behavior of standard corporate VPN clients, which normally reroute all your network traffic through the VPN, this one tries to minimize your contact with an intrusive VPN. This is also known as a split-tunnel VPN, since it splits your traffic between the VPN tunnel and your normal network interfaces.

vpn-slice makes it easy to set up a split-tunnel VPN:

  • By default, it only routes traffic for specific hosts or subnets through the VPN.
  • It automatically looks up named hosts, using the VPN's DNS servers, and adds entries for them to your /etc/hosts (which it cleans up after VPN disconnection), however it does not otherwise alter your /etc/resolv.conf at all.
  • It has many additional options to customize routing and lookup (for example, --route-splits to additionally route traffic for specific subnets requested by the server). Run vpn-slice --help to see them all.

Who this is for

If you are using a VPN to route all your traffic for privacy reasons (or to avoid censorship in repressive countries), then you do not want to use this.

The purpose of this tool is almost the opposite; it makes it easy to connect to a VPN while minimizing the traffic that passes over the VPN.

This is for people who have to connect to the high-security VPNs of corporations or other bureaucracies (which monitor and filter and otherwise impede network traffic), and thus wish to route as little traffic as possible through those VPNs.

Requirements

  • Python 3.5+
  • Either of the following:
    • dnspython module (preferred, tested with v1.16.0)
    • dig command-line DNS lookup tool (tested with v9.9.5 and v9.10.3)
  • Supported OSes:

Installation

From PyPI

You can install the latest build from PyPI with pip (make sure you are using the Python 3.x version, usually invoked with pip3).

You should install as root (e.g. using sudo), because openconnect or vpnc will need to be able to invoke vpn-slice while running as root:

# latest release from PyPI
$ sudo pip3 install "vpn-slice[dnspython,setproctitle]"

# latest development version
$ sudo pip3 install "https://github.com/dlenski/vpn-slice/archive/master.zip#egg=vpn-slice[dnspython,setproctitle]"

(If your system doesn't support dnspython or setproctitle, for some reason, then omit those.)

As an RPM

You can use the bdist_rpm target to package vpn-slice as an RPM, and thereby install it with your distribution's packaging system, allowing it to keep track of installed files. See the documentation for important details about the portability and reusability of RPM packages built in this way:

$ python3 setup.py bdist_rpm --requires=python3-dns,python3-setproctitle
$ sudo dnf install dist/vpn-slice-*.noarch.rpm

On macOS

On macOS, you can also install from the Homebrew repository:

$ brew install vpn-slice

First steps

Before trying to use vpn-slice with openconnect or vpnc, check that it works properly on your platform, and can verify that it has all of the access and dependencies that it needs (to modify /etc/hosts, alter routing table, etc.):

$ sudo vpn-slice --self-test
***************************************************************************
*** Self-test passed. Try using vpn-slice with openconnect or vpnc now. ***
***************************************************************************

If you run the self-test as a non-root user, it will tell you what required access it is unable to obtain:

$ vpn-slice --self-test
WARNING: Couldn't configure hosts provider: Cannot read/write /etc/hosts
******************************************************************************************
*** Self-test did not pass. Double-check that you are running as root (e.g. with sudo) ***
******************************************************************************************
Aborting because providers for hosts are required; use --help for more information

When you start trying to use vpn-slice for real, you should use the diagnostic options (e.g openconnect -s 'vpn-slice --verbose --dump') to troubleshoot and understand its behavior.

Usage

You should specify vpn-slice as your connection script with openconnect or vpnc. It has been tested with vpnc v0.5.3, OpenConnect v7.06+ (Cisco AnyConnect and Juniper protocols) and v8.0+ (PAN GlobalProtect protocol).

For example:

$ sudo openconnect gateway.bigcorp.com -u user1234 \
    -s 'vpn-slice 192.168.1.0/24 hostname1 alias2=alias2.bigcorp.com=192.168.1.43'
$ cat /etc/hosts
...
192.168.1.1 dns0.tun0					# vpn-slice-tun0 AUTOCREATED
192.168.1.2 dns1.tun0					# vpn-slice-tun0 AUTOCREATED
192.168.1.57 hostname1 hostname1.bigcorp.com		# vpn-slice-tun0 AUTOCREATED
192.168.1.43 alias2 alias2.bigcorp.com		# vpn-slice-tun0 AUTOCREATED

or

# With most versions of vpnc, you *must* specify an absolute path
# for the disconnect hook to work correctly, due to a bug.
#
# I reported this bug, but the original maintainers no longer maintain vpnc.
#   https://lists.unix-ag.uni-kl.de/pipermail/vpnc-devel/2016-August/004199.html
#
# However, some Linux distro packagers have picked up my patch in recent
# releases, e.g. Ubuntu 17.04:
#   https://changelogs.ubuntu.com/changelogs/pool/universe/v/vpnc/vpnc_0.5.3r550-3/changelog
#
$ sudo vpnc config_file \
       --script '/path/to/vpn-slice 192.168.1.0/24 hostname1 alias2=alias2.bigcorp.com=192.168.1.43'

Notice that vpn-slice accepts several different kinds of routes and hostnames on the command line:

  • Hostnames alone (hostname1) as well as host-to-IP aliases (alias2=alias2.bigcorp.com=192.168.1.43). The former are first looked up using the VPN's DNS servers. Both are also added to the routing table, as well as to /etc/hosts (unless --no-host-names is specified). As in this example, multiple aliases can be specified for a single IP address.
  • Subnets to include (10.0.0.0/8) in the VPN routes as well as subnets to explicitly exclude (%10.123.0.0/24).

There are many command-line options to alter the behavior of vpn-slice; try vpn-slice --help to show them all.

Diagnostics

Running with --verbose makes it explain what it is doing, while running with --dump shows the environment variables passed in by the caller.

Inspiration and credits

  • @jagtesh's split-tunnelling tutorial gist taught me the basics of how to set up a split-tunnel VPN by wrapping the standard vpnc-script.
  • @apenwarr's sshuttle has the excellent --auto-hosts and --seed-hosts options. These inspired the automatic host lookup feature.
  • @gmacon's PR #11 substantially refactored the code to separate the OS-dependent parts more cleanly, and added macOS support.
  • @joelbu's PR #30 added support for IPv6 DNS lookups using dig.

License

GPLv3 or later.

TODO / Help Wanted

  • Better error-explaining
  • Fix timing issues
  • Improve IPv6 support
  • Support OSes other than Linux and macOS
    • Other Unix-like operating systems should be pretty easy

vpn-slice's People

Contributors

branchvincent avatar dimitripapadopoulos avatar dlenski avatar dodok1 avatar doomedraven avatar gmacon avatar henrik242 avatar jensheinrich avatar josmo avatar letalvoj avatar mschilli87 avatar rikardev avatar smh avatar st31ny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vpn-slice's Issues

File "/usr/local/bin/vpn-slice", line 8, in <module>

upgraded from vpn-slice 0.9.1 to vpn-slice-0.11 with
pip3 install https://github.com/dlenski/vpn-slice/archive/master.zip

$ vpn-slice --version
Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 397, in main
    providers = get_default_providers()
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 44, in get_default_providers
    hosts = PosixHostsFileProvider(),
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/posix.py", line 67, in __init__
    super().__init__('/etc/hosts')
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/posix.py", line 49, in __init__
    raise OSError('Cannot read/write {}'.format(path))
OSError: Cannot read/write /etc/hosts

MacOS: AttributeError: 'NoTunnelPrepProvider' object has no attribute 'create_tunnel'

Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 10, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 408, in main
    do_pre_init(env, args, providers)
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 74, in do_pre_init
    providers['prep'].create_tunnel()
AttributeError: 'NoTunnelPrepProvider' object has no attribute 'create_tunnel'

DNS timeout issues with v0.14.1

$ vpn-slice --version
vpn-slice 0.14.1
Connected as XXXX + YYYYYY/64, using SSL, with DTLS disabled
WARNING: IPv6 address or netmask set. Support for IPv6 in vpn-slice should be considered BETA-QUALITY.
WARNING: IPv6 address or netmask set. Support for IPv6 in vpn-slice should be considered BETA-QUALITY.
Blocked incoming traffic from VPN interface with iptables.
Added routes for 3 nameservers, 1 subnets, 0 aliases.
Restored routes for 0 excluded subnets. []
Adding /etc/hosts entries for 3 nameservers...
  XXX = dns0.tun0
  YYY = dns1.tun0
  ZZZZZZZZ = dns2.tun0
Looking up 55 hosts using VPN DNS servers...
WARNING: Lookup for xxx on VPN DNS servers failed:
	The DNS operation timed out after 30.00084924697876 seconds
WARNING: Lookup for yyy on VPN DNS servers failed:
	The DNS operation timed out after 30.000951528549194 seconds
WARNING: Lookup for zzz on VPN DNS servers failed:
	The DNS operation timed out after 30.000957012176514 seconds
WARNING: Lookup for sss on VPN DNS servers failed:
	The DNS operation timed out after 30.00096583366394 seconds
^CSend BYE packet: Aborted by caller

reverting back to v0.14 resolves these issues for me:

$ vpn-slice --version
vpn-slice 0.14
Connected as XXXX + YYYYYYYYY/64, using SSL, with DTLS disabled
WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
Blocked incoming traffic from VPN interface with iptables.
Added routes for 3 nameservers, 1 subnets, 0 aliases.
Restored routes for 0 excluded subnets.
Adding /etc/hosts entries for 3 nameservers...
  XXX = dns0.tun0
  YYY = dns1.tun0
  ZZZZZZZZ = dns2.tun0
Looking up 55 hosts using VPN DNS servers...
[...]
Added hostnames and aliases for 98 addresses to /etc/hosts.
Added 92 routes for named hosts.
Connection setup done, child process 2644287 exiting.

There must have been changes between v0.14 and v0.14.1 causing above timeouts.
Anything I can test on my side?

thanks,
Chris

configuration question

not sure if there is something wrong with my python or maybe it's wrong usage, but getting error with below:

$ sudo openconnect https://myaccess.mycompanyvpn.com --no-dtls -s 'vpn-slice my.company.com'
[... asked for username/password as usual for my vpn connection โ€ฆ]
Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 30, Keepalive 20
Connected as 10.175.232.71 + 2606:b400:8f0:82:8000::b/64, using SSL
[...]
Traceback (most recent call last):
  File "/usr/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.1', 'console_scripts', 'vpn-slice')()
  File "/usr/lib/python3.6/site-packages/vpn_slice/main.py", line 259, in main
    env = parse_env()
  File "/usr/lib/python3.6/site-packages/vpn_slice/main.py", line 211, in parse_env
    if envar in environ: val = maker(environ[envar])
  File "/usr/lib/python3.6/ipaddress.py", line 1915, in __init__
    raise AddressValueError("Unexpected '/' in %r" % address)
ipaddress.AddressValueError: Unexpected '/' in '2606:b400:8f0:82:8000::b/64'
Script 'vpn-slice my.company.com' returned error 1

Noob question: I'm getting http traffic blocked by VPN OpenDNS

Hey there,

First of all, thanks for the amazing work in vpn-slice!

I'm using vpn-slice with OpenConnect, using some shell functions plus an script to supply all the hosts, CIDR ranges to vpn-slice:

function vpn-up() {
  if [[ -z $VPN_HOST ]]
  then
    echo "Please set VPN_HOST env var"
    return
  fi
  if [[ "$1" == "split" ]]
  then
    echo "Starting the vpn with split tunneling ..."
    sudo openconnect --background --script='~/custom-vpn-slice' --user=$USER  $VPN_HOST
  else
    echo "Starting the vpn ..."
    sudo openconnect --background --user=$USER  $VPN_HOST
  fi
}

function vpn-split() {
  vpn-up split
}

function vpn-down() {
  sudo kill -2 `pgrep openconnect`
}

and custom-vpn-slice has:

#!/bin/sh
vpn-slice --prevent-idle-timeout \
host_x \
host_y \
cidr_range_a \
cidr_range_b

When I ran vpn-split the traffic is routed properly through the VPN, however when I check my public IP address with websites like http://ip4.me/ I'm getting reported the VPN IP address. And when I kill OpenConnect (vpn-down) I'm getting reported the ISP IP (which was what I expected when the VPN was up).

Also when I visit some websites I got an alert message from the company OpenDNS about the website been blocked. That also happened after I kill OpenConnect (vpn-down). I checked in another machine using Cisco AnyConnect instead of OpenConnect + vpn-slice and the traffic is not blocked

Wondering what I'm missing if my setup

Multiple iptables INPUT entries after a while

I'm using vpn-slice 0.15 like follows.

$ sudo cat /etc/systemd/system/vpn.client.service
[Unit]
Description=Connect to Client VPN
After=network.target

[Service]
Type=simple
Environment=password=abc123
ExecStart=/bin/sh -c 'echo $password | sudo openconnect --passwd-on-stdin -s \'vpn-slice 123.123.123.0/24\' --interface=tunC --protocol=gp --user=vpnuser --usergroup=gateway --servercert pin-sha256:<some fingerprint> vpn.client.com'
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

Please notice: it's openconnect with protocol gp.

And it works perfectly and does exactly what I need... But there is one small nuisance that's bothering me.

After some time the iptables accumulates entries like following.

$sudo iptables -vnL --line-numbers
...
4        0     0 DROP       all  --  tunC *       0.0.0.0/0            0.0.0.0/0
5        0     0 ACCEPT     all  --  tunC *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
6        0     0 DROP       all  --  tunC *       0.0.0.0/0            0.0.0.0/0
7        0     0 ACCEPT     all  --  tunC *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED

I think this happens when other side resets the connection for whatever reason.

Invoke script outside of openconnect

Hi @dlenski ,

How can we run this script after connecting to VPN ? I want to add some domain names to be able to connect via ssh, outside of VPN.

I'm using cisco anyconnect :)

Thanks,
Daniel.

Unable to establish connection

Unable to make a connection, without using vpn-slice it's working.
I'm using this command

sudo openconnect https://125.209.98.228 --no-dtls -s 'vpn-slice my.mycompany.com'

These are messages of the terminal.

Connected as 192.168.21.2, using SSL
/bin/sh: vpn-slice: command not found
Script 'vpn-slice my.mycompany.com' returned error 127
/bin/sh: vpn-slice: command not found
Script 'vpn-slice my.mycompany.com' returned error 127

vpn-slice does not tunnel IP subnets

Hi @dlenski

Firstly, thank you very much for your work on vpn-slice

I am trying to route the IP subnets through VPN connection using openconnect
and vpn-slice.

It works if I specify /32 subnet. For example if I do

sudo openconnect \
  mywork.company \
  --protocol=gp \
  --user=username \
  --os=linux-64 \
  --usergroup=gw \
  -s \
    'vpn-slice 192.168.37.105/32 --dump --verbose'

I will be able to connect to 192.168.37.105 through VPN

However, if I use

sudo openconnect \
  mywork.company \
  --protocol=gp \
  --user=username \
  --os=linux-64 \
  --usergroup=gw \
  -s \
    'vpn-slice 192.168.37.105/31 --dump --verbose'

I cannot connect to 192.168.37.105

The --dump and --verbose show this warning

Looking up 1 hosts using VPN DNS servers...
ESP session established with server
ESP tunnel connected; exiting HTTPS mainloop.
WARNING: Lookup for 192.168.37.105/31 on VPN DNS servers failed.
Added hostnames and aliases for 1 addresses to /etc/hosts.
Added 0 routes for named hosts.

Below is information of openconnect and vpn-slice I am uing

OpenConnect version v8.02-1
vpn-slice 0.9.1
OS Debian buster

Do you have any idea as why it does not work with IP subnet?

Thank you very much in advance.

Cheers
Bang

possibility to provide whole domain for VPN tunelling

is there any possibility to provide whole domain instead of single links in domain for vpn tunneling?
e.g.
instead of providing single subdomains
sub1.mycompany.com
sub2.mycompany.com

to be able to provide mycompany.com as attribute?

Need guinea pigs for -K/--prevent-idle-timeouts

In recent commits, I added a new option:

  -K, --prevent-idle-timeout
                        Prevent idle timeout by doing random DNS lookups
                        (interval set by $IDLE_TIMEOUT, defaulting to 10
                        minutes)

With this option, vpn-slice will keep on running in the background, and will issue randomly-timed DNS requests to a random selection of named hosts and routed IP addresses, in order to try and trick the VPN gateway to not disconnecting the client due to idle timeout. (See a4a6e77 for details of exactly what it does.)

I'd appreciate others testing it and letting me know if it works for you as well.

(related OpenConnect merge-request #67 from me, to export the IDLE_TIMEOUT variable to the script)

IPv6 address being parsed as IPv4

Hello Dan,
Hello everyone,

I get the following traceback

$ sudo openconnect sslvpn.myschool.tld -u [email protected] -g student-net -s 'vpn-slice --dump netseminar.myschool.tld'
POST https://sslvpn.myschool.tld/student-net
Connected to 1.2.3.4:443
SSL negotiation with sslvpn.myschool.tld
Connected to HTTPS on sslvpn.myschool.tld
XML POST enabled
Fuer eine Verbindung in die entsprechende VPN-Gruppe (VPZ) muss beim Feld "Connect to" "sslvpn.myschool.tld/VPZ_NAME" eingegeben werden, beim Feld Benutzername "[email protected]"
=> Aktuell ist student-net selektiert
=> Login: [email protected]
Bitte geben Sie Benutzernamen und Passwort ein.
Password:
POST https://sslvpn.myschool.tld/
Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 30, Keepalive 30
Connected as 5.6.7.8 + 2001:1:2:3:4::ab/115, using SSL, with DTLS in progress
Established DTLS connection (using GnuTLS). Ciphersuite (DTLS1.2)-(ECDHE-(null))-(AES-256-GCM).
Exception while setting dns from environment variable INTERNAL_IP4_DNS='31.31.31.31 32.32.32.32 2001:555:8888::c'
Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.11', 'console_scripts', 'vpn-slice')()
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 399, in main
    p, args, env = parse_args_and_env()
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 357, in parse_args_and_env
    env = parse_env(environ)
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 293, in parse_env
    try: val = maker(environ[envar])
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 276, in <lambda>
    ('dns','INTERNAL_IP4_DNS',lambda x: [IPv4Address(x) for x in x.split()],[]),
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 276, in <listcomp>
    ('dns','INTERNAL_IP4_DNS',lambda x: [IPv4Address(x) for x in x.split()],[]),
  File "/usr/lib64/python3.7/ipaddress.py", line 1327, in __init__
    self._ip = self._ip_int_from_string(addr_str)
  File "/usr/lib64/python3.7/ipaddress.py", line 1161, in _ip_int_from_string
    raise AddressValueError("Expected 4 octets in %r" % ip_str)
ipaddress.AddressValueError: Expected 4 octets in '2001:67c:10ec::c'
Script 'vpn-slice --dump netseminar.myschool.tld' returned error 1
Exception while setting dns from environment variable INTERNAL_IP4_DNS='31.31.31.31 32.32.32.32 2001:555:8888::c'
Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.11', 'console_scripts', 'vpn-slice')()
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 399, in main
    p, args, env = parse_args_and_env()
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 357, in parse_args_and_env
    env = parse_env(environ)
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 293, in parse_env
    try: val = maker(environ[envar])
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 276, in <lambda>
    ('dns','INTERNAL_IP4_DNS',lambda x: [IPv4Address(x) for x in x.split()],[]),
  File "/usr/local/lib/python3.7/site-packages/vpn_slice/main.py", line 276, in <listcomp>
    ('dns','INTERNAL_IP4_DNS',lambda x: [IPv4Address(x) for x in x.split()],[]),
  File "/usr/lib64/python3.7/ipaddress.py", line 1327, in __init__
    self._ip = self._ip_int_from_string(addr_str)
  File "/usr/lib64/python3.7/ipaddress.py", line 1161, in _ip_int_from_string
    raise AddressValueError("Expected 4 octets in %r" % ip_str)
ipaddress.AddressValueError: Expected 4 octets in '2001:555:8888::c'
Script 'vpn-slice --dump netseminar.myschool.tld' returned error 1

It seems to me that the environment variable INTERNAL_IP4_DNS should never contain an IPv6 address, I suspect this might be a mistake of my organization, would you agree?
Do you happen to have an idea how I could work around this?

Best
--Joel

Add support for Dynamic Split Include Tunneling

When authenticating to Cisco ASA it responds with the following section in xml:

<custom-attr>
<dynamic-split-include-domains><![CDATA[domain1.com, domain2.com]]></dynamic-split-include-domains>
</custom-attr>

Is it possible to add those automatically when connecting via openconnect?

Could not install per instructions

I do a lot of Python programming, but oddly almost never use pip because I am able to use the system packages in Fedora for most things. When I ran into into error: could not create '/usr/local/lib/python3.7': Permission denied per your instructions I recalled having read about caveats of throwing sudo at pip, at least on Fedora. A quick search led me to this concise and helpful page where it recommended running with the --user option, thus:

pip3 install --user https://github.com/dlenski/vpn-slice/archive/master.zip

and this worked for me. Perhaps worthy of a mention for Fedora users or can this be applied everywhere? (Your $ prompt suggests the install shouldn't need root authority.)

KeyError: 'gateway' on MacOS 10.15 Catalina

I mainly want to use vpn-slice to stop openconnect from overwriting my DNS configurations, but I still want access to all pushed subnets. I start vpn-slice with option -S only (hope this is correct). Unfortunately, I'm unable to see it working, bec it immediately errors our with the KeyError above. A --dump listing is below. Hope that's helpful

Called by /usr/local/Cellar/openconnect/8.10/bin/openconnect (PID 45008) with environment variables for vpnc-script:
  reason                  => reason=<reasons.connect: 2>
  VPNGATEWAY              => gateway=IPv4Address('168.87.2.217')
  TUNDEV                  => tundev='utun3'
  CISCO_DEF_DOMAIN        => domain=['mycompany.org']
  INTERNAL_IP4_ADDRESS    => myaddr=IPv4Address('172.28.160.43')
  INTERNAL_IP4_MTU        => mtu=1406
  INTERNAL_IP4_NETMASK    => netmask=IPv4Address('255.255.255.128')
  INTERNAL_IP4_NETMASKLEN => netmasklen=25
  INTERNAL_IP4_NETADDR    => network=IPv4Network('172.28.160.0/25')
  INTERNAL_IP4_DNS        => dns=[IPv4Address('172.26.247.19'), IPv4Address('172.25.232.19')]
  CISCO_SPLIT_INC         => nsplitinc=28
  CISCO_SPLIT_EXC         => nsplitexc=1
  IDLE_TIMEOUT            => idle_timeout=1800
  CISCO_*SPLIT_INC_*      => splitinc=[IPv4Network('173.240.76.142/32'), IPv4Network('173.240.68.18/32'), IPv4Network('173.240.75.9/32'), IPv4Network('150.175.57.150/32'), IPv4Network('150.175.58.110/32'), IPv4Network('150.175.57.50/32'), IPv4Network('150.175.58.10/32'), IPv4Network('15.131.135.0/25'), IPv4Network('15.131.130.0/23'), IPv4Network('89.202.125.44/32'), IPv4Network('89.202.125.15/32'), IPv4Network('89.202.116.103/32'), IPv4Network('89.202.116.78/32'), IPv4Network('89.202.116.69/32'), IPv4Network('89.202.116.68/32'), IPv4Network('89.202.116.62/32'), IPv4Network('15.189.160.0/24'), IPv4Network('99.247.64.0/24'), IPv4Network('99.247.32.0/29'), IPv4Network('99.247.27.0/24'), IPv4Network('192.168.0.0/16'), IPv4Network('10.0.0.0/8'), IPv4Network('15.189.128.0/19'), IPv4Network('15.141.224.0/19'), IPv4Network('15.141.0.0/19'), IPv4Network('172.16.0.0/12'), IPv4Network('168.246.0.0/16'), IPv4Network('147.167.0.0/16')]
  CISCO_*SPLIT_EXC_*      => splitexc=[IPv4Network('0.0.0.0/32')]
Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.14.2', 'console_scripts', 'vpn-slice')()
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/__main__.py", line 520, in main
    do_connect(env, args)
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/__main__.py", line 133, in do_connect
    gwr = providers.route.get_route(env.gateway)
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/mac.py", line 74, in get_route
    'via': info_d['gateway'],
KeyError: 'gateway'
Script 'vpn-slice -v --dump -S' returned error 1
^CSend BYE packet: Aborted by caller

Implied security risks

Hi,

Thank you for this ! Works perfectly ^^
This is more a question than an issue. I am noob with routing/networking so I was wondering if you could explain what risks, if any, I am taking by using vpn-slice. Can my network admin (who provides the VPN) identify that I have exposed the private network ?

It would be great if you could point me to some attack that could be done which would compromise the private network so that I can learn how to protect against it.

Many thanks for making this so easy to use !

Issue with subnet not getting resolved via vpn's dns (using systemd-resolved)

Hi is there any known issue with systemd-resolved?

I am pushing some subnets thru vpn-slice the connect seems to go well and connect. I can reach some hosts but host on a particular subnet I am unable to reach. It so happens its the same subnet the vpn's dns server is a part of. It is a /16 class a subnet 10.10.0.0/16

Interestingly enough when i append --dump i can see the vpn pushing routes my way which are identical to the routes I am pushing at it, also its passing along some search domains.

If the vpn is passing all this info how do I make use of it, I am unable to ping short names based on the hosts that I can reach.

I have had to resort to disabling resovled and using dnsmasq to manually force traffic from the subnets pushed above to the vpn and i can reach all that I am to reach.

Is there a way to make it work with systemd-resolved inclusive of the use of the search domains being pushed at me?

openconnect v8
vpn-slice 0.11
ubuntu 18.04

command in use

sudo ./openconnect --protocol=gp --user=xxx \
    --csd-wrapper=./scripts/hip-report.sh \
    --servercert pin-sha256:xxx xxx --dump \
    --script='/home/xxx/.local/bin/vpn-slice --dump 
        xxx/32 xxx/25 xxx/26 xxx/25 xxx/26 xxx/32 xxx/29 xxx/27 xxx/32 10.10.0.0/16' 

Is there support for glob hosts?

Hi.
I want to use this script, but there's many hosts with a predictable format that I want to use this script with, without having to list them all.
Is there a way to specify hosts with a glob, something like: test-*.bigcorp.com?
Thanks.

Add type hints and set up Mypy

OK, as I mentioned in #53 (comment), I've started thinking about setting up Mypy to try to catch some of these silly errors.

Here's what I've come up with so far:

  • Type hints were added in Python 3.5, but this project currently supports Python >=3.3. Would there be any objection to raising the minimum supported version to 3.5?
  • We should model the information read from the environment explicitly so that Mypy can know about it. It'd be handy to use Data Classes for that, which was added to Python in 3.7. We could still support Pythons 3.5 and 3.6 if we are prepared to add a dependency on Attrs for those old versions.
  • One of the things that makes Mypy hard to use in general is that lots of third-party packages don't have hints. I think we'll be OK on this front, since we don't have many third-party dependencies, and I noticed that dnspython does have hints when I was looking at it earlier.

Terminating openconnect does not restore network.

Because of wrong configuration, I try to terminate Openconnect and reconfiguring it. But after openconnect is terminated, the network still go through VPN. This problem doesnโ€™t exist for default script.

problem adding hosts by name on MacOS

Hello,
didn't found vpn-slice on stackoverflow so I'm trying to ask for help here.

When I'm using openconnect on Ubuntu I just configure route 192.168.1.0 255.255.255.0 and everything communicates through VPN.

However I'd like to use MAC and route only work related traffic through VPN and everything else "normally".
Something like this works perfectly for some usecases sudo openconnect --cafile=./myvpn.com.pem --servercert pin-sha256:somecert --disable-ipv6 -u me -s 'vpn-slice 192.168.1.0/24 somehost.myvpn.com' myvpn.com.
I've recently realised that there are some domains that I'm only able to access through VPN but with configuration above I'm not able to do so. So for example if I'd like to connect to som.weird.example.com what would be the configuration? I've tried to modify script like this -s 'vpn-slice 192.168.1.0/24 somehost.myvpn.com som.weird.example.com' but that didn't worked. Is that possible at all?

Thanks

slice fails for me with openconnect globalprotect

Hello,

I would be really thankful for some help with setting up slice. I need the VPN to get access to one server behind the firewall, https://den-dev-git-01.extendthereach.com.

Is this the right call ? Without the slice, the connection works.

vonkad@mycompanyDell ~/openconnect (globalprotect) $ sudo ./openconnect --protocol=gp sslvpn.mycompany.com -u dvonka -s '/home/vonkad/.local/bin/vpn-slice den-dev-git-01.extendthereach.com' --dump 
Please enter your username and password
Password: 
POST https://sslvpn.mycompany.com/ssl-vpn/login.esp
Attempting to connect to server 66.35.44.241:443
Connected to 66.35.44.241:443
SSL negotiation with sslvpn.mycompany.com
Connected to HTTPS on sslvpn.mycompany.com
> POST /ssl-vpn/login.esp HTTP/1.1d
> Host: sslvpn.mycompany.com
> User-Agent: PAN GlobalProtect
> X-Pad: 000000000000000000000000000000000000000000000
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 147
> 
> jnlpReady=jnlpReady&ok=Login&direct=yes&clientVer=4100&prot=https:&server=sslvpn.mycompany.com&computer=mycompanyDell&user=dvonka&passwd=SecretPassword
Got HTTP response: HTTP/1.1 200 OK
Server: 
Date: Mon, 26 Feb 2018 13:43:59 GMT
Content-Type: application/xml; charset=UTF-8
Content-Length: 622
Connection: keep-alive
ETag: "28632-1e6f-5a0a2e6e"
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
X-FRAME-OPTIONS: DENY
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
Set-Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e; secure; HttpOnly
HTTP body length:  (622)
< <?xml version="1.0" encoding="utf-8"?><jnlp><application-desc><argument>(null)</argument><argument>be7c669a4bd32db811cce0f03edd9703</argument><argument>18a23d6ea3e868de7affd6f17a11d23c4515eed7</argument><argument>GP-gateway-N</argument><argument>dvonka</argument><argument>auth_sequence_emergency</argument><argument>vsys1</argument><argument>extendthereach</argument><argument>(null)</argument><argument></argument><argument></argument><argument></argument><argument>tunnel</argument><argument>-1</argument><argument>4100</argument><argument></argument><argument></argument><argument></argument></application-desc></jnlp>
GlobalProtect login returned authentication-source=auth_sequence_emergency
POST https://sslvpn.mycompany.com/ssl-vpn/getconfig.esp
> POST /ssl-vpn/getconfig.esp HTTP/1.1
> Host: sslvpn.mycompany.com
> User-Agent: PAN GlobalProtect
> Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e
> X-Pad: 0000000000
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 246
> 
> client-type=1&protocol-version=p1&app-version=3.0.1-10&os-version=linux-64&clientos=linux-64&hmac-algo=sha1%2cmd5&enc-algo=aes-128-cbc%2caes-256-cbc&authcookie=be7c669a4bd32db811cce0f03edd9703&portal=GP-gateway-N&user=dvonka&domain=extendthereach
Got HTTP response: HTTP/1.1 200 OK
Server: 
Date: Mon, 26 Feb 2018 13:43:59 GMT
Content-Type: application/xml; charset=UTF-8
Content-Length: 1921
Connection: keep-alive
ETag: "2862c-1f2-5a0a2e6e"
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
X-FRAME-OPTIONS: DENY
HTTP body length:  (1921)
< 
< 	<response status="success">
< 		<need-tunnel>yes</need-tunnel>
< 		<ssl-tunnel-url>/ssl-tunnel-connect.sslvpn</ssl-tunnel-url>
< 		<portal>GP-gateway-N</portal>
< 		<user>dvonka</user>
< 		<lifetime>43200</lifetime>
< 		<timeout>7200</timeout>
< 		<disconnect-on-idle>7200</disconnect-on-idle>
< 		<bw-c2s>1000</bw-c2s>
< 		<bw-s2c>1000</bw-s2c>
< 		<gw-address>66.35.44.241</gw-address>
< 		<ip-address>192.168.60.167</ip-address>
< 		<netmask>255.255.255.255</netmask>
< 		<dns>
< 			<member>10.10.20.5</member>
< 			<member>10.10.20.6</member>
< 		</dns> 
< 		<wins>
< 		</wins> 
< 		<default-gateway>192.168.60.167</default-gateway>
< 		<mtu>0</mtu>
< 		<dns-suffix>
< 			<member>extendthereach.com</member>
< 			<member>mycompany.com</member>
< 		</dns-suffix> 
< 		<no-direct-access-to-local-network>no</no-direct-access-to-local-network>
< 		<access-routes>
< 			<member>0.0.0.0/0</member>
< 			<member>10.10.0.0/16</member>
< 			<member>10.50.0.0/16</member>
< 			<member>10.51.0.0/16</member>
< 			<member>10.52.0.0/16</member>
< 			<member>10.53.0.0/16</member>
< 			<member>10.54.0.0/16</member>
< 			<member>10.56.0.0/16</member>
< 			<member>192.168.110.0/24</member>
< 			<member>192.168.160.0/24</member>
< 			<member>192.168.168.0/24</member>
< 			<member>10.10.20.5/32</member>
< 			<member>10.10.20.6/32</member>
< 		</access-routes> 
< 		<ipsec>
< 			<udp-port>4501</udp-port>
< 			<ipsec-mode>esp-tunnel</ipsec-mode>
< 			<enc-algo>aes-128-cbc</enc-algo>
< 			<hmac-algo>sha1</hmac-algo>
< 			<c2s-spi>0x3F64D21E</c2s-spi>
< 			<s2c-spi>0xBC9EB11F</s2c-spi>
< 			<akey-s2c>
< 				<bits>160</bits>
< 				<val>5696baee6fa3b005bdfad6aa0ec2494668cf9dbc</val>
< 			</akey-s2c> 
< 			<ekey-s2c>
< 				<bits>128</bits>
< 				<val>148fdbd776651a572ed91b1148bbdae3</val>
< 			</ekey-s2c> 
< 			<akey-c2s>
< 				<bits>160</bits>
< 				<val>655b6346854195fb6428fdf3ad474beecaa39e33</val>
< 			</akey-c2s> 
< 			<ekey-c2s>
< 				<bits>128</bits>
< 				<val>4274ac37fe102ae12b6c189a4fbb8326</val>
< 			</ekey-c2s> 
< 		</ipsec> 
< 	</response>
Tunnel timeout (rekey interval) is 120 minutes.
TCP_INFO rcv mss 1460, snd mss 1460, adv mss 1460, pmtu 1500
No MTU received. Calculated 1422
POST https://sslvpn.mycompany.com/ssl-vpn/hipreportcheck.esp
> POST /ssl-vpn/hipreportcheck.esp HTTP/1.1
> Host: sslvpn.mycompany.com
> User-Agent: PAN GlobalProtect
> Cookie: PHPSESSID=f3f7bb2a35954f6f6c900d11983ad36e
> X-Pad: 00000000000000000000000000000000000000000000
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 212
> 
> client-role=global-protect-full&authcookie=be7c669a4bd32db811cce0f03edd9703&portal=GP-gateway-N&user=dvonka&domain=extendthereach&computer=mycompanyDell&client-ip=192.168.60.167&md5=32b43a0c73f194a07188858b8b15ccb3
Got HTTP response: HTTP/1.1 200 OK
Server: 
Date: Mon, 26 Feb 2018 13:43:59 GMT
Content-Type: application/xml; charset=UTF-8
Content-Length: 107
Connection: keep-alive
ETag: "2862f-63c-5a0a2e6e"
X-Content-Type-Options: nosniff
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Security-Policy: default-src 'self'
Expires: Thu, 19 Nov 1981 08:52:00 GMT
X-FRAME-OPTIONS: DENY
HTTP body length:  (107)
< 
< 	<response status="success">
< 		<hip-report-needed>yes</hip-report-needed>
< 		<delay>0</delay>
< 	</response>
Gateway says HIP report submission is needed.
WARNING: Server asked us to submit HIP report with md5sum 32b43a0c73f194a07188858b8b15ccb3.
VPN connectivity may be disabled or limited without HIP report submission.
You need to provide a --csd-wrapper argument with the HIP report submission script.
Send ESP probes
Connected as 192.168.60.167, using SSL
Traceback (most recent call last):
  File "/home/vonkad/.local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.1', 'console_scripts', 'vpn-slice')()
  File "/home/vonkad/.local/lib/python3.5/site-packages/vpn_slice/main.py", line 294, in main
    env = parse_env()
  File "/home/vonkad/.local/lib/python3.5/site-packages/vpn_slice/main.py", line 244, in parse_env
    assert net.netmask==nm
AssertionError
Script '/home/vonkad/.local/bin/vpn-slice den-dev-git-01.extendthereach.com' returned error 1
Traceback (most recent call last):
  File "/home/vonkad/.local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.1', 'console_scripts', 'vpn-slice')()
  File "/home/vonkad/.local/lib/python3.5/site-packages/vpn_slice/main.py", line 294, in main
    env = parse_env()
  File "/home/vonkad/.local/lib/python3.5/site-packages/vpn_slice/main.py", line 244, in parse_env
    assert net.netmask==nm
AssertionError
Script '/home/vonkad/.local/bin/vpn-slice den-dev-git-01.extendthereach.com' returned error 1
ESP session established with server
ESP tunnel connected; exiting HTTPS mainloop.

vpn-slice is not creating /dev/net/tun

Hi there!
Thanks for the script. But I'm not able to get it working for some reason. The problem is that vpnc-slice is not creating /dev/net/tun so it fails to run after a fresh boot. I try to create the interface manually using these commands:

mkdir -p /dev/net
mknod -m 0640 /dev/net/tun c 10 200

as it happens in the default vpnc-script. But after this I'm unable to connect with this error:

vpnc: can't initialise tunnel interface: Operation not permitted

The only way to connect using vpn-slice is to connect to VPN using default vpnc-script, disconnect from it and then connect using vpn-slice. It seems like I'm missing something obvious, but I've spent over 4 hours finding it. Please help.

Windows support

This package looks great - I would like to use it on Windows 10. However, ...

C:\Users\bers>vpn-slice
WARNING: Couldn't configure platform provider: 'OSError' object is not callable
Traceback (most recent call last):
  File "c:\users\bers\appdata\local\programs\python\python38\lib\site-packages\vpn_slice\util.py", line 17, in __getattr__
    return self[k]
KeyError: 'process'

Is Windows support planned?

Running vpn-slice as a non-root user

Hello,

OpenConnect can be executed as a non-root user according to the documentation I found on the web (https://www.infradead.org/openconnect/nonroot.html), haven't tried yet myself, but seems like it could work as long as the interface is created before running OpenConnect.
Now, vpn-slice writes to the /ets/hosts file and adds routes, operations that usually are performed by root.

Is there a way we can execute vpn-slice without being root?

Thanks!

DNS lookup timeout

I just tried to run vpn-slice for the first time using a single hostname and got the following.

WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
Blocked incoming traffic from VPN interface with iptables.
Added routes for 2 nameservers, 0 subnets, 0 aliases.
Restored routes for 0 excluded subnets.
Adding /etc/hosts entries for 2 nameservers...
  xxx.xxx.xxx.xxx = dns0.tun0
  yyy.yyy.yyy.yyy = dns1.tun0
Looking up 1 hosts using VPN DNS servers...
WARNING: Lookup for hostname on VPN DNS servers failed:
	name 'cmd' is not defined
Added hostnames and aliases for 2 addresses to /etc/hosts.
Added 0 routes for named hosts.
Connection setup done, child process 249994 exiting.

I think name 'cmd' is not defined is unrelated and just a regression from 3a4bbdb, but I still don't know why the lookup times out.

dig +short hostname works independently of the VPN connection and returns an IPv4 address and dig +short @dns0.tun0 hostname works after connection setup is done.

0.14 upgrade broke machine names on remote network.

my script includes -i option to get machine names on the remote network. up to version 0.13 i could access (and ping) machines on the remote network by name. After 0.14 upgrade, I can no longer access machines by name - I have to use the IP address of the machine I want to access. I use VNC to connect to remote machines, and do not want to rely on fixed IP addresses.

ie:
vpnc <conf-file> --script 'vpn-slice -i <machine1> <machine2> <machine3> ... '

Also: I use Manjaro Linux, and install vpn-slice from the AUR.
https://aur.archlinux.org/packages/vpn-slice/

Crash on macos catalina: UnboundLocalError: local variable 'line' referenced before assignment

Hi again,

I usually am connected to my personal wireguard VPN, then use openconnect to connect to work VPN. This works well after you last fix. However today I tried connecting to work, without being connected to wireguard first, this caused the crash below! I tested this twice and then connected to wireguard, then tested twice and it's very consistent. Hope this is enough to fix the below crash.

WARNING: no firewall provider available; can't block incoming traffic
route: writing to routing socket: not in table
Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.14.2', 'console_scripts', 'vpn-slice')()
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/__main__.py", line 520, in main
    do_connect(env, args)
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/__main__.py", line 176, in do_connect
    exc_subnets = [(dest, providers.route.get_route(dest)) for dest in args.exc_subnets]
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/__main__.py", line 176, in <listcomp>
    exc_subnets = [(dest, providers.route.get_route(dest)) for dest in args.exc_subnets]
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/mac.py", line 70, in get_route
    keys = line.split()
UnboundLocalError: local variable 'line' referenced before assignment
Script 'vpn-slice -v -S' returned error 1

Error when stopping openconnect

When I stop openconnect (not running in the background) with ctrl+c, it show the following error.

Send BYE packet: Aborted by caller
Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.14.2', 'console_scripts', 'vpn-slice')()
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/__main__.py", line 527, in main
    do_post_connect(env, args)
  File "/usr/local/Cellar/vpn-slice/0.14.2/libexec/lib/python3.8/site-packages/vpn_slice/__main__.py", line 266, in do_post_connect
    sleep(delay)
KeyboardInterrupt

After this I am not able to start another tunnel with openconnect, it seems vpn-slice is hanging at that point.

comments on nftables in README?

I'm in the process of setting up split-tunneling on a Debian 10 machine, and I'm ... concerned? ... about a possible conflict between iptables and nftables. Specifically, I've set up a firewall using a dead simple nftables config file, and I'm worried that installing iptables utilities and unleashing split-vpn will... mess things up.

... okay, much internet-reading later ...

It looks like there are compatibility layers in place for iptables over nftables -- in Debian 10, it looks like this is what you get in the package iptables--but I'm definitely getting the feeling that going forward, the thing "to do" (so yes I guess this is really just a feature/enhancement request) is to rewrite to target nftables directly.

Um... and then support both nftables and iptables for legacy systems. Ha! Ha! Software maintenance is fun!

inet prefix is expected rather than ...

Hi,

today I needed to access some new internal site (inside vpn) and got this error:

Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 30, Keepalive 20
Connected as 10.175.197.68 + 2606:b400:8f0:81:8000::5b5/64, using SSL
WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
WARNING: Lookup for bigip-sage.us.mycompany.com on VPN DNS servers failed.
Error: inet prefix is expected rather than "bigip-sage.us.mycompany.com".
Traceback (most recent call last):
  File "/usr/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.1', 'console_scripts', 'vpn-slice')()
  File "/usr/lib/python3.6/site-packages/vpn_slice/main.py", line 315, in main
    do_post_connect(env, args)
  File "/usr/lib/python3.6/site-packages/vpn_slice/main.py", line 180, in do_post_connect
    iproute('route', 'replace', ip, 'dev', env.tundev)
  File "/usr/lib/python3.6/site-packages/vpn_slice/linux.py", line 77, in iproute
    sp.check_call(cl)
  File "/usr/lib/python3.6/subprocess.py", line 291, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/usr/bin/ip', 'route', 'replace', 'bigip-sage.us.mycompany.com', 'dev', 'tun0']' returned non-zero exit status 1.

anything on my side to check that would help correcting the issue?

thanks,
Chris

DNS servers not used for name resolution (question)

Hello,

Is there any reason why the VPN Slice script wouldn't add the VPN DNS servers to the host for name resolution?
At the moment, the DNS servers are only added to the /etc/hosts file and used for resolving only the domains provided as parameters.
Although this generally works, I found some apps that ignore the /etc/hosts and fail when resolving internal DNS records. Modifying my resolv.conf fixes the issue but I would like to understand if this is something the script itself could do at start up time.

Thanks,
Jonathan

Not writing to /etc/hosts

I've been using this script for a while now, and has been working great. Today I did a fresh install of Ubuntu 20.04, and when I run this it seems to connect okay, but it never seems to write to /etc/hosts, so it never forwards the traffic.

If I run without the script, I can get the full VPN just fine.

When I kill openconnect while I'm running the script, vpn-slice keeps to keep running and I have to manually kill it. When I do, I get the following message in my terminal:

/usr/bin/dig: isc_socket_bind: address not available

While it is running, it will slowly start printing out messages like this to my terminal:

WARNING: Lookup for my-example-domain.com on VPN DNS servers failed.

Is there something I'm doing wrong?

Mac OS version

Hello
Answering for your question in TODO:
Yep, need version VPN-slice for MacOS

PyPI package name: Why underscore instead of dash?

Hi Dan (@dlenski),

First of all: Thx for the nice tool.

I want to package it for Gentoo Linux but ran into an issue:

While the package is referred to as vpn-slice basically everywhere I came across it, incl. its PyPI page, the actual tarball is called vpn_slice-0.14.1.tar.gz.
I hacked around it in my ebuild for download, but (unsurprisingly) the extracted package
directory (vpn_slice-0.14.1) now doesn't match the package name I assigned (vpn-slice-0.14.1) either.
Before further obfuscating the ebuild, I decided to dig a bit first and found that all versions of vpn-slice on PyPI seem to be provided by vpn_slice-<version>.tar.gz archives.

This is not the case for what-vpn, so I figured you might be willing to change it for this package as well.

FWIW, PEP8 discourages the use of underscore in package names.

So I'd really like to avoid packaging this as vpn_slice, but before manually overwriting everything that Gentoo assumes about Python packages, I figured I first make sure there is an actual reason for this naming inconsistency.

Cheers,
Marcel

Support for attempt-reconnect reason

OpenConnect 8.02 added a new vpnc-script reason: attempt-reconnect. Currently, vpn-slice ignores the reconnect event, but with both before and after events, it might make more sense to do the disconnect actions before and connect actions after. Thoughts?

Hat tip to @modib for bringing this to my attention.

Inverting the split tunnel specification?

Basically, I am trying to figure out how to route everything but a certain subnet through the openconnect VPN connection.

All of the documentation for vpn-slice seems to assume I want to route only a specific subnet or handful of things through the VPN, but is it possible to do it the other way around? Am I missing something obvious? The VPN I am connecting to is a fairly complicated an undocumented little universe of legacy networks, I just need to keep access to a few local things. Like vpn-slice --everything-but importanthost1.local importanthost2.local

Am I just missing something obvious?

Dig responds with FORMERR without +nocookie or +noedns

Hi @dlenski!

Once again, thank you for making global protect access on Linux a breeze.
I could never get the DNS resolution working with vpn-slice and had some time today to dig (pun intended).
The problem for me is explained in this post and appears to be MS DNS specific.

Once I dropped in either the +nocookie or +noedns flag, it worked. I'm not too clued up on the implications, however.

Issue with "Connect Banner:"

Hi,

Upgrade to Fedora 32 yesterday and vpn-slice stopped working.
openconnect-8.10-1.fc32.x86_64 seems to spew out a new message (below) that the fc30 version did not. Without the vpn-slice script my vpn works (but obviously unsliced!), with it this message seems to be swallowed by the script and disrupts behaviour.
I tried downgraded to openconnect-8.05-2.fc32, but the same issue there and have been unable to suppress this message in other ways.

Connect Banner:
| Access to this device is limited to authorised personnel only. Unauthorised access or use of this device may be subject to civil or criminal prosecution.
| 

$reason not set

When running:

openconnect -v --script-tun -u test -c /vpn/cert.pem -s 'vpn-slice 10.0.0.0/8' server

I get error:

Must be called as vpnc-script, with $reason set

I also get errors:

Failed to read from SSL socket: The transmitted packet is too large (EMSGSIZE).
Failed to recv DPD request (1406)
openconnect --version
OpenConnect version v8.02-1+deb10u1
Using GnuTLS. 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

How to still use VPN DNS servers for anything that doesn't resolve via original DNS servers?

I've got split tunnelling working with:

openconnect -b vpn.myvpn.com  -s 'vpn-slice 10.0.0.0/8'

Then I can successfully ping 10.n.n.n, while also not affecting other traffic.

The only thing I can't get working though is to still be able to use remote/internal DNS server?

So that I could ping myserver.mycompany.com, without explicitly adding it to the vpn-slice args?

I did confirm I had access via:

dig @<my internal DNS> myserver.mycompany.com

And it resolved - so I installed resolvconf, and added:

nameserver <my internal DNS>
search <my company domain>

to /etc/resolvconf/resolv.conf.d/tail.

After restarting resolv.conf, I see the right thing in /etc/resolv.conf, but it still won't resolvd internal domains.

My ideal would be for the usual local domain server to be tried first, and only if that failed to try the internal one.

Any ideas how to do this please? Perhaps I need dnsmasq?

support for "other" vpn systems (enhancement request)

It would be really cool if this script could reconfigure routing after it's been set up by a different vpn solution. I imagine this would involve inspecting the current routing table, and then deleting/creating routes as needed.

I'd be interested in looking into how to do this, but don't currently have enough knowledge about how all the routing etc works to know what the right way to do it would be. If you have some pointers for where I could get up to speed with that, that would be great.

Thanks!

KeyError: 'network6' when called with -I without INTERNAL_IP6_ADDRESS

When connecting to a GlobalConnect VPN that doesn't issue IPv6 addresses, vpn-slice -IS fails with the following stack trace:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/vpn_slice/util.py", line 17, in __getattr__
    return self[k]
KeyError: 'network6'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.9.1', 'console_scripts', 'vpn-slice')()
  File "/usr/local/lib/python3.6/dist-packages/vpn_slice/main.py", line 340, in main
    p, args, env = parse_args_and_env()
  File "/usr/local/lib/python3.6/dist-packages/vpn_slice/main.py", line 333, in parse_args_and_env
    if env.network6: args.subnets.append(env.network6)
  File "/usr/local/lib/python3.6/dist-packages/vpn_slice/util.py", line 19, in __getattr__
    raise AttributeError(*e.args)
AttributeError: network6
Script 'vpn-slice -IS' returned error 1
User cancelled (SIGINT/SIGTERM); exiting.

The code depends on a dictionary key (network6) that isn't added unless INTERNAL_IP6_ADDRESS is in the environment.

PR with a fix incoming.

Openconnect, is it possible to force using IPv4?

Just started trying to use vpn-slice today,
and I am using OpenConnect version v7.08-3ubuntu0.18.04.1
Cmd line as below :
-s 'vpn-slice --verbose 10.191.0.0/16'
But always got below error.
Is it possibel to force it to use IPv4 ?

WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
WARNING: IPv6 address or netmask set, but this version of vpn-slice has only rudimentary support for them.
Blocked incoming traffic from VPN interface with iptables.
RTNETLINK answers: No buffer space available
Traceback (most recent call last):
  File "/usr/bin/vpn-slice", line 11, in <module>
    load_entry_point('vpn-slice==0.13', 'console_scripts', 'vpn-slice')()
  File "/export/morgan/.local/lib/python3.6/site-packages/vpn_slice/__main__.py", line 462, in main
    do_connect(env, args)
  File "/export/morgan/.local/lib/python3.6/site-packages/vpn_slice/__main__.py", line 163, in do_connect
    providers.route.add_address(env.tundev, env.myaddr6)
  File "/export/morgan/.local/lib/python3.6/site-packages/vpn_slice/linux.py", line 72, in add_address
    self._iproute('address', 'add', address, dev=device)
  File "/export/morgan/.local/lib/python3.6/site-packages/vpn_slice/linux.py", line 48, in _iproute
    subprocess.check_call(cl)
  File "/usr/lib/python3.6/subprocess.py", line 311, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/sbin/ip', 'address', 'add', '2606:b400:c24:81:8000::27d', 'dev', 'tun0']' returned non-zero exit status 2.
Script 'vpn-slice --verbose 10.191.0.0/16' returned error 1

Multiple variants of similar hostnames?

Hi, So I'm new to the vpn configurations like this and networking in general, so I could be asking a very stupid question, but can I configure this to use multiple hostnames that are similar. I'm trying to connect to my office network, and we have things like account.dev.mycompany.com, addressbook.dev.mycompany.com, cart.dev.mycompany.com and so on...
so can i do something like a wildcard? *.dev.mycompany.com... (i mean not exactly like that... but you get the point)
since those are different services they are on different IPs, so i can't just add XXX.XXX.XXX.XXX and be done with it.

or just somehow tell it to use all local resources?

I see there is also a discussion about exclusions... i guess this could also work for me. i would just add exclusions to my most frequently used sites outside of the corporate ones, and just be content with the rest being routed through the corporate network... but i'm not sure if it's implemented?

Using without sudo

After sudo setcap cap_net_admin+ep /usr/bin/openconnect I can run openconnect without sudo.

Is there a way to use vpn-slice without sudo?

This is error in Centos 8 with Python 3.6:

  File "/home/knude/.virtualenvs/vpn-slice/bin/vpn-slice", line 8, in <module>
    sys.exit(main())
  File "/home/knude/.virtualenvs/vpn-slice/lib/python3.6/site-packages/vpn_slice/__main__.py", line 422, in main
    finalize_args_and_env(args, env)
  File "/home/knude/.virtualenvs/vpn-slice/lib/python3.6/site-packages/vpn_slice/__main__.py", line 379, in finalize_args_and_env
    if os.path.basename(exe) in ('dash','bash','sh','tcsh','csh','ksh','zsh'):
  File "/usr/lib64/python3.6/posixpath.py", line 146, in basename
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not NoneType

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.