]> www.infradead.org Git - users/dwmw2/vpnc-scripts.git/commitdiff
On newer versions of Windows, need `validate=no` when adding DNS servers
authorDaniel Lenski <dlenski@gmail.com>
Sat, 22 Jan 2022 21:48:16 +0000 (13:48 -0800)
committerDaniel Lenski <dlenski@gmail.com>
Mon, 24 Jan 2022 01:39:45 +0000 (17:39 -0800)
This should fix https://gitlab.com/openconnect/openconnect/-/issues/375.
It appears that on newer Windows systems, `netsh interface ipvX add dns` can
take a long time to run, over 10 seconds. (See
https://gitlab.com/openconnect/openconnect/-/issues/375#note_818616048 for
examples.)

This appears to be because of unwanted network I/O. Specifically, unless
`validate=no` is specified, Windows will try to immediately connect to the
server. Because OpenConnect is not yet exchanging packets over the tunnel
when the vpnc-script is invoked, and hasn't even added IP *routes* for the
tunnel yet, this connection cannot succeed in most configurations. If it
can't connect:

1. It times out after ~10 seconds.
2. It prints a warning: "The configured DNS server is incorrect or does not exist."
3. It nevertheless adds the specified DNS server for the interface.
4. It returns success (exit status 0).

This combination of effects explains why we weren't detecting and displaying
the error.

The `validate` option appears to be poorly documented; it appears in the help
output of `netsh interface ipvX add dns` on Windows 10, but it doesn't
appear in Microsoft's web documentation of `netsh interface ipvX add dns`
for Windows 2008
(https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc731521(v=ws.10)#add-dnsserver),
which is what their "netsh overview" documentation for Windows 2012
(https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/jj129394(v=ws.11))
refers readers to for comprehensive information.

Furthermore, the `validate` option does not exist on older versions of
Windows, but it's *enabled by default* on Windows 10. This means that
we have to be sure to append `validate=no` on newer versions of Windows,
but *not* to append it on older version.

Bang-up job as usual, Microsoft. ðŸ¤¬

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
vpnc-script-win.js

index 29b53c8308d0a83a10d1d23f021343fe16ceee90..982ca6d8fb17eb383e72e82adff5ed6e7fca7201 100644 (file)
@@ -97,6 +97,14 @@ case "pre-init":
     break;
 case "connect":
     var gw = getDefaultGateway();
+
+    var winVer = null;
+    if (run("ver").match(/version\s+((\d+\.)+\d+)/i)) {
+        winVer = RegExp.$1;
+        echo(INFO, "Running on Windows version: " + winVer);
+    } else
+        echo(ERROR, "Could not determine Windows version from 'ver' command");
+
     // Use INTERNAL_IP4_ADDRESS as the "gateway" address for the
     // VPN tunnel connection. As noted in the OpenConnect source,
     // "It's a tunnel; having a gateway is meaningless." Setting
@@ -162,7 +170,12 @@ case "connect":
         var dns = env("INTERNAL_IP4_DNS").split(/ /);
         for (var i = 0; i < dns.length; i++) {
             var protocol = dns[i].indexOf(":") !== -1 ? "ipv6" : "ipv4";
-            run("netsh interface " + protocol + " add dns " + env("TUNIDX") + " " + dns[i]);
+            // With 'validate=yes' (the default on newer Windows versions), Windows will try to
+            // connect to the DNS server, time out after ~10 seconds, and print a warning, but
+            // nevertheless add the specified server. Adding 'validate=no' is thus necessary.
+            // FIXME: determine the earliest Windows version that actually requires this flag.
+            run("netsh interface " + protocol + " add dns " + env("TUNIDX") + " " + dns[i]
+                + (winVer >= "10." ? " validate=no" : ""));
         }
         echo(INFO, "Configured " + dns.length + " DNS servers: " + dns.join(" "));
     }