Page MenuHomeVyOS Platform

OpenVPN op_mode tools broken
Open, Requires assessmentPublicBUG

Description

Most of them don’t return anything, even when a tunnel is up. Some return errors:

Traceback (most recent call last):
  File "/usr/libexec/vyos/op_mode/show_openvpn.py", line 152, in <module>
    data = get_status(args.mode, intf)
  File "/usr/libexec/vyos/op_mode/show_openvpn.py", line 66, in get_status
    with open(status_file, 'r') as f:
FileNotFoundError: [Errno 2] No such file or directory: '/opt/vyatta/etc/openvpn/status/vtun1.status'

Details

Difficulty level
Unknown (require assessment)
Version
1.3
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Unspecified (possibly destroys the router)

Event Timeline

kroy created this task.
jjakob added a subscriber: jjakob.Mar 31 2020, 4:48 AM

While you're looking at it, can you try to move it to a systemd service? I opened a task for discussion: T2185

pasik added a subscriber: pasik.Mar 31 2020, 6:57 AM

Thank you for the assignment but I have not looked at or touched the OpenVPN code (and never used OpenVPN myself).
This issue with the op_mode, not config mode, so so it must have been there for a while.
I could change the code to check that the file exist, and prevent this fault but I am not sure it would be the right thing todo.

The file exists on my system (1.3-rolling-202003291001):

-rw------- 1 root root 377 Mar 31 11:44 /opt/vyatta/etc/openvpn/status/vtun0.status

and show openvpn server works:

vyos@rt-home:~$ show openvpn server 

OpenVPN status on vtun0

Client CN       Remote Host           Local Host            TX bytes    RX bytes   Connected Since
---------       -----------           ----------            --------    --------   ---------------
client          v.v.v.v:42663         N/A                   7.9 GB      428.5 MB   Sun Mar 29 20:39:43 2020

What I see in op_mode/show_openvpn.py is that it takes a list of all vtun interfaces, but doesn't check if they're disabled. This would cause the above error.

@jjakob if what you say is correct then the solution should look like. I can not test it tho (simply as I do not know how to setup OpenVPN and have no lab to make it work).

diff --git a/src/op_mode/show_openvpn.py b/src/op_mode/show_openvpn.py
index 06b9029..d9d7872 100755
--- a/src/op_mode/show_openvpn.py
+++ b/src/op_mode/show_openvpn.py
@@ -20,6 +20,7 @@ import argparse

 from sys import exit
 from vyos.config import Config
+from vyos.ifconfig import Interface

 outp_tmpl = """
 {% if clients %}
@@ -149,6 +150,8 @@ if __name__ == '__main__':
             interfaces.append(intf)

     for intf in interfaces:
+        if Interface(intf, debug=False).get_oper_state() != 'up':
+            continue
         data = get_status(args.mode, intf)
         local_host = config.return_effective_value('interfaces openvpn {} local-host'.format(intf))
         local_port = config.return_effective_value('interfaces openvpn {} local-port'.format(intf))
c-po added a subscriber: c-po.Mar 31 2020, 4:42 PM

Why must the operstate be up? I't rather check if the tunnel is configured (/opt/vyatta/etc/openvpn/status/vtun1.something) exists and then run the commands.
Thus if the tunnel is down due to remote end beeing offline it would not report it as operstate is down (if operstate is properly implemented in OpenVPN)

@cpo is it what you have in mind:

diff --git a/src/op_mode/show_openvpn.py b/src/op_mode/show_openvpn.py
index 06b9029..32918dd 100755
--- a/src/op_mode/show_openvpn.py
+++ b/src/op_mode/show_openvpn.py
@@ -15,6 +15,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #

+import os
 import jinja2
 import argparse

@@ -63,6 +64,9 @@ def get_status(mode, interface):
         'clients': [],
     }

+    if not os.path.exists(status_file):
+        return data
+
     with open(status_file, 'r') as f:
         lines = f.readlines()
         for line_no, line in enumerate(lines):

I would check in main, before get_status, if a interface is disabled in config, then I'd just print "vtunX is disabled" and skip all other processing for that interface. If a interface is enabled but its status file isn't readable, print "Error: status file for vtunX is not readable" (I'd use try/except around the open in get_status, and return a exception so that main can print the error).

As indicated, I could not test this patch.

@jjakob can we close this task ?

jjakob added a comment.EditedApr 27 2020, 7:20 PM

They're still broken here. Maybe a different bug. It would be nice to switch to 'status-version' 2 or 3 too for more info.

vyos@rt-home:~$ show openvpn server 

vyos@rt-home:~$ ps afx|grep vpn
 2299 ?        Ss     0:02 /usr/sbin/openvpn --daemon openvpn-vtun1 --config vtun1.conf --status vtun1.status 30 --writepid vtun1.pid
 2346 ?        Ss     0:02 /usr/sbin/openvpn --daemon openvpn-vtun2 --config vtun2.conf --status vtun2.status 30 --writepid vtun2.pid
 2415 ?        Ss    16:31 /usr/sbin/openvpn --daemon openvpn-vtun0 --config vtun0.conf --status vtun0.status 30 --writepid vtun0.pid
11021 pts/0    S+     0:00  |           \_ grep vpn
vyos@rt-home:~$ show openvpn site-to-site 

vyos@rt-home:~$

@jjakob sorry for wasting your time here :-( I will try to replicate.

vyos@vyos:~$ show interfaces openvpn vtun1
vtun1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 127.0.0.1 peer 10.255.1.2/32 scope host vtun1
       valid_lft forever preferred_lft forever
    inet6 fe80::a6ba:dc03:94c5:6b42/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

    RX:  bytes  packets  errors  dropped  overrun       mcast
             0        0       0        0        0           0
    TX:  bytes  packets  errors  dropped  carrier  collisions
           380        5       0        0        0           0

vyos@vyos:~$ show openvpn server

vyos@vyos:~$ ps afx|grep vpn
 3855 pts/0    S+     0:00              \_ grep vpn
 3436 ?        Ss     0:00 /usr/sbin/openvpn --daemon openvpn-vtun1 --config vtun1.conf --status vtun1.status 30 --writepid vtun1.pid

vyos@vyos:~$ show openvpn site-to-site
vyos@vyos:~$ show configuration commands | grep interf | grep -v stuff
set interfaces ethernet eth0 address 'dhcp'
set interfaces ethernet eth2 hw-id '08:00:27:b0:d2:dc'
set interfaces ethernet eth3 address '111.0.0.1/24'
set interfaces ethernet eth3 hw-id '08:00:27:7d:b4:d1'
set interfaces loopback lo
set interfaces openvpn vtun1 local-address 127.0.0.1
set interfaces openvpn vtun1 local-host '111.0.0.1'
set interfaces openvpn vtun1 local-port '1195'
set interfaces openvpn vtun1 mode 'site-to-site'
set interfaces openvpn vtun1 persistent-tunnel
set interfaces openvpn vtun1 protocol 'udp'
set interfaces openvpn vtun1 remote-address '10.255.1.2'
set interfaces openvpn vtun1 remote-port '1195'
set interfaces openvpn vtun1 shared-secret-key-file '/config/auth/openvpn-1.key'

Wrong location of status file - it was moved to /run/openvpn