Skip to contentSkip to conversation

Add Windows DNS Leak fix using WFP ('block-outside-dns')

PATCH Superseded ValdikSS 9 participants 69 messages Oct 26, 2015 – Dec 13, 2015

lore
Share & tools
lore

ValdikSS

author
#0 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

This option is silently ignored on non-Windows platforms and works on Vista+.
External DNS is blocked even if no DNS server configured (user may configure it in the tap interface itself). This option could be ignored from server push using route-nopull.

---
 doc/openvpn.8           |  11 ++-
 src/openvpn/Makefile.am |   2 +-
 src/openvpn/init.c      |  24 +++++++
 src/openvpn/options.c   |  14 ++++
 src/openvpn/options.h   |   1 +
 src/openvpn/win32.c     | 175 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h     |  62 +++++++++++++++++
 7 files changed, 286 insertions(+), 3 deletions(-)
doc/openvpn.8 +9 -2
index b6d5aed..1f60451 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
  When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5517,6 +5517,13 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block external DNS servers on other network adapters to prevent
+DNS leaks. This option blocks svchost.exe from accessing
+any DNS server except one inside the tunnel. It uses WFP and
+could be used on Windows Vista and newer.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +22 -0
index c5c0ab6..b1c23fd 100644
@@ -1468,6 +1468,22 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 +#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");
+            }
+      }
+      else
+           msg (M_NONFATAL, "Can't block outside DNS without configured DNS server");
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1612,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 +#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_NONFATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/options.c +14 -0
index 2f8915d..a7f50cc 100644
@@ -696,6 +696,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -797,6 +800,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1651,6 +1655,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6222,6 +6229,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#if _WIN32_WINNT >= 0x0600
+      options->block_outside_dns = true;
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
    bool use_peer_id;
src/openvpn/win32.c +174 -0

188 lines not on this page · raw message

src/openvpn/win32.h +61 -0

70 lines not on this page · raw message

Signature · 1 line
2.6.2
author
#1 lore raw

PATCH v2 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

This option is silently ignored on non-Windows platforms and works on Vista+.
External DNS is blocked even if no DNS server configured (user may configure it in the tap interface itself). This option could be ignored from server push using route-nopull.

v2:
* Add missing libs to MSVC project file.
* Add ifndef for FWPM_SESSION_FLAG_DYNAMIC to silence warning in MSVC.
* Use const WCHAR for firewall name.
* Block all traffic to TCP/UDP port 53 except for OpenVPN itself. Blocking only svchost.exe is not reliable as user could disable dnscache service making all applications resolve DNS from their processes.

---
 doc/openvpn.8               |  11 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  24 +++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 172 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  64 +++++++++++++++++
 8 files changed, 287 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +9 -2
index b6d5aed..136473e 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
  When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5517,6 +5517,13 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block external DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses WFP and
+works on Windows Vista and later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +22 -0
index c5c0ab6..b1c23fd 100644
@@ -1468,6 +1468,22 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 +#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");
+            }
+      }
+      else
+           msg (M_NONFATAL, "Can't block outside DNS without configured DNS server");
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1612,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 +#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_NONFATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 2f8915d..a7f50cc 100644
@@ -696,6 +696,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -797,6 +800,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1651,6 +1655,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6222,6 +6229,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#if _WIN32_WINNT >= 0x0600
+      options->block_outside_dns = true;
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
    bool use_peer_id;
src/openvpn/win32.c +171 -0

185 lines not on this page · raw message

src/openvpn/win32.h +63 -0

72 lines not on this page · raw message

Signature · 1 line
2.6.2
author
#2 lore raw

It seems that Thunderbird scrabbled the patch. Here is the attachment.

Quoted 441 lines · ValdikSS

This option is silently ignored on non-Windows platforms and works on Vista+.
External DNS is blocked even if no DNS server configured (user may configure it in the tap interface itself). This option could be ignored from server push using route-nopull.

v2:
* Add missing libs to MSVC project file.
* Add ifndef for FWPM_SESSION_FLAG_DYNAMIC to silence warning in MSVC.
* Use const WCHAR for firewall name.
* Block all traffic to TCP/UDP port 53 except for OpenVPN itself. Blocking only svchost.exe is not reliable as user could disable dnscache service making all applications resolve DNS from their processes.

---
 doc/openvpn.8               |  11 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  24 +++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 172 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  64 +++++++++++++++++
 8 files changed, 287 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +9 -2
index b6d5aed..136473e 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
  When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5517,6 +5517,13 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block external DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses WFP and
+works on Windows Vista and later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +22 -0
index c5c0ab6..b1c23fd 100644
@@ -1468,6 +1468,22 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 +#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");
+            }
+      }
+      else
+           msg (M_NONFATAL, "Can't block outside DNS without configured DNS server");
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1612,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 +#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_NONFATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 2f8915d..a7f50cc 100644
@@ -696,6 +696,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -797,6 +800,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1651,6 +1655,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6222,6 +6229,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#if _WIN32_WINNT >= 0x0600
+      options->block_outside_dns = true;
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
    bool use_peer_id;
src/openvpn/win32.c +171 -0
index 7c89a5a..4c44901 100644
@@ -37,6 +37,10 @@
  #ifdef WIN32
 +#include <fwpmu.h>
+#include <fwpmtypes.h>
+#include <iphlpapi.h>
+
 #include "buffer.h"
 #include "error.h"
 #include "mtu.h"
@@ -57,6 +61,17 @@ static struct WSAData wsa_state; /* GLOBAL */
 static bool pause_exit_enabled = false; /* GLOBAL */
  /*
+ * WFP firewall name.
+ */
+const WCHAR * FIREWALL_NAME = L"OpenVPN"; /* GLOBAL */
+
+/*
+ * WFP handle and GUID.
+ */
+static HANDLE m_hEngineHandle = NULL; /* GLOBAL */
+static GUID m_subLayerGUID; /* GLOBAL */
+
+/*
  * win32_signal is used to get input from the keyboard
  * if we are running in a console, or get input from an
  * event object if we are running as a service.
@@ -1019,4 +1034,161 @@ win_get_tempdir()
   WideCharToMultiByte (CP_UTF8, 0, wtmpdir, -1, tmpdir, sizeof (tmpdir), NULL, NULL);
   return tmpdir;
 }
+
+#if _WIN32_WINNT >= 0x0600
+bool
+win_wfp_init()
+{
+    ZeroMemory(&m_subLayerGUID, sizeof(GUID));
+    DWORD dwFwAPiRetCode = ERROR_BAD_COMMAND;
+    FWPM_SESSION0 session = {0};
+    RPC_STATUS rpcStatus = {0};
+    FWPM_SUBLAYER0 SubLayer = {0};
+
+    /* Add temporary filters which don't survive reboots or crashes. */
+    session.flags = FWPM_SESSION_FLAG_DYNAMIC;
+
+    dmsg (D_LOW, "Opening WFP engine");
+    dwFwAPiRetCode = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &m_hEngineHandle);
+
+    if (dwFwAPiRetCode != ERROR_SUCCESS)
+    {
+        msg (M_NONFATAL, "Can't open WFP engine");
+        return false;
+    }
+
+    rpcStatus = UuidCreate(&SubLayer.subLayerKey);
+    if (rpcStatus != NO_ERROR)
+        return false;
+    CopyMemory(&m_subLayerGUID, &SubLayer.subLayerKey, sizeof(SubLayer.subLayerKey));
+
+    /* Populate packet filter layer information. */
+    SubLayer.displayData.name = FIREWALL_NAME;
+    SubLayer.displayData.description = FIREWALL_NAME;
+    SubLayer.flags = 0;
+    SubLayer.weight = 0x100;
+
+    /* Add packet filter to our interface. */
+    dmsg (D_LOW, "Adding WFP sublayer");
+    dwFwAPiRetCode = FwpmSubLayerAdd0(m_hEngineHandle, &SubLayer, NULL);
+    if (dwFwAPiRetCode != ERROR_SUCCESS)
+    {
+        msg (M_NONFATAL, "Can't add WFP sublayer");
+        return false;
+    }
+    return true;
+}
+
+bool
+win_wfp_uninit()
+{
+    dmsg (D_LOW, "Uninitializing WFP");
+    DWORD dwFwAPiRetCode = ERROR_BAD_COMMAND;
+    if (m_hEngineHandle) {
+        FwpmSubLayerDeleteByKey0(m_hEngineHandle, &m_subLayerGUID);
+        ZeroMemory(&m_subLayerGUID, sizeof(GUID));
+        FwpmEngineClose0(m_hEngineHandle);
+        m_hEngineHandle = NULL;
+    }
+    return true;
+}
+
+bool
+win_wfp_add_filter (HANDLE engineHandle,
+                    const FWPM_FILTER0 *filter,
+                    PSECURITY_DESCRIPTOR sd,
+                    UINT64 *id)
+{
+    if (FwpmFilterAdd0(engineHandle, filter, sd, id) != ERROR_SUCCESS)
+    {
+        msg (M_NONFATAL, "Can't add WFP filter");
+        return false;
+    }
+    return true;
+}
+
+bool
+win_wfp_block_dns (const NET_IFINDEX index)
+{
+    dmsg (D_LOW, "Blocking DNS using WFP");
+    NET_LUID tapluid;
+    NETIO_STATUS ret;
+    DWORD dwFwAPiRetCode = ERROR_BAD_COMMAND;
+    UINT64 filterid;
+    WCHAR openvpnpath[MAX_PATH];
+    FWP_BYTE_BLOB *openvpnblob = NULL;
+
+    FWPM_FILTER0 Filter = {0};
+    FWPM_FILTER_CONDITION0 Condition[2] = {0};
+
+    ret = ConvertInterfaceIndexToLuid(index, &tapluid);
+    if (ret == NO_ERROR)
+        dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value);
+
+    /* Get OpenVPN path. */
+    GetModuleFileNameW(NULL, openvpnpath, MAX_PATH);
+
+    if (FwpmGetAppIdFromFileName0(openvpnpath, &openvpnblob) != ERROR_SUCCESS)
+        return false;
+
+    /* Prepare filter. */
+    Filter.subLayerKey = m_subLayerGUID;
+    Filter.displayData.name = FIREWALL_NAME;
+    Filter.weight.type = FWP_EMPTY;
+    Filter.filterCondition = Condition;
+    Filter.numFilterConditions = 2;
+
+    /* First filter. Block IPv4 DNS queries except from OpenVPN itself. */
+    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
+    Filter.action.type = FWP_ACTION_BLOCK;
+
+    Condition[0].fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
+    Condition[0].matchType = FWP_MATCH_EQUAL;
+    Condition[0].conditionValue.type = FWP_UINT16;
+    Condition[0].conditionValue.uint16 = 53;
+
+    Condition[1].fieldKey = FWPM_CONDITION_ALE_APP_ID;
+    Condition[1].matchType = FWP_MATCH_NOT_EQUAL;
+    Condition[1].conditionValue.type = FWP_BYTE_BLOB_TYPE;
+    Condition[1].conditionValue.byteBlob = openvpnblob;
+
+    /* Add filter condition to our interface. */
+    if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
+        return false;
+    dmsg (D_LOW, "Filter (Block IPv4 DNS) added with ID=%I64d", filterid);
+
+    /* Second filter. Block IPv6 DNS queries except from OpenVPN itself. */
+    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
+
+    /* Add filter condition to our interface. */
+    if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
+        return false;
+    dmsg (D_LOW, "Filter (Block IPv6 DNS) added with ID=%I64d", filterid);
+
+    /* Third filter. Permit IPv4 DNS queries from TAP. */
+    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
+    Filter.action.type = FWP_ACTION_PERMIT;
+
+    Condition[1].fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
+    Condition[1].matchType = FWP_MATCH_EQUAL;
+    Condition[1].conditionValue.type = FWP_UINT64;
+    Condition[1].conditionValue.uint64 = &tapluid.Value;
+
+    /* Add filter condition to our interface. */
+    if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
+        return false;
+    dmsg (D_LOW, "Filter (Permit IPv4 DNS queries from TAP) added with ID=%I64d", filterid);
+
+    /* Forth filter. Permit IPv6 DNS queries from TAP. */
+    Filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
+
+    /* Add filter condition to our interface. */
+    if (!win_wfp_add_filter(m_hEngineHandle, &Filter, NULL, &filterid))
+        return false;
+    dmsg (D_LOW, "Filter (Permit IPv6 DNS queries from TAP) added with ID=%I64d", filterid);
+
+    return true;
+}
+
+#endif
 #endif
src/openvpn/win32.h +55 -0
index cc18f02..d26b247 100644
@@ -27,6 +27,10 @@
 #define OPENVPN_WIN32_H
  #include "mtu.h"
+#if _WIN32_WINNT >= 0x0600
+#include <initguid.h>
+#include <fwpmtypes.h>
+#endif
  /* location of executables */
 #define SYS_PATH_ENV_VAR_NAME "SystemRoot"  /* environmental variable name that normally contains the system path */
@@ -271,5 +275,65 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 +#if _WIN32_WINNT >= 0x0600
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_add_filter (HANDLE engineHandle,
+                        const FWPM_FILTER0 *filter,
+                        PSECURITY_DESCRIPTOR sd,
+                        UINT64 *id);
+bool win_wfp_uninit();
+bool win_wfp_init();
+
+/* WFP-related define and GUIDs */
+#ifndef FWPM_SESSION_FLAG_DYNAMIC
+#define FWPM_SESSION_FLAG_DYNAMIC 0x00000001
+#endif
+
+// c38d57d1-05a7-4c33-904f-7fbceee60e82
+DEFINE_GUID(
+   FWPM_LAYER_ALE_AUTH_CONNECT_V4,
+   0xc38d57d1,
+   0x05a7,
+   0x4c33,
+   0x90, 0x4f, 0x7f, 0xbc, 0xee, 0xe6, 0x0e, 0x82
+);
+
+// 4a72393b-319f-44bc-84c3-ba54dcb3b6b4
+DEFINE_GUID(
+   FWPM_LAYER_ALE_AUTH_CONNECT_V6,
+   0x4a72393b,
+   0x319f,
+   0x44bc,
+   0x84, 0xc3, 0xba, 0x54, 0xdc, 0xb3, 0xb6, 0xb4
+);
+
+// d78e1e87-8644-4ea5-9437-d809ecefc971
+DEFINE_GUID(
+   FWPM_CONDITION_ALE_APP_ID,
+   0xd78e1e87,
+   0x8644,
+   0x4ea5,
+   0x94, 0x37, 0xd8, 0x09, 0xec, 0xef, 0xc9, 0x71
+);
+
+// c35a604d-d22b-4e1a-91b4-68f674ee674b
+DEFINE_GUID(
+   FWPM_CONDITION_IP_REMOTE_PORT,
+   0xc35a604d,
+   0xd22b,
+   0x4e1a,
+   0x91, 0xb4, 0x68, 0xf6, 0x74, 0xee, 0x67, 0x4b
+);
+
+// 4cd62a49-59c3-4969-b7f3-bda5d32890a4
+DEFINE_GUID(

src/openvpn/win32.h const char *win_get_tempdir(); · line 338

Quoted 10 lines
src/openvpn/win32.h +8 -0
+   FWPM_CONDITION_IP_LOCAL_INTERFACE,
+   0x4cd62a49,
+   0x59c3,
+   0x4969,
+   0xb7, 0xf3, 0xbd, 0xa5, 0xd3, 0x28, 0x90, 0xa4
+);
+
+#endif
 #endif
 #endif

From 29891bb13c4a60743de2b002a474a51f3a8ad3b0 Mon Sep 17 00:00:00 2001
In-Reply-To: <[email protected]...>
References: <[email protected]...>
From: ValdikSS <[email protected]...>
Date: Tue, 27 Oct 2015 20:20:29 +0300
Subject: [PATCH v2] Add Windows DNS Leak fix using WFP ('block-outside-dns')

This option is silently ignored on non-Windows platforms and works on Vista+.
External DNS is blocked even if no DNS server configured (user may configure it in the tap interface itself). This option could be ignored from server push using route-nopull.

v2:
* Add missing libs to MSVC project file.
* Add ifndef for FWPM_SESSION_FLAG_DYNAMIC to silence warning in MSVC.
* Use const WCHAR for firewall name.
* Block all traffic to TCP/UDP port 53 except for OpenVPN itself. Blocking only svchost.exe is not reliable as user could disable dnscache service making all applications resolve DNS from their processes.

---
 doc/openvpn.8               |  11 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  24 +++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 172 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  64 +++++++++++++++++
 8 files changed, 287 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +9 -2
index b6d5aed..136473e 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5517,6 +5517,13 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block external DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses WFP and
+works on Windows Vista and later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +24 -0
index c5c0ab6..b1c23fd 100644
@@ -1468,6 +1468,22 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");
+            }
+      }
+      else
+           msg (M_NONFATAL, "Can't block outside DNS without configured DNS server");
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1612,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_NONFATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 2f8915d..a7f50cc 100644
@@ -696,6 +696,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -797,6 +800,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1651,6 +1655,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6222,6 +6229,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#if _WIN32_WINNT >= 0x0600
+      options->block_outside_dns = true;
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +172 -0

188 lines not on this page · raw message

src/openvpn/win32.h +64 -0

75 lines not on this page · raw message

Signature · 1 line
2.6.2
#6 lore raw
In reply to ValdikSS

Hi,

Quoted 6 lines · ValdikSS

This option is silently ignored on non-Windows platforms and works on Vista+.
External DNS is blocked even if no DNS server configured (user may configure it in the tap interface itself).
This option could be ignored from server push using route-nopull.

Quoted 8 lines

v2:
* Add missing libs to MSVC project file.
* Add ifndef for FWPM_SESSION_FLAG_DYNAMIC to silence warning in MSVC.
* Use const WCHAR for firewall name.
* Block all traffic to TCP/UDP port 53 except for OpenVPN itself. Blocking only svchost.exe is not reliable as user could disable dnscache service making all applications resolve DNS from their processes.

I tested this on Windows 7 and ran into some problems.

Blocking dns through all interfaces except the tun/tap works (tested by sniffing the traffic etc.).

But most often (see below) name resolution fails after the vpn is connected:

openvpn: git-master + this patch locally compiled using mingw (64bit)
LAN: IP (dhcp): 192.168.0.110 dns (dhcp): 1192.168.0.30 TUN/TAP: IP (automatic): 10.9.0.10 dns (fixed): 8.8.8.8 Windows firewall: disabled

openvpn --config some-config.ovpn --block-outside-dns --verb4 --redirect-gateway def1

Name resolution times-out after connect (checked by ping and browser). But nslookup continues to work, so direct connection to 8.8.8.8:53 via the tun is working. In this state, the only strange thing I notice is

ipconfig /displaydns
returns "Could not display the resolver cache". as if the dnscache service is stopped, but it is running.

Name resolution starts to work again after a
(i) ipconfig /registerdns
OR
(ii) sc stop dnscache (starting it again is also ok) OR
(iii) wait for several minutes
/displaydns also displlays the cache correctly after that.

On restarting the vpn (SIGHUP or SIGUSR1), it goes back to the non resolving state again. Once start working there are no obvious delays with dns -- tested only on a fast connection to the vpn server.

I could not enable logging of the firewall without which its hard to say what's going on. I can only guess the system continues to try only 192.168.0.30 which gets blocked by the filter.

So, how to enable firewall logging? -- enabling via netsh or Windows firewall UI (wf.msc) does not generate any logs. Also the firewall rules added by the program does not show up in the firewall UI or in netsh advfirewall outputs. How to make these filters visible in the UI and how to log the dropped connections? The filters are in place and do work, but doesnt show up in the UI -- is that expected? The UI continues to show firewall as disabled with no filters in place.

I couldn't find anything wrong with the code, but I'm not familiar with WFP.

Thanks
,

author
#7 lore raw

Hi.
It stops resolving DNS right after connection for me every time too, but that lasts 15 seconds at most, not the minutes.
I've no idea what could be wrong. Lev has a similar issue. I can't reproduce it in Windows 7, Windows 8.1 and Windows 10 on both VMs and real hardware.

Quoted 47 lines · Selva Nair

Hi,

On Wed, Oct 28, 2015 at 3:47 AM, ValdikSS <[email protected]... <mailto:[email protected]...>> wrote:

I tested this on Windows 7 and ran into some problems.

Blocking dns through all interfaces except the tun/tap works (tested by sniffing the traffic etc.).

But most often (see below) name resolution fails after the vpn is connected:

openvpn: git-master + this patch locally compiled using mingw (64bit)
LAN: IP (dhcp): 192.168.0.110 dns (dhcp): 1192.168.0.30 TUN/TAP: IP (automatic): 10.9.0.10 dns (fixed): 8.8.8.8 Windows firewall: disabled

openvpn --config some-config.ovpn --block-outside-dns --verb4 --redirect-gateway def1

Name resolution times-out after connect (checked by ping and browser). But nslookup continues to work, so direct connection to 8.8.8.8:53
<http://8.8.8.8:53> via the tun is working. In this state, the only strange thing I notice is

ipconfig /displaydns
returns "Could not display the resolver cache". as if the dnscache service is stopped, but it is running.

Name resolution starts to work again after a
(i) ipconfig /registerdns
OR
(ii) sc stop dnscache (starting it again is also ok) OR
(iii) wait for several minutes
/displaydns also displlays the cache correctly after that.

On restarting the vpn (SIGHUP or SIGUSR1), it goes back to the non resolving state again. Once start working there are no obvious delays with dns -- tested only on a fast connection to the vpn server.

I could not enable logging of the firewall without which its hard to say what's going on. I can only guess the system continues to try only 192.168.0.30 which gets blocked by the filter.

So, how to enable firewall logging? -- enabling via netsh or Windows firewall UI (wf.msc) does not generate any logs. Also the firewall rules added by the program does not show up in the firewall UI or in netsh advfirewall outputs. How to make these filters visible in the UI and how to log the dropped connections? The filters are in place and do work, but doesnt show up in the UI -- is that expected? The UI continues to show firewall as disabled with no filters in place.

I couldn't find anything wrong with the code, but I'm not familiar with WFP.

Thanks
,

#3 lore raw
In reply to ValdikSS

Hi,

Here are some comments on the code -- there is one apparent memory leak (see below).

.\"*********************************************************

Quoted 4 lines

.TP
+.B \-\-block\-outside\-dns
+Block external DNS servers on other network adapters to prevent

the word "external" is not required nor appropriate as it blocks all, isn't it?

Quoted 11 lines
src/openvpn/init.c +5 -0
@@ -1468,6 +1468,22 @@ do_open_tun (struct context *c)
                   "up",
                   c->c2.es);
 +#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else

src/openvpn/init.c do_open_tun (struct context *c) · line 1485

Quoted 10 lines
src/openvpn/init.c +8 -0
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");
+            }
+      }
+      else
+           msg (M_NONFATAL, "Can't block outside DNS without configured
 DNS server");
 

This error/warning is unnecessary and confusing. If the user does not want to block-outside-dns, why say "can't block"? And why the "without configured DNS server" remark?

in win32.c
+
+ ret = ConvertInterfaceIndexToLuid(index, &tapluid);
+ if (ret == NO_ERROR)
+ dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value);
+

Is it safe to ignore the ret != NO_ERROR case? May be it is...

+

Quoted 6 lines
src/openvpn/init.c +4 -0
+    /* Get OpenVPN path. */
+    GetModuleFileNameW(NULL, openvpnpath, MAX_PATH);
+
+    if (FwpmGetAppIdFromFileName0(openvpnpath, &openvpnblob) !=

ERROR_SUCCESS)

openvpnblob is allocated here, but not freed anywhere. Need to free it before return.

Finally, to nitpick,
There are a couple of unused variables
Some local vars could be eliminated (rpcStatus, dwFwAPIRetCode, ret) FIREWALL_NAME defined as const, but passed to non-const ZeroMemory --> CLEAR
CopyMemory --> memcpy

Regards,

Selva

author
#4 lore raw
Quoted 6 lines · Selva Nair

Hi,

Here are some comments on the code -- there is one apparent memory leak (see below).

the word "external" is not required nor appropriate as it blocks all, isn't it?

I'm not a native speaker. If you say that, probably you're right.

Quoted 4 lines

This error/warning is unnecessary and confusing. If the user does not want to block-outside-dns, why say "can't block"? And why the "without configured DNS server" remark?

That's a garbage. There used to be a check for configured 'dhcp-option DNS' and I forgot to remove that. Thanks.

Quoted 23 lines

in win32.c

src/openvpn/win32.c +5 -0
+
+    ret = ConvertInterfaceIndexToLuid(index, &tapluid);
+    if (ret == NO_ERROR)
+        dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value);
+

Is it safe to ignore the ret != NO_ERROR case? May be it is...

openvpnblob is allocated here, but not freed anywhere. Need to free it before return.

Finally, to nitpick,
There are a couple of unused variables
Some local vars could be eliminated (rpcStatus, dwFwAPIRetCode, ret) FIREWALL_NAME defined as const, but passed to non-const ZeroMemory --> CLEAR
CopyMemory --> memcpy

Regards,

Selva

author
#8 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns').

In reply to ValdikSS

This option is silently ignored on non-Windows platforms.

---
 doc/openvpn.8               |  11 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  22 ++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  12 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 170 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  60 ++++++++++++++++
 8 files changed, 277 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +9 -2
index b6d5aed..9e08ae0 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
  When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5517,6 +5517,13 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses WFP and
+works on Windows Vista or later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +20 -0
index c5c0ab6..5db861d 100644
@@ -1468,6 +1468,20 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 +#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");
+            }
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1610,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 +#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_NONFATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +0 -1
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-

<AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>

       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>

- <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>

       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +12 -0
index 2f8915d..dc6f837 100644
@@ -696,6 +696,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -797,6 +800,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1651,6 +1655,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6222,6 +6227,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#ifdef WIN32
+      options->block_outside_dns = true;
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
    bool use_peer_id;
src/openvpn/win32.c +169 -0

183 lines not on this page · raw message

src/openvpn/win32.h +59 -0

68 lines not on this page · raw message

Signature · 1 line
2.6.2

From 17d910f064e1274e8b6b732118f58d92a112cf60 Mon Sep 17 00:00:00 2001
In-Reply-To: <[email protected]...>
References: <[email protected]...>
From: ValdikSS <[email protected]...>
Date: Sun, 25 Oct 2015 21:23:09 +0300
Subject: [PATCH v3-master] Add Windows DNS Leak fix using WFP
('block-outside-dns').

This option is silently ignored on non-Windows platforms.

---
 doc/openvpn.8               |  11 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  22 ++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  12 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 170 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  60 ++++++++++++++++
 8 files changed, 277 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +9 -2
index b6d5aed..9e08ae0 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5517,6 +5517,13 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses WFP and
+works on Windows Vista or later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +22 -0
index c5c0ab6..5db861d 100644
@@ -1468,6 +1468,20 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");
+            }
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1610,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_NONFATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +12 -0
index 2f8915d..dc6f837 100644
@@ -696,6 +696,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -797,6 +800,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1651,6 +1655,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6222,6 +6227,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#ifdef WIN32
+      options->block_outside_dns = true;
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +170 -0

186 lines not on this page · raw message

src/openvpn/win32.h +60 -0

71 lines not on this page · raw message

Signature · 1 line
2.6.2
author
#5 lore raw
In reply to Selva Nair

Fixed all the issues you mentioned, please try v3-master.
Still can't reproduce the problems you and Lev have. Set TAP adapter DNS to static addresses, works fine. Played a bit with static DNS also on internet interface, also works as expected.
Tested with W10, can't run W7 yet.

Quoted 33 lines · Selva Nair

Hi,

Here are some comments on the code -- there is one apparent memory leak (see below).

the word "external" is not required nor appropriate as it blocks all, isn't it?

This error/warning is unnecessary and confusing. If the user does not want to block-outside-dns, why say "can't block"? And why the "without configured DNS server" remark?

in win32.c

src/openvpn/win32.c +5 -0
+
+    ret = ConvertInterfaceIndexToLuid(index, &tapluid);
+    if (ret == NO_ERROR)
+        dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value);
+

Is it safe to ignore the ret != NO_ERROR case? May be it is...

openvpnblob is allocated here, but not freed anywhere. Need to free it before return.

Finally, to nitpick,
There are a couple of unused variables
Some local vars could be eliminated (rpcStatus, dwFwAPIRetCode, ret) FIREWALL_NAME defined as const, but passed to non-const ZeroMemory --> CLEAR
CopyMemory --> memcpy

Regards,

Selva

#9 lore raw

Re: [Openvpn-devel] [PATCH v3-master] Add Windows DNS Leak fix using WFP ('block-outside-dns').

In reply to ValdikSS

Hi,

I couldn't apply the patch (its not against master? )

Also it looks like the memory leak not properly fixed (see below). But before making a new version please see the general comment in the following mail too.

in win32.c

src/openvpn/win32.c win_get_tempdir() · line 1082

Quoted 7 lines
src/openvpn/win32.c +7 -0
+}
+
+bool
+win_wfp_uninit()
+{
+    dmsg (D_LOW, "Uninitializing WFP");
+    DWORD dwFwAPiRetCode = ERROR_BAD_COMMAND;

unused variable ?

src/openvpn/win32.c win_get_tempdir() · line 1111

Quoted 7 lines
src/openvpn/win32.c +7 -0
+
+bool
+win_wfp_block_dns (const NET_IFINDEX index)
+{
+    dmsg (D_LOW, "Blocking DNS using WFP");
+    NET_LUID tapluid;
+    NETIO_STATUS ret;

unused variable ?

Quoted 1 line

+ DWORD dwFwAPiRetCode = ERROR_BAD_COMMAND;

unused variable? I feel like a compiler

[..]

Review

Quoted 2 lines
(quoted diff) +2 -0
+    dmsg (D_LOW, "Filter (Permit IPv6 DNS queries from TAP) added with ID=%I64d", filterid);
+

You need another free(openvpnblob) here, isn't it?

src/openvpn/win32.c win_get_tempdir() · line 1191

Quoted 7 lines
src/openvpn/win32.c +7 -0
+    return true;
+
+    err:
+        free(openvpnblob);
+        return false;
+}
+

in win32.h

src/openvpn/win32.h const char *win_get_tempdir(); · line 279

Quoted 4 lines
src/openvpn/win32.h +4 -0
+bool win_wfp_add_filter (HANDLE engineHandle,
+                        const FWPM_FILTER0 *filter,
+                        PSECURITY_DESCRIPTOR sd,
+                        UINT64 *id);

No need to expose this --- could be made static in win32.c and removed from here...

Thanks,

Selva

#10 lore raw

Re: [Openvpn-devel] [PATCH v3-master] Add Windows DNS Leak fix using WFP ('block-outside-dns').

In reply to ValdikSS

Hi,

I feel some of the errors may have to be treated as FATAL. I understand this patch was discussed in the last IRC meeting, so may be I'm misunderstanding this, please bear with me.

I presume, the main purpose of the option is to work around something seen as a serious security issue for some people (dns leak). If so, when a user specifies --block-outside-dns, and we fail to block it, shouldn't we exit?

src/openvpn/init.c do_open_tun (struct context *c) · line 1479

Quoted 10 lines · ValdikSS
src/openvpn/init.c +9 -0
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_NONFATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_NONFATAL, "Blocking DNS failed!");

M_FATAL here and a few other places?

Further, if there is an error during the set up of a filter, all previously setup filters should be removed, This may become a non-issue if errors are made FATAL.

Selva

author
#11 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to ValdikSS

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 +++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  22 ++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 166 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  56 +++++++++++++++
 8 files changed, 272 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +9 -2
index 2978b7f..dc7eea1 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
  When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5562,6 +5562,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses +Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +20 -0
index c5c0ab6..dfc1314 100644
@@ -1468,6 +1468,20 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 +#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_FATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_FATAL, "Blocking DNS failed!");
+            }
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1610,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 +#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
- <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
- <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 901d710..9cd83a7 100644
@@ -699,6 +699,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -800,6 +803,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1654,6 +1658,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6253,6 +6258,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#ifdef WIN32
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
    bool use_peer_id;
src/openvpn/win32.c +165 -0

179 lines not on this page · raw message

src/openvpn/win32.h +55 -0

64 lines not on this page · raw message

Signature · 1 line
2.6.2
#12 lore raw

Hi,

Quoted 4 lines · ValdikSS

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except
for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

This version looks fine and works as promised (tested on Win 7 and 10).

I'm told many win10 users badly need this, so ACK from me.

Note: The patch appears damaged by the mailer. To test I had to pull the block-external-dns-master branch (with last
commit 76dddc52cc3da95a0681ca660d264e297bf39039)
from https://github.com/ValdikSS/openvpn-with-patches

Selva

#13 lore raw
In reply to ValdikSS

Hi,

Quoted 2 lines · ValdikSS

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

Indeed, what Selva said - the patch is whitespace-mangled. Valdikss, could you please send it with "git-send-email"?

src/openvpn/init.c do_open_tun (struct context *c) · line 1472

Quoted 8 lines
src/openvpn/init.c +2 -0
@@ -1468,6 +1468,20 @@ do_open_tun (struct context *c)
  		   "up",
  		   c->c2.es);
  +#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {

these extra blanks should not be there... thus it won't apply without force.

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
author
#14 lore raw

I can't figure out why Thunderbird corrupts my patches.
Please use the attached version.
I still need help with 2.3 build system. If somebody willing to help me, please use the attached version.

Quoted 10 lines · Gert Doering

Hi,

On Thu, Nov 19, 2015 at 06:20:19PM +0300, ValdikSS wrote:
Indeed, what Selva said - the patch is whitespace-mangled. Valdikss, could you please send it with "git-send-email"?

these extra blanks should not be there... thus it won't apply without force.

gert

From b248fe9e956b389eb8e4b9bbb091848060f71b98 Mon Sep 17 00:00:00 2001
In-Reply-To: <[email protected]...>
References: <[email protected]...>
From: ValdikSS <[email protected]...>
Date: Tue, 24 Nov 2015 20:41:42 +0300
Subject: [PATCH v4-master] Add Windows DNS Leak fix using WFP
('block-outside-dns')

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 +++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  22 ++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  16 +++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 168 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  60 ++++++++++++++++
 8 files changed, 280 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index b6d5aed..c60ce00 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5517,6 +5517,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses 
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +22 -0
index c5c0ab6..36ebc8d 100644
@@ -1468,6 +1468,20 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_FATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_FATAL, "Blocking DNS failed!");
+            }
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1610,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +16 -0
index 2f8915d..b77c9dd 100644
@@ -696,6 +696,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -797,6 +800,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1651,6 +1655,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6222,6 +6229,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#if _WIN32_WINNT >= 0x0600
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +168 -0

184 lines not on this page · raw message

src/openvpn/win32.h +60 -0

71 lines not on this page · raw message

Signature · 1 line
2.6.2

From c3acf0031fa9b6debe834049d397d6595cead559 Mon Sep 17 00:00:00 2001
In-Reply-To: <[email protected]...>
References: <[email protected]...>
From: ValdikSS <[email protected]...>
Date: Thu, 19 Nov 2015 18:12:45 +0300
Subject: [PATCH v4-master] Add Windows DNS Leak fix using WFP
('block-outside-dns')

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 +++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  22 ++++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 166 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |  56 +++++++++++++++
 8 files changed, 272 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 2978b7f..dc7eea1 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5562,6 +5562,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses 
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +22 -0
index c5c0ab6..dfc1314 100644
@@ -1468,6 +1468,20 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+          if (!win_wfp_init())
+            msg (M_FATAL, "Initialising WFP failed!");
+            else
+            {
+                dmsg (D_LOW, "Blocking outside DNS");
+                if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+                    msg (M_FATAL, "Blocking DNS failed!");
+            }
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1610,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 901d710..9cd83a7 100644
@@ -699,6 +699,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -800,6 +803,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1654,6 +1658,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6253,6 +6258,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#ifdef WIN32
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index c642aa0..873c159 100644
@@ -587,6 +587,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +166 -0

182 lines not on this page · raw message

src/openvpn/win32.h +56 -0

67 lines not on this page · raw message

Signature · 1 line
2.6.2
#15 lore raw

Now that I can build OpenVPN-Windows I will help, although it will take me a while to work out how .. I only have access to W7 but from what I have read that is the only Windows you do *not* have.

BTW: Many thanks for your exceptional efforts on this problem :)

Regards

----- Original Message ----- From: "ValdikSS" <[email protected]...>
To: "Gert Doering" <[email protected]...>
Cc: "openvpn-devel" <[email protected]>
Sent: Tuesday, November 24, 2015 5:49 PM
Subject: Re: [Openvpn-devel] [PATCH v4-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

I can't figure out why Thunderbird corrupts my patches.
Please use the attached version.
I still need help with 2.3 build system. If somebody willing to help me, please use the attached version.

Quoted 10 lines · Gert Doering

Hi,

On Thu, Nov 19, 2015 at 06:20:19PM +0300, ValdikSS wrote:
Indeed, what Selva said - the patch is whitespace-mangled. Valdikss, could you please send it with "git-send-email"?

these extra blanks should not be there... thus it won't apply without force.

gert

--------------------------------------------------------------------------------

Quoted 6 lines

------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK. Use one codebase in this all-in-one HTML5 development environment. Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741551&iu=/4140

--------------------------------------------------------------------------------

Quoted 5 lines

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

#16 lore raw
In reply to ValdikSS

Hi,

Quoted 1 line · ValdikSS

I can't figure out why Thunderbird corrupts my patches.

Because you're not using git send-email :)

 $ git send-email [email protected] -1

will magically do everything perfectly (added options available to set
in-reply-to: to make threading work, etc., and you can configure it via .git/config to use the right SMTP server with authentication etc).

It's mostly there because clients are just too brain damaged to leave patches alone. *Attachment* sometimes works, and sometimes not (supposedly thunderbird gets that part right, but gmail for example fails even this)

Quoted 1 line

Please use the attached version.

I'll see if that applies...

Quoted 1 line

I still need help with 2.3 build system. If somebody willing to help me, please use the attached version.

Well, the 2.3 version would need all the #ifdefs around the code if not running at VISTA level, and *no* changes to the build system part (so, 2.3 out of the box would simply not "see" this code at all).

Samuli would then have to change part of his build system to enable VISTA API level and add these extra libraries - but that would have to be an out-of-tree patch applied only to the Vista-and-up installers.

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#17 lore raw

Hi,

Quoted 10 lines · Gert Doering
Quoted 1 line

I still need help with 2.3 build system. If somebody willing to help me,

please use the attached version.

Well, the 2.3 version would need all the #ifdefs around the code if not running at VISTA level, and *no* changes to the build system part (so, 2.3 out of the box would simply not "see" this code at all).

Samuli would then have to change part of his build system to enable VISTA API level and add these extra libraries - but that would have to be an out-of-tree patch applied only to the Vista-and-up installers.

Not sure I understand this. The patch I had tested all along had ifdef _WINNT_WIN32 >= 0x0600 around everything. So the code nicely silences itself when built for XP (I did not try this though). I built only 64 bit version for vista+.

And this was against the master. Now the new sets of patches have different
ifdefs: _WINNT_WIN32 >= 0x600 for 2.3, and if defined(WIN32) for master. This appears unnecessary. Two patches are still needed as some context lines have changed between 2.3 and master, but the code could be the same, and, in particular, the ifdefs could be just _WINNT_WIN32 >= 0x600.

May be you mean the same?

Selva

#28 lore raw
In reply to ValdikSS

Hi,

Quoted 2 lines · ValdikSS

I can't figure out why Thunderbird corrupts my patches.

Its not a thunderbird-specific malady, almost every mail client messes up with line breaks, adds extra spaces etc. As Gert suggested please use git send-email. That makes it easy for everyone..

Quoted 4 lines

Please use the attached version.
I still need help with 2.3 build system. If somebody willing to help me, please use the attached version.

The patch for 2.3 doesn't apply. Hope its not just me.. In fact both patches apply to the master (after some coaxing and with different offsets, of course). That shows something is wrong, as some contexts have to be different in 2.3 and master. For example:

Checking patch src/openvpn/init.c...
error: while searching for:
"up",
c->c2.es);

      /* possibly add routes */
      if ((route_order() == ROUTE_AFTER_TUN) &&

(!c->options.route_delay_defined))
do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,

error: patch failed: src/openvpn/init.c:1468

The problem is route_order() == ROUTE_AFTER_TUN is not in 2.3, its in master.

Similarly in options.c

error: while searching for:

      VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
    }

#endif
#if PASSTOS_CAPABILITY
else if (streq (p[0], "passtos") && !p[1]) <--- this line doesn't
match the one in 2.3

    {

Could you please check whether the patch is really against 2.3?

Also please see why the code has to be different for 2.3 and master -- why not just use ifdef _WINNT_WIN32 ?

Selva

P.S.
There are tons of whitespace errors as well, but that could be worked around..

author
#18 lore raw
In reply to Selva Nair

It's cron2 who wanted clear ifdefs for master, because there's no WinXP support there.
I need help with 2.3 build system. While the code itself would compile fine, it won't link because I can't figure out how to link libraries available in vista+ only for vista+ build and do not link it for XP.

Quoted 15 lines · Selva Nair

Hi,

On Tue, Nov 24, 2015 at 3:11 PM, Gert Doering <[email protected]... <mailto:[email protected]...>> wrote:

Not sure I understand this. The patch I had tested all along had ifdef _WINNT_WIN32 >= 0x0600 around everything. So the code nicely silences itself when built for XP (I did not try this though). I built only 64 bit version for vista+.

And this was against the master. Now the new sets of patches have different ifdefs: _WINNT_WIN32 >= 0x600 for 2.3, and if defined(WIN32) for master. This appears unnecessary. Two patches are still needed as some context lines have changed between 2.3 and master, but the code could be the same, and, in particular, the ifdefs could be just _WINNT_WIN32 >= 0x600.

May be you mean the same?

Selva

#19 lore raw
Quoted 2 lines · ValdikSS

It's cron2 who wanted clear ifdefs for master, because there's no WinXP support there.

If WinXP support is really going away in 2.4, agreed, ifdef WIN32 is cleaner. That apart, the patch doesn't apply to 2.3, please send in if you have an updated one.

For the build issue, may be Samuli can help. I built only for Vista+, but will try building on XP.

Selva

#27 lore raw
In reply to Selva Nair

Hi,

Quoted 4 lines · Selva Nair

Not sure I understand this. The patch I had tested all along had ifdef _WINNT_WIN32 >= 0x0600 around everything. So the code nicely silences itself when built for XP (I did not try this though). I built only 64 bit version for vista+.

That was the v3 patch, and we decided that we always build master with VISTA+, and do not want extra #ifdef's if we can avoid them.

Quoted 5 lines

And this was against the master. Now the new sets of patches have different
ifdefs: _WINNT_WIN32 >= 0x600 for 2.3, and if defined(WIN32) for master. This appears unnecessary. Two patches are still needed as some context lines have changed between 2.3 and master, but the code could be the same, and, in particular, the ifdefs could be just _WINNT_WIN32 >= 0x600.

No #ifdef if they are not needed.

In 2.3 they are needed, because we need to build for XP and Vista+ - in master, XP support has been dropped and we always build Vista+, so we do not need the #ifdef bits for _WINNT_WIN32

I'm not sure why we grew #if defined(WIN32) though... that might be due to "other platforms do not have the functionality at all, so we should not pretend to understand the option" (comment from Arne). But maybe these should be #ifdef HAVE_BLOCK_EXTERNAL_DNS which itself is conditionalized on WIN32 today - it might appear for other platforms, who knows. No really strong opinion there yet.

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#21 lore raw
In reply to ValdikSS

Hi,

Quoted 2 lines · ValdikSS

I need help with 2.3 build system. While the code itself would compile fine, it won't link because I can't figure out how to link libraries available in vista+ only for vista+ build and do not link it for XP.

Cross-build using ubuntu 14.04 and mingw64, and run configure with "configure ... LIBS='-lwhatyouneed'" for the vista+ build.

For 2.3, that should be good enough.

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#20 lore raw
In reply to Selva Nair

Hi,

Quoted 6 lines · Selva Nair
Quoted 2 lines · ValdikSS

It's cron2 who wanted clear ifdefs for master, because there's no WinXP support there.

If WinXP support is really going away in 2.4,

It already is - the GetBestRoute2() stuff is not available on XP, and since we decide long ago that we'll stop XP support in 2.4 if it becomes too painful, this was the point of no return.

Theoretically, this could be handled at runtime (try to open the right library and find the symbol, and if the library is not there, just disable the functionality) but this is something we did not consider important - we do not care about XP in 2.4, period :-)

If someone really *really* cares about XP support in 2.4 and submits clean patches that do not cause extra build work for Samuli, we might reconsider
- but hey, XP is really dead (and who wants XP can still just stick to 2.3.x which we'll continue supporting for a while)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#29 lore raw
In reply to ValdikSS

Hi,

Quoted 3 lines · ValdikSS

I can't figure out why Thunderbird corrupts my patches.
Please use the attached version.
I still need help with 2.3 build system. If somebody willing to help me, please use the attached version.

Thanks for the attachments, this should work out nicely.

There is something I'd ask you to change, though - all these new additions to win32.h are really only needed for the benefit of win32.c (the DEFINE_GUID stuff), but win32.h is included from a LOT of places
- so it would be much cleaner to have this inside win32.c, and only export the function prototypes

src/openvpn/win32.h const char *win_get_tempdir(); · line 281

Quoted 3 lines
src/openvpn/win32.h +3 -0
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+bool win_wfp_init();

towards users.

Another thing I wonder - why have two functions for _init() and _block_dns(), which in the end is either called both, or not at all. Couldn't this be just folded into one function (_block_dns()) which calls _init() internally?

This would reduce the impact on other code paths even further...

Lastly, not all of the new #include files are #ifdef'ed for _WIN32_WINNT
- are these all available on XP already, even if the libraries are not?

thanks,

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#22 lore raw
In reply to Gert Doering

Hi,

Quoted 4 lines · Gert Doering

Hi,

Quoted 1 line · ValdikSS

I need help with 2.3 build system. While the code itself would compile

Quoted 9 lines

fine, it won't link because I can't figure out how to link libraries available in vista+

Quoted 1 line

only for vista+ build and do not link it for XP.

Cross-build using ubuntu 14.04 and mingw64, and run configure with "configure ... LIBS='-lwhatyouneed'" for the vista+ build.

For 2.3, that should be good enough.

Aha, so original question about building for winxp is probably related to the extra libs added to Makefile.am? I think it should not be there in the patch for 2.3 so that the code builds cleanly for XP+ with the current 2.3 build setup. Then build specially for vista+ as Gert wrote above.

Selva

#23 lore raw

Am 25.11.15 um 15:15 schrieb Selva Nair:

Quoted 16 lines

Hi,

On Wed, Nov 25, 2015 at 2:54 AM, Gert Doering <[email protected]... <mailto:[email protected]...>> wrote:

Hi,

On Wed, Nov 25, 2015 at 08:31:23AM +0300, ValdikSS wrote:
> I need help with 2.3 build system. While the code itself would compile fine, it won't link because I can't figure out how to link libraries available in vista+
> only for vista+ build and do not link it for XP.

Cross-build using ubuntu 14.04 and mingw64, and run configure with "configure ... LIBS='-lwhatyouneed'" for the vista+ build.

Quoted 8 lines

For 2.3, that should be good enough.

Aha, so original question about building for winxp is probably related to the extra libs added to Makefile.am? I think it should not be there in the patch for 2.3 so that the code builds cleanly for XP+ with the current 2.3 build setup. Then build specially for vista+ as Gert wrote above.

I am not sure if we want to ship separate WIN XP and Vista+ versions.

Arne

#24 lore raw

Hi,

Quoted 1 line · Arne Schwabe

I am not sure if we want to ship separate WIN XP and Vista+ versions.

We are in agremeent that we do *not* want that :-) - but we *do* want this patch to work around Win10 DNS brokenness, and that binary won't run on XP.

Which of the options do we want less...?

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#68 lore raw
In reply to ValdikSS
Quoted 3 lines · ValdikSS

I can't figure out why Thunderbird corrupts my patches.
Please use the attached version.
I still need help with 2.3 build system. If somebody willing to help me, please use the attached version.

Thunderbird works great in many areas, but my experience with patches are poor. It often does some odd mangling with line lengths and other things. I've even heard rumours of Linux kernel developers rejecting patches when Thunderbird is the MUA, as it will "always" be wrong (but that's 5-6 years ago, might have improved).

And in particular if you use Enigmail with inline signatures, then enigmail makes a really big mess. It will do a select-all -> reformat -> copy -> send clipboard to gpg -> gpg result to clipboard -> paste. What is less worse is to use PGP/MIME ... which I had to do for all these ML discussions, as it even messed up the '>' blocks completely and other git log messages when replying.

As others have said already ... For patches, configure git send-email, it is fairly simple and you won't have so much complaints from us :)

Signature · 3 lines
kind regards,

David Sommerseth
#25 lore raw
In reply to Gert Doering

Just a small suggestion: I think the following will work:

- Check the version of the current operating system.
- Dynamically loading related DLLs (in this case, should be WFP-related libraries) using LoadLibrary() only if OpenVPN is running Windows Vista+, and pops a warning for XP users who has that option enabled.
- On Vista+, get addresses of those APIs that we want to call (via GetProcAddress() ), and then use them as function pointers.

Pros: one binary works for all Windows.
Cons: the code is a bit messier.

I've done this before for my own projects that must be running on both XP and later versions of Windows, and it works reliably. I can look into this later this week (if ValdikSS doesn't have cycles).

Best,
Fish

-----Original Message-----
From: Gert Doering [mailto:[email protected]...]
Sent: Wednesday, November 25, 2015 6:55 AM
To: Arne Schwabe <[email protected]...>
Cc: openvpn-devel <[email protected]>
Subject: Re: [Openvpn-devel] [PATCH v4-master] Add Windows DNS Leak fix using WFP ('block-outside-dns')

Hi,

Quoted 1 line · Arne Schwabe

I am not sure if we want to ship separate WIN XP and Vista+ versions.

We are in agremeent that we do *not* want that :-) - but we *do* want this patch to work around Win10 DNS brokenness, and that binary won't run on XP.

Which of the options do we want less...?

gert

Signature · 7 lines
USENET is *not* the non-clickable part of WWW!
 
//www.muc.de/~gert/
Gert Doering - Munich, Germany
[email protected]...
fax: +49-89-35655025
[email protected]...
author
#30 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Gert Doering

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 211 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 8 files changed, 259 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 9889540..7e73073 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5574,6 +5574,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +17 -0
index c5c0ab6..9f3da60 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1605,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 36290a0..ef068fc 100644
@@ -704,6 +704,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -805,6 +808,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1673,6 +1677,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6263,6 +6268,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#ifdef WIN32
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index ebc0591..2f6c8b4 100644
@@ -585,6 +585,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +211 -0

221 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.2
author
#31 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Gert Doering

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 211 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 8 files changed, 259 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 9889540..7e73073 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5574,6 +5574,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +17 -0
index c5c0ab6..9f3da60 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1605,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 36290a0..ef068fc 100644
@@ -704,6 +704,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -805,6 +808,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1673,6 +1677,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6263,6 +6268,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#ifdef WIN32
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index ebc0591..2f6c8b4 100644
@@ -585,6 +585,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +211 -0

221 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.2
author
#66 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Gert Doering

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   0
 src/openvpn/options.c       |  16 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 215 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 7 files changed, 262 insertions(+), 2 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 46c1e0c..95aafdd 100644
@@ -1119,8 +1119,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5454,6 +5454,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/init.c +17 -0
index ceef4f7..e8a96c2 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if (!c->options.route_delay_defined)
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1594,6 +1603,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +0 -0
old mode 100755
new mode 100644
src/openvpn/options.c +16 -0
index f609aa6..45c29ba 100644
@@ -715,6 +715,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -814,6 +817,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1678,6 +1682,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6312,6 +6319,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#if _WIN32_WINNT >= 0x0600
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos"))
     {
src/openvpn/options.h +1 -0
index 40cf71e..622706a 100644
@@ -593,6 +593,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +215 -0

225 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.2
author
#32 lore raw
In reply to ValdikSS

Sorry for double post. This patch comes with removed wfp_init, moved defines to win32.c from win32.h, whitespace fix in documentation.

author
#67 lore raw
In reply to ValdikSS

This patch for release/2.3 has vista ifdefs in code and no build system modifications, so the linking would fail if it is compiled for vista+, so you need to add LIBS='-lfwpuclnt -lrpcrt4' to configure as Gert suggested.

#34 lore raw

Hi,

I did some tests on the patch for 2.3 [*]. Build for vista+ needed some hacking of configure.ac (but that's not relevant for this patch).

For XP+, it builds out of the box. When the resulting exe is run on windows 7 with --block-outside-dns, it prints the following warning

"NOTE: block-outside-dns option works only on Windows"

Apart from the confusing warning, I had expected the process to exit with unknown option error.

+#if _WIN32_WINNT >= 0x0600

Quoted 4 lines
src/openvpn/options.c +3 -0
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on

Windows");

This has to be something like "... not supported in this version or build" or some such..

In fact, that #else clause short-circuits the default error handling of unknown/unsupported options. It may be best to omit it altogether and let the final if-block handle the unknown option. Or at least use msglevel_fc in place of M_WARN so that it will exit if appropriate to do so.

+#endif

Selva

[*] v5 2.3 patch with the missing include <initguid.h> manually added.

author
#35 lore raw

Hi!

You have the point, note is confusing on XP. Changed it to "…on Windows Vista or later".

Non-fatal note message is intended to have one config file on various platforms without any modifications. On the other hand, you probably would still use ignore-unknown-option to comply with outdated versions. As my own preference, I'd like to keep it non-fatal, but if you think this is inappropriate behaviour, I'll change that.

Quoted 20 lines · Selva Nair

Hi,

I did some tests on the patch for 2.3 [*]. Build for vista+ needed some hacking of configure.ac <http://configure.ac> (but that's not relevant for this patch).

For XP+, it builds out of the box. When the resulting exe is run on windows 7 with --block-outside-dns, it prints the following warning

"NOTE: block-outside-dns option works only on Windows"

Apart from the confusing warning, I had expected the process to exit with unknown option error.

This has to be something like "... not supported in this version or build" or some such..

In fact, that #else clause short-circuits the default error handling of unknown/unsupported options. It may be best to omit it altogether and let the final if-block handle the unknown option. Or at least use msglevel_fc in place of M_WARN so that it will exit if appropriate to do so.

Selva

[*] v5 2.3 patch with the missing include <initguid.h> manually added.

author
#64 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Selva Nair

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  14 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 212 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 8 files changed, 260 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 9889540..7e73073 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5574,6 +5574,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +17 -0
index c5c0ab6..9f3da60 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1605,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +14 -0
index 36290a0..11cfe7f 100644
@@ -704,6 +704,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -805,6 +808,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1673,6 +1677,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6263,6 +6268,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#ifdef WIN32
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows Vista or later");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos") && !p[1])
     {
src/openvpn/options.h +1 -0
index ebc0591..2f6c8b4 100644
@@ -585,6 +585,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +212 -0

222 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.2
author
#65 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Selva Nair

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   0
 src/openvpn/options.c       |  16 ++++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 216 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 7 files changed, 263 insertions(+), 2 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 46c1e0c..95aafdd 100644
@@ -1119,8 +1119,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5454,6 +5454,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/init.c +17 -0
index ceef4f7..e8a96c2 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if (!c->options.route_delay_defined)
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1594,6 +1603,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +0 -0
old mode 100755
new mode 100644
src/openvpn/options.c +16 -0
index f609aa6..e817dc0 100644
@@ -715,6 +715,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -814,6 +817,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1678,6 +1682,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6312,6 +6319,15 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
     }
 #endif
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+#if _WIN32_WINNT >= 0x0600
+      options->block_outside_dns = true;
+#else
+      msg (M_WARN, "NOTE: block-outside-dns option works only on Windows Vista or later");
+#endif
+    }
 #if PASSTOS_CAPABILITY
   else if (streq (p[0], "passtos"))
     {
src/openvpn/options.h +1 -0
index 40cf71e..622706a 100644
@@ -593,6 +593,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +216 -0

226 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.2
#36 lore raw
In reply to ValdikSS

Hi,

Quoted 5 lines · ValdikSS

Hi!

You have the point, note is confusing on XP. Changed it to "…on Windows Vista or later".

That doesn't make it any less confusing. If I run a generic 2.3 (i.e no wfp) build on on windows 7. I'll get that warning even though I am on "vista or later". So it has to be something like "..not supported in this build" or whatever... We can't anticipate on what version of windows a build without wfp compiled-in may be run..

Quoted 4 lines

Non-fatal note message is intended to have one config file on various platforms without any modifications.

There is already a way to handle that. So why break it for someone who doesn't want to ignore unknown options? In my view a better way is to let the existing code in options.c handle it appropriately (as fatal or warn depending on other options, whether its being pushed or read from config etc..)

Having said that there are other options such as --user and --group which just generate a warning on windows. It may be its just me being pedantic. Anyone else?

Selva

#37 lore raw

Am 28.11.15 um 18:25 schrieb Selva Nair:

Quoted 23 lines

Hi,

On Sat, Nov 28, 2015 at 10:08 AM, ValdikSS <[email protected]... <mailto:[email protected]...>> wrote:

Hi!

You have the point, note is confusing on XP. Changed it to "…on Windows Vista or later".

That doesn't make it any less confusing. If I run a generic 2.3 (i.e no wfp) build on on windows 7. I'll get that warning even though I am on "vista or later". So it has to be something like "..not supported in this build" or whatever... We can't anticipate on what version of windows a build without wfp compiled-in may be run..

Non-fatal note message is intended to have one config file on various platforms without any modifications.

Quoted 5 lines

There is already a way to handle that. So why break it for someone who doesn't want to ignore unknown options? In my view a better way is to let the existing code in options.c handle it appropriately (as fatal or warn depending on other options, whether its being pushed or read from config etc..)

I am also voting on fatal error if the option is unknown. You can always use setenv opt block-outside-dns or use ignore-unknown-option if you do not want it to fail.

Arne

#26 lore raw
In reply to Fish Wang

Hi,

Quoted 9 lines · Fish Wang

Just a small suggestion: I think the following will work:

- Check the version of the current operating system.
- Dynamically loading related DLLs (in this case, should be WFP-related libraries) using LoadLibrary() only if OpenVPN is running Windows Vista+, and pops a warning for XP users who has that option enabled.
- On Vista+, get addresses of those APIs that we want to call (via GetProcAddress() ), and then use them as function pointers.

Quoted 6 lines

Pros: one binary works for all Windows.
Cons: the code is a bit messier.

I've done this before for my own projects that must be running on both XP and later versions of Windows, and it works reliably. I can look into this later this week (if ValdikSS doesn't have cycles).

This would definitely be something I'd like to have a look at.

Depending how *much* messier the code gets (especially: what settings does it need to get built? WINXP or VISTA?) this might be a good way to avoid having to build two different openvpn.exe executables.

OTOH, we need two installers anyway as the NDIS6 tap driver does not work on XP - so if we bundle openvpn-xp.exe with the old tap driver and openvpn-vista+.exe with the ndis6 tap driver, it's not that much worse than what we have now...

And yes, time to get 2.4 out :-)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
author
#38 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Arne Schwabe

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  10 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 212 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 8 files changed, 256 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 9889540..7e73073 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5574,6 +5574,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +17 -0
index c5c0ab6..9f3da60 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1605,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +10 -0
index 36290a0..4b98275 100644
@@ -704,6 +704,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -805,6 +808,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1673,6 +1677,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6192,6 +6197,11 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_IPWIN32);
       options->tuntap_options.register_dns = true;
     }
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+      options->block_outside_dns = true;
+    }
   else if (streq (p[0], "rdns-internal") && !p[1])
      /* standalone method for internal use
       *
src/openvpn/options.h +1 -0
index ebc0591..2f6c8b4 100644
@@ -585,6 +585,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +212 -0

222 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.2
author
#62 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Arne Schwabe

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   0
 src/openvpn/options.c       |  14 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 216 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 7 files changed, 261 insertions(+), 2 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 46c1e0c..95aafdd 100644
@@ -1119,8 +1119,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5454,6 +5454,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/init.c +17 -0
index ceef4f7..e8a96c2 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if (!c->options.route_delay_defined)
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1594,6 +1603,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +0 -0
old mode 100755
new mode 100644
src/openvpn/options.c +14 -0
index f609aa6..457ff3e 100644
@@ -715,6 +715,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -814,6 +817,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1678,6 +1682,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6241,6 +6248,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_IPWIN32);
       options->tuntap_options.register_dns = true;
     }
+#if _WIN32_WINNT >= 0x0600
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+      options->block_outside_dns = true;
+    }
+#endif
   else if (streq (p[0], "rdns-internal"))
      /* standalone method for internal use
       *
src/openvpn/options.h +1 -0
index 40cf71e..622706a 100644
@@ -593,6 +593,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +216 -0

226 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.2
author
#63 lore raw
In reply to Arne Schwabe

I **hope** I get it right this time.

Quoted 7 lines · Arne Schwabe

Am 28.11.15 um 18:25 schrieb Selva Nair:
I am also voting on fatal error if the option is unknown. You can always use setenv opt block-outside-dns or use ignore-unknown-option if you do not want it to fail.

Arne

#39 lore raw
In reply to ValdikSS

Hi,

Quoted 3 lines · ValdikSS

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except
for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

v7 looks good and behaves as promised..

Tested v7-master and v7-2.3 (the latter built with and without wfp) on windows 7 and windows 10 (64 bit only). For windows 7, also see the note below.

Selva

Note: On windows7 I would suggest to use this option with either a script that does "ipconfig /registerdns" or with the config option --register-dns (the latter is slow as it restarts the dnsclient service etc., but may be pushed). Without registerdns, at least on my win7 machine, any public dns servers on other interfaces get queries through the tunnel for a long while after the connection is up. As if those dns servers have been specified on the tunnel interface! It doesn't appear to have anything to do with this patch.

#40 lore raw

These may have been fixed by now, but noticed some issues in the original patch that was discussed in the OpenVPN-devel IRC meeting several weeks ago.

* win_adapter_index_to_luid is declared to return a NET_LUID but not all code paths return a value.

* wcscat(svchostpath, L"\\svchost.exe") isn't checking for buffer overflow.

* FwpmGetAppIdFromFileName0 must be paired with a
corresponding FwpmFreeMemory0

James

author
#41 lore raw

These issues should be fixed. Please check PATCH v7.

Quoted 12 lines · James Yonan

These may have been fixed by now, but noticed some issues in the original patch that was discussed in the OpenVPN-devel IRC meeting several weeks ago.

* win_adapter_index_to_luid is declared to return a NET_LUID but not all code paths return a value.

* wcscat(svchostpath, L"\\svchost.exe") isn't checking for buffer overflow.

* FwpmGetAppIdFromFileName0 must be paired with a
corresponding FwpmFreeMemory0

James

#42 lore raw

Hi,

Quoted 2 lines · ValdikSS

These issues should be fixed. Please check PATCH v7.

I think you missed the NET_LUID one. I had thought this was fixed earlier, but v7 still has this issue

Quoted 7 lines · James Yonan
Quoted 1 line

These may have been fixed by now, but noticed some issues in the

original patch that was discussed in the OpenVPN-devel IRC meeting several weeks ago.

Quoted 3 lines

* win_adapter_index_to_luid is declared to return a NET_LUID but not all code paths return a value.

The relevant code is

+ if (ConvertInterfaceIndexToLuid(index, &tapluid) == NO_ERROR)
+ dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value);

which leaves tapluid undefined if there was an error.

Selva

author
#43 lore raw

Indeed.
Pushed fixed version to github repo.
https://github.com/ValdikSS/openvpn-with-patches/commit/287ceb11abfa33ee331ba2651572908cbad008d1

If there is no other remarks, I'll send PATCH v8.

Quoted 16 lines · Selva Nair

Hi,

On Fri, Dec 4, 2015 at 12:14 AM, ValdikSS <[email protected]... <mailto:[email protected]...>> wrote:

I think you missed the NET_LUID one. I had thought this was fixed earlier, but v7 still has this issue

The relevant code is

+ if (ConvertInterfaceIndexToLuid(index, &tapluid) == NO_ERROR)
+ dmsg (D_LOW, "Tap Luid: %I64d", tapluid.Value);

which leaves tapluid undefined if there was an error.

Selva

author
#44 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  10 ++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 216 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 8 files changed, 260 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 9889540..7e73073 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5574,6 +5574,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +17 -0
index c5c0ab6..9f3da60 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1605,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +10 -0
index 36290a0..4b98275 100644
@@ -704,6 +704,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -805,6 +808,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1673,6 +1677,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6192,6 +6197,11 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_IPWIN32);
       options->tuntap_options.register_dns = true;
     }
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+      options->block_outside_dns = true;
+    }
   else if (streq (p[0], "rdns-internal") && !p[1])
      /* standalone method for internal use
       *
src/openvpn/options.h +1 -0
index ebc0591..2f6c8b4 100644
@@ -585,6 +585,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +216 -0

226 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.3
author
#61 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to ValdikSS

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   0
 src/openvpn/options.c       |  14 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 220 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 7 files changed, 265 insertions(+), 2 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 46c1e0c..95aafdd 100644
@@ -1119,8 +1119,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5454,6 +5454,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/init.c +17 -0
index ceef4f7..e8a96c2 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if (!c->options.route_delay_defined)
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1594,6 +1603,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +0 -0
old mode 100755
new mode 100644
src/openvpn/options.c +14 -0
index f609aa6..457ff3e 100644
@@ -715,6 +715,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -814,6 +817,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1678,6 +1682,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6241,6 +6248,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_IPWIN32);
       options->tuntap_options.register_dns = true;
     }
+#if _WIN32_WINNT >= 0x0600
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+      options->block_outside_dns = true;
+    }
+#endif
   else if (streq (p[0], "rdns-internal"))
      /* standalone method for internal use
       *
src/openvpn/options.h +1 -0
index 40cf71e..622706a 100644
@@ -593,6 +593,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +220 -0

230 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.3
#45 lore raw
In reply to ValdikSS

Hi,

Sorry for the late response.

+bool
+win_wfp_uninit()
+{
+ dmsg (D_LOW, "Uninitializing WFP");
+ if (m_hEngineHandle) {

+        FwpmSubLayerDeleteByKey0(m_hEngineHandle, &m_subLayerGUID);
+        CLEAR(m_subLayerGUID);
+        FwpmEngineClose0(m_hEngineHandle);
+        m_hEngineHandle = NULL;

FwpmSubLayerDeleteByKey0 will likely fail if there is a filter associated with sublayer. On the other side, FwpmEngineClose0 seems to be enough to remove blocking.

I think the correct way would be to create GUID for filter same way as you did for sublayer and copy it to filter.filterKey. In uninit method, before deleting sublayer you call FwpmFilterDeleteByKey0 with that guid.

-Lev

#46 lore raw
Quoted 11 lines · Lev Stipakov
src/openvpn/win32.c +9 -0
+bool
+win_wfp_uninit()
+{
+    dmsg (D_LOW, "Uninitializing WFP");
+    if (m_hEngineHandle) {
+        FwpmSubLayerDeleteByKey0(m_hEngineHandle, &m_subLayerGUID);
+        CLEAR(m_subLayerGUID);
+        FwpmEngineClose0(m_hEngineHandle);
+        m_hEngineHandle = NULL;
Quoted 7 lines

FwpmSubLayerDeleteByKey0 will likely fail if there is a filter associated with sublayer. On the other side, FwpmEngineClose0 seems to be enough to remove blocking.

I think the correct way would be to create GUID for filter same way as you did for sublayer and copy it to filter.filterKey. In uninit method, before deleting sublayer you call FwpmFilterDeleteByKey0 with that guid.

That sounds useful for yet another reason as well. Its only necessary to delete and recreate the permit filters when the tun restarts. The block filters need be set up only once.

Selva

author
#47 lore raw

That would break name resolver on reconnection if remote is a hostname.

Quoted 12 lines · Selva Nair

On Thu, Dec 10, 2015 at 4:55 AM, Lev Stipakov <[email protected]... <mailto:[email protected]...>> wrote:

That sounds useful for yet another reason as well. Its only necessary to delete and recreate the permit filters when the tun restarts. The block filters need be set up only once.

Selva

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

#50 lore raw
In reply to Lev Stipakov

Hi,

Quoted 1 line · Lev Stipakov

Sorry for the late response.

[..]

Quoted 3 lines

FwpmSubLayerDeleteByKey0 will likely fail if there is a filter associated with sublayer. On the other side, FwpmEngineClose0 seems to be enough to remove blocking.

So, is this something that needs to be fixed before we release 2.3.9, or can it wait for improvement later on?

I just agreed with Samuli that we are going to release 2.3.9 on Monday, and this should go in - so either I get a v9 "with nice and shiny" until Sunday, or someone tells me "v8 is good enough, go for it"...

Thanks :-)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#48 lore raw
In reply to ValdikSS
Quoted 2 lines · ValdikSS

That would break name resolver on reconnection if remote is a hostname.

Yes, I meant to leave the block all and permit openvpn.exe filters always on and delete/re-add only the filters for the tun/tap interface. Well, its probably just a cosmetic change, so no strong opinion.

Selva

author
#51 lore raw
In reply to Gert Doering

It's a very minor actually, FwpmSubLayerDeleteByKey0 is indeed fails every time but it doesn't break anything since we close the engine right after. Lev suggested to use a correct way with making a filter GUID and deleting it before deleting sublayer, but I'd better go with just closing the engine without deleting everything. I don't see any drawbacks, that should be perfectly OK for a dynamic session.

Is this correct, Lev? If yes, I'll push v9 today or tomorrow morning.

Quoted 23 lines · Gert Doering

Hi,

On Thu, Dec 10, 2015 at 11:55:16AM +0200, Lev Stipakov wrote:
[..]
So, is this something that needs to be fixed before we release 2.3.9, or can it wait for improvement later on?

I just agreed with Samuli that we are going to release 2.3.9 on Monday, and this should go in - so either I get a v9 "with nice and shiny" until Sunday, or someone tells me "v8 is good enough, go for it"...

Thanks :-)

gert

------------------------------------------------------------------------------

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

author
#49 lore raw
In reply to Selva Nair

No, I'm afraid it would fail by default since DNS queries are (usually) made from svchost.exe. Whitelisting openvpn.exe is done to not to break OpenVPN on UDP port 53. I could be incorrect tho.

Quoted 12 lines · Selva Nair

On Thu, Dec 10, 2015 at 11:24 AM, ValdikSS <[email protected]... <mailto:[email protected]...>> wrote:

Yes, I meant to leave the block all and permit openvpn.exe filters always on and delete/re-add only the filters for the tun/tap interface. Well, its probably just a cosmetic change, so no strong opinion.

Selva

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

#52 lore raw
In reply to ValdikSS
Quoted 6 lines · ValdikSS

It's a very minor actually, FwpmSubLayerDeleteByKey0 is indeed fails every time but it doesn't break anything since we close the engine right after. Lev suggested to use a correct way with making a filter GUID and deleting it before deleting sublayer, but I'd better go with just closing the engine without deleting everything. I don't see any drawbacks, that should be perfectly OK for a dynamic session.

Provided it doesn't leak memory. As the current implementation of wfp_add_filter does return the id of the added filter (in &filterid) , its easy to save them into some globals and delete all the filters in wfp_uninit.

However, If you are sure there is no leak, just closing the engine is fine.

Other than this v8 is good to go.

Selva

author
#53 lore raw

I'm not totally sure about that, but I suppose it shouldn't leak. Here's what Microsoft's Best Practice says:

Quoted 6 lines

Use dynamic sessions.

Many applications add filtering policy objects at start, and then delete these objects at stop. By using a dynamic session, you guarantee that these objects are deleted even if the application crashes. Furthermore, simply closing the engine handle at stop is more efficient than making individual calls to delete each object.

https://msdn.microsoft.com/en-us/library/windows/desktop/bb442411%28v=vs.85%29.aspx

Quoted 2 lines

If /session/.*flags* is set to *FWPM_SESSION_FLAG_DYNAMIC*, any WFP objects added during the session are automatically deleted when the session ends. If the session is not dynamic, the caller needs to explicitly delete all WFP objects added during the session.

https://technet.microsoft.com/ru-ru/aa364040

Quoted 20 lines · Selva Nair

On Thu, Dec 10, 2015 at 11:49 AM, ValdikSS <[email protected]... <mailto:[email protected]...>> wrote:

Provided it doesn't leak memory. As the current implementation of wfp_add_filter does return the id of the added filter (in &filterid) , its easy to save them into some globals and delete all the filters in wfp_uninit.

However, If you are sure there is no leak, just closing the engine is fine.

Other than this v8 is good to go.

Selva

------------------------------------------------------------------------------

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

#54 lore raw

Hi,

Quoted 9 lines · ValdikSS

Use dynamic sessions.

Many applications add filtering policy objects at start, and then delete these objects at stop. By using a dynamic session, you guarantee that these objects are deleted even if the application crashes. Furthermore, simply closing the engine handle at stop is more efficient than making individual calls to delete each object.

Going by that just closing the engine appears good enough. I never tested

really changing the tapluid between a SIGHUP restart (how to trigger that) to know whether any old filters hang around after a _uninit. Anyway, those are very unlikely cases and we cant guarad against everything up front.

I would say go for v9 with a simple closing of the engine.

Thanks,

Selva

author
#55 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   0
 src/openvpn/options.c       |  14 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 215 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 7 files changed, 260 insertions(+), 2 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 46c1e0c..95aafdd 100644
@@ -1119,8 +1119,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5454,6 +5454,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/init.c +17 -0
index ceef4f7..e8a96c2 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if (!c->options.route_delay_defined)
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1594,6 +1603,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if _WIN32_WINNT >= 0x0600
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +0 -0
old mode 100755
new mode 100644
src/openvpn/options.c +14 -0
index f609aa6..457ff3e 100644
@@ -715,6 +715,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#if _WIN32_WINNT >= 0x0600
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -814,6 +817,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1678,6 +1682,9 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+#if _WIN32_WINNT >= 0x0600
+  SHOW_BOOL (block_outside_dns);
+#endif
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6241,6 +6248,13 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_IPWIN32);
       options->tuntap_options.register_dns = true;
     }
+#if _WIN32_WINNT >= 0x0600
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+      options->block_outside_dns = true;
+    }
+#endif
   else if (streq (p[0], "rdns-internal"))
      /* standalone method for internal use
       *
src/openvpn/options.h +1 -0
index 40cf71e..622706a 100644
@@ -593,6 +593,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +215 -0

225 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.4
author
#58 lore raw

PATCH 1/1 Add Windows DNS Leak fix using WFP ('block-outside-dns')

In reply to Selva Nair

This option blocks all out-of-tunnel communication on TCP/UDP port 53 (except for OpenVPN itself), preventing DNS Leaks on Windows 8.1 and 10.

---
 doc/openvpn.8               |  12 ++-
 src/openvpn/Makefile.am     |   2 +-
 src/openvpn/init.c          |  17 ++++
 src/openvpn/openvpn.vcxproj |   4 +-
 src/openvpn/options.c       |  10 +++
 src/openvpn/options.h       |   1 +
 src/openvpn/win32.c         | 211 ++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/win32.h         |   3 +
 8 files changed, 255 insertions(+), 5 deletions(-)
 mode change 100755 => 100644 src/openvpn/openvpn.vcxproj
doc/openvpn.8 +10 -2
index 9889540..7e73073 100644
@@ -1129,8 +1129,8 @@ When used with
 .B \-\-client
 or
 .B \-\-pull,
-accept options pushed by server EXCEPT for routes and dhcp options
-like DNS servers.
+accept options pushed by server EXCEPT for routes, block-outside-dns and dhcp
+options like DNS servers.
 
 When used on the client, this option effectively bars the
 server from adding routes to the client's routing table,
@@ -5574,6 +5574,14 @@ adapter list to the syslog or log file after the TUN/TAP adapter
 has been brought up and any routes have been added.
 .\"*********************************************************
 .TP
+.B \-\-block\-outside\-dns
+Block DNS servers on other network adapters to prevent
+DNS leaks. This option prevents any application from accessing
+TCP or UDP port 53 except one inside the tunnel. It uses
+Windows Filtering Platform (WFP) and works on Windows Vista or
+later.
+.\"*********************************************************
+.TP
 .B \-\-dhcp\-renew
 Ask Windows to renew the TAP adapter lease on startup.
 This option is normally unnecessary, as Windows automatically
src/openvpn/Makefile.am +1 -1
index c840f16..c55a520 100644
@@ -127,5 +127,5 @@ openvpn_LDADD = \
 	$(OPTIONAL_DL_LIBS)
 if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
-openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
+openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm -lfwpuclnt -lrpcrt4
 endif
src/openvpn/init.c +17 -0
index c5c0ab6..9f3da60 100644
@@ -1468,6 +1468,15 @@ do_open_tun (struct context *c)
 		   "up",
 		   c->c2.es);
 
+#if defined(WIN32)
+      if (c->options.block_outside_dns)
+      {
+        dmsg (D_LOW, "Blocking outside DNS");
+        if (!win_wfp_block_dns(c->c1.tuntap->adapter_index))
+            msg (M_FATAL, "Blocking DNS failed!");
+      }
+#endif
+
       /* possibly add routes */
       if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
 	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
@@ -1596,6 +1605,14 @@ do_close_tun (struct context *c, bool force)
 		       "down",
 		       c->c2.es);
 
+#if defined(WIN32)
+            if (c->options.block_outside_dns)
+            {
+                if (!win_wfp_uninit())
+                    msg (M_FATAL, "Uninitialising WFP failed!");
+            }
+#endif
+
 	  /* actually close tun/tap device based on --down-pre flag */
 	  if (c->options.down_pre)
 	    do_close_tun_simple (c);
src/openvpn/openvpn.vcxproj +2 -2
old mode 100755
new mode 100644
index b117b0b..821c46c
@@ -64,7 +64,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
@@ -89,7 +89,7 @@
       <AdditionalIncludeDirectories>$(SOURCEBASE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>libeay32.lib;ssleay32.lib;lzo2.lib;pkcs11-helper.dll.lib;gdi32.lib;ws2_32.lib;wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;Fwpuclnt.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OPENSSL_HOME)/lib;$(LZO_HOME)/lib;$(PKCS11H_HOME)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Console</SubSystem>
src/openvpn/options.c +10 -0
index 36290a0..4b98275 100644
@@ -704,6 +704,9 @@ static const char usage_message[] =
   "                       optional parameter controls the initial state of ex.\n"
   "--show-net-up   : Show " PACKAGE_NAME "'s view of routing table and net adapter list\n"
   "                  after TAP adapter is up and routes have been added.\n"
+#ifdef WIN32
+  "--block-outside-dns   : Block DNS on other network adapters to prevent DNS leaks\n"
+#endif
   "Windows Standalone Options:\n"
   "\n"
   "--show-adapters : Show all TAP-Windows adapters.\n"
@@ -805,6 +808,7 @@ init_options (struct options *o, const bool init_gc)
   o->tuntap_options.dhcp_lease_time = 31536000; /* one year */
   o->tuntap_options.dhcp_masq_offset = 0;       /* use network address as internal DHCP server address */
   o->route_method = ROUTE_METHOD_ADAPTIVE;
+  o->block_outside_dns = false;
 #endif
 #if P2MP_SERVER
   o->real_hash_size = 256;
@@ -1673,6 +1677,7 @@ show_settings (const struct options *o)
 #ifdef WIN32
   SHOW_BOOL (show_net_up);
   SHOW_INT (route_method);
+  SHOW_BOOL (block_outside_dns);
   show_tuntap_options (&o->tuntap_options);
 #endif
 #endif
@@ -6192,6 +6197,11 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_IPWIN32);
       options->tuntap_options.register_dns = true;
     }
+  else if (streq (p[0], "block-outside-dns") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_IPWIN32);
+      options->block_outside_dns = true;
+    }
   else if (streq (p[0], "rdns-internal") && !p[1])
      /* standalone method for internal use
       *
src/openvpn/options.h +1 -0
index ebc0591..2f6c8b4 100644
@@ -585,6 +585,7 @@ struct options
   bool exit_event_initial_state;
   bool show_net_up;
   int route_method;
+  bool block_outside_dns;
 #endif
 
   bool use_peer_id;
src/openvpn/win32.c +211 -0

221 lines not on this page · raw message

src/openvpn/win32.h +3 -0
index cc18f02..a5baebd 100644
@@ -271,5 +271,8 @@ const char *win_get_tempdir();
 /* Convert a string from UTF-8 to UCS-2 */
 WCHAR *wide_string (const char* utf8, struct gc_arena *gc);
 
+bool win_wfp_block_dns(const NET_IFINDEX index);
+bool win_wfp_uninit();
+
 #endif
 #endif
Signature · 1 line
2.6.4
#60 lore raw
In reply to ValdikSS
Quoted 5 lines · ValdikSS

I'd better go with just
closing the engine without deleting everything. I don't see any drawbacks, that should be perfectly OK for a dynamic session.

Is this correct, Lev? If yes, I'll push v9 today or tomorrow morning.

Removing non-working FwpmSubLayerDeleteByKey0 call is indeed step into right direction, rest is up to you :) I already mentioned above what I would do.

Just for the record - this patch does not work on my only win10 box with DNS leak - it blocks leaks but each DNS request takes 10 seconds, so I cannot give an ACK. On the other hand, it works for others in this discussion and is optional in any case (should not break things). So I won't say NACK either.

-Lev

#56 lore raw
In reply to ValdikSS

ACK. Lots of people have reviewed this, and it made the patch better :-)
- so I list them all, and take the final blame (ACK) on me...

Your patch has been applied to the release/2.3 branch.

commit dd628d2e0d786e478fd99d54000dceaa42d53855 (release/2.3)

Author: ValdikSS
Date:   Thu Dec 10 23:51:35 2015 +0300
     Add Windows DNS Leak fix using WFP ('block-outside-dns')

     Reviewed-by: Selva Nair <[email protected]...>
     Reviewed-by: Lev Stipakov <[email protected]...>
     Reviewed-by: James Yonan <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/10743
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#59 lore raw
In reply to ValdikSS

ACK. I verified that this patch is identical to the 2.3 patch except for the option check in options.c, and the #ifdef for VISTA+ - so same ACK here, and same list of reviewers. Thanks.

Your patch has been applied to the master branch.

commit 38c8565810f892a41a2ea0d18a707676119f1af0 (master)

Author: ValdikSS
Date:   Thu Dec 10 23:51:55 2015 +0300
     Add Windows DNS Leak fix using WFP ('block-outside-dns')

     Reviewed-by: Selva Nair <[email protected]...>
     Reviewed-by: Lev Stipakov <[email protected]...>
     Reviewed-by: James Yonan <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/10744
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#57 lore raw
In reply to Gert Doering
Quoted 3 lines · Gert Doering

ACK. Lots of people have reviewed this, and it made the patch better :-)
- so I list them all, and take the final blame (ACK) on me...

Thanks (for assuming the blame :). And, ValdikSS, thanks for putting up with all the opinionated comments.

Cheers,

Selva