Openvpn custom --route-up script in 23.05 rc2


I upgraded to 23.05 rc2 on my WRT1900ACS.
I noticed that I now get this error message (that I didn't have with OpenWRT 22.03)

openvpn(custom_config)[28561]: Multiple --route-up scripts defined. The previously configured script is overridden.

my /etc/config/openvpn:

package openvpn

config openvpn custom_config
        option enable 1
        option config /etc/openvpn/client.conf

and my /etc/openvpn/client.conf:

dev tun
proto udp4
remote my.server 1194
resolv-retry infinite
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client.crt
key /etc/openvpn/client.key
remote-cert-tls server
tls-auth /etc/openvpn/ta.key 1
verb 1
mute 4
route-up '/sbin/ip route add default via dev tun0 table 10'
user openvpn
group openvpn

The problem is that my custom "route-up" is no longer executed.
It appears that the function openvpn_add_instance() in /etc/init.d/openvpn now contains some --route-up argument which overrides what is in my client.conf file.
Any idea how to fix this the clean OpenWRT way? I know I could probably edit /etc/init.d/openvpn, but I'd prefer a solution which would survive accross updates.

I only want that route to be added once the OpenVPN tunnel is up.


1 Like

Declare the VPN interface and its default route with UCI:

I noticed this too.
It looks like extra up and down scripts are executed but not an extra route-up script
Try with
up '/sbin/ip route add default via dev tun0 table 10'

Although, as it concerns routing, the preferable script is route-up


Thanks, this seems to work:

config route
        option interface 'vpn'
        option target ''
        option gateway ''
        option table '10'

the route gets added when the OpenVPN link is up, and gets deleted when its down, exactly as I want.

1 Like

I tried adding simple 'up' and 'route-up' directives to my /etc/openvpn/client.conf

I get the following warnings:

Tue Aug  1 10:33:32 2023 daemon.warn openvpn(custom_config)[12090]: Multiple --up scripts defined.  The previously configured script is overridden.
Tue Aug  1 10:33:32 2023 daemon.warn openvpn(custom_config)[12090]: Multiple --route-up scripts defined.  The previously configured script is overridden.

So it seems neither up or route-up can be used in the openvpn configuration file.

I used an up script and that was working despite the warning

It's a bit weird.

My directive in my client.conf file was

up '/bin/echo up >> /tmp/ovpn.log'

And the result in /tmp/ovpn.log was

up tun0 1500 1552 init

As if the OpenWRT scripts were adding arguments to my up command.

It is actually pretty weird
There are actually -up -route-up and -down commands already as you can see from the commandline ( ps | grep openvpn ) I have been trying to follow the bouncing ball as to what that does but it is pretty complicated and I am not quite sure exactly what it does but it seems to parse the .ovpn file for up and down (but not for route-up?) and on ifup and ifdown it executes that.

I could be completely mistaken and I have not delved further into it as I got side tracked:


But I will look further into it and hope to find some documentation about it

This is what I know so far

--up and --down scripts which are entered in the openvpn.config are executed, --route-up and --pre-down are not executed

The OpenVPN scripting is really complicated and uses a cascade of scripts.

You can see from the command line (ps | grep openvpn) that ther are already --up --route-up---pre-down and --down scripts set.
Hence the warning of multiple the log

Scripts involved:
/usr/libexec/openvpn-hotplug > /sbin/hotplug-call > /etc/hotplug.d/openvpn/01-user

I have not found any documentation other than:
But I am still searching

I have the idea that this all is done to use hotplug -up and -down, up and down actions can be placed in /etc/openvpn.user

In the --up and --down sequence the existing --up and --down scripts which have been entered in the openvpn.config are also executed so far so good.

The problem is that --route-up and --pre-down are not executed by the hotplug scripts.

My take as there are no hotplug --route-up and --pre-down this should not be parsed at all so that should be removed form the command line.
The command line should only contain the hotplug --up and --down.

I removed --route-up and --pre-down from the command line and now --route-up and-pre-down scripts are executed.

I attach a patch to do that so that you have an idea what and where to delete.

# openvpn.init-allow-scripts.patch by egc to allow OpenVPN route-up and route-pre-down scripts
# execute this patch from openwrt/feeds with
# patch -p 1 -i openvpn.init-allow-scripts.patch
--- a/packages/net/openvpn/files/openvpn.init	2023-06-19 11:05:15.739576942 +0200
+++ b/packages/net/openvpn/files/openvpn.init	2023-08-03 14:29:47.430909092 +0200
@@ -154,8 +154,6 @@
 		--config "$conf" \
 		--up "/usr/libexec/openvpn-hotplug up $name" \
 		--down "/usr/libexec/openvpn-hotplug down $name" \
-		--route-up "/usr/libexec/openvpn-hotplug route-up $name" \
-		--route-pre-down "/usr/libexec/openvpn-hotplug route-pre-down $name" \
 		${client:+--ipchange "/usr/libexec/openvpn-hotplug ipchange $name"} \
 		${up:+--setenv user_up "$up"} \
 		${down:+--setenv user_down "$down"} \

As said it is rather complicated (to me at least) and I could be totally wrong and/or there is a far better way to deal with this.

I hope someone with real knowledge chimes in :slight_smile:

well these two lines were added in this commit,

so it sounds like they have some use. The problem is that both hotplug triggered commands and those defined in the openvpn config should be executed.

For --up and --down that works but there are no hotplug --route-up nor --pre-down commands so that does not work.
Maybe if those --route-up and --pre-down commands could be added for hotplug it would work but for now it does not.

Ok I am closer to a better solution, the patch is not complete --route-up and other missing options should be added on other scripts too, to set these variables in the environment.

I think I know how and will look into it :slight_smile:

Yes, but using the specified UID and GID:

Which have no permission to create routes.
So, either use UCI/netifd, or Hotplug, or run as root which is suboptimal.

from what I understand there is a feature in openvpn in which the process starts as root and then downgrades to the specified user after the initialization is complete (therefore possibly after route-up script is executed). I see this in my log:

NOTE: UID/GID downgrade will be delayed because of --client, --pull, or

using UCI is fine with me, it's working well and I will likely keep this configuration.

But I agree that it is counter intuitive if --route-up/down directives in config files have no effect in OpenWRT.

1 Like

I fully agree :slight_smile:

Maybe you can circumvent this is some way but the beauty of these scripts is that they are triggered on the right moment and you can use the environmental variables from OpenVPN

To clarify --up and --down scripts are working.

I have this in my openvpn config file to grab the DNS servers pushed by the ISP, and then set those exclusively to use by DNSMasq (replacing the resolv file) and also route those DNS servers via the tunnel (in case of PBR).
On --down the situation is reversed

In openvpn config file:

up /etc/openvpn/update-resolv-conf-3
down /etc/openvpn/update-resolv-conf-3

This is the accompanying script which works for me:

# File name: update-resolv-conf-3
# Description: Script to grab DNS servers from the tunnel for exclusive use by DNSMasq and routes those via the tunnel to prevent DNS leaks
# Version: 270723
# Install:
#  Copy this cript to /etc/openvpn
#  Make executable: chmod +x /etc/openvpn/update-resolv-conf-3
#  Add in the OpenVPN config file these three lines:
#   up /etc/openvpn/update-resolv-conf-3
#   down /etc/openvpn/update-resolv-conf-3
# Fundamentals:
#  Gets the pushed DNS servers and DNS servers manually set in conf file with: dhcp-option DNS <ip-address-of-DNS-server>
#  DNS servers are set in a new resolv file which is used exclusively by DNSMasq to prevent DNS leaks.
#  Sets route for the DNS servers via the tunnel, necessary when using PBR
#  To stop getting the pushed DNS servers by the OpenVPN server add to conf file: pull-filter ignore "dhcp-option DNS"


#set -x


case $script_type in
	#env > /tmp/vpn_env_var_up
	# if $DEF_RESOLVF exists when the tunnel is brought up it indicates a dirty ifdown so reset to defaults
	[[ "$VPN_RESOLVF" = "$(uci get dhcp.@dnsmasq[0].resolvfile)" ]] && { uci set dhcp.@dnsmasq[0].resolvfile="/tmp/resolv.conf.d/"; \
		rm -fr "$DEF_RESOLVF" >/dev/null 2>&1; logger -t $(basename $0)[$$] -p user.notice "Dirty ifdown detected reset DNSMasq to default"; }
	# Instead of removing the resolv file consider: uci set dhcp.@dnsmasq[0].resolvfile="/tmp/resolv.conf.d/" 
	# Instead of setting the resolv file consider removing as it will default then: uci del dhcp.@dnsmasq[0].resolvfile 
	# Get DNS servers and DNS servers manually set in conf file
	env | grep 'dhcp-option DNS' | awk '{ print "nameserver " $3 }' > $VPN_RESOLVF
	# Get DNS servers set in conf file, redundant as the above already gets it
	#grep -e "^dhcp-option DNS" $VPN_CONF | awk '{ print "nameserver " $3 }' >> $VPN_RESOLVF
	if [[ ! -s "$VPN_RESOLVF" ]]; then
		logger -t $(basename $0)[$$] -p user.warning "No VPN DNS servers found, using default servers!"
		rm -fr "$VPN_RESOLVF" >/dev/null 2>&1
		return 0
	# Make sure DNS servers are always routed via the tunnel e.g. in case of PBR
	if [[ -s $VPN_RESOLVF ]]; then
		while read dns; do
			ip route add $(echo $dns | awk '{print $2}') dev $dev
			# alternative do not route the DNS servers set in the conf file as that can easily be done in the conf file with
			# route <ip-address-of-DNS-server> vpn_gateway|net_gateway
			#grep -q "^dhcp-option DNS $dns" $VPN_CONF || ip route add $(echo $dns | awk '{print $2}') dev $dev 2> /dev/null
		done < $VPN_RESOLVF
	# Save default resolv file
	uci get dhcp.@dnsmasq[0].resolvfile > $DEF_RESOLVF
	# Replace default resolv file
	uci set dhcp.@dnsmasq[0].resolvfile=$VPN_RESOLVF
	uci commit dhcp
	/etc/init.d/dnsmasq restart &
	logger -t $(basename $0)[$$] -p user.notice "Exclusively using OpenVPN DNS server(s) from $VPN_RESOLVF"
	#env > /tmp/vpn_env_var_down
	# Restore dns, deleting the resolv file path will use default
	if [[ -s $DEF_RESOLVF ]]; then
		uci set dhcp.@dnsmasq[0].resolvfile=$(cat $DEF_RESOLVF)
	elif [[ -e $DEF_RESOLVF ]]; then
		uci del dhcp.@dnsmasq[0].resolvfile
	else	#no DNS servers present so did not run
		logger -t $(basename $0)[$$] -p user.notice "No OpenVPN DNS server(s) set so nothing to do on ifdown"
		return 0
	uci commit dhcp
	/etc/init.d/dnsmasq restart &
	# Remove routing of DNS servers, often redundant as the routes are removed anyway if the interface disappears
	if [[ -s $VPN_RESOLVF ]]; then
	while read dns; do
		ip route del $(echo $dns | awk '{print $2}') dev $dev
	done < $VPN_RESOLVF
	# Remove vpn resolv file
	rm -fr "$VPN_RESOLVF" >/dev/null 2>&1
	rm -fr "$DEF_RESOLVF" >/dev/null 2>&1
	logger -t $(basename $0)[$$] -p user.notice "Default DNS server(s) restored"
exit 0
#) 2>&1 | logger -t $(basename $0)[$$] &

The problem, as I now see it, is that --route-up, --route-pre-down and --ipchange are not working.
It looks like this patch has been adding these options but a large part of the infrastructure to deal with this is missing.

I am looking into it and trying to add the necessary infrastructure so that those options can be used again, but it is rather complicated so do not hold your breath.

I have made a pull-request with an idea to solve this.

Hopefully it is good enough to be accepted so that we can use --route-up , --route-pre-down and --ipchange (only for client) events in the openvpn config file again.

Edit (3 jan-2024):
The patch I submitted has been accepted, so Main build you should be good.

I will see if I can get this backported to 23.05.2

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.