Daniel Lenski [Sat, 22 Jan 2022 20:52:35 +0000 (12:52 -0800)]
Add logLevel and logTimestamps options to vpnc-script-win.js
Based on discussions about how to improve vpnc-script logging in
https://gitlab.com/openconnect/vpnc-scripts/-/issues/32#note_810779624.
See https://gitlab.com/openconnect/openconnect/-/merge_requests/328,
which makes OpenConnect send its verbosity level to the vpnc-script
as $LOG_LEVEL.
In the future, $LOG_TIMESTAMPS should probably also be passed by
OpenConnect, although this may be unnecessary since most OS's logging
systems can add timestamps on their own.
Daniel Lenski [Tue, 30 Nov 2021 18:06:44 +0000 (10:06 -0800)]
Always use INTERNAL_IP4_ADDRESS as "gateway" on Windows
It appears that Windows's 'netsh' utility doesn't like the VPN interface
having a "gateway" address of 0.0.0.1, which is what vpnc-script-win.js
would attempt to use if INTERNAL_IP4_NETMASK is /0. See
https://gitlab.com/openconnect/openconnect/-/merge_requests/306#note_745139972.
As noted in the OpenConnect source, "It's a tunnel; having a gateway is
meaningless."
Setting the "gateway" address for Windows to match INTERNAL_IP4_ADDRESS
seems like the simplest way to make 'netsh' configure routingly correctly in
all cases, including when the INTERNAL_IP4_NETMASK is either /0 or /32.
Daniel Lenski [Wed, 17 Nov 2021 19:34:00 +0000 (19:34 +0000)]
Another bugfix when determining the controlling PID
In 596d947a ("Use $VPNPID when provided by OpenConnect"), I inadvertently
included an extra space, which entirely defeated the purpose of checking
if this variable is empty.
Ville Skyttä [Fri, 12 Nov 2021 22:06:22 +0000 (00:06 +0200)]
Use `grep -E` instead of `egrep`
`egrep` has been deprecated in GNU grep since 2007, and in current
post 3.7 Git it has been made to emit obsolescence warnings:
https://git.savannah.gnu.org/cgit/grep.git/commit/?id=a9515624709865d480e3142fd959bccd1c9372d1
Ville Skyttä [Fri, 12 Nov 2021 21:47:56 +0000 (23:47 +0200)]
Use `command -v` instead of `which`
`which` is not standard and might not be installed, whereas `command -v`
is in POSIX and its predecessor specs at least since 1994,
specified to produce no output when the arg command is not found.
https://pubs.opengroup.org/onlinepubs/7908799/xcu/command.html
`which` is also deprecated in Debian's debianutils 5.0+ and emits a
warning when used. At the moment, 5.0+ is only in Debian unstable, and
there is no other package in it providing `which`.
https://salsa.debian.org/debian/debianutils/-/commit/3a8dd10b4502f7bae8fc6973c13ce23fc9da7efb
Daniel Lenski [Fri, 24 Sep 2021 15:07:00 +0000 (08:07 -0700)]
Ensure that vpnc-script-win.js works even if INTERNAL_IP4_{NETADDR,NETMASK} are unset
Not all protocols supported by OpenConnect consistently set the variables
INTERNAL_IP4_{NETADDR,NETMASK} in all cases.
This should be fixed within OpenConnect itself as part of
https://gitlab.com/openconnect/openconnect/-/merge_requests/215, but in the
meantime (and for older versions of OpenConnect/vpnc) we need to ensure that
vpnc-script-win.js works correctly even when these are unset.
Daniel Lenski [Wed, 22 Sep 2021 19:12:00 +0000 (19:12 +0000)]
Add polyfill for String.prototype.trim in vpnc-script-win.js
As noted in https://gitlab.com/openconnect/openconnect/-/issues/312#note_684460541,
Windows Scripting Host's "JScript" does not appear to support
the `String.prototype.trim` method, apparently due to being
based on a very old ECMAScript standard.
The straightforward solution is to use the JavaScript polyfill
described in https://stackoverflow.com/a/35456830.
Daniel Lenski [Thu, 16 Sep 2021 19:56:55 +0000 (12:56 -0700)]
Use $VPNPID when provided by OpenConnect
See https://gitlab.com/openconnect/openconnect/-/merge_requests/278. Once
merged, OpenConnect will send its PID to the vpnc-script as $VPNPID. The
vpnc-script should use this in preference to trying to figure out its
grandparent's PID on its own.
Daniel Lenski [Thu, 16 Sep 2021 03:00:08 +0000 (20:00 -0700)]
Bugfix default route handling by using GRANDparent process ID to uniquely identify connection
In 01d3b8c0, I tried to fix an issue with default route restoration when
multiple "stacked" VPNs were running. However, this actually caused more
problems than it solved, by breaking default route restoration in the
"usual" case of a single VPN.
The problem is that OpenConnect (and vpnc) always call the vpnc-script via
an intermediary, ephemeral shell process. So the GRANDparent process ID
must be used to persistently identify the VPN connection between vpnc-script
'connect' and 'disconnect' invocations.
Daniel Lenski [Thu, 1 Apr 2021 15:43:12 +0000 (08:43 -0700)]
always exclude TUNDEV when finding/setting gateway route
The previous commit didn't fix #20, because 'ip route get' doesn't preserve the onlink flag.
(See https://gitlab.com/openconnect/vpnc-scripts/-/issues/20#note_542783676)
We should just use the 'ip route show' version across-the-board; it's more complex, but appears
to be quite robus. If we have to use it to get the gateway route correctly, then we simply
remove the redundancy in the code. *BSD code ('route'-based) can be similarly simplified.
Daniel Lenski [Wed, 31 Mar 2021 23:23:38 +0000 (16:23 -0700)]
vpnc-script-win: make VPN addresses/gateways "non-persistent", and delete them on disconnect
Persisting the state of IPv4 configuration of these interfaces is generally
unhelpful (as with DNS/WINS settings).
Two approaches. We do both:
1. Make the addresses ephemeral ("netsh ... store=active", as opposed to the
"store=persistent" default). This ensures that the addresses won't last
past reboot.
2. Delete the addresses upon disconnection.
Aaron LI [Sun, 13 Dec 2020 08:38:38 +0000 (16:38 +0800)]
Add DragonFly BSD support and improve FreeBSD support
Support DragonFly BSD for TUN creation and destroy in the same way as
FreeBSD.
No need to load the `if_tun` kernel module, because the `ifconfig(8)`
utility on FreeBSD and DragonFly BSD will auto load it if necessary
(the `-n` option suppresses this behavior; see man page for details).
This feature was added to `ifconfig(8)` in 1999:
https://github.com/freebsd/freebsd/commit/4d16916f800d4c5ee37fb3c93ca6981ad9b33eb3
In addition, FreeBSD 13 has merged `if_tun` and `if_tap` into a single
module named `if_tuntap`. So this change improves the FreeBSD
support.
Signed-off-by: Aaron LI <aly@aaronly.me> Signed-off-by: Daniel Lenski <dlenski@gmail.com>
Daniel Lenski [Tue, 8 Dec 2020 07:31:50 +0000 (23:31 -0800)]
fix another ifconfig syntax difference between Linux and *BSDs
See https://gitlab.com/openconnect/vpnc-scripts/-/merge_requests/9#note_466328301 :
> Thanks. I don't know how this one was missed; the [FreeBSD man
> page](https://www.freebsd.org/cgi/man.cgi?ifconfig) and [macOS man
> page](https://ss64.com/osx/ifconfig.html) clearly show that `delete` has
> to come _after_ the address.
>
> However, Linux's ifconfig [requires `del` to come
> before](https://linux.die.net/man/8/ifconfig), and _only_ works for
> removing IPv6 addresses… so this needs to be reworked a bit to not break
> on Linux.
Daniel Lenski [Tue, 8 Dec 2020 06:12:05 +0000 (22:12 -0800)]
use `ip netns` instead of ocserv `listen-netns` config option for test configs
`listen-netns` is new in ocserv 1.1.1, while iproute2's `ip netns` will work
more universally on Linux, allowing testing on older Linux distributions (see
https://gitlab.com/openconnect/vpnc-scripts/-/commit/c95a3ad0e77963fea73c185ff0308e1edabe522c#note_457425702)
Trygve Aaberge [Sun, 12 Aug 2018 09:53:31 +0000 (11:53 +0200)]
Use systemd-resolve to check if resolved is running
resolved may be included in nsswitch.conf even though systemd-resolved
is not running. E.g. Arch Linux includes resolved in nsswitch.conf by
default, but systemd-resolved is not enabled by default, which causes
this script to fail updating dns.
This patch uses the systemd-resolve command, which is included with
systemd, to check if systemd-resolved is actually running.
Signed-off-by: Trygve Aaberge <trygveaa@gmail.com> Signed-off-by: Daniel Lenski <dlenski@gmail.com>
Daniel Lenski [Fri, 27 Nov 2020 19:54:23 +0000 (11:54 -0800)]
CI: don't need to install ocserv and which
These are already included in the Centos7 build image: https://gitlab.com/openconnect/build-images/-/blob/master/openconnect-cli/centos7/Dockerfile#L11
Daniel Lenski [Sat, 28 Nov 2020 02:27:08 +0000 (18:27 -0800)]
numerous fixes for Linux IPv6 configuration using ifconfig/route/netstat
Trying to ensure that none of the commands executed change in any way on the actual non-Linux OSes which
we cannot directly test with CI currently.
- add missing $route_syntax_gw
- need new syntax variants:
- $ifconfig_syntax_add_inet6 ('add' on Linux, 'inet6' on *BSDs)
- $route_syntax_ipv6 ('-6' on Linux, '-inet6' on *BSDs)
- special handling for IPv6 route addition deletion on Linux:
- '-host'/-net' are REQUIRED on *BSDs but Linux 'route' rejects them
⇒ add $route_syntax_ipv6_{host,net} for these cases
- Linux 'route' rejects local adapter's IPv6 address as gateway with "SIOCADDRT: invalid argument"
⇒ use 'dev $DEVICE' instead of 'gw $NETGW' in this case on Linux
Daniel Lenski [Wed, 25 Nov 2020 21:48:20 +0000 (13:48 -0800)]
try running tests with *BSD-ish tools (ifconfig/route/netstat) for additional coverage
Things that should be improved:
* Need a better way to disable iproute2. Most likely the sanest way to
do this will actually be to split the vpnc-script into two versions, rather than
try to maintain its one-size-fits-all structure.
* Need a better way to enable tracing in vpnc-script. This really should be added
to OpenConnect itself (in part, by adding `-x` to the `sh /path/to/vpnc-script`
exec) since we're frequently requesting it of real users for real issues.
James Hennessy [Sun, 17 Feb 2019 19:18:05 +0000 (14:18 -0500)]
Don't use /sbin/resolvconf if it just points to resolvectl.
On Fedora 29 systems, resolvconf is a symbolic link to resolvectl, but
using resolvectl won't work unless "resolve" appears on the "hosts" line
of /etc/nsswitch. If we reach the point of considering resolvconf, then
"resolve" is not enabled and resolvectl should be avoided.
Daniel Lenski [Wed, 25 Nov 2020 16:37:05 +0000 (08:37 -0800)]
include calling process ID in DEFAULT_ROUTE_FILE{,_IPV6}
This should allow multiple "stacked" VPNs to run concurrently while
preserving the default route(s). There is still a race condition if they
aren't terminated in the correct order.
Ignatios Souvatzis [Thu, 14 May 2020 12:02:08 +0000 (14:02 +0200)]
Patch: make ipv6 in ipv4 and ipv6 in ipv6 tunnels work on (Net)BSD
Hello all,
since my uni's computing centre added inside ipv6 to their tunnel two
days ago I found that OpenConnect hat problems tearing down and
often, setting up the routes.
Three items I had to fix or enhance:
a) an ifconfig ... del ... somewhere. Correct syntax on all BSD's
I've been in touch with over the last decades is ifconifg ... delete ...
b) route handling for the default route was not really there - it wasn't
restored on shutting down the tunnel.
I've done a ::/1 + 8000::1 instead of default (== ::/0) trick here,
in concept what OpenVPN does for IPv4 (0.0.0.0/1 + 128.0.0.0/1)
(has higher priority as more-specific than default due to the shorter
mask, and is unlikely to be more specific than any real local route).
c) protection of the ipv6 transport route didn't work, as it implicitly
assumed always going via ipv4.
This wasn't a problem as long as the inner addresses were
IPv4-only, but broke the tunnel once the effective ipv6 default
route kicked in via the tunnel.
Daniel Lenski [Wed, 30 Sep 2020 19:22:43 +0000 (12:22 -0700)]
preserve metric in fix_ip_get_output
This will allow us to keep, for example, both a lower-metric route to the
VPN gateway through an Ethernet interface, and a higher-metric route to the
VPN gateway through a WiFi interface.
Daniel Lenski [Fri, 25 Sep 2020 00:16:00 +0000 (17:16 -0700)]
make do_attempt_reconnect work with route/ifconfig
Unlike with iproute2, there is no way to determine which interface(s)
have routes that actually match the VPN gateway, so we simply try
finding a default-route gateway, as upon initial connection.
For this to work properly, we need to ensure that get_default_gw excludes
TUNDEV (since the goal is to prevent loopback), and only uses the first
match.
Daniel Lenski [Fri, 25 Sep 2020 00:14:00 +0000 (17:14 -0700)]
add working do_attempt_reconnect
This initial implementation requires iproute2. It find all routes that match
the VPN gateway (excluding those matching "dev $TUNDEV", since the goal is
to prevent loopback), and simply tries adding them one-by-one.
See https://gitlab.com/openconnect/openconnect/-/issues/17 for the original
motivation for adding `reason=attempt-reconnect`.
See https://github.com/dlenski/vpn-slice/pull/14#issuecomment-489293114 for
a discussion of the complexities of implementing it correctly.
Daniel Lenski [Thu, 8 Oct 2020 00:51:29 +0000 (17:51 -0700)]
don't try to set an explicit route to VPN gateway if localhost, and ignore bogus non-forwardable exclude routes
This should fix confusing errors (see https://gitlab.com/openconnect/openconnect/-/issues/172 and
https://gitlab.com/openconnect/openconnect/-/issues/173) and close #8.
Per IANA (https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml#note1),
there are other IPv4 blocks which are effectively unrouteable (not "Forwardable"), but the ones included here
(0.*, 127.*, 169.254.*) are the ones we've actually seen in real VPNs in the wild.
Daniel Lenski [Fri, 25 Sep 2020 16:14:02 +0000 (16:14 +0000)]
Ignore link-local routes in set_default_route
See https://gitlab.com/openconnect/openconnect/-/issues/180#note_418673102, and https://superuser.com/a/1067742 for an explanation of what these routes mean on macOS.