Windows Community Edition does not install routes like other implementations
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
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.
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.
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)
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
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)
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.
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
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.
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
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.
I have spare gear around so I'll mess with the server
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```
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" ;-) ).
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.
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 ;-)