OpenVPN on Debian – Fix Connection Rejection and systemd Issues

debianopenvpnsystemd

I'm extremely confused by this, and it seems completely wrong but I have no idea how so I'll start from the beginning.

I configured openvpn on my Debian server using this guide. After I copied the necessary files over to my archlinux desktop and attempted to run the script, I noticed the connection just timed out:

$ openvpn server.ovpn
Thu Aug  2 18:50:29 2018 OpenVPN 2.4.6 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Apr 24 2018
Thu Aug  2 18:50:29 2018 library versions: OpenSSL 1.1.0h  27 Mar 2018, LZO 2.10
Thu Aug  2 18:50:29 2018 TCP/UDP: Preserving recently used remote address: [AF_INET]<server-ip>:1194
Thu Aug  2 18:50:29 2018 Socket Buffers: R=[212992->212992] S=[212992->212992]
Thu Aug  2 18:50:29 2018 UDP link local: (not bound)
Thu Aug  2 18:50:29 2018 UDP link remote: [AF_INET]<server-ip>:1194
Thu Aug  2 18:50:29 2018 NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
Thu Aug  2 18:51:29 2018 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Thu Aug  2 18:51:29 2018 TLS Error: TLS handshake failed
Thu Aug  2 18:51:29 2018 SIGUSR1[soft,tls-error] received, process restarting
Thu Aug  2 18:51:29 2018 Restart pause, 5 second(s)
^CThu Aug  2 18:51:32 2018 SIGINT[hard,init_instance] received, process exiting

I thought it might be a firewall issue so I decided to temporarily drop my firewall while I tested this, but no luck (I've done this on both my client and my server):

$ sudo iptables -L -v
Chain INPUT (policy ACCEPT 15 packets, 1056 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 8 packets, 768 bytes)
 pkts bytes target     prot opt in     out     source               destination

I decided to make sure I was actually attempting to make a connection, so I opened wireshark and saw this:

1   <my-ip>         <server-ip> OpenVPN 56  MessageType: P_CONTROL_HARD_RESET_CLIENT_V2
2   <server-ip>     <my-ip>     ICMP    84  Destination unreachable (Port unreachable)
3   <my-ip>         <server-ip> OpenVPN 56  MessageType: P_CONTROL_HARD_RESET_CLIENT_V2
4   <server-ip>     <my-ip>     ICMP    84  Destination unreachable (Port unreachable)
15  <my-ip>         <server-ip> OpenVPN 56  MessageType: P_CONTROL_HARD_RESET_CLIENT_V2
16  <server-ip>     <my-ip>     ICMP    84  Destination unreachable (Port unreachable)
29  <my-ip>         <server-ip> OpenVPN 56  MessageType: P_CONTROL_HARD_RESET_CLIENT_V2
32  <server-ip>     <my-ip>     ICMP    84  Destination unreachable (Port unreachable)
51  <my-ip>         <server-ip> OpenVPN 56  MessageType: P_CONTROL_HARD_RESET_CLIENT_V2
52  <server-ip>     <my-ip>     ICMP    84  Destination unreachable (Port unreachable)

Since I know there's no firewall rule blocking it, I went to see if open vpn is even, running:

$ sudo lsof -i | grep -i vpn
$ sudo ps ax | grep -i vpn
19969 pts/0    S+     0:00 grep -i vpn

Nothing comes back. I check the systemd to make sure it didn't crash:

$ systemctl status openvpn
● openvpn.service - OpenVPN service
   Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor preset: enabled)
   Active: active (exited) since Thu 2018-08-02 09:37:24 CDT; 11h ago
  Process: 12769 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 12769 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 4915)
   CGroup: /system.slice/openvpn.service

It says it exited success, but then I noticed, "ExecStart=/bin/true". What the heck? I open up the service file, and see this:

$ cat /lib/systemd/system/openvpn.service
# This service is actually a systemd target,
# but we are using a service since targets cannot be reloaded.

[Unit]
Description=OpenVPN service
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecReload=/bin/true
WorkingDirectory=/etc/openvpn

[Install]
WantedBy=multi-user.target

I admit, openvpn is a complex piece of software I don't fully understand, but how is ExecStart=/bin/true correct? I have a hard time believing this is just a placeholder that somehow made it into production since someone much smarter than I would have caught it by now, but I just don't understand. What is the point of this and how do I make openvpn wait to preform the handshake?

Best Answer

I admit, openvpn is a complex piece of software I don't fully understand, but how is ExecStart=/bin/true correct?

This isn't a feature of OpenVPN really, instead it is a feature of systemd. On most systems with systemd, OpenVPN will ship with a template unit and a generator. This allows your system to support multiple OpenVPN instances and for systemd to montitor and control each VPN separately

On Debian systems the template unit you would want to look at is here. /lib/systemd/system/openvpn@.service, and the generator is here /lib/systemd/system-generators/openvpn-generator.

That template unit has a ExecStart like this.

ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid

For example on my system I have a couple VPN configs running

# systemctl list-units | grep openvpn
openvpn.service                 loaded active exited    OpenVPN service                                                              
openvpn@zoredachesrv.service    loaded active running   OpenVPN connection to zoredachesrv                                              
openvpn@p2p-to-valiant.service  loaded active running   OpenVPN connection to p2p-to-valiant   

You can query an individual openvpn instances with a command like systemctl status openvpn@zoredachesrv.service.

If you just added this configuration, you might have to use systemctl daemon-reload for systemd to recognize the new units.

If your configuration is literally named 'server.conf' and that isn't obfuscated then you would use systemctl status openvpn@server.service

As for troubleshooting your problem, I would suggest you examine you check if openvpn is running and has a socket open lsof -ni | grep openvpn. Then also check to see what OpenVPN has reported errors or anything to your system log grep openvpn /var/log/syslog | tail -50. One of these two things should give you a hint about what is going on.