summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2019-09-06 18:09:50 +0200
committerChristian Poessinger <christian@poessinger.com>2019-09-06 18:09:52 +0200
commit26ace9a7b92020bffebe85897cd3790342820612 (patch)
treec67e50c7773bc59c0cd4fd7577809066ed9e58d1
parent2e3b701f9045c4a557c99ee311c11d4a6f4f7b78 (diff)
downloadvyos-1x-26ace9a7b92020bffebe85897cd3790342820612.tar.gz
vyos-1x-26ace9a7b92020bffebe85897cd3790342820612.zip
openvpn: T1548: always restart OpenVPN
Previous implementations sent a SIGUSR1 to OpenVPN to initialte a restart after the configuration changed - as this was the same as the client keepalive mechanism did. Unfortunately on SIGUSR1 OpenVPN does not re-read the configuration file. Thus changed options were never taken into account.
-rwxr-xr-xsrc/conf_mode/interface-openvpn.py54
1 files changed, 27 insertions, 27 deletions
diff --git a/src/conf_mode/interface-openvpn.py b/src/conf_mode/interface-openvpn.py
index fe08cd51e..548c78535 100755
--- a/src/conf_mode/interface-openvpn.py
+++ b/src/conf_mode/interface-openvpn.py
@@ -25,10 +25,11 @@ import jinja2
from copy import deepcopy
from grp import getgrnam
from ipaddress import ip_address,ip_network,IPv4Interface
+from netifaces import interfaces
from psutil import pid_exists
from pwd import getpwnam
-from signal import SIGUSR1
from subprocess import Popen, PIPE
+from time import sleep
from vyos.config import Config
from vyos import ConfigError
@@ -819,47 +820,46 @@ def generate(openvpn):
return None
def apply(openvpn):
- interface = openvpn['intf']
-
pid = 0
- pidfile = '/var/run/openvpn/{}.pid'.format(interface)
+ pidfile = '/var/run/openvpn/{}.pid'.format(openvpn['intf'])
if os.path.isfile(pidfile):
pid = 0
with open(pidfile, 'r') as f:
pid = int(f.read())
- # If tunnel interface has been deleted - stop service
- if openvpn['deleted'] or openvpn['disable']:
- directory = os.path.dirname(get_config_name(interface))
-
- # we only need to stop the demon if it's running
- # daemon could have died or killed by someone
- if pid_exists(pid):
- cmd = 'start-stop-daemon --stop --quiet'
- cmd += ' --pidfile ' + pidfile
- subprocess_cmd(cmd)
+ # Always stop OpenVPN service. We can not send a SIGUSR1 for restart of the
+ # service as the configuration is not re-read. Stop daemon only if it's
+ # running - it could have died or killed by someone evil
+ if pid_exists(pid):
+ cmd = 'start-stop-daemon --stop --quiet'
+ cmd += ' --pidfile ' + pidfile
+ subprocess_cmd(cmd)
- # cleanup old PID file
- if os.path.isfile(pidfile):
- os.remove(pidfile)
+ # cleanup old PID file
+ if os.path.isfile(pidfile):
+ os.remove(pidfile)
+ # Do some cleanup when OpenVPN is disabled/deleted
+ if openvpn['deleted'] or openvpn['disable']:
# cleanup old configuration file
- if os.path.isfile(get_config_name(interface)):
- os.remove(get_config_name(interface))
+ if os.path.isfile(get_config_name(openvpn['intf'])):
+ os.remove(get_config_name(openvpn['intf']))
# cleanup client config dir
- if os.path.isdir(directory + '/ccd/' + interface):
+ directory = os.path.dirname(get_config_name(openvpn['intf']))
+ if os.path.isdir(directory + '/ccd/' + openvpn['intf']):
try:
- os.remove(directory + '/ccd/' + interface + '/*')
+ os.remove(directory + '/ccd/' + openvpn['intf'] + '/*')
except:
pass
return None
- # Send SIGUSR1 to the process instead of creating a new process
- if pid_exists(pid):
- os.kill(pid, SIGUSR1)
- return None
+ # On configuration change we need to wait for the 'old' interface to
+ # vanish from the Kernel, if it is not gone, OpenVPN will report:
+ # ERROR: Cannot ioctl TUNSETIFF vtun10: Device or resource busy (errno=16)
+ while openvpn['intf'] in interfaces():
+ sleep(0.250) # 250ms
# No matching OpenVPN process running - maybe it got killed or none
# existed - nevertheless, spawn new OpenVPN process
@@ -868,13 +868,13 @@ def apply(openvpn):
cmd += ' --exec /usr/sbin/openvpn'
# now pass arguments to openvpn binary
cmd += ' --'
- cmd += ' --config ' + get_config_name(interface)
+ cmd += ' --config ' + get_config_name(openvpn['intf'])
# execute assembled command
subprocess_cmd(cmd)
-
return None
+
if __name__ == '__main__':
try:
c = get_config()