summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/openvpn/server.conf.tmpl13
-rw-r--r--data/templates/openvpn/service-override.conf.tmpl20
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py14
-rwxr-xr-xsrc/conf_mode/vpn_sstp.py40
-rw-r--r--src/etc/systemd/system/openvpn@.service.d/10-override.conf (renamed from src/etc/systemd/system/openvpn@.service.d/override.conf)0
5 files changed, 56 insertions, 31 deletions
diff --git a/data/templates/openvpn/server.conf.tmpl b/data/templates/openvpn/server.conf.tmpl
index bc2790965..7a0470d0e 100644
--- a/data/templates/openvpn/server.conf.tmpl
+++ b/data/templates/openvpn/server.conf.tmpl
@@ -224,16 +224,3 @@ auth {{ hash }}
auth-user-pass {{ auth_user_pass_file }}
auth-retry nointeract
{% endif %}
-
-{% if openvpn_option is defined and openvpn_option is not none %}
-#
-# Custom options added by user (not validated)
-#
-{% for option in openvpn_option %}
-{% for argument in option.split('--') %}
-{% if argument is defined and argument != '' %}
---{{ argument }}
-{% endif %}
-{% endfor %}
-{% endfor %}
-{% endif %}
diff --git a/data/templates/openvpn/service-override.conf.tmpl b/data/templates/openvpn/service-override.conf.tmpl
new file mode 100644
index 000000000..069bdbd08
--- /dev/null
+++ b/data/templates/openvpn/service-override.conf.tmpl
@@ -0,0 +1,20 @@
+[Service]
+ExecStart=
+ExecStart=/usr/sbin/openvpn --daemon openvpn-%i --config %i.conf --status %i.status 30 --writepid %i.pid
+{%- if openvpn_option is defined and openvpn_option is not none %}
+{% for option in openvpn_option %}
+{# Remove the '--' prefix from variable if it is presented #}
+{% if option.startswith('--') %}
+{% set option = option.split('--', maxsplit=1)[1] %}
+{% endif %}
+{# Workaround to pass '--push' options properly. Previously openvpn accepted this option without values in double-quotes #}
+{# But now it stopped doing this, so we need to add them for compatibility #}
+{# HOWEVER! This is a raw option and we do not promise that this or any other trick will work for all the cases. #}
+{# Using 'openvpn-option' you take all responsibility for compatibility for yourself. #}
+{% if option.startswith('push') and not (option.startswith('push "') and option.endswith('"')) %}
+{% set option = 'push \"%s\"'|format(option.split('push ', maxsplit=1)[1]) %}
+{% endif %}
+ --{{ option }}
+{%- endfor %}
+{% endif %}
+
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 7f4aa367f..735b39ba3 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -66,6 +66,7 @@ cfg_file = '/run/openvpn/{ifname}.conf'
otp_path = '/config/auth/openvpn'
otp_file = '/config/auth/openvpn/{ifname}-otp-secrets'
secret_chars = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
+service_file = '/run/systemd/system/openvpn@{ifname}.service.d/20-override.conf'
def get_config(config=None):
"""
@@ -98,7 +99,7 @@ def get_config(config=None):
# originate comes with defaults, which will enable the
# totp plugin, even when not set via CLI so we
# need to check this first and drop those keys
- if 'totp' not in tmp_openvpn['server']:
+ if dict_search('server.totp', tmp_openvpn) == None:
del openvpn['server']['mfa']['totp']
return openvpn
@@ -584,6 +585,11 @@ def generate(openvpn):
if os.path.isdir(ccd_dir):
rmtree(ccd_dir, ignore_errors=True)
+ # Remove systemd directories with overrides
+ service_dir = os.path.dirname(service_file.format(**openvpn))
+ if os.path.isdir(service_dir):
+ rmtree(service_dir, ignore_errors=True)
+
if 'deleted' in openvpn or 'disable' in openvpn:
return None
@@ -619,6 +625,12 @@ def generate(openvpn):
render(cfg_file.format(**openvpn), 'openvpn/server.conf.tmpl', openvpn,
formater=lambda _: _.replace(""", '"'), user=user, group=group)
+ # Render 20-override.conf for OpenVPN service
+ render(service_file.format(**openvpn), 'openvpn/service-override.conf.tmpl', openvpn,
+ formater=lambda _: _.replace(""", '"'), user=user, group=group)
+ # Reload systemd services config to apply an override
+ call(f'systemctl daemon-reload')
+
return None
def apply(openvpn):
diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py
index 68139dc47..68980e5ab 100755
--- a/src/conf_mode/vpn_sstp.py
+++ b/src/conf_mode/vpn_sstp.py
@@ -26,6 +26,7 @@ from vyos.pki import wrap_private_key
from vyos.template import render
from vyos.util import call
from vyos.util import dict_search
+from vyos.util import write_file
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -34,6 +35,10 @@ cfg_dir = '/run/accel-pppd'
sstp_conf = '/run/accel-pppd/sstp.conf'
sstp_chap_secrets = '/run/accel-pppd/sstp.chap-secrets'
+cert_file_path = os.path.join(cfg_dir, 'sstp-cert.pem')
+cert_key_path = os.path.join(cfg_dir, 'sstp-cert.key')
+ca_cert_file_path = os.path.join(cfg_dir, 'sstp-ca.pem')
+
def get_config(config=None):
if config:
conf = config
@@ -72,22 +77,32 @@ def verify(sstp):
ssl = sstp['ssl']
+ # CA
if 'ca_certificate' not in ssl:
raise ConfigError('SSL CA certificate missing on SSTP config')
+ ca_name = ssl['ca_certificate']
+
+ if ca_name not in sstp['pki']['ca']:
+ raise ConfigError('Invalid CA certificate on SSTP config')
+
+ if 'certificate' not in sstp['pki']['ca'][ca_name]:
+ raise ConfigError('Missing certificate data for CA certificate on SSTP config')
+
+ # Certificate
if 'certificate' not in ssl:
raise ConfigError('SSL certificate missing on SSTP config')
cert_name = ssl['certificate']
- if ssl['ca_certificate'] not in sstp['pki']['ca']:
- raise ConfigError('Invalid CA certificate on SSTP config')
-
if cert_name not in sstp['pki']['certificate']:
raise ConfigError('Invalid certificate on SSTP config')
pki_cert = sstp['pki']['certificate'][cert_name]
+ if 'certificate' not in pki_cert:
+ raise ConfigError('Missing certificate data for certificate on SSTP config')
+
if 'private' not in pki_cert or 'key' not in pki_cert['private']:
raise ConfigError('Missing private key for certificate on SSTP config')
@@ -98,27 +113,18 @@ def generate(sstp):
if not sstp:
return None
- cert_file_path = os.path.join(cfg_dir, 'sstp-cert.pem')
- cert_key_path = os.path.join(cfg_dir, 'sstp-cert.key')
- ca_cert_file_path = os.path.join(cfg_dir, 'sstp-ca.pem')
+ # accel-cmd reload doesn't work so any change results in a restart of the daemon
+ render(sstp_conf, 'accel-ppp/sstp.config.tmpl', sstp)
cert_name = sstp['ssl']['certificate']
pki_cert = sstp['pki']['certificate'][cert_name]
- with open(cert_file_path, 'w') as f:
- f.write(wrap_certificate(pki_cert['certificate']))
-
- with open(cert_key_path, 'w') as f:
- f.write(wrap_private_key(pki_cert['private']['key']))
-
ca_cert_name = sstp['ssl']['ca_certificate']
pki_ca = sstp['pki']['ca'][ca_cert_name]
- with open(ca_cert_file_path, 'w') as f:
- f.write(wrap_certificate(pki_ca['certificate']))
-
- # accel-cmd reload doesn't work so any change results in a restart of the daemon
- render(sstp_conf, 'accel-ppp/sstp.config.tmpl', sstp)
+ write_file(cert_file_path, wrap_certificate(pki_cert['certificate']))
+ write_file(cert_key_path, wrap_private_key(pki_cert['private']['key']))
+ write_file(ca_cert_file_path, wrap_certificate(pki_ca['certificate']))
if dict_search('authentication.mode', sstp) == 'local':
render(sstp_chap_secrets, 'accel-ppp/chap-secrets.config_dict.tmpl',
diff --git a/src/etc/systemd/system/openvpn@.service.d/override.conf b/src/etc/systemd/system/openvpn@.service.d/10-override.conf
index 03fe6b587..03fe6b587 100644
--- a/src/etc/systemd/system/openvpn@.service.d/override.conf
+++ b/src/etc/systemd/system/openvpn@.service.d/10-override.conf