OpenVPN auto connect

I’m trying to enable OpenVPN autoconnection with Gnome/NetworkManager/systemd-resolved. My server pushes DNS search domains. I have tried services.openvpn.servers approach, but it didn’t update systemd-resolved configs.

Now I’m trying to setup NetworkManager dispatcher to start VPN when new connection is up:

systemd = {
  services = {
    NetworkManager-dispatcher = {
      path = [
        pkgs.networkmanager
      ];
    };
  };
};
networking = {
  networkmanager = {
    dispatcherScripts = [
      {
        source = pkgs.writeText "upHook" ''
          #!${pkgs.bash}/bin/bash
          VPN_CONN_NAME="MyVPN"

          if [ -z "''${1:-}" ]; then exit 0; fi # check if interface name is defined
          if [ "$1" = "$VPN_CONN_NAME" ]; then exit 0; fi # check if interface is not VPN
          if [ "$2" != "up" ]; then exit 0; fi # execute ony if interface became up

          ip -d link show "$1" | grep -qE 'link/(none|ipip|gre)|tunnel type'
          INTERFACE_IS_NOT_TUNNEL=$?
          if [ "$INTERFACE_IS_NOT_TUNNEL" = 0 ]; then exit 0; fi # ignore tunnel interfaces

          nmcli connection up "$VPN_CONN_NAME"
        '';
        type = "basic";
      }
    ];
  };
};

It kind of works - connecton is established but pulling DHCP options from server fails:

oct 20 15:48:37 my-hostname dbus-daemon[1223]: [system] Activating via systemd: service name='org.freedesktop.nm_dispatcher' unit='dbus-org.freedesktop.nm-dispatcher.service' requested by ':1.16' (uid=0 pid=1431 comm="/nix/store/dbb14yjxbhlh65izylnwnkz2647ylzis-networ")
oct 20 15:48:37 my-hostname systemd-resolved[1179]: enp104s0f0u1: Bus client set default route setting: yes
oct 20 15:48:37 my-hostname systemd-resolved[1179]: enp104s0f0u1: Bus client set DNS server list to: x.x.x.x
oct 20 15:48:37 my-hostname systemd[1]: Starting Network Manager Script Dispatcher Service...
oct 20 15:48:37 my-hostname dbus-daemon[1223]: [system] Successfully activated service 'org.freedesktop.nm_dispatcher'
oct 20 15:48:37 my-hostname systemd[1]: Started Network Manager Script Dispatcher Service.
oct 20 15:48:38 my-hostname nm-openvpn[13623]: OpenVPN 2.6.14 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] [DCO]
oct 20 15:48:38 my-hostname nm-openvpn[13623]: library versions: OpenSSL 3.4.2 1 Jul 2025, LZO 2.10
oct 20 15:48:38 my-hostname nm-openvpn[13623]: DCO version: N/A
oct 20 15:48:38 my-hostname nm-openvpn[13623]: WARNING: No server certificate verification method has been enabled.  See http://openvpn.net/howto.html#mitm for more info.
oct 20 15:48:38 my-hostname nm-openvpn[13623]: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
oct 20 15:48:38 my-hostname nm-openvpn[13623]: TCP/UDP: Preserving recently used remote address: [AF_INET]:y.y.y.y::15695
oct 20 15:48:38 my-hostname nm-openvpn[13623]: UDPv4 link local: (not bound)
oct 20 15:48:38 my-hostname nm-openvpn[13623]: UDPv4 link remote: [AF_INET]:y.y.y.y::15695
oct 20 15:48:38 my-hostname nm-openvpn[13623]: NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
oct 20 15:48:39 my-hostname nm-openvpn[13623]: [server] Peer Connection Initiated with [AF_INET]:y.y.y.y::15695
oct 20 15:48:39 my-hostname nm-openvpn[13623]: TUN/TAP device tun9 opened
oct 20 15:48:39 my-hostname nm-openvpn[13623]: /nix/store/1nj3qgpwws1838b1slwa2mnpwli20bf1-NetworkManager-openvpn-1.12.0/libexec/nm-openvpn-service-openvpn-helper --debug 0 13618 --bus-name org.freedesktop.NetworkManager.openvpn.Connection_12 --tun -- tun9 1500 0 z.z.z.z 255.255.255.0 init
oct 20 15:48:39 my-hostname nm-openvpn[13623]: UID set to nm-openvpn
oct 20 15:48:39 my-hostname nm-openvpn[13623]: GID set to nm-openvpn
oct 20 15:48:39 my-hostname nm-openvpn[13623]: Capabilities retained: CAP_NET_ADMIN
oct 20 15:48:39 my-hostname nm-openvpn[13623]: Initialization Sequence Completed
oct 20 15:48:39 my-hostname systemd-resolved[1179]: enp104s0f0u1: Bus client set DNS server list to: x.x.x.x, ::
oct 20 15:48:40 my-hostname boltd[1221]: probing: timeout, done: [2990891] (2000000)
oct 20 15:48:41 my-hostname ModemManager[2353]: <msg> [base-manager] couldn't check support for device '/sys/devices/pci0000:00/0000:00:08.3/0000:68:00.0/usb3/3-1': not supported by any plugin
oct 20 15:50:09 my-hostname nm-dispatcher[13583]: req:4 'up' [enp104s0f0u1], "/etc/NetworkManager/dispatcher.d/03userscript0001": complete: process failed with Script '/etc/NetworkManager/dispatcher.d/03userscript0001' exited with status 3
oct 20 15:50:09 my-hostname NetworkManager[1431]: <warn>  [1760968209.0645] dispatcher: (63) /etc/NetworkManager/dispatcher.d/03userscript0001 failed (failed): Script '/etc/NetworkManager/dispatcher.d/03userscript0001' exited with status 3
oct 20 15:50:09 my-hostname systemd-resolved[1179]: tun9: Bus client set search domain list to: example.com, example.co.uk
oct 20 15:50:09 my-hostname systemd-resolved[1179]: tun9: Bus client set default route setting: no
oct 20 15:50:09 my-hostname systemd-resolved[1179]: tun9: Bus client set DNS server list to: <some IPs>
oct 20 15:50:19 my-hostname systemd[1]: NetworkManager-dispatcher.service: Deactivated successfully.

As you can see nmcli connection up fails. It’s nice that NM retries and connection is set up properly in the end but obviously something goes wrong. If I start connection from Gnome GUI or execute this script manually (with sudo or without) connection is established in a blink of the eye:

oct 20 16:19:13 my-hostname nm-openvpn[15116]: OpenVPN 2.6.14 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] [DCO]
oct 20 16:19:13 my-hostname nm-openvpn[15116]: library versions: OpenSSL 3.4.2 1 Jul 2025, LZO 2.10
oct 20 16:19:13 my-hostname nm-openvpn[15116]: DCO version: N/A
oct 20 16:19:13 my-hostname nm-openvpn[15116]: WARNING: No server certificate verification method has been enabled.  See http://openvpn.net/howto.html#mitm for more info.
oct 20 16:19:13 my-hostname nm-openvpn[15116]: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
oct 20 16:19:13 my-hostname nm-openvpn[15116]: TCP/UDP: Preserving recently used remote address: [AF_INET]:y.y.y.y::15695
oct 20 16:19:13 my-hostname nm-openvpn[15116]: UDPv4 link local: (not bound)
oct 20 16:19:13 my-hostname nm-openvpn[15116]: UDPv4 link remote: [AF_INET]:y.y.y.y::15695
oct 20 16:19:13 my-hostname nm-openvpn[15116]: NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
oct 20 16:19:13 my-hostname nm-openvpn[15116]: [server] Peer Connection Initiated with [AF_INET]:y.y.y.y::15695
oct 20 16:19:13 my-hostname nm-openvpn[15116]: TUN/TAP device tun9 opened
oct 20 16:19:13 my-hostname nm-openvpn[15116]: /nix/store/1nj3qgpwws1838b1slwa2mnpwli20bf1-NetworkManager-openvpn-1.12.0/libexec/nm-openvpn-service-openvpn-helper --debug 0 15111 --bus-name org.freedesktop.NetworkManager.openvpn.Connection_17 --tun -- tun9 1500 0 z.z.z.z 255.255.255.0 init
oct 20 16:19:14 my-hostname nm-openvpn[15116]: UID set to nm-openvpn
oct 20 16:19:14 my-hostname nm-openvpn[15116]: GID set to nm-openvpn
oct 20 16:19:14 my-hostname nm-openvpn[15116]: Capabilities retained: CAP_NET_ADMIN
oct 20 16:19:14 my-hostname nm-openvpn[15116]: Initialization Sequence Completed
oct 20 16:19:14 my-hostname dbus-daemon[1223]: [system] Activating via systemd: service name='org.freedesktop.nm_dispatcher' unit='dbus-org.freedesktop.nm-dispatcher.service' requested by ':1.16' (uid=0 pid=1431 comm="/nix/store/dbb14yjxbhlh65izylnwnkz2647ylzis-networ")
oct 20 16:19:14 my-hostname systemd[1]: Starting Network Manager Script Dispatcher Service...
oct 20 16:19:14 my-hostname dbus-daemon[1223]: [system] Successfully activated service 'org.freedesktop.nm_dispatcher'
oct 20 16:19:14 my-hostname systemd[1]: Started Network Manager Script Dispatcher Service.
oct 20 16:19:14 my-hostname systemd-resolved[1179]: tun9: Bus client set search domain list to: example.com, example.co.uk
oct 20 16:19:14 my-hostname systemd-resolved[1179]: tun9: Bus client set default route setting: no
oct 20 16:19:14 my-hostname systemd-resolved[1179]: tun9: Bus client set DNS server list to: <some IPs>

I would be very grateful for some advice how to solve this issue or for better approach to this problem :slight_smile:

EDIT: Notice lag before systemd-resolved update in the broken case. My guess is that nm-dispatcher is missing some dependency (like systemd or dbus but adding them to path dodn’t fix the issue.