openvpn icon indicating copy to clipboard operation
openvpn copied to clipboard

Windows Community Edition does not install routes like other implementations

Open wayne47git opened this issue 3 weeks ago • 14 comments

Describe the bug I have dozens of OpenVPN connections around the country connecting FreeBSD servers and Edgerouters and attempted to use the same process to create links to my Windows11 notebook running 2.6.17 to FreeBSD and Ubuntu servers. Eventually it became clear that Windows fails to create any gateway routes back to the server.

This was first noticed on a FreeBSD server with jails. The main conf file contains lines like: push "route AAA.BBB.CC.DD 255.255.255.225" # The jails on this host

which resulted in an error (timestamp removed) only on Windows: OpenVPN ROUTE: OpenVPN needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options OpenVPN ROUTE: failed to parse/resolve route for host/network: AAA.BBB.CC.DD

I ignored that, choosing to get OpenVPN working correctly before worrying about the jail. Note, however, that in every other instance, this works correctly.

Eventually, it became clear that OpenVPN on Windows as a client fails to install gateway routes to the server. An example ccd file (that works everywhere else) would contain the single line: ifconfig-push 172.16.26.1 172.16.26.3 Note that the Windows client does properly install a route for 172.16.26.3

For windows clients, it was required to add one more line: because it defaults to net30: push "topology subnet"

While the VPN would come up, no traffic would be routed. The only fix I could determine was to run (as Administrator) a route add command: route add 172.16.23.1 172.16.23.3

To Reproduce See above

Expected behavior I expected OpenVPN to act like every other implementation and tell the client to install a gateway route back to the server for the OpenVPN link as well as any associated route it created.

Version information (please complete the following information):

  • OS: Windows 11 (client)
  • OpenVPN version: 2.6.17

wayne47git avatar Dec 16 '25 02:12 wayne47git

On windows the recommended ways to start openvpn are (I) use openvpn-gui when run interactively by the user (ii) use openvpnservice to start the tunnel at boot (iii) or a combination of the two to support interactive connections before logon.

In all these cases, setting up of routes will work correctly. Openvpn itself will run with limited privileges, but tasks requiring elevation will get handled by a service.

If you just start openvpn.exe from the command line, it has to be run with admin privileges for routes to be setup. This is not recommended.

selvanair avatar Dec 16 '25 02:12 selvanair

Sorry, I left out the fact that I manually start OpenVPN from the GUI. The routes do not get installed, though I do see the push command in the log.

wayne47git avatar Dec 16 '25 03:12 wayne47git

Please include an openvpn log with verb 3 or verb 4. Otherwise this is all just guesswork.

I guess that there is no route-gateway being pushed, because you're sort of working around the normal mechanics in OpenVPN by not having a topology set on the server, and then trying to fix that by pushing things.

Windows can not do arbitrary local/remote IP combinations because it always sees the VPN interface as a "network". So either you go for topology net30 - in which case local/remote IP of ifconfig-push need to be in a /30 (4 address subnet starting on a number dividable by 4) - or for topology subnet, in which case the 2nd parameter of ifconfig-push needs to be a subnet mask (255.255.255.0). To make route setup work, you need to either push "route-gateway $gateway-ip", or include the gateway IP in the pushed route (3rd field).

The easiest way - and most forward-compatible - is propably to use topology subnet on the server, in which case most of this will be handled automatically (like, pushing a route-gateway and topology)

cron2 avatar Dec 16 '25 07:12 cron2

Log below. I am using topology subnet on the server and still see the failure. Note that I do not want to route all traffic through the VPN, routes are only pushed for specific addresses (generally all the IP addresses on the server plus the VPN itself). As a reminder, I have this line in the conf file on the server. On every other implementation, this install the proper gateway route on the client. Since the gateway on the client is the IP of the server-side of the OpenVPN link, it is up to the server to push it to the client: push "route <Jail IP> 255.255.255.225" # The jails on this host Here is the associated ccd file (I did try the commented out push with no luck):

ifconfig-push   172.16.26.3 172.16.26.1
# Fails push            "route <Jail IP> 255.255.255.225 172.16.26.3 1"
# Windows seems to default to net30
push "topology subnet"

Timestamp-removed, sanitized client (Win11) log with the issues I see as separated blocks.

DEPRECATED OPTION: --cipher set to 'AES-256-CBC' but missing in --data-ciphers (AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305). OpenVPN ignores --cipher for cipher negotiations.
Current Parameter Settings:
  config = 'configR6.ovpn'
  mode = 0
  show_ciphers = DISABLED
  show_digests = DISABLED
  show_engines = DISABLED
  genkey = DISABLED
  genkey_filename = '[UNDEF]'
  key_pass_file = '[UNDEF]'
  show_tls_ciphers = DISABLED
  connect_retry_max = 0
Connection profiles [0]:
  proto = udp
  local = '[UNDEF]'
  local_port = '[UNDEF]'
  remote = 'Server IP'
  remote_port = '1194'
  remote_float = DISABLED
  bind_defined = DISABLED
  bind_local = DISABLED
  bind_ipv6_only = DISABLED
  connect_retry_seconds = 1
  connect_timeout = 120
  socks_proxy_server = '[UNDEF]'
  socks_proxy_port = '[UNDEF]'
  tun_mtu = 1500
  tun_mtu_defined = ENABLED
  link_mtu = 1500
  link_mtu_defined = DISABLED
  tun_mtu_extra = 0
  tun_mtu_extra_defined = DISABLED
  tls_mtu = 1250
  mtu_discover_type = -1
  fragment = 0
  mssfix = 1492
  mssfix_encap = ENABLED
  mssfix_fixed = DISABLED
  explicit_exit_notification = 0
  tls_auth_file = '[INLINE]'
  key_direction = 1
  tls_crypt_file = '[UNDEF]'
  tls_crypt_v2_file = '[UNDEF]'
Connection profiles END
  remote_random = DISABLED
  ipchange = '[UNDEF]'
  dev = 'tun'
  dev_type = '[UNDEF]'
  dev_node = '[UNDEF]'
  tuntap_options.disable_dco = DISABLED
  lladdr = '[UNDEF]'
  topology = 1
  ifconfig_local = '[UNDEF]'
  ifconfig_remote_netmask = '[UNDEF]'
  ifconfig_noexec = DISABLED
  ifconfig_nowarn = DISABLED
  ifconfig_ipv6_local = '[UNDEF]'
  ifconfig_ipv6_netbits = 0
  ifconfig_ipv6_remote = '[UNDEF]'
  shaper = 0
  mtu_test = 0
  mlock = DISABLED
  keepalive_ping = 0
  keepalive_timeout = 0
  inactivity_timeout = 0
  session_timeout = 0
  inactivity_minimum_bytes = 0
  ping_send_timeout = 0
  ping_rec_timeout = 0
  ping_rec_timeout_action = 0
  ping_timer_remote = DISABLED
  remap_sigusr1 = 0
  persist_tun = ENABLED
  persist_local_ip = DISABLED
  persist_remote_ip = DISABLED
  persist_key = ENABLED
  passtos = DISABLED
  resolve_retry_seconds = 1000000000
  resolve_in_advance = DISABLED
  username = '[UNDEF]'
  groupname = '[UNDEF]'
  chroot_dir = '[UNDEF]'
  cd_dir = '[UNDEF]'
  writepid = '[UNDEF]'
  up_script = '[UNDEF]'
  down_script = '[UNDEF]'
  down_pre = DISABLED
  up_restart = DISABLED
  up_delay = DISABLED
  daemon = DISABLED
  log = ENABLED
  suppress_timestamps = DISABLED
  machine_readable_output = DISABLED
  nice = 0
  verbosity = 4
  mute = 0
  gremlin = 0
  status_file = '[UNDEF]'
  status_file_version = 1
  status_file_update_freq = 60
  occ = ENABLED
  rcvbuf = 0
  sndbuf = 0
  sockflags = 0
  fast_io = DISABLED
  comp.alg = 0
  comp.flags = 152
  route_script = '[UNDEF]'
  route_default_gateway = '[UNDEF]'
  route_default_metric = 0
  route_noexec = DISABLED
  route_delay = 0
  route_delay_window = 30
  route_delay_defined = DISABLED
  route_nopull = DISABLED
  route_gateway_via_dhcp = DISABLED
  allow_pull_fqdn = DISABLED
  Pull filters:
    ignore "route-method"
  management_addr = '127.0.0.1'
  management_port = '25341'
  management_user_pass = 'stdin'
  management_log_history_cache = 250
  management_echo_buffer_size = 100
  management_client_user = '[UNDEF]'
  management_client_group = '[UNDEF]'
  management_flags = 6
  shared_secret_file = '[UNDEF]'
  key_direction = 1
  ciphername = 'AES-256-CBC'
  ncp_ciphers = 'AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305'
  authname = 'SHA1'
  engine = DISABLED
  replay = ENABLED
  mute_replay_warnings = DISABLED
  replay_window = 64
  replay_time = 15
  packet_id_file = '[UNDEF]'
  test_crypto = DISABLED
  tls_server = DISABLED
  tls_client = ENABLED
  ca_file = '[INLINE]'
  ca_path = '[UNDEF]'
  dh_file = '[UNDEF]'
  cert_file = '[INLINE]'
  extra_certs_file = '[UNDEF]'
  priv_key_file = '[INLINE]'
  pkcs12_file = '[UNDEF]'
  cryptoapi_cert = '[UNDEF]'
  cipher_list = '[UNDEF]'
  cipher_list_tls13 = '[UNDEF]'
  tls_cert_profile = '[UNDEF]'
  tls_verify = '[UNDEF]'
  tls_export_peer_cert_dir = '[UNDEF]'
  verify_x509_type = 0
  verify_x509_name = '[UNDEF]'
  crl_file = '[UNDEF]'
  ns_cert_type = 0
  remote_cert_ku[i] = 65535
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_ku[i] = 0
  remote_cert_eku = 'TLS Web Server Authentication'
  ssl_flags = 192
  tls_timeout = 2
  renegotiate_bytes = -1
  renegotiate_packets = 0
  renegotiate_seconds = 3600
  handshake_window = 60
  transition_window = 3600
  single_session = DISABLED
  push_peer_info = DISABLED
  tls_exit = DISABLED
  tls_crypt_v2_metadata = '[UNDEF]'
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_protected_authentication = DISABLED
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_private_mode = 00000000
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_cert_private = DISABLED
  pkcs11_pin_cache_period = -1
  pkcs11_id = '[UNDEF]'
  pkcs11_id_management = DISABLED
  server_network = 0.0.0.0
  server_netmask = 0.0.0.0
  server_network_ipv6 = ::
  server_netbits_ipv6 = 0
  server_bridge_ip = 0.0.0.0
  server_bridge_netmask = 0.0.0.0
  server_bridge_pool_start = 0.0.0.0
  server_bridge_pool_end = 0.0.0.0
  ifconfig_pool_defined = DISABLED
  ifconfig_pool_start = 0.0.0.0
  ifconfig_pool_end = 0.0.0.0
  ifconfig_pool_netmask = 0.0.0.0
  ifconfig_pool_persist_filename = '[UNDEF]'
  ifconfig_pool_persist_refresh_freq = 600
  ifconfig_ipv6_pool_defined = DISABLED
  ifconfig_ipv6_pool_base = ::
  ifconfig_ipv6_pool_netbits = 0
  n_bcast_buf = 256
  tcp_queue_limit = 64
  real_hash_size = 256
  virtual_hash_size = 256
  client_connect_script = '[UNDEF]'
  learn_address_script = '[UNDEF]'
  client_disconnect_script = '[UNDEF]'
  client_crresponse_script = '[UNDEF]'
  client_config_dir = '[UNDEF]'
  ccd_exclusive = DISABLED
  //tmp_dir = 'C:\Users\XXXXX\AppData\Local\Temp\'
  push_ifconfig_defined = DISABLED
  push_ifconfig_local = 0.0.0.0
  push_ifconfig_remote_netmask = 0.0.0.0
  push_ifconfig_ipv6_defined = DISABLED
  push_ifconfig_ipv6_local = ::/0
  push_ifconfig_ipv6_remote = ::
  enable_c2c = DISABLED
  duplicate_cn = DISABLED
  cf_max = 0
  cf_per = 0
  cf_initial_max = 100
  cf_initial_per = 10
  max_clients = 1024
  max_routes_per_client = 256
  auth_user_pass_verify_script = '[UNDEF]'
  auth_user_pass_verify_script_via_file = DISABLED
  auth_token_generate = DISABLED
  force_key_material_export = DISABLED
  auth_token_lifetime = 0
  auth_token_secret_file = '[UNDEF]'
  vlan_tagging = DISABLED
  vlan_accept = all
  vlan_pvid = 1
  client = ENABLED
  pull = ENABLED
  auth_user_pass_file = '[UNDEF]'
  show_net_up = DISABLED
  route_method = 3
  block_outside_dns = DISABLED
  ip_win32_defined = DISABLED
  ip_win32_type = 1
  dhcp_masq_offset = 0
  dhcp_lease_time = 31536000
  tap_sleep = 0
  dhcp_options = 0x00000000
  dhcp_renew = DISABLED
  dhcp_pre_release = DISABLED
  domain = '[UNDEF]'
  netbios_scope = '[UNDEF]'
  netbios_node_type = 0
  disable_nbt = DISABLED
OpenVPN 2.6.17 [git:v2.6.17/fa20154d58ca609b] Windows [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [AEAD] [DCO] built on Nov 28 2025
Windows version 10.0 (Windows 10 or greater), amd64 executable
library versions: OpenSSL 3.6.0 1 Oct 2025, LZO 2.10
DCO version: 1.3.3
MANAGEMENT: TCP Socket listening on [AF_INET]127.0.0.1:25341
Need hold release from management interface, waiting...
MANAGEMENT: Client connected from [AF_INET]127.0.0.1:49692
MANAGEMENT: CMD 'state on'
MANAGEMENT: CMD 'log on all'
MANAGEMENT: CMD 'echo on all'
MANAGEMENT: CMD 'bytecount 5'
MANAGEMENT: CMD 'state'
MANAGEMENT: CMD 'hold off'
MANAGEMENT: CMD 'hold release'
Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Control Channel MTU parms [ mss_fix:0 max_frag:0 tun_mtu:1250 tun_max_mtu:0 headroom:126 payload:1600 tailroom:126 ET:0 ]
Data Channel MTU parms [ mss_fix:0 max_frag:0 tun_mtu:1500 tun_max_mtu:1600 headroom:136 payload:1768 tailroom:562 ET:0 ]
TCP/UDP: Preserving recently used remote address: [AF_INET]<Server IP>:1194
ovpn-dco device [OpenVPN Data Channel Offload] opened
UDP link local: (not bound)
UDP link remote: [AF_INET]<Server IP>:1194
MANAGEMENT: >STATE:1765898362,WAIT,,,,,,
MANAGEMENT: >STATE:1765898362,AUTH,,,,,,
TLS: Initial packet from [AF_INET]<Server IP>:1194, sid=b1449560 07394a06
VERIFY OK: depth=1, CN=r6.msen.com
VERIFY KU OK
Validating certificate extended key usage
++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
VERIFY EKU OK
VERIFY OK: depth=0, CN=r6-server
Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, peer certificate: 2048 bits RSA, signature: RSA-SHA256, peer temporary key: 253 bits X25519
[r6-server] Peer Connection Initiated with [AF_INET]<Server IP>:1194
TLS: move_session: dest=TM_ACTIVE src=TM_INITIAL reinit_src=1
TLS: tls_multi_process: initial untrusted session promoted to trusted

PUSH: Received control message: 'PUSH_REPLY,route <Jail IP> 255.255.255.225,ping 10,ping-restart 120,topology subnet,ifconfig 172.16.26.3 172.16.26.1,peer-id 0,cipher AES-256-GCM,protocol-flags cc-exit tls-ekm dyn-tls-crypt,tun
-mtu 1500'

OPTIONS IMPORT: --ifconfig/up options modified
OPTIONS IMPORT: route options modified
OPTIONS IMPORT: tun-mtu set to 1500
interactive service msg_channel=648
ROUTE_GATEWAY 192.168.0.1/255.255.255.0 I=15 HWADDR=04:f0:ee:67:b6:d2

OpenVPN ROUTE: OpenVPN needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options
OpenVPN ROUTE: failed to parse/resolve route for host/network: <Jail IP>
do_ifconfig, ipv4=1, ipv6=0

MANAGEMENT: >STATE:1765898362,ASSIGN_IP,,172.16.26.3,,,,
INET address service: add 172.16.26.3/-1
IPv4 MTU set to 1500 on interface 4 using service
Data Channel MTU parms [ mss_fix:1400 max_frag:0 tun_mtu:1500 tun_max_mtu:1600 headroom:136 payload:1768 tailroom:562 ET:0 ]
Outgoing dynamic tls-crypt: Cipher 'AES-256-CTR' initialized with 256 bit key
Outgoing dynamic tls-crypt: Using 256 bit message hash 'SHA256' for HMAC authentication
Incoming dynamic tls-crypt: Cipher 'AES-256-CTR' initialized with 256 bit key
Incoming dynamic tls-crypt: Using 256 bit message hash 'SHA256' for HMAC authentication
Initialization Sequence Completed
MANAGEMENT: >STATE:1765898362,CONNECTED,SUCCESS,172.16.26.3,<Server IP>,1194,,
Data Channel: cipher 'AES-256-GCM', peer-id: 0
Timers: ping 10, ping-restart 120
Protocol options: protocol-flags cc-exit tls-ekm dyn-tls-crypt

wayne47git avatar Dec 16 '25 16:12 wayne47git

As I said, ifconfig 172.16.26.3 172.16.26.1 is not a valid spec, no matter what topology used. In topology subnet mode, this must be a subnet, as in ifconfig 172.16.26.3 255.255.255.0 (or whatever network size you want to see routed). OpenVPN should really hard refuse such an incoming config, and not try to accomodate something (I do wonder how ipconfig /all looks like, afterwards) - would make troubleshooting more obvious.

When you have that, push the route as route <Jail IP> 255.255.255.225 <gateway ip> (and do not use .225 there but .255...), with a gateway ip out of the ifconfig-subnet).

Technically it does not really matter what IP you use, but it needs to be "something in the subnet" so Windows knows "route this into the VPN". It's not actually used for anything besides an indirection "route -> gateway -> interface", so it does not need to be the actual server IP.

So you could push

topology subnet
ifconfig 172.16.26.3 255.255.255.248
route <Jail IP> 255.255.255.255 172.16.26.1

and it should do the thing.

(the server should be pushing topology subnet on its own - if it's not doing this it might be because you either do not run a p2mp server, or because something in the per-client config resets the push-list)

cron2 avatar Dec 16 '25 16:12 cron2

Oh, another thing

# Fails push            "route <Jail IP> 255.255.255.225 172.16.26.3 1"

of course it does - the gateway IP given in the route line is the same IP as assigned to the client by ifconfig-push (172.16.26.3). This no work.

cron2 avatar Dec 16 '25 16:12 cron2

The main conf file already contains ifconfig 172.16.26.1 255.255.255.0 to give the server .1 and allocate a /24 for the various clients

On all the other, working, ccd files I use this to have the server tell the client what route to install: ifconfig-push 172.16.26.3 172.16.26.1

Same server, Edgerouter client properly installs the routes:

172.16.26.1     0.0.0.0         255.255.255.255 UH        0 0          0 vtun6
172.16.26.2     0.0.0.0         255.255.255.255 UH        0 0          0 vtun6

I had tried various things to get that route statement to work. Yours results in the error: Warning: route gateway is not reachable on any active network adapters: 172.16.26.1

wayne47git avatar Dec 16 '25 16:12 wayne47git

Not sure where I should start...

Basically, your setup is a mixture of "real server" and "sort of server" configs. A "real p2mp" server would have --server 172.16.26.1 255.255.255.0 in the config, and will then happily do the IP address allocation and pushing of correct topology and route-gateway to the clients.

What you have is a server that runs topology subnet and clients that run topology p2p - which works fine on everything that is not Windows. I explained that already: Windows must have a subnet. Subnet being "something with 255.255.255.x" in the pushed ifconfig statement, or two IP addresses that are adjacent and in the same /30 subnet (so 1. and .2 will work, .1 and .3 will not - you could use .5 and .6, and that would work as well).

This all aside: route gateway is not reachable on any active network adapters: 172.16.26.1 is a consequence of not pushing a subnet-ifconfig. Push ifconfig 172.16.26.3 255.255.255.0 and the route will work (because then windows will know that 172.16.26.1 is on the VPN adapter).

Summarizing:

either do

ifconfig-push 172.16.26.6 172.16.26.5
push "route-gateway 172.16.26.5"
push "route <Jail IP> 255.255.255.255"

(no topology subnet, but having client IP and "fake server IP" in the same /30)

or do what I already posted above, with a pushed netmask

push "topology subnet"
ifconfig-push 172.16.26.3 255.255.255.248
push "route <Jail IP> 255.255.255.255 172.16.26.1"

but you always need "subnet acceptable to windows" to start with.

cron2 avatar Dec 16 '25 17:12 cron2

My intent was to have a real server, hence the ifconfig 172.16.26.1 255.255.255.0 in the main conf file, and have it allocate a single IP address to each client with .1 as the gateway

I think what you are saying is that Windows does not work correctly in that case. I don't want to break any of my existing VPNs. So I allocated a higher /30 in the ccd file:

   # Warning: Windows REQUIRES a /30 so this uses 172.16.26.4 - 172.16.26.7
ifconfig-push   172.16.26.5 255.255.255.248 

Which properly installs a route to .5 (it also installs one to .7 but that's not a huge deal. Might be useful to tell the poor user that WIndows does not work the same and requires a /30 in the log file.

Pushing the jail IP still does not work: push "route <Jail IP> 255.255.255.255 172.16.26.1" generates an error: ERROR route addition failed using service: The parameter is incorrect. [status=87 if_index=4

but if I add it manually, everything works fine. I can live with that bug.

Thanks for all the help

wayne47git avatar Dec 16 '25 18:12 wayne47git

Well, a "real server" would use --server <ip> <mask> and do all the IP allocation and pushing automatically, and it would work with windows clients as well - but it would need changing your existing setup, which I understand always brings risks.

With the ifconfig-push written that way, it really should work (you need the push "topology subnet" as well). There should not be a route to .7 - actually there should only be a route for .0 255.255.255.248.

Can you share "route print" when the VPN is active, and also the log file starting from the PUSH_REPLY line? Something is still missing, but we're closing in.

cron2 avatar Dec 16 '25 18:12 cron2

I have spare gear around so I'll mess with the server on a new setup and see if I can roll it out everywhere eventually. I have notes in the config files that that syntax does not work right but it's been decades since then and I do not remember the issues. I think the mask should be .252, (/30) not .248 (/29) ?

Here's the complete ccd file with topology:

   # Windows seems to default to net30
push "topology subnet"
   # Warning: Windows REQUIRES a /30 so this uses 172.16.26.4 - 172.16.26.7
ifconfig-push   172.16.26.5 255.255.255.248
#    # The jails on this host 
push            "route <Jail IP> 255.255.255.255 172.16.26.1"

I wanted to start clean so did a reboot of the machine. It appears the the error message is caused by the line in the conf file (which works for all for all non-windows clients): push "route AAA.BBB.CC.DD 255.255.255.225" # The jails on this host but the push in the ccd file causes the route to be installed after the error. I'm guessing that I had cruft left with all my testing.

Here's the route table on the notebook. Again, the .7 route is not a huge issue unless it's going to break something else.

===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.1     192.168.0.49     50
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    331
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    331
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    331
      172.16.26.0  255.255.255.248         On-link       172.16.26.5    281
      172.16.26.5  255.255.255.255         On-link       172.16.26.5    281
      172.16.26.7  255.255.255.255         On-link       172.16.26.5    281
      192.168.0.0    255.255.255.0         On-link      192.168.0.49    306
     192.168.0.49  255.255.255.255         On-link      192.168.0.49    306
    192.168.0.255  255.255.255.255         On-link      192.168.0.49    306
     <Jail IP>     255.255.255.255      172.16.26.1      172.16.26.5    225
        224.0.0.0        240.0.0.0         On-link         127.0.0.1    331
        224.0.0.0        240.0.0.0         On-link       172.16.26.5    281
        224.0.0.0        240.0.0.0         On-link      192.168.0.49    306
  255.255.255.255  255.255.255.255         On-link         127.0.0.1    331
  255.255.255.255  255.255.255.255         On-link       172.16.26.5    281
  255.255.255.255  255.255.255.255         On-link      192.168.0.49    306
===========================================================================

And the requested part of the log file:

PUSH: Received control message: 'PUSH_REPLY,route <Jail IP> 255.255.255.225,ping 10,ping-restart 120,topology subnet,route <Jail IP> 255.255.255.255 172.16.26.1,ifconfig 172.16.26.5 255.255.255.248,peer-id 1,cipher AES-256-GCM,protocol-flags cc-exit tls-ekm dyn-tls-crypt,tun-mtu 1500'
OPTIONS IMPORT: --ifconfig/up options modified
OPTIONS IMPORT: route options modified
OPTIONS IMPORT: tun-mtu set to 1500
interactive service msg_channel=628
ROUTE_GATEWAY 192.168.0.1/255.255.255.0 I=15 HWADDR=04:f0:ee:67:b6:d2
OpenVPN ROUTE: OpenVPN needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options
OpenVPN ROUTE: failed to parse/resolve route for host/network: <Jail IP>
do_ifconfig, ipv4=1, ipv6=0
MANAGEMENT: >STATE:1765911803,ASSIGN_IP,,172.16.26.5,,,,
INET address service: add 172.16.26.5/29
IPv4 MTU set to 1500 on interface 4 using service
MANAGEMENT: >STATE:1765911803,ADD_ROUTES,,,,,,
C:\Windows\system32\route.exe ADD <Jail IP> MASK 255.255.255.255 172.16.26.1 METRIC 200
Route addition via service succeeded
Data Channel MTU parms [ mss_fix:1400 max_frag:0 tun_mtu:1500 tun_max_mtu:1600 headroom:136 payload:1768 tailroom:562 ET:0 ]
Outgoing dynamic tls-crypt: Cipher 'AES-256-CTR' initialized with 256 bit key
Outgoing dynamic tls-crypt: Using 256 bit message hash 'SHA256' for HMAC authentication
Incoming dynamic tls-crypt: Cipher 'AES-256-CTR' initialized with 256 bit key
Incoming dynamic tls-crypt: Using 256 bit message hash 'SHA256' for HMAC authentication
Initialization Sequence Completed
MANAGEMENT: >STATE:1765911803,CONNECTED,SUCCESS,172.16.26.5,<Server IP>,1194,,
Data Channel: cipher 'AES-256-GCM', peer-id: 1
Timers: ping 10, ping-restart 120
Protocol options: protocol-flags cc-exit tls-ekm dyn-tls-crypt```

wayne47git avatar Dec 16 '25 19:12 wayne47git

This is all a bit messy due to topology, windows, and history.

With the old net30 default, a --server config would allocate a /30 for each client, and send them ifconfig $base+1 $base+2 so windows would actually work. With the modern topology subnet, using server $network.0 $netmask would basically assign a /30 to the server-side tun, route the rest of the network into the tun, and then assign individual IPs to each client, pushing ifconfig $ip $netmask. 255.255.255.248 would work (space for 3 or 4 clients), or you could use something bigger.

In my suggested config I used .248 because there it does not really matter, the windows client just needs something acceptable.

So, after all the explanation ;-) - back to your example. The error comes from the pushed route with no gateway info - which can be solved by adding a

push "route-gateway 172.16.26.1"

to the CCD file (and then the route "with that gateway" should no longer be needed).

This works out of the box with topology subnet, server ... because the server will know that the client needs it (see the manpage for details, --server is basically a macro for "do what is needed to make this all work" ;-) ).

cron2 avatar Dec 16 '25 19:12 cron2

That gives me the Warning: route gateway is not reachable on any active network adapters: 172.16.26.1 again. I can live with the error. As I said, I'll try to set up things with server directive.

wayne47git avatar Dec 16 '25 20:12 wayne47git

Mmmmh. I think the problem is one of option ordering... the route-gateway needs to be seen before the route (because it sets the default for any route "after this point in option parsing"). Config statements appended by a CCD file will then not work to make a prior route work.

That said, to get rid of the error, the CCD could contain (at the beginning) a push-remove route statement. But if it works and you do not mind that error, just leave it as it is ;-)

cron2 avatar Dec 16 '25 21:12 cron2