summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/vyos/ifconfig.py34
-rwxr-xr-xsrc/conf_mode/interface-wireguard.py427
2 files changed, 240 insertions, 221 deletions
diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py
index 0bc4eff17..30bfa5735 100644
--- a/python/vyos/ifconfig.py
+++ b/python/vyos/ifconfig.py
@@ -1288,7 +1288,7 @@ class WireGuardIf(Interface):
def __init__(self, ifname):
super().__init__(ifname, type='wireguard')
- self.wg_config = {
+ self.config = {
'port': 0,
'private-key': None,
'pubkey': None,
@@ -1299,36 +1299,36 @@ class WireGuardIf(Interface):
'keepalive': 0
}
- def wg_update(self):
- if not self.wg_config['private-key']:
+ def update(self):
+ if not self.config['private-key']:
raise ValueError("private key required")
else:
# fmask permission check?
pass
cmd = "wg set {} ".format(self._ifname)
- cmd += "listen-port {} ".format(self.wg_config['port'])
- cmd += "fwmark {} ".format(str(self.wg_config['fwmark']))
- cmd += "private-key {} ".format(self.wg_config['private-key'])
- cmd += "peer {} ".format(self.wg_config['pubkey'])
- cmd += " preshared-key {} ".format(self.wg_config['psk'])
+ cmd += "listen-port {} ".format(self.config['port'])
+ cmd += "fwmark {} ".format(str(self.config['fwmark']))
+ cmd += "private-key {} ".format(self.config['private-key'])
+ cmd += "peer {} ".format(self.config['pubkey'])
+ cmd += " preshared-key {} ".format(self.config['psk'])
cmd += " allowed-ips "
- for aip in self.wg_config['allowed-ips']:
- if aip != self.wg_config['allowed-ips'][-1]:
+ for aip in self.config['allowed-ips']:
+ if aip != self.config['allowed-ips'][-1]:
cmd += aip + ","
else:
cmd += aip
- if self.wg_config['endpoint']:
- cmd += " endpoint {}".format(self.wg_config['endpoint'])
- cmd += " persistent-keepalive {}".format(self.wg_config['keepalive'])
+ if self.config['endpoint']:
+ cmd += " endpoint {}".format(self.config['endpoint'])
+ cmd += " persistent-keepalive {}".format(self.config['keepalive'])
self._cmd(cmd)
# remove psk since it isn't required anymore and is saved in the cli
# config only !!
- if self.wg_config['psk'] != '/dev/null':
- if os.path.exists(self.wg_config['psk']):
- os.remove(self.wg_config['psk'])
+ if self.config['psk'] != '/dev/null':
+ if os.path.exists(self.config['psk']):
+ os.remove(self.config['psk'])
"""
Remove a peer of an interface, peers are identified by their public key.
@@ -1336,7 +1336,7 @@ class WireGuardIf(Interface):
and the interface is needed, to remove the entry.
"""
- def wg_remove_peer(self, peerkey):
+ def remove_peer(self, peerkey):
cmd = "sudo wg set {0} peer {1} remove".format(
self._ifname, str(peerkey))
self._cmd(cmd)
diff --git a/src/conf_mode/interface-wireguard.py b/src/conf_mode/interface-wireguard.py
index 40356da51..265491993 100755
--- a/src/conf_mode/interface-wireguard.py
+++ b/src/conf_mode/interface-wireguard.py
@@ -24,227 +24,246 @@ import subprocess
from vyos.config import Config
from vyos import ConfigError
-from vyos.ifconfig import WireGuardIf as wg_if
+from vyos.ifconfig import WireGuardIf
ifname = str(os.environ['VYOS_TAGNODE_VALUE'])
-wg_intfc = wg_if(ifname)
+intfc = WireGuardIf(ifname)
dir = r'/config/auth/wireguard'
pk = dir + '/private.key'
pub = dir + '/public.key'
psk_file = dir + '/psk'
+
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:
- sl.syslog(sl.LOG_NOTICE, "modprobe wireguard failed")
- raise ConfigError("modprobe wireguard failed")
+ if not os.path.exists('/sys/module/wireguard'):
+ sl.syslog(sl.LOG_NOTICE, "loading wirguard kmod")
+ if os.system('sudo modprobe wireguard') != 0:
+ sl.syslog(sl.LOG_NOTICE, "modprobe wireguard failed")
+ raise ConfigError("modprobe wireguard failed")
+
def get_config():
- c = Config()
- if not c.exists('interfaces wireguard'):
- return None
-
- config_data = {
- ifname : {
- 'addr' : '',
- 'descr' : ifname,
- 'lport' : None,
- 'status' : 'exists',
- 'state' : 'enabled',
- 'fwmark' : 0x00,
- 'mtu' : 1420,
- 'peer' : {}
- }
- }
-
- c.set_level('interfaces wireguard')
- if not c.exists_effective(ifname):
- config_data[ifname]['status'] = 'create'
-
- if not c.exists(ifname) and c.exists_effective(ifname):
- config_data[ifname]['status'] = 'delete'
-
- if config_data[ifname]['status'] != 'delete':
- if c.exists(ifname + ' address'):
- config_data[ifname]['addr'] = c.return_values(ifname + ' address')
- if c.exists(ifname + ' disable'):
- config_data[ifname]['state'] = 'disable'
- if c.exists(ifname + ' port'):
- config_data[ifname]['lport'] = c.return_value(ifname + ' port')
- if c.exists(ifname + ' fwmark'):
- config_data[ifname]['fwmark'] = c.return_value(ifname + ' fwmark')
- if c.exists(ifname + ' description'):
- config_data[ifname]['descr'] = c.return_value(ifname + ' description')
- if c.exists(ifname + ' mtu'):
- config_data[ifname]['mtu'] = c.return_value(ifname + ' mtu')
- if c.exists(ifname + ' peer'):
- for p in c.list_nodes(ifname + ' peer'):
- if not c.exists(ifname + ' peer ' + p + ' disable'):
- config_data[ifname]['peer'].update(
- {
- p : {
- 'allowed-ips' : [],
- 'endpoint' : '',
- 'pubkey' : ''
- }
- }
- )
- if c.exists(ifname + ' peer ' + p + ' pubkey'):
- config_data[ifname]['peer'][p]['pubkey'] = c.return_value(ifname + ' peer ' + p + ' pubkey')
- if c.exists(ifname + ' peer ' + p + ' allowed-ips'):
- config_data[ifname]['peer'][p]['allowed-ips'] = c.return_values(ifname + ' peer ' + p + ' allowed-ips')
- if c.exists(ifname + ' peer ' + p + ' endpoint'):
- config_data[ifname]['peer'][p]['endpoint'] = c.return_value(ifname + ' peer ' + p + ' endpoint')
- if c.exists(ifname + ' peer ' + p + ' persistent-keepalive'):
- config_data[ifname]['peer'][p]['persistent-keepalive'] = c.return_value(ifname + ' peer ' + p + ' persistent-keepalive')
- if c.exists(ifname + ' peer ' + p + ' preshared-key'):
- config_data[ifname]['peer'][p]['psk'] = c.return_value(ifname + ' peer ' + p + ' preshared-key')
-
- return config_data
+ c = Config()
+ if not c.exists('interfaces wireguard'):
+ return None
+
+ config_data = {
+ ifname: {
+ 'addr': '',
+ 'descr': ifname,
+ 'lport': None,
+ 'status': 'exists',
+ 'state': 'enabled',
+ 'fwmark': 0x00,
+ 'mtu': 1420,
+ 'peer': {}
+ }
+ }
+
+ c.set_level('interfaces wireguard')
+ if not c.exists_effective(ifname):
+ config_data[ifname]['status'] = 'create'
+
+ if not c.exists(ifname) and c.exists_effective(ifname):
+ config_data[ifname]['status'] = 'delete'
+
+ if config_data[ifname]['status'] != 'delete':
+ if c.exists(ifname + ' address'):
+ config_data[ifname]['addr'] = c.return_values(ifname + ' address')
+ if c.exists(ifname + ' disable'):
+ config_data[ifname]['state'] = 'disable'
+ if c.exists(ifname + ' port'):
+ config_data[ifname]['lport'] = c.return_value(ifname + ' port')
+ if c.exists(ifname + ' fwmark'):
+ config_data[ifname]['fwmark'] = c.return_value(ifname + ' fwmark')
+ if c.exists(ifname + ' description'):
+ config_data[ifname]['descr'] = c.return_value(
+ ifname + ' description')
+ if c.exists(ifname + ' mtu'):
+ config_data[ifname]['mtu'] = c.return_value(ifname + ' mtu')
+ if c.exists(ifname + ' peer'):
+ for p in c.list_nodes(ifname + ' peer'):
+ if not c.exists(ifname + ' peer ' + p + ' disable'):
+ config_data[ifname]['peer'].update(
+ {
+ p: {
+ 'allowed-ips': [],
+ 'endpoint': '',
+ 'pubkey': ''
+ }
+ }
+ )
+ if c.exists(ifname + ' peer ' + p + ' pubkey'):
+ config_data[ifname]['peer'][p]['pubkey'] = c.return_value(
+ ifname + ' peer ' + p + ' pubkey')
+ if c.exists(ifname + ' peer ' + p + ' allowed-ips'):
+ config_data[ifname]['peer'][p]['allowed-ips'] = c.return_values(
+ ifname + ' peer ' + p + ' allowed-ips')
+ if c.exists(ifname + ' peer ' + p + ' endpoint'):
+ config_data[ifname]['peer'][p]['endpoint'] = c.return_value(
+ ifname + ' peer ' + p + ' endpoint')
+ if c.exists(ifname + ' peer ' + p + ' persistent-keepalive'):
+ config_data[ifname]['peer'][p]['persistent-keepalive'] = c.return_value(
+ ifname + ' peer ' + p + ' persistent-keepalive')
+ if c.exists(ifname + ' peer ' + p + ' preshared-key'):
+ config_data[ifname]['peer'][p]['psk'] = c.return_value(
+ ifname + ' peer ' + p + ' preshared-key')
+
+ return config_data
+
def verify(c):
- if not c:
- return None
+ if not c:
+ return None
- if not os.path.exists(pk):
- raise ConfigError("No keys found, generate them by executing: \'run generate wireguard keypair\'")
+ if not os.path.exists(pk):
+ raise ConfigError(
+ "No keys found, generate them by executing: \'run generate wireguard keypair\'")
+
+ if c[ifname]['status'] != 'delete':
+ if not c[ifname]['addr']:
+ raise ConfigError("ERROR: IP address required")
+ if not c[ifname]['peer']:
+ raise ConfigError("ERROR: peer required")
+ for p in c[ifname]['peer']:
+ if not c[ifname]['peer'][p]['allowed-ips']:
+ raise ConfigError("ERROR: allowed-ips required for peer " + p)
+ if not c[ifname]['peer'][p]['pubkey']:
+ raise ConfigError("peer pubkey required for peer " + p)
- if c[ifname]['status'] != 'delete':
- if not c[ifname]['addr']:
- raise ConfigError("ERROR: IP address required")
- if not c[ifname]['peer']:
- raise ConfigError("ERROR: peer required")
- for p in c[ifname]['peer']:
- if not c[ifname]['peer'][p]['allowed-ips']:
- raise ConfigError("ERROR: allowed-ips required for peer " + p)
- if not c[ifname]['peer'][p]['pubkey']:
- raise ConfigError("peer pubkey required for peer " + p)
def apply(c):
- ### no wg config left, delete all wireguard devices, if any
- if not c:
- net_devs = os.listdir('/sys/class/net/')
- for dev in net_devs:
- if os.path.isdir('/sys/class/net/' + dev):
- buf = open('/sys/class/net/' + dev + '/uevent', 'r').read()
- if re.search("DEVTYPE=wireguard", buf, re.I|re.M):
- wg_intf = re.sub("INTERFACE=", "", re.search("INTERFACE=.*", buf, re.I|re.M).group(0))
- sl.syslog(sl.LOG_NOTICE, "removing interface " + wg_intf)
- subprocess.call(['ip l d dev ' + wg_intf + ' >/dev/null'], shell=True)
- return None
-
- ### interface removal
- if c[ifname]['status'] == 'delete':
- sl.syslog(sl.LOG_NOTICE, "removing interface " + ifname)
- wg_intfc.remove()
- return None
-
- c_eff = Config()
- c_eff.set_level('interfaces wireguard')
-
- ## interface state
- if c[ifname]['state'] == 'disable':
- sl.syslog(sl.LOG_NOTICE, "disable interface " + ifname)
- wg_intfc.state = 'down'
- else:
- if not wg_intfc.state == 'up':
- sl.syslog(sl.LOG_NOTICE, "enable interface " + ifname)
- wg_intfc.state = 'up'
-
- ## IP address
- if not c_eff.exists_effective(ifname + ' address'):
- for ip in c[ifname]['addr']:
- wg_intfc.add_addr(ip)
- else:
- addr_eff = c_eff.return_effective_values(ifname + ' address')
- addr_rem = list(set(addr_eff) - set(c[ifname]['addr']))
- addr_add = list(set(c[ifname]['addr']) - set(addr_eff))
-
- if len(addr_rem) !=0:
- for ip in addr_rem:
- sl.syslog(sl.LOG_NOTICE, "remove IP address {0} from {1}".format(ip,ifname))
- wg_intfc.del_addr(ip)
-
- if len(addr_add) !=0:
- for ip in addr_add:
- sl.syslog(sl.LOG_NOTICE, "add IP address {0} to {1}".format(ip,ifname))
- wg_intfc.add_addr(ip)
-
- ## interface MTU
- if c[ifname]['mtu'] != 1420:
- wg_intfc.mtu = int(c[ifname]['mtu'])
- else:
- ## default is set to 1420 in config_data
- wg_intfc.mtu = int(c[ifname]['mtu'])
-
- ## ifalias for snmp from description
- descr_eff = c_eff.return_effective_value(ifname + ' description')
- if descr_eff != c[ifname]['descr']:
- wg_intfc.ifalias = str(c[ifname]['descr'])
-
- ## peer deletion
- peer_eff = c_eff.list_effective_nodes(ifname + ' peer')
- peer_cnf = []
-
- try:
+ # no wg config left, delete all wireguard devices, if any
+ if not c:
+ net_devs = os.listdir('/sys/class/net/')
+ for dev in net_devs:
+ if os.path.isdir('/sys/class/net/' + dev):
+ buf = open('/sys/class/net/' + dev + '/uevent', 'r').read()
+ if re.search("DEVTYPE=wireguard", buf, re.I | re.M):
+ wg_intf = re.sub("INTERFACE=", "", re.search(
+ "INTERFACE=.*", buf, re.I | re.M).group(0))
+ sl.syslog(sl.LOG_NOTICE, "removing interface " + wg_intf)
+ subprocess.call(
+ ['ip l d dev ' + wg_intf + ' >/dev/null'], shell=True)
+ return None
+
+ # interface removal
+ if c[ifname]['status'] == 'delete':
+ sl.syslog(sl.LOG_NOTICE, "removing interface " + ifname)
+ intfc.remove()
+ return None
+
+ c_eff = Config()
+ c_eff.set_level('interfaces wireguard')
+
+ # interface state
+ if c[ifname]['state'] == 'disable':
+ sl.syslog(sl.LOG_NOTICE, "disable interface " + ifname)
+ intfc.state = 'down'
+ else:
+ if not intfc.state == 'up':
+ sl.syslog(sl.LOG_NOTICE, "enable interface " + ifname)
+ intfc.state = 'up'
+
+ # IP address
+ if not c_eff.exists_effective(ifname + ' address'):
+ for ip in c[ifname]['addr']:
+ intfc.add_addr(ip)
+ else:
+ addr_eff = c_eff.return_effective_values(ifname + ' address')
+ addr_rem = list(set(addr_eff) - set(c[ifname]['addr']))
+ addr_add = list(set(c[ifname]['addr']) - set(addr_eff))
+
+ if len(addr_rem) != 0:
+ for ip in addr_rem:
+ sl.syslog(
+ sl.LOG_NOTICE, "remove IP address {0} from {1}".format(ip, ifname))
+ intfc.del_addr(ip)
+
+ if len(addr_add) != 0:
+ for ip in addr_add:
+ sl.syslog(
+ sl.LOG_NOTICE, "add IP address {0} to {1}".format(ip, ifname))
+ intfc.add_addr(ip)
+
+ # interface MTU
+ if c[ifname]['mtu'] != 1420:
+ intfc.mtu = int(c[ifname]['mtu'])
+ else:
+ # default is set to 1420 in config_data
+ intfc.mtu = int(c[ifname]['mtu'])
+
+ # ifalias for snmp from description
+ descr_eff = c_eff.return_effective_value(ifname + ' description')
+ if descr_eff != c[ifname]['descr']:
+ intfc.ifalias = str(c[ifname]['descr'])
+
+ # peer deletion
+ peer_eff = c_eff.list_effective_nodes(ifname + ' peer')
+ peer_cnf = []
+
+ try:
+ for p in c[ifname]['peer']:
+ peer_cnf.append(p)
+ except KeyError:
+ pass
+
+ peer_rem = list(set(peer_eff) - set(peer_cnf))
+ for p in peer_rem:
+ pkey = c_eff.return_effective_value(ifname + ' peer ' + p + ' pubkey')
+ intfc.remove_peer(pkey)
+
+ # peer key update
+ for p in peer_eff:
+ if p in peer_cnf:
+ ekey = c_eff.return_effective_value(
+ ifname + ' peer ' + p + ' pubkey')
+ nkey = c[ifname]['peer'][p]['pubkey']
+ if nkey != ekey:
+ sl.syslog(
+ sl.LOG_NOTICE, "peer {0} pubkey changed from {1} to {2} on interface {3}".format(p, ekey, nkey, ifname))
+ print (
+ "peer {0} pubkey changed from {1} to {2} on interface {3}".format(p, ekey, nkey, ifname))
+ intfc.remove_peer(ekey)
+
+ intfc.config['private-key'] = pk
for p in c[ifname]['peer']:
- peer_cnf.append(p)
- except KeyError:
- pass
-
- peer_rem = list(set(peer_eff) - set(peer_cnf))
- for p in peer_rem:
- pkey = c_eff.return_effective_value( ifname + ' peer ' + p +' pubkey')
- wg_intfc.wg_remove_peer(pkey)
-
- ## peer key update
- for p in peer_eff:
- if p in peer_cnf:
- ekey = c_eff.return_effective_value( ifname + ' peer ' + p +' pubkey')
- nkey = c[ifname]['peer'][p]['pubkey']
- if nkey != ekey:
- sl.syslog(sl.LOG_NOTICE, "peer {0} pubkey changed from {1} to {2} on interface {3}".format(p, ekey, nkey, ifname))
- print ("peer {0} pubkey changed from {1} to {2} on interface {3}".format(p, ekey, nkey, ifname))
- wg_intfc.wg_remove_peer(ekey)
-
- wg_intfc.wg_config['private-key'] = pk
- for p in c[ifname]['peer']:
- wg_intfc.wg_config['pubkey'] = str(c[ifname]['peer'][p]['pubkey'])
- wg_intfc.wg_config['allowed-ips'] = (c[ifname]['peer'][p]['allowed-ips'])
-
- ## listen-port
- if c[ifname]['lport']:
- wg_intfc.wg_config['port'] = c[ifname]['lport']
-
- ## fwmark
- if c[ifname]['fwmark']:
- wg_intfc.wg_config['fwmark'] = c[ifname]['fwmark']
-
- ## endpoint
- if c[ifname]['peer'][p]['endpoint']:
- wg_intfc.wg_config['endpoint'] = c[ifname]['peer'][p]['endpoint']
-
- ## persistent-keepalive
- if 'persistent-keepalive' in c[ifname]['peer'][p]:
- wg_intfc.wg_config['keepalive'] = c[ifname]['peer'][p]['persistent-keepalive']
-
- ## preshared-key - needs to be read from a file
- if 'psk' in c[ifname]['peer'][p]:
- old_umask = os.umask(0o077)
- open(psk_file, 'w').write(str(c[ifname]['peer'][p]['psk']))
- os.umask(old_umask)
- wg_intfc.wg_config['psk'] = psk_file
-
- wg_intfc.wg_update()
+ intfc.config['pubkey'] = str(c[ifname]['peer'][p]['pubkey'])
+ intfc.config['allowed-ips'] = (c[ifname]['peer'][p]['allowed-ips'])
+
+ # listen-port
+ if c[ifname]['lport']:
+ intfc.config['port'] = c[ifname]['lport']
+
+ # fwmark
+ if c[ifname]['fwmark']:
+ intfc.config['fwmark'] = c[ifname]['fwmark']
+
+ # endpoint
+ if c[ifname]['peer'][p]['endpoint']:
+ intfc.config['endpoint'] = c[ifname]['peer'][p]['endpoint']
+
+ # persistent-keepalive
+ if 'persistent-keepalive' in c[ifname]['peer'][p]:
+ intfc.config['keepalive'] = c[ifname][
+ 'peer'][p]['persistent-keepalive']
+
+ # preshared-key - needs to be read from a file
+ if 'psk' in c[ifname]['peer'][p]:
+ old_umask = os.umask(0o077)
+ open(psk_file, 'w').write(str(c[ifname]['peer'][p]['psk']))
+ os.umask(old_umask)
+ intfc.config['psk'] = psk_file
+
+ intfc.update()
if __name__ == '__main__':
- try:
- check_kmod()
- c = get_config()
- verify(c)
- apply(c)
- except ConfigError as e:
- print(e)
- sys.exit(1)
+ try:
+ check_kmod()
+ c = get_config()
+ verify(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ sys.exit(1)