Solved Mullvad via openvpn - up could not execute external program

I'm new to FreeBSD and am trying to connect to Mullvad VPN using OpenVPN.

When running 'sudo openvpn --config <mullvad config>', I get as an error:

Code:
2021-04-20 22:26:00 us=458140 /usr/local/etc/openvpn/update-resolv-conf tun0 1
500 1552 10.15.0.7 255.255.0.0 init
2021-04-20 22:26:00 us=459080 WARNING: Failed running command (--up/--down): c
ould not execute external program
2021-04-20 22:26:00 us=459103 Exiting due to fatal error

Permissions for the files and folders (/usr/local/etc/openvpn/):

Code:
drwxr-xr-x   2 root  wheel     7B Apr 20 22:25 .
drwxr-xr-x  39 root  wheel    69B Apr 20 20:57 ..
-rw-r--r--   1 root  wheel   982B Apr 20 22:25 mullvad_XX_all.conf
-rw-r--r--   1 root  wheel   2.1K Apr 20 20:26 mullvad_ca.crt
-rw-r--r--   1 root  wheel    19B Apr 20 20:26 mullvad_userpass.txt
-rwxrwxrwx   1 root  wheel   1.3K Apr 20 22:21 update-resolv-conf

In the Mullvad config file I changed the location of the script:
  • from '/etc/openvpn/update-resolv-conf'
  • to '/usr/local/etc/openvpn/update-resolv-conf'
The script is a bash script and bash is installed.

How can I get better error messaging to debug this? Does anyone had similar issues? Also, is there an easier option to connect to a vpn on FreeBSD?

Thanks heaps!
 
This is not a good answer. I've come across to routes in OpenVPN and there are two options. Either the OpenVPN sets the routes using OS commands or the route addition is delegated to the "up" and "down" scripts. Either you wan't to pull the routes from the host or set them you self. These are the "--route-noexec" and "--route-nopull" from man openvpn. This was not a good answer - it could be the case here as well (could), I hope it helps. e
 

SirDice

Administrator
Staff member
Administrator
Moderator
Code:
-rwxrwxrwx 1 root wheel 1.3K Apr 20 22:21 update-resolv-conf

Please stop setting 777 permissions on something when you think it's a permission issue. You have no idea how dangerous that is. Set some proper permissions on it like 755.

And in order for OpenVPN to allow the up/down scripts to run you will need to set script-security 2.

Code:
  --script-security level
	      This  directive offers policy-level control over OpenVPN's usage
	      of external programs and scripts.	 Lower level values  are  more
	      restrictive,  higher  values  are	more permissive.  Settings for
	      level:

	      0	-- Strictly no calling of external programs.
	      1	-- (Default) Only call built-in	executables such as  ifconfig,
	      ip, route, or netsh.
	      2	 --  Allow  calling  of	 built-in executables and user-defined
	      scripts.
	      3	-- Allow passwords to be passed	to scripts  via	 environmental
	      variables	(potentially unsafe).
See openvpn(8).
 

SirDice

Administrator
Staff member
Administrator
Moderator
This was done in desperation as a trial.
Write permissions have nothing to do with being able to read or execute something. You should really read up on unix permissions, if you understand them you will also understand why 777 is dangerous and useless in pretty much all cases.
 
script-security 2 is set.

Code:
# mullvad-...-all.conf
...
proto udp
auth-user-pass mullvad_userpass.txt
ca mullvad_ca.crt
tun-ipv6
script-security 2
up /usr/local/etc/openvpn/update-resolv-conf
down /usr/local/etc/openvpn/update-resolv-conf
fast-io
...


And in order for OpenVPN to allow the up/down scripts to run you will need to set script-security 2.

Code:
  --script-security level
          This  directive offers policy-level control over OpenVPN's usage
          of external programs and scripts.     Lower level values  are  more
          restrictive,  higher  values  are    more permissive.  Settings for
          level:

          0    -- Strictly no calling of external programs.
          1    -- (Default) Only call built-in    executables such as  ifconfig,
          ip, route, or netsh.
          2     --  Allow  calling  of     built-in executables and user-defined
          scripts.
          3    -- Allow passwords to be passed    to scripts  via     environmental
          variables    (potentially unsafe).
See openvpn(8).
 
Apologies, I copied the wrong config file. It's actually in /usr/local/etc/openvpn/, as mentioned in the original post. Still no success... I'll edit the last answer to show this correctly

This stuff doesn't belong in /etc/. It should go in /usr/local/etc/openvpn.
 

SirDice

Administrator
Staff member
Administrator
Moderator
Can you post the script itself? It might fail because the script itself fails for some reason.
 
Can you post the script itself? It might fail because the script itself fails for some reason.

GNU bash 5.1.4 is installed. When running the script in as a cli ("bash update-resolv-conf"), it terminates with no error (assuming it stops in the first three lines... not a bash expert..)


Code:
#!/bin/bash
#
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#
# Used snippets of resolvconf script by Thomas Hood and Chris Hanson.
# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL.
#
# Example envs set from openvpn:
#
#     foreign_option_1='dhcp-option DNS 193.43.27.132'
#     foreign_option_2='dhcp-option DNS 193.43.27.133'
#     foreign_option_3='dhcp-option DOMAIN be.bnc.ch'
#

[ -x /sbin/resolvconf ] || exit 0
[ "$script_type" ] || exit 0
[ "$dev" ] || exit 0

split_into_parts()
{
    part1="$1"
    part2="$2"
    part3="$3"
}

case "$script_type" in
  up)
    NMSRVRS=""
    SRCHS=""
    for optionvarname in ${!foreign_option_*} ; do
        option="${!optionvarname}"
        echo "$option"
        split_into_parts $option
        if [ "$part1" = "dhcp-option" ] ; then
            if [ "$part2" = "DNS" ] ; then
                NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
            elif [ "$part2" = "DOMAIN" ] ; then
                SRCHS="${SRCHS:+$SRCHS }$part3"
            fi
        fi
    done
    R=""
    [ "$SRCHS" ] && R="search $SRCHS
"
    for NS in $NMSRVRS ; do
            R="${R}nameserver $NS
"
    done
    echo -n "$R" | /sbin/resolvconf -a "${dev}.openvpn"
    ;;
  down)
    /sbin/resolvconf -d "${dev}.openvpn"
    ;;
esac
 

SirDice

Administrator
Staff member
Administrator
Moderator
It was the script she-bang that needed to be changed to #!/usr/local/bin/bash.
Yes, there is no /bin/bash on FreeBSD. Looking at the script itself I see no reason to use bash at all actually. You can probably use #!/bin/sh without a problem too.
 
Top