summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/interfaces-openvpn.xml47
-rw-r--r--python/vyos/ifconfig.py30
-rwxr-xr-xsrc/conf_mode/interface-bonding.py5
-rwxr-xr-xsrc/conf_mode/interface-openvpn.py27
-rwxr-xr-xsrc/conf_mode/interface-wireguard.py26
-rwxr-xr-xsrc/services/vyos-hostsd2
6 files changed, 122 insertions, 15 deletions
diff --git a/interface-definitions/interfaces-openvpn.xml b/interface-definitions/interfaces-openvpn.xml
index f11f27e23..fb2564cbd 100644
--- a/interface-definitions/interfaces-openvpn.xml
+++ b/interface-definitions/interfaces-openvpn.xml
@@ -518,29 +518,76 @@
<help>Transport Layer Security (TLS) options</help>
</properties>
<children>
+ <leafNode name="auth-file">
+ <properties>
+ <help>File containing tls static key for tls-auth</help>
+ <valueHelp>
+ <format>file</format>
+ <description>File in /config/auth directory</description>
+ </valueHelp>
+ <constraint>
+ <validator name="file-exists" argument="--directory /config/auth"/>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="ca-cert-file">
<properties>
<help>File containing certificate for Certificate Authority (CA)</help>
+ <valueHelp>
+ <format>file</format>
+ <description>File in /config/auth directory</description>
+ </valueHelp>
+ <constraint>
+ <validator name="file-exists" argument="--directory /config/auth"/>
+ </constraint>
</properties>
</leafNode>
<leafNode name="cert-file">
<properties>
<help>File containing certificate for this host</help>
+ <valueHelp>
+ <format>file</format>
+ <description>File in /config/auth directory</description>
+ </valueHelp>
+ <constraint>
+ <validator name="file-exists" argument="--directory /config/auth"/>
+ </constraint>
</properties>
</leafNode>
<leafNode name="crl-file">
<properties>
<help>File containing certificate revocation list (CRL) for this host</help>
+ <valueHelp>
+ <format>file</format>
+ <description>File in /config/auth directory</description>
+ </valueHelp>
+ <constraint>
+ <validator name="file-exists" argument="--directory /config/auth"/>
+ </constraint>
</properties>
</leafNode>
<leafNode name="dh-file">
<properties>
<help>File containing Diffie Hellman parameters (server only)</help>
+ <valueHelp>
+ <format>file</format>
+ <description>File in /config/auth directory</description>
+ </valueHelp>
+ <constraint>
+ <validator name="file-exists" argument="--directory /config/auth"/>
+ </constraint>
</properties>
</leafNode>
<leafNode name="key-file">
<properties>
<help>File containing this host's private key</help>
+ <valueHelp>
+ <format>file</format>
+ <description>File in /config/auth directory</description>
+ </valueHelp>
+ <constraint>
+ <validator name="file-exists" argument="--directory /config/auth"/>
+ </constraint>
</properties>
</leafNode>
<leafNode name="tls-version-min">
diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py
index 0793fad39..750a7cc70 100644
--- a/python/vyos/ifconfig.py
+++ b/python/vyos/ifconfig.py
@@ -1057,6 +1057,36 @@ class BondIf(EthernetIf):
def __init__(self, ifname):
super().__init__(ifname, type='bond')
+ def remove(self):
+ """
+ Remove interface from operating system. Removing the interface
+ deconfigures all assigned IP addresses and clear possible DHCP(v6)
+ client processes.
+ Example:
+ >>> from vyos.ifconfig import Interface
+ >>> i = Interface('eth0')
+ >>> i.remove()
+ """
+ # when a bond member gets deleted, all members are placed in A/D state
+ # even when they are enabled inside CLI. This will make the config
+ # and system look async.
+ slave_list = []
+ for s in self.get_slaves():
+ slave = {
+ 'ifname' : s,
+ 'state': Interface(s).state
+ }
+ slave_list.append(slave)
+
+ # remove bond master which places members in disabled state
+ super().remove()
+
+ # replicate previous interface state before bond destruction back to
+ # physical interface
+ for slave in slave_list:
+ i = Interface(slave['ifname'])
+ i.state = slave['state']
+
@property
def xmit_hash_policy(self):
"""
diff --git a/src/conf_mode/interface-bonding.py b/src/conf_mode/interface-bonding.py
index f0a33beff..ac3e1b867 100755
--- a/src/conf_mode/interface-bonding.py
+++ b/src/conf_mode/interface-bonding.py
@@ -279,11 +279,6 @@ def verify(bond):
raise ConfigError('can not enslave interface {} which already ' \
'belongs to {}'.format(intf, tmp))
- # we can not add disabled slave interfaces to our bond
- if conf.exists('interfaces ethernet ' + intf + ' disable'):
- raise ConfigError('can not enslave disabled interface {}' \
- .format(intf))
-
# can not add interfaces with an assigned address to a bond
if conf.exists('interfaces ethernet ' + intf + ' address'):
raise ConfigError('can not enslave interface {} which has an address ' \
diff --git a/src/conf_mode/interface-openvpn.py b/src/conf_mode/interface-openvpn.py
index 984410eb1..35e7928c2 100755
--- a/src/conf_mode/interface-openvpn.py
+++ b/src/conf_mode/interface-openvpn.py
@@ -175,6 +175,10 @@ tls-version-min {{tls_version_min}}
dh {{ tls_dh }}
{% endif %}
+{%- if tls_auth %}
+tls-auth {{tls_auth}}
+{% endif %}
+
{%- if 'active' in tls_role %}
tls-client
{%- elif 'passive' in tls_role %}
@@ -281,6 +285,7 @@ default_config_data = {
'server_topology': '',
'shared_secret_file': '',
'tls': False,
+ 'tls_auth': '',
'tls_ca_cert': '',
'tls_cert': '',
'tls_crl': '',
@@ -537,6 +542,11 @@ def get_config():
if conf.exists('server reject-unconfigured-clients'):
openvpn['server_reject_unconfigured'] = True
+ # File containing TLS auth static key
+ if conf.exists('tls auth-file'):
+ openvpn['tls_auth'] = conf.return_value('tls auth-file')
+ openvpn['tls'] = True
+
# File containing certificate for Certificate Authority (CA)
if conf.exists('tls ca-cert-file'):
openvpn['tls_ca_cert'] = conf.return_value('tls ca-cert-file')
@@ -723,11 +733,17 @@ def verify(openvpn):
if not checkCertHeader('-----BEGIN CERTIFICATE-----', openvpn['tls_ca_cert']):
raise ConfigError('Specified ca-cert-file "{}" is invalid'.format(openvpn['tls_ca_cert']))
- if not checkCertHeader('-----BEGIN CERTIFICATE-----', openvpn['tls_cert']):
- raise ConfigError('Specified cert-file "{}" is invalid'.format(openvpn['tls_cert']))
+ if openvpn['tls_auth']:
+ if not checkCertHeader('-----BEGIN OpenVPN Static key V1-----', openvpn['tls_auth']):
+ raise ConfigError('Specified auth-file "{}" is invalid'.format(openvpn['tls_auth']))
+
+ if openvpn['tls_cert']:
+ if not checkCertHeader('-----BEGIN CERTIFICATE-----', openvpn['tls_cert']):
+ raise ConfigError('Specified cert-file "{}" is invalid'.format(openvpn['tls_cert']))
- if not checkCertHeader('-----BEGIN (?:RSA )?PRIVATE KEY-----', openvpn['tls_key']):
- raise ConfigError('Specified key-file "{}" is not valid'.format(openvpn['tls_key']))
+ if openvpn['tls_key']:
+ if not checkCertHeader('-----BEGIN (?:RSA )?PRIVATE KEY-----', openvpn['tls_key']):
+ raise ConfigError('Specified key-file "{}" is not valid'.format(openvpn['tls_key']))
if openvpn['tls_crl']:
if not checkCertHeader('-----BEGIN X509 CRL-----', openvpn['tls_crl']):
@@ -739,7 +755,8 @@ def verify(openvpn):
if openvpn['tls_role']:
if openvpn['mode'] in ['client', 'server']:
- raise ConfigError('Cannot specify "tls role" in client-server mode')
+ if not openvpn['tls_auth']:
+ raise ConfigError('Cannot specify "tls role" in client-server mode')
if openvpn['tls_role'] == 'active':
if openvpn['protocol'] == 'tcp-passive':
diff --git a/src/conf_mode/interface-wireguard.py b/src/conf_mode/interface-wireguard.py
index d51a7a08d..4ae3251fe 100755
--- a/src/conf_mode/interface-wireguard.py
+++ b/src/conf_mode/interface-wireguard.py
@@ -26,12 +26,16 @@ from vyos.config import Config
from vyos import ConfigError
from vyos.ifconfig import WireGuardIf
-ifname = str(os.environ['VYOS_TAGNODE_VALUE'])
-intfc = WireGuardIf(ifname)
+try:
+ ifname = str(os.environ['VYOS_TAGNODE_VALUE'])
+ intfc = WireGuardIf(ifname)
+except KeyError:
+ print("Interface not specified")
+ sys.exit(1)
kdir = r'/config/auth/wireguard'
-def check_kmod():
+def _check_kmod():
if not os.path.exists('/sys/module/wireguard'):
sl.syslog(sl.LOG_NOTICE, "loading wirguard kmod")
if os.system('sudo modprobe wireguard') != 0:
@@ -39,6 +43,19 @@ def check_kmod():
raise ConfigError("modprobe wireguard failed")
+def _migrate_default_keys():
+ if os.path.exists('{}/private.key'.format(kdir)) and not os.path.exists('{}/default/private.key'.format(kdir)):
+ sl.syslog(sl.LOG_NOTICE, "migrate keypair to default")
+ old_umask = os.umask(0o027)
+ location = '{}/default'.format(kdir)
+ subprocess.call(['sudo mkdir -p ' + location], shell=True)
+ subprocess.call(['sudo chgrp vyattacfg ' + location], shell=True)
+ subprocess.call(['sudo chmod 750 ' + location], shell=True)
+ os.rename('{}/private.key'.format(kdir),'{}/private.key'.format(location))
+ os.rename('{}/public.key'.format(kdir),'{}/public.key'.format(location))
+ os.umask(old_umask)
+
+
def get_config():
c = Config()
if not c.exists('interfaces wireguard'):
@@ -257,7 +274,8 @@ def apply(c):
if __name__ == '__main__':
try:
- check_kmod()
+ _check_kmod()
+ _migrate_default_keys()
c = get_config()
verify(c)
apply(c)
diff --git a/src/services/vyos-hostsd b/src/services/vyos-hostsd
index 8f70eb4e9..e7ecd8573 100755
--- a/src/services/vyos-hostsd
+++ b/src/services/vyos-hostsd
@@ -43,7 +43,7 @@ hosts_tmpl_source = """
# Local host
127.0.0.1 localhost
-127.0.1.1 {{ host_name }}{% if domain_name %}.{{ domain_name }}{% endif %}
+127.0.1.1 {{ host_name }}{% if domain_name %}.{{ domain_name }} {{ host_name }}{% endif %}
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback