Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F117521250
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/debian/changelog b/debian/changelog
index 415cee0ff..477ce8a56 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,108 +1,114 @@
+vyos-1x (1.2.0-11) unstable; urgency=low
+
+ * Fix: T1217 - cant delete wireguard wg0 interface
+
+ -- hagbard <vyosdev@derith.de> Wed, 30 Jan 2019 14:54:45 -0800
+
vyos-1x (1.2.0-10) unstable; urgency=low
* T1178: Scheduled script breaks ability to modify configuration
-- hagbard <vyosdev@derith.de> Tue, 22 Jan 2019 13:35:09 -0800
vyos-1x (1.2.0-9) unstable; urgency=low
* T1168: Upgrade: 1,1,7 -> 1.2.0-epa2
- keyword change in config
-- hagbard <vyosdev@derith.de> Mon, 07 Jan 2019 11:42:49 -0800
vyos-1x (1.2.0-8) unstable; urgency=low
* T1162: WireGuard: Unable to modify tunnels - KeyError: 'state'
-- hagbard <vyosdev@derith.de> Sun, 06 Jan 2019 15:58:40 -0800
vyos-1x (1.2.0-7) unstable; urgency=low
* T1061: Wireguard: Missing option to administrativly shutdown interface
-- hagbard <vyosdev@derith.de> Fri, 30 Nov 2018 10:22:41 -0800
vyos-1x (1.2.0-6) unstable; urgency=medium
* adding vyos-accel-ppp-ipoe-kmod for T989
-- hagbard <vyosdev@derith.de> Thu, 22 Nov 2018 10:56:15 -0800
vyos-1x (1.2.0-5) unstable; urgency=medium
* T835: accel-ppp: pppoe implementation
-- hagbard <vyosdev@derith.de> Fri, 09 Nov 2018 10:49:48 -0800
vyos-1x (1.2.0-4) unstable; urgency=medium
* T240 adds feature system integrity check
-- hagbard <vyosdev@derith.de> Mon, 29 Oct 2018 11:10:18 -0700
vyos-1x (1.2.0-3) unstable; urgency=medium
* T933: adding vmac_xmit_base if use_vmac has been chosen
to avoid split-brain
-- hagbard <vyosdev@derith.de> Thu, 25 Oct 2018 11:14:44 -0700
vyos-1x (1.2.0-2) unstable; urgency=medium
* T773: adding wireguard support
-- hagbard <vyosdev@derith.de> Sat, 11 Aug 2018 15:51:34 -0700
vyos-1x (1.2.0-1) unstable; urgency=medium
* T666, T616: new implementation of the VRRP CLI.
-- Daniil Baturin <daniil@baturin.org> Fri, 27 Jul 2018 10:25:52 +0200
vyos-1x (1.0.6) unstable; urgency=medium
* T736: Rewrite remote logging (syslog) to XML/Python
-- hagbard <vyosdev@derith.de> Tue, 24 Jul 2018 10:59:25 -0700
vyos-1x (1.0.5) unstable; urgency=medium
* T606: Error in DNS Forwarder listen-on
* T608: Cannot configure broadcast-relay service
-- Christian Poessinger <christian@poessinger.com> Thu, 19 Apr 2018 21:16:28 +0200
vyos-1x (1.0.4) unstable; urgency=medium
* T560: dns-forwarding: replace dnsmasq with pdns-recursor
* T588: Rewrite 'service dns forwarding' in new XML style format
-- Christian Poessinger <christian@poessinger.com> Sun, 15 Apr 2018 16:13:32 +0200
vyos-1x (1.0.3) unstable; urgency=medium
* T379: Add UDP broadcast relay support
* mdns repeater scripts - remove python subprocess
* Support setting optional 'type' node in command templates
-- Christian Poessinger <christian@poessinger.com> Sat, 06 Jan 2018 13:18:30 +0100
vyos-1x (1.0.2) unstable; urgency=low
* Added mdns-repeater configuration nodes
-- Christian Poessinger <christian@poessinger.com> Sat, 09 Dec 2017 10:39:35 +0100
vyos-1x (1.0.1) unstable; urgency=low
* Added the Python library for reading VyOS configs
-- Daniil Baturin <daniil@baturin.org> Thu, 17 Aug 2017 22:22:17 -0400
vyos-1x (1.0.0) unstable; urgency=low
* Created the package
-- Daniil Baturin <daniil@baturin.org> Thu, 17 Aug 2017 20:17:04 -0400
diff --git a/src/conf_mode/wireguard.py b/src/conf_mode/wireguard.py
index 57baaee1c..e893dba47 100755
--- a/src/conf_mode/wireguard.py
+++ b/src/conf_mode/wireguard.py
@@ -1,363 +1,364 @@
#!/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 syslog as sl
import subprocess
from vyos.config import Config
from vyos import ConfigError
dir = r'/config/auth/wireguard'
pk = dir + '/private.key'
pub = dir + '/public.key'
psk_file = r'/tmp/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")
def get_config():
c = Config()
if not c.exists('interfaces wireguard'):
return None
c.set_level('interfaces')
intfcs = c.list_nodes('wireguard')
intfcs_eff = c.list_effective_nodes('wireguard')
new_lst = list(set(intfcs) - set(intfcs_eff))
del_lst = list(set(intfcs_eff) - set(intfcs))
config_data = {
'interfaces' : {}
}
### setting defaults and determine status of the config
for intfc in intfcs:
cnf = 'wireguard ' + intfc
# default data struct
config_data['interfaces'].update(
{
intfc : {
'addr' : '',
'descr' : intfc, ## snmp ifAlias
'lport' : '',
'status' : 'exists',
'state' : 'enabled',
'mtu' : '1420',
'peer' : {}
}
}
)
### determine status either delete or create
for i in new_lst:
config_data['interfaces'][i]['status'] = 'create'
for i in del_lst:
config_data['interfaces'].update(
{
i : {
'status': 'delete'
}
}
)
### based on the status, setup conf values
for intfc in intfcs:
cnf = 'wireguard ' + intfc
if config_data['interfaces'][intfc]['status'] != 'delete':
### addresses
if c.exists(cnf + ' address'):
config_data['interfaces'][intfc]['addr'] = c.return_values(cnf + ' address')
### interface up/down
if c.exists(cnf + ' disable'):
config_data['interfaces'][intfc]['state'] = 'disable'
### listen port
if c.exists(cnf + ' port'):
config_data['interfaces'][intfc]['lport'] = c.return_value(cnf + ' port')
### description
if c.exists(cnf + ' description'):
config_data['interfaces'][intfc]['descr'] = c.return_value(cnf + ' description')
### mtu
if c.exists(cnf + ' mtu'):
config_data['interfaces'][intfc]['mtu'] = c.return_value(cnf + ' mtu')
### peers
if c.exists(cnf + ' peer'):
for p in c.list_nodes(cnf + ' peer'):
if not c.exists(cnf + ' peer ' + p + ' disable'):
config_data['interfaces'][intfc]['peer'].update(
{
p : {
'allowed-ips' : [],
'endpoint' : '',
'pubkey' : ''
}
}
)
if c.exists(cnf + ' peer ' + p + ' pubkey'):
config_data['interfaces'][intfc]['peer'][p]['pubkey'] = c.return_value(cnf + ' peer ' + p + ' pubkey')
if c.exists(cnf + ' peer ' + p + ' allowed-ips'):
config_data['interfaces'][intfc]['peer'][p]['allowed-ips'] = c.return_values(cnf + ' peer ' + p + ' allowed-ips')
if c.exists(cnf + ' peer ' + p + ' endpoint'):
config_data['interfaces'][intfc]['peer'][p]['endpoint'] = c.return_value(cnf + ' peer ' + p + ' endpoint')
if c.exists(cnf + ' peer ' + p + ' persistent-keepalive'):
config_data['interfaces'][intfc]['peer'][p]['persistent-keepalive'] = c.return_value(cnf + ' peer ' + p + ' persistent-keepalive')
if c.exists(cnf + ' peer ' + p + ' preshared-key'):
config_data['interfaces'][intfc]['peer'][p]['psk'] = c.return_value(cnf + ' peer ' + p + ' preshared-key')
return config_data
def verify(c):
if not c:
return None
for i in c['interfaces']:
if c['interfaces'][i]['status'] != 'delete':
if not c['interfaces'][i]['addr']:
raise ConfigError("address required for interface " + i)
if not c['interfaces'][i]['peer']:
raise ConfigError("peer required on interface " + i)
for p in c['interfaces'][i]['peer']:
if not c['interfaces'][i]['peer'][p]['allowed-ips']:
raise ConfigError("allowed-ips required on interface " + i + " for peer " + p)
if not c['interfaces'][i]['peer'][p]['pubkey']:
raise ConfigError("pubkey from your peer is mandatory on " + i + " for peer " + p)
def apply(c):
### no wg config left, delete all wireguard devices on the os
if not c:
net_devs = os.listdir('/sys/class/net/')
for dev in net_devs:
- 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)
+ 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
###
## find the diffs between effective config an new config
###
c_eff = Config()
c_eff.set_level('interfaces wireguard')
### link status up/down aka interface disable
for intf in c['interfaces']:
if not c['interfaces'][intf]['status'] == 'delete':
if c['interfaces'][intf]['state'] == 'disable':
sl.syslog(sl.LOG_NOTICE, "disable interface " + intf)
subprocess.call(['ip l s dev ' + intf + ' down ' + ' &>/dev/null'], shell=True)
else:
sl.syslog(sl.LOG_NOTICE, "enable interface " + intf)
subprocess.call(['ip l s dev ' + intf + ' up ' + ' &>/dev/null'], shell=True)
### deletion of a specific interface
for intf in c['interfaces']:
if c['interfaces'][intf]['status'] == 'delete':
sl.syslog(sl.LOG_NOTICE, "removing interface " + intf)
subprocess.call(['ip l d dev ' + intf + ' &>/dev/null'], shell=True)
### peer deletion
peer_eff = c_eff.list_effective_nodes( intf + ' peer')
peer_cnf = []
try:
for p in c['interfaces'][intf]['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( intf + ' peer ' + p +' pubkey')
remove_peer(intf, pkey)
### peer pubkey update
### wg identifies peers by its pubky, so we have to remove the peer first
### it will recreated it then below with the new key from the cli config
for p in peer_eff:
if p in peer_cnf:
ekey = c_eff.return_effective_value( intf + ' peer ' + p +' pubkey')
nkey = c['interfaces'][intf]['peer'][p]['pubkey']
if nkey != ekey:
sl.syslog(sl.LOG_NOTICE, "peer " + p + ' changed pubkey from ' + ekey + 'to key ' + nkey + ' on interface ' + intf)
remove_peer(intf, ekey)
### new config
if c['interfaces'][intf]['status'] == 'create':
if not os.path.exists(pk):
raise ConfigError("No keys found, generate them by executing: \'run generate wireguard keypair\'")
subprocess.call(['ip l a dev ' + intf + ' type wireguard 2>/dev/null'], shell=True)
for addr in c['interfaces'][intf]['addr']:
add_addr(intf, addr)
subprocess.call(['ip l set up dev ' + intf + ' mtu ' + c['interfaces'][intf]['mtu'] + ' &>/dev/null'], shell=True)
configure_interface(c, intf)
### config updates
if c['interfaces'][intf]['status'] == 'exists':
### IP address change
addr_eff = re.sub("\'", "", c_eff.return_effective_values(intf + ' address')).split()
addr_rem = list(set(addr_eff) - set(c['interfaces'][intf]['addr']))
addr_add = list(set(c['interfaces'][intf]['addr']) - set(addr_eff))
if len(addr_rem) != 0:
for addr in addr_rem:
del_addr(intf, addr)
if len(addr_add) != 0:
for addr in addr_add:
add_addr(intf, addr)
## mtu update
mtu = c['interfaces'][intf]['mtu']
if mtu != 1420:
sl.syslog(sl.LOG_NOTICE, "setting mtu to " + mtu + " on " + intf)
subprocess.call(['ip l set mtu ' + mtu + ' dev ' + intf + ' &>/dev/null'], shell=True)
### persistent-keepalive
for p in c['interfaces'][intf]['peer']:
val_eff = ""
val = ""
try:
val = c['interfaces'][intf]['peer'][p]['persistent-keepalive']
except KeyError:
pass
if c_eff.exists_effective(intf + ' peer ' + p + ' persistent-keepalive'):
val_eff = c_eff.return_effective_value(intf + ' peer ' + p + ' persistent-keepalive')
### disable keepalive
if val_eff and not val:
c['interfaces'][intf]['peer'][p]['persistent-keepalive'] = 0
### set new keepalive value
if not val_eff and val:
c['interfaces'][intf]['peer'][p]['persistent-keepalive'] = val
## wg command call
configure_interface(c, intf)
### ifalias for snmp from description
if c['interfaces'][intf]['status'] != 'delete':
descr_eff = c_eff.return_effective_value(intf + ' description')
cnf_descr = c['interfaces'][intf]['descr']
if descr_eff != cnf_descr:
with open('/sys/class/net/' + str(intf) + '/ifalias', 'w') as fh:
fh.write(str(cnf_descr))
def configure_interface(c, intf):
for p in c['interfaces'][intf]['peer']:
## config init for wg call
wg_config = {
'interface' : intf,
'port' : 0,
'private-key' : pk,
'pubkey' : '',
'psk' : '/dev/null',
'allowed-ips' : [],
'fwmark' : 0x00,
'endpoint' : None,
'keepalive' : 0
}
## mandatory settings
wg_config['pubkey'] = c['interfaces'][intf]['peer'][p]['pubkey']
wg_config['allowed-ips'] = c['interfaces'][intf]['peer'][p]['allowed-ips']
## optional settings
# listen-port
if c['interfaces'][intf]['lport']:
wg_config['port'] = c['interfaces'][intf]['lport']
## endpoint
if c['interfaces'][intf]['peer'][p]['endpoint']:
wg_config['endpoint'] = c['interfaces'][intf]['peer'][p]['endpoint']
## persistent-keepalive
if 'persistent-keepalive' in c['interfaces'][intf]['peer'][p]:
wg_config['keepalive'] = c['interfaces'][intf]['peer'][p]['persistent-keepalive']
## preshared-key - is only read from a file, it's called via sudo redirection doesn't work either
if 'psk' in c['interfaces'][intf]['peer'][p]:
old_umask = os.umask(0o077)
open(psk_file, 'w').write(str(c['interfaces'][intf]['peer'][p]['psk']))
os.umask(old_umask)
wg_config['psk'] = psk_file
### assemble wg command
cmd = "sudo wg set " + intf
cmd += " listen-port " + str(wg_config['port'])
cmd += " private-key " + wg_config['private-key']
cmd += " peer " + wg_config['pubkey']
cmd += " preshared-key " + wg_config['psk']
cmd += " allowed-ips "
for ap in wg_config['allowed-ips']:
if ap != wg_config['allowed-ips'][-1]:
cmd += ap + ","
else:
cmd += ap
if wg_config['endpoint']:
cmd += " endpoint " + wg_config['endpoint']
if wg_config['keepalive'] != 0:
cmd += " persistent-keepalive " + wg_config['keepalive']
else:
cmd += " persistent-keepalive 0"
sl.syslog(sl.LOG_NOTICE, cmd)
#print (cmd)
subprocess.call([cmd], shell=True)
""" remove psk_file """
if os.path.exists(psk_file):
os.remove(psk_file)
def add_addr(intf, addr):
# see https://phabricator.vyos.net/T949
ret = subprocess.call(['ip a a dev ' + intf + ' ' + addr + ' &>/dev/null'], shell=True)
sl.syslog(sl.LOG_NOTICE, "ip a a dev " + intf + " " + addr)
def del_addr(intf, addr):
ret = subprocess.call(['ip a d dev ' + intf + ' ' + addr + ' &>/dev/null'], shell=True)
sl.syslog(sl.LOG_NOTICE, "ip a d dev " + intf + " " + addr)
def remove_peer(intf, peer_key):
cmd = 'sudo wg set ' + str(intf) + ' peer ' + peer_key + ' remove &>/dev/null'
ret = subprocess.call([cmd], shell=True)
sl.syslog(sl.LOG_NOTICE, "peer " + peer_key + " removed from " + intf)
if __name__ == '__main__':
try:
check_kmod()
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
Sat, Sep 26, 2:29 PM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4285398
Default Alt Text
(17 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment