From 289f513c3babca73f2ab8504b6b235ca0afa1ae5 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 23 Jun 2020 16:27:29 +0200 Subject: wireguard: T2632: support PSK on multiple peers It was not possible to configure two WG peers with both utilized a pre-shared key. This has been corrected. WG psk can only be read from a file when starting the interface. The code for creating this temporary file has been moved into the ifconfig.WireGuardIf() class. Tested with: ============ set interfaces wireguard wg0 address '192.0.2.0/31' set interfaces wireguard wg0 peer one allowed-ips '0.0.0.0/0' set interfaces wireguard wg0 peer one preshared-key 'e+SIIUcrnrSDHhbTtpjwKhSlSdUALA5ZvoCjfQXcvmA=' set interfaces wireguard wg0 peer one pubkey '/qQGAQ2HfLSZBSCpdgps04r9wRlK7bSFraCH9+MScmw=' set interfaces wireguard wg0 peer two allowed-ips '0.0.0.0/0' set interfaces wireguard wg0 peer two pubkey '/qQGAQ2HfLSZBSCpdgfooor9wRlK7bSFraCH9+MScmw=' --- python/vyos/ifconfig/wireguard.py | 58 +++++++++++++++++------------------ src/conf_mode/interfaces-wireguard.py | 9 ++---- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py index 027b5ea8c..a90a66ac3 100644 --- a/python/vyos/ifconfig/wireguard.py +++ b/python/vyos/ifconfig/wireguard.py @@ -149,10 +149,10 @@ class WireGuardIf(Interface): default = { 'type': 'wireguard', 'port': 0, - 'private-key': None, + 'private_key': None, 'pubkey': None, - 'psk': '/dev/null', - 'allowed-ips': [], + 'psk': '', + 'allowed_ips': [], 'fwmark': 0x00, 'endpoint': None, 'keepalive': 0 @@ -166,8 +166,8 @@ class WireGuardIf(Interface): } } options = Interface.options + \ - ['port', 'private-key', 'pubkey', 'psk', - 'allowed-ips', 'fwmark', 'endpoint', 'keepalive'] + ['port', 'private_key', 'pubkey', 'psk', + 'allowed_ips', 'fwmark', 'endpoint', 'keepalive'] """ Wireguard interface class, contains a comnfig dictionary since @@ -180,44 +180,44 @@ class WireGuardIf(Interface): >>> from vyos.ifconfig import WireGuardIf as wg_if >>> wg_intfc = wg_if("wg01") >>> print (wg_intfc.wg_config) - {'private-key': None, 'keepalive': 0, 'endpoint': None, 'port': 0, - 'allowed-ips': [], 'pubkey': None, 'fwmark': 0, 'psk': '/dev/null'} + {'private_key': None, 'keepalive': 0, 'endpoint': None, 'port': 0, + 'allowed_ips': [], 'pubkey': None, 'fwmark': 0, 'psk': '/dev/null'} >>> wg_intfc.wg_config['keepalive'] = 100 >>> print (wg_intfc.wg_config) - {'private-key': None, 'keepalive': 100, 'endpoint': None, 'port': 0, - 'allowed-ips': [], 'pubkey': None, 'fwmark': 0, 'psk': '/dev/null'} + {'private_key': None, 'keepalive': 100, 'endpoint': None, 'port': 0, + 'allowed_ips': [], 'pubkey': None, 'fwmark': 0, 'psk': '/dev/null'} """ def update(self): - if not self.config['private-key']: + if not self.config['private_key']: raise ValueError("private key required") else: # fmask permission check? pass - cmd = "wg set {} ".format(self.config['ifname']) - 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.config['allowed-ips']: - if aip != self.config['allowed-ips'][-1]: - cmd += aip + "," - else: - cmd += aip + cmd = 'wg set {ifname}'.format(**self.config) + cmd += ' listen-port {port}'.format(**self.config) + cmd += ' fwmark "{fwmark}" '.format(**self.config) + cmd += ' private-key {private_key}'.format(**self.config) + cmd += ' peer {pubkey}'.format(**self.config) + cmd += ' persistent-keepalive {keepalive}'.format(**self.config) + cmd += ' allowed-ips {}'.format(', '.join(self.config['allowed-ips'])) + if self.config['endpoint']: - cmd += " endpoint '{}'".format(self.config['endpoint']) - cmd += " persistent-keepalive {}".format(self.config['keepalive']) + cmd += ' endpoint "{endpoint}"'.format(**self.config) + + psk_file = '' + if self.config['psk']: + psk_file = '/tmp/{ifname}.psk'.format(**self.config) + with open(psk_file, 'w') as f: + f.write(self.config['psk']) + cmd += f' preshared-key {psk_file}' self._cmd(cmd) - # remove psk since it isn't required anymore and is saved in the cli - # config only !! - if self.config['psk'] != '/dev/null': - if os.path.exists(self.config['psk']): - os.remove(self.config['psk']) + # PSK key file is not required to be stored persistently as its backed by CLI + if os.path.exists(psk_file): + os.remove(psk_file) def remove_peer(self, peerkey): """ diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py index ab3e073ae..c24c9a7ce 100755 --- a/src/conf_mode/interfaces-wireguard.py +++ b/src/conf_mode/interfaces-wireguard.py @@ -275,7 +275,7 @@ def apply(wg): # peer pubkey # setting up the wg interface - w.config['private-key'] = c['pk'] + w.config['private_key'] = c['pk'] for peer in wg['peer']: # peer pubkey @@ -300,13 +300,8 @@ def apply(wg): if peer['persistent_keepalive']: w.config['keepalive'] = peer['persistent_keepalive'] - # maybe move it into ifconfig.py - # preshared-key - needs to be read from a file if peer['psk']: - psk_file = '/config/auth/wireguard/psk' - with open(psk_file, 'w') as f: - f.write(peer['psk']) - w.config['psk'] = psk_file + w.config['psk'] = peer['psk'] w.update() -- cgit v1.2.3