mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-19 19:15:22 +00:00
VPN: IPsec: Virtual Tunnel Interfaces - optionally hook vti tunnel configuration to connection up event in order to support dynamic dns scenarios. closes https://github.com/opnsense/core/issues/6781
Simplify ipsec_configure_vti() to make sure we only drop interfaces when not required anymore (tunnel address cleanup is unconditional) and only set local/remote address when configured.
This commit is contained in:
parent
fb0f9764e0
commit
7182c0455f
@ -1731,26 +1731,7 @@ function ipsec_configure_vti($verbose = false, $device = null)
|
||||
continue;
|
||||
}
|
||||
|
||||
$local_configured = null;
|
||||
$remote_configured = null;
|
||||
if (!empty($configured_intf[$intf])) {
|
||||
if (!is_ipaddr($configured_intf[$intf]['local'])) {
|
||||
$local_configured = ipsec_resolve($configured_intf[$intf]['local']);
|
||||
} else {
|
||||
$local_configured = $configured_intf[$intf]['local'];
|
||||
}
|
||||
if (!is_ipaddr($configured_intf[$intf]['remote'])) {
|
||||
$remote_configured = ipsec_resolve($configured_intf[$intf]['remote']);
|
||||
} else {
|
||||
$remote_configured = $configured_intf[$intf]['remote'];
|
||||
}
|
||||
}
|
||||
if (
|
||||
empty($configured_intf[$intf])
|
||||
|| empty($intf_details['tunnel'])
|
||||
|| $local_configured != $intf_details['tunnel']['src_addr']
|
||||
|| $remote_configured != $intf_details['tunnel']['dest_addr']
|
||||
) {
|
||||
if (empty($configured_intf[$intf])) {
|
||||
log_msg(sprintf("destroy interface %s", $intf), LOG_DEBUG);
|
||||
legacy_interface_destroy($intf);
|
||||
unset($current_interfaces[$intf]);
|
||||
@ -1797,7 +1778,10 @@ function ipsec_configure_vti($verbose = false, $device = null)
|
||||
if (legacy_interface_create('ipsec', $intf) === null) {
|
||||
break;
|
||||
}
|
||||
mwexecf('/sbin/ifconfig %s reqid %s', [$intf, $intf_details['reqid']]);
|
||||
}
|
||||
// [re]initialise if_ipsec
|
||||
mwexecf('/sbin/ifconfig %s reqid %s', [$intf, $intf_details['reqid']]);
|
||||
if (!empty($intf_details['local']) && !empty($intf_details['remote'])) {
|
||||
mwexecf('/sbin/ifconfig %s %s tunnel %s %s up', [
|
||||
$intf,
|
||||
is_ipaddrv6($intf_details['local']) ? 'inet6' : 'inet',
|
||||
|
||||
@ -92,6 +92,18 @@ class Swanctl extends BaseModel
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(empty((string)$node->local) && !empty((string)$node->remote)) ||
|
||||
(!empty((string)$node->local) && empty((string)$node->remote))
|
||||
) {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
gettext("A local and remote address should be provided or both should be left empty"),
|
||||
$key . ".local"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($vti_inets['local'] != $vti_inets['remote']) {
|
||||
$messages->appendMessage(new Message(gettext("Protocol families should match"), $key . ".local"));
|
||||
}
|
||||
|
||||
@ -365,13 +365,11 @@
|
||||
<local type="NetworkField">
|
||||
<NetMaskAllowed>N</NetMaskAllowed>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
<Required>Y</Required>
|
||||
<ValidationMessage>Please specify a valid address.</ValidationMessage>
|
||||
</local>
|
||||
<remote type="NetworkField">
|
||||
<NetMaskAllowed>N</NetMaskAllowed>
|
||||
<WildcardEnabled>N</WildcardEnabled>
|
||||
<Required>Y</Required>
|
||||
<ValidationMessage>Please specify a valid address.</ValidationMessage>
|
||||
</remote>
|
||||
<tunnel_local type="NetworkField">
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
handle swanctl.conf updown event
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import argparse
|
||||
import tempfile
|
||||
@ -37,7 +36,7 @@ import syslog
|
||||
from configparser import ConfigParser
|
||||
from lib import list_spds
|
||||
|
||||
spd_filename = '/usr/local/etc/swanctl/reqid_events.conf'
|
||||
events_filename = '/usr/local/etc/swanctl/reqid_events.conf'
|
||||
|
||||
spd_add_cmd = 'spdadd -%(ipproto)s %(source)s %(destination)s any ' \
|
||||
'-P out ipsec %(protocol)s/tunnel/%(local)s-%(remote)s/unique:%(reqid)s;'
|
||||
@ -54,47 +53,64 @@ if __name__ == '__main__':
|
||||
if cmd_args.action and cmd_args.action.startswith('up'):
|
||||
syslog.openlog('charon', facility=syslog.LOG_LOCAL4)
|
||||
syslog.syslog(syslog.LOG_NOTICE, '[UPDOWN] received %s event for reqid %s' % (cmd_args.action, cmd_args.reqid))
|
||||
if os.path.exists(spd_filename):
|
||||
if os.path.exists(events_filename):
|
||||
cnf = ConfigParser()
|
||||
cnf.read(spd_filename)
|
||||
cnf.read(events_filename)
|
||||
spds = []
|
||||
vtis = []
|
||||
for section in cnf.sections():
|
||||
if cnf.get(section, 'reqid') == cmd_args.reqid \
|
||||
or cnf.get(section, 'connection_child') == cmd_args.connection_child:
|
||||
spds.append({
|
||||
'reqid': cmd_args.reqid,
|
||||
'local' : cmd_args.local,
|
||||
'remote' : cmd_args.remote,
|
||||
'destination': os.environ.get('PLUTO_PEER_CLIENT')
|
||||
})
|
||||
for opt in cnf.options(section):
|
||||
if cnf.get(section, opt).strip() != '':
|
||||
spds[-1][opt] = cnf.get(section, opt).strip()
|
||||
if section.startswith('spd_'):
|
||||
spds.append({
|
||||
'reqid': cmd_args.reqid,
|
||||
'local' : cmd_args.local,
|
||||
'remote' : cmd_args.remote,
|
||||
'destination': os.environ.get('PLUTO_PEER_CLIENT')
|
||||
})
|
||||
for opt in cnf.options(section):
|
||||
if cnf.get(section, opt).strip() != '':
|
||||
spds[-1][opt] = cnf.get(section, opt).strip()
|
||||
elif section.startswith('vti_'):
|
||||
vtis.append({
|
||||
'reqid': cmd_args.reqid,
|
||||
'local' : cmd_args.local,
|
||||
'remote' : cmd_args.remote
|
||||
})
|
||||
|
||||
# (re)apply manual policies if specified
|
||||
cur_spds = list_spds(automatic=False)
|
||||
set_key = []
|
||||
for spd in cur_spds:
|
||||
policy_found = False
|
||||
for mspd in spds:
|
||||
if mspd['source'] == spd['src'] and mspd['destination'] == spd['dst']:
|
||||
policy_found = True
|
||||
if policy_found or spd['reqid'] == cmd_args.reqid:
|
||||
set_key.append('spddelete -n %(src)s %(dst)s any -P %(direction)s;' % spd)
|
||||
for vti in vtis:
|
||||
if None in vti.values():
|
||||
# incomplete, skip
|
||||
continue
|
||||
intf = 'ipsec%s' % vti['reqid']
|
||||
proto = 'inet6' if vti['local'].find(':') > -1 else 'inet'
|
||||
subprocess.run(['/sbin/ifconfig', intf, 'reqid', vti['reqid']])
|
||||
subprocess.run(['/sbin/ifconfig', intf, proto, 'tunnel', vti['local'], vti['remote']])
|
||||
|
||||
for spd in spds:
|
||||
if None in spd.values():
|
||||
# incomplete, skip
|
||||
continue
|
||||
spd['ipproto'] = '4' if spd.get('source', '').find(':') == -1 else '6'
|
||||
syslog.syslog(
|
||||
syslog.LOG_NOTICE,
|
||||
'[UPDOWN] add manual policy : %s' % (spd_add_cmd % spd)[7:]
|
||||
)
|
||||
set_key.append(spd_add_cmd % spd)
|
||||
if len(set_key) > 0:
|
||||
f = tempfile.NamedTemporaryFile(mode='wt', delete=False)
|
||||
f.write('\n'.join(set_key))
|
||||
f.close()
|
||||
subprocess.run(['/sbin/setkey', '-f', f.name], capture_output=True, text=True)
|
||||
os.unlink(f.name)
|
||||
# (re)apply manual policies if specified
|
||||
cur_spds = list_spds(automatic=False)
|
||||
set_key = []
|
||||
for spd in cur_spds:
|
||||
policy_found = False
|
||||
for mspd in spds:
|
||||
if mspd['source'] == spd['src'] and mspd['destination'] == spd['dst']:
|
||||
policy_found = True
|
||||
if policy_found or spd['reqid'] == cmd_args.reqid:
|
||||
set_key.append('spddelete -n %(src)s %(dst)s any -P %(direction)s;' % spd)
|
||||
|
||||
for spd in spds:
|
||||
if None in spd.values():
|
||||
# incomplete, skip
|
||||
continue
|
||||
spd['ipproto'] = '4' if spd.get('source', '').find(':') == -1 else '6'
|
||||
syslog.syslog(
|
||||
syslog.LOG_NOTICE,
|
||||
'[UPDOWN] add manual policy : %s' % (spd_add_cmd % spd)[7:]
|
||||
)
|
||||
set_key.append(spd_add_cmd % spd)
|
||||
if len(set_key) > 0:
|
||||
f = tempfile.NamedTemporaryFile(mode='wt', delete=False)
|
||||
f.write('\n'.join(set_key))
|
||||
f.close()
|
||||
subprocess.run(['/sbin/setkey', '-f', f.name], capture_output=True, text=True)
|
||||
os.unlink(f.name)
|
||||
|
||||
@ -16,3 +16,14 @@ description = {{spd.description}}
|
||||
uuid = {{spd['@uuid']}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for vti in helpers.toList('OPNsense.Swanctl.VTIs.VTI') %}
|
||||
{% if vti.enabled == '1' and vti.local|default('') == '' and vti.remote|default('') == '' %}
|
||||
|
||||
[vti_{{vti['@uuid']|replace('-', '')}}]
|
||||
reqid = {{vti.reqid}}
|
||||
description = {{vti.description}}
|
||||
uuid = {{vti['@uuid']}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user