Skip to content

Commit c02d527

Browse files
authored
[fix] Support multiple wireguard tunnels on same device #657
Fixes #657
1 parent 2504eaa commit c02d527

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

openwisp_controller/config/base/config.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -543,9 +543,9 @@ def get_vpn_context(self):
543543
}
544544
)
545545
if vpnclient.public_key:
546-
context['public_key'] = vpnclient.public_key
546+
context[f'pub_key_{vpn_id}'] = vpnclient.public_key
547547
if vpnclient.private_key:
548-
context['private_key'] = vpnclient.private_key
548+
context[f'pvt_key_{vpn_id}'] = vpnclient.private_key
549549
if vpn.subnet:
550550
if vpnclient.ip:
551551
context[vpn_context_keys['ip_address']] = vpnclient.ip.ip_address

openwisp_controller/config/base/vpn.py

+1
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ def _get_auto_context_keys(self):
372372
'public_key': 'public_key_{}'.format(pk),
373373
'ip_address': 'ip_address_{}'.format(pk),
374374
'vpn_subnet': 'vpn_subnet_{}'.format(pk),
375+
'private_key': 'pvt_key_{}'.format(pk),
375376
}
376377
)
377378
if self._is_backend_type('vxlan'):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Generated by Django 4.0.5 on 2022-06-24 06:31
2+
3+
from django.db import migrations
4+
5+
from ..migrations import get_swapped_model
6+
7+
8+
def get_wireguard_and_vxlan_wireguard_templates(apps):
9+
template_model = get_swapped_model(apps, 'config', 'Template')
10+
return template_model.objects.filter(type='vpn', vpn__backend__contains='Wireguard')
11+
12+
13+
def allow_multiple_wireguard_tunneling(apps, schema_editor):
14+
templates = get_wireguard_and_vxlan_wireguard_templates(apps).iterator()
15+
for template in templates:
16+
config = template.config
17+
interfaces = config['interfaces']
18+
vpn_id = template.vpn.pk.hex
19+
changed = False
20+
for interface in interfaces:
21+
interface_type = interface.get('type', None)
22+
private_key = interface.get('private_key', None)
23+
if interface_type != 'wireguard' or not private_key:
24+
continue
25+
if private_key not in [
26+
'{{private_key}}',
27+
'{{ private_key }}',
28+
]:
29+
continue
30+
interface['private_key'] = '{{pvt_key_%s}}' % vpn_id
31+
changed = True
32+
if not changed:
33+
continue
34+
template.config = config
35+
template.save(update_fields=['config'])
36+
37+
38+
def disallow_multiple_wireguard_tunneling(apps, schema_editor):
39+
templates = get_wireguard_and_vxlan_wireguard_templates(apps).iterator()
40+
for template in templates:
41+
config = template.config
42+
interfaces = config['interfaces']
43+
vpn_id = template.vpn.pk.hex
44+
changed = False
45+
for interface in interfaces:
46+
interface_type = interface.get('type', None)
47+
private_key = interface.get('private_key', None)
48+
if interface_type != 'wireguard' or not private_key:
49+
continue
50+
if f'pvt_key_{vpn_id}' not in private_key:
51+
continue
52+
interface['private_key'] = '{{private_key}}'
53+
changed = True
54+
if not changed:
55+
continue
56+
template.config = config
57+
template.save(update_fields=['config'])
58+
59+
60+
class Migration(migrations.Migration):
61+
62+
dependencies = [
63+
('config', '0041_default_groups_organizationconfigsettings_permission'),
64+
]
65+
66+
operations = [
67+
migrations.RunPython(
68+
code=allow_multiple_wireguard_tunneling,
69+
reverse_code=disallow_multiple_wireguard_tunneling,
70+
),
71+
]

0 commit comments

Comments
 (0)