Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F119064375
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/conf_mode/interface-wireguard.py b/src/conf_mode/interface-wireguard.py
index 0dcce6b1c..7a684bafa 100755
--- a/src/conf_mode/interface-wireguard.py
+++ b/src/conf_mode/interface-wireguard.py
@@ -1,283 +1,285 @@
#!/usr/bin/env python3
#
# Copyright (C) 2018 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
import sys
import os
import re
import subprocess
from copy import deepcopy
from netifaces import interfaces
from vyos import ConfigError
from vyos.config import Config
from vyos.configdict import list_diff
from vyos.ifconfig import WireGuardIf
kdir = r'/config/auth/wireguard'
def _check_kmod():
if not os.path.exists('/sys/module/wireguard'):
if os.system('sudo modprobe wireguard') != 0:
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)):
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'):
return None
dflt_cnf = {
'intfc': '',
'addr': [],
'addr_remove': [],
'descr': '',
'lport': None,
'delete': False,
'state': 'up',
'fwmark': 0x00,
'mtu': 1420,
'peer': {},
'peer_remove': [],
'pk': '{}/default/private.key'.format(kdir)
}
if os.getenv('VYOS_TAGNODE_VALUE'):
ifname = str(os.environ['VYOS_TAGNODE_VALUE'])
wg = deepcopy(dflt_cnf)
wg['intfc'] = ifname
wg['descr'] = ifname
else:
print("ERROR: VYOS_TAGNODE_VALUE undefined")
sys.exit(1)
c.set_level('interfaces wireguard')
# interface removal state
if not c.exists(ifname) and c.exists_effective(ifname):
wg['delete'] = True
if not wg['delete']:
c.set_level('interfaces wireguard {}'.format(ifname))
if c.exists('address'):
wg['addr'] = c.return_values('address')
# determine addresses which need to be removed
eff_addr = c.return_effective_values('address')
wg['addr_remove'] = list_diff(eff_addr, wg['addr'])
# ifalias description
if c.exists('description'):
wg['descr'] = c.return_value('description')
# link state
if c.exists('disable'):
wg['state'] = 'down'
# local port to listen on
if c.exists('port'):
wg['lport'] = c.return_value('port')
# fwmark value
if c.exists('fwmark'):
wg['fwmark'] = c.return_value('fwmark')
# mtu
if c.exists('mtu'):
wg['mtu'] = c.return_value('mtu')
# private key
if c.exists('private-key'):
wg['pk'] = "{0}/{1}/private.key".format(
kdir, c.return_value('private-key'))
# peer removal, wg identifies peers by its pubkey
peer_eff = c.list_effective_nodes('peer')
peer_rem = list_diff(peer_eff, c.list_nodes('peer'))
for p in peer_rem:
wg['peer_remove'].append(
c.return_effective_value('peer {} pubkey'.format(p)))
# peer settings
if c.exists('peer'):
for p in c.list_nodes('peer'):
if not c.exists('peer ' + p + ' disable'):
wg['peer'].update(
{
p: {
'allowed-ips': [],
'endpoint': '',
'pubkey': ''
}
}
)
# peer allowed-ips
if c.exists('peer ' + p + ' allowed-ips'):
wg['peer'][p]['allowed-ips'] = c.return_values(
'peer ' + p + ' allowed-ips')
# peer endpoint
if c.exists('peer ' + p + ' endpoint'):
wg['peer'][p]['endpoint'] = c.return_value(
'peer ' + p + ' endpoint')
# persistent-keepalive
if c.exists('peer ' + p + ' persistent-keepalive'):
wg['peer'][p]['persistent-keepalive'] = c.return_value(
'peer ' + p + ' persistent-keepalive')
# preshared-key
if c.exists('peer ' + p + ' preshared-key'):
wg['peer'][p]['psk'] = c.return_value(
'peer ' + p + ' preshared-key')
# peer pubkeys
key_eff = c.return_effective_value(
'peer {peer} pubkey'.format(peer=p))
key_cfg = c.return_value(
'peer {peer} pubkey'.format(peer=p))
wg['peer'][p]['pubkey'] = key_cfg
# on a pubkey change we need to remove the pubkey first
# peers are identified by pubkey, so key update means
# peer removal and re-add
if key_eff != key_cfg and key_eff != None:
wg['peer_remove'].append(key_cfg)
return wg
def verify(c):
if not c:
return None
if not os.path.exists(c['pk']):
raise ConfigError(
"No keys found, generate them by executing: \'run generate wireguard [keypair|named-keypairs]\'")
if not c['delete']:
if not c['addr']:
raise ConfigError("ERROR: IP address required")
if not c['peer']:
raise ConfigError("ERROR: peer required")
for p in c['peer']:
if not c['peer'][p]['allowed-ips']:
raise ConfigError("ERROR: allowed-ips required for peer " + p)
if not c['peer'][p]['pubkey']:
raise ConfigError("peer pubkey required for peer " + p)
+ if not c['peer'][p]['endpoint']:
+ raise ConfigError("peer endpoint required for peer " + p)
def apply(c):
# no wg configs left, remove all interface from system
# maybe move it into ifconfig.py
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))
subprocess.call(
['ip l d dev ' + wg_intf + ' >/dev/null'], shell=True)
return None
# init wg class
intfc = WireGuardIf(c['intfc'])
# single interface removal
if c['delete']:
intfc.remove()
return None
# remove IP addresses
for ip in c['addr_remove']:
intfc.del_addr(ip)
# add IP addresses
for ip in c['addr']:
intfc.add_addr(ip)
# interface mtu
intfc.set_mtu(int(c['mtu']))
# ifalias for snmp from description
intfc.set_alias(str(c['descr']))
# remove peers
if c['peer_remove']:
for pkey in c['peer_remove']:
intfc.remove_peer(pkey)
# peer pubkey
# setting up the wg interface
intfc.config['private-key'] = c['pk']
for p in c['peer']:
# peer pubkey
intfc.config['pubkey'] = str(c['peer'][p]['pubkey'])
# peer allowed-ips
intfc.config['allowed-ips'] = c['peer'][p]['allowed-ips']
# local listen port
if c['lport']:
intfc.config['port'] = c['lport']
# fwmark
if c['fwmark']:
intfc.config['fwmark'] = c['fwmark']
# endpoint
if c['peer'][p]['endpoint']:
intfc.config['endpoint'] = c['peer'][p]['endpoint']
# persistent-keepalive
if 'persistent-keepalive' in c['peer'][p]:
intfc.config['keepalive'] = c['peer'][p]['persistent-keepalive']
# maybe move it into ifconfig.py
# preshared-key - needs to be read from a file
if 'psk' in c['peer'][p]:
psk_file = '/config/auth/wireguard/psk'
old_umask = os.umask(0o077)
open(psk_file, 'w').write(str(c['peer'][p]['psk']))
os.umask(old_umask)
intfc.config['psk'] = psk_file
intfc.update()
# interface state
intfc.set_state(c['state'])
return None
if __name__ == '__main__':
try:
_check_kmod()
_migrate_default_keys()
c = get_config()
verify(c)
apply(c)
except ConfigError as e:
print(e)
sys.exit(1)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 6, 9:56 AM (7 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4642259
Default Alt Text
(9 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment