mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-15 09:04:39 +00:00
VPN/IPsec - add event handler for manual spd entries if reqid is set.
This commit is contained in:
parent
ed7afdb77d
commit
759dd48aed
7
plist
7
plist
@ -335,6 +335,7 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/KeyPairsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/LeasesController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/LegacySubsystemController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/ManualSpdController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/PoolsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/PreSharedKeysController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/Api/SadController.php
|
||||
@ -359,6 +360,7 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogPSK.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogPool.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogRemote.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogSPD.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogVTI.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LoopbackSettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VipSettingsController.php
|
||||
@ -600,6 +602,7 @@
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/FieldTypes/IKEAdressField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/FieldTypes/IPsecProposalField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/FieldTypes/PoolsField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/FieldTypes/SPDField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/FieldTypes/VTIField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/IPsec.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/IPsec.xml
|
||||
@ -884,12 +887,14 @@
|
||||
/usr/local/opnsense/scripts/ipsec/connect.py
|
||||
/usr/local/opnsense/scripts/ipsec/disconnect.py
|
||||
/usr/local/opnsense/scripts/ipsec/get_legacy_vti.php
|
||||
/usr/local/opnsense/scripts/ipsec/lib/__init__.py
|
||||
/usr/local/opnsense/scripts/ipsec/list_leases.py
|
||||
/usr/local/opnsense/scripts/ipsec/list_sad.py
|
||||
/usr/local/opnsense/scripts/ipsec/list_spd.py
|
||||
/usr/local/opnsense/scripts/ipsec/list_status.py
|
||||
/usr/local/opnsense/scripts/ipsec/saddelete.py
|
||||
/usr/local/opnsense/scripts/ipsec/spddelete.py
|
||||
/usr/local/opnsense/scripts/ipsec/updown_event.py
|
||||
/usr/local/opnsense/scripts/netflow/dump_log.py
|
||||
/usr/local/opnsense/scripts/netflow/export_details.py
|
||||
/usr/local/opnsense/scripts/netflow/flowctl_stats.py
|
||||
@ -1043,6 +1048,8 @@
|
||||
/usr/local/opnsense/service/templates/OPNsense/IPFW/ipfw_rule_tables.conf
|
||||
/usr/local/opnsense/service/templates/OPNsense/IPFW/rc.conf.d
|
||||
/usr/local/opnsense/service/templates/OPNsense/IPFW/rules.macro
|
||||
/usr/local/opnsense/service/templates/OPNsense/IPsec/+TARGETS
|
||||
/usr/local/opnsense/service/templates/OPNsense/IPsec/reqid_events.conf
|
||||
/usr/local/opnsense/service/templates/OPNsense/Macros/interface.macro
|
||||
/usr/local/opnsense/service/templates/OPNsense/Monit/+TARGETS
|
||||
/usr/local/opnsense/service/templates/OPNsense/Monit/monitrc
|
||||
|
||||
@ -174,6 +174,12 @@ class Swanctl extends BaseModel
|
||||
if (!isset($data['connections'][$parent]['children'])) {
|
||||
$data['connections'][$parent]['children'] = [];
|
||||
}
|
||||
if (!empty($thisnode['reqid'])) {
|
||||
// trigger updown event handler when a reqid is set.
|
||||
// currently this only handles manual spd entries, we may extend/refactor the script later
|
||||
// if needed
|
||||
$thisnode['updown'] = '/usr/local/opnsense/scripts/ipsec/updown_event.py';
|
||||
}
|
||||
$data['connections'][$parent]['children'][$node_uuid] = $thisnode;
|
||||
} else {
|
||||
$data['connections'][$parent][$key . '-' . $node_uuid] = $thisnode;
|
||||
|
||||
57
src/opnsense/scripts/ipsec/lib/__init__.py
Normal file
57
src/opnsense/scripts/ipsec/lib/__init__.py
Normal file
@ -0,0 +1,57 @@
|
||||
"""
|
||||
Copyright (c) 2022 Ad Schellevis <ad@opnsense.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
import subprocess
|
||||
|
||||
|
||||
def list_spds(req_id=None, automatic=True):
|
||||
result = []
|
||||
setkey_text = subprocess.run(['/sbin/setkey', '-PD'], capture_output=True, text=True).stdout.strip()
|
||||
this_record = None
|
||||
line_num = 0
|
||||
for line in setkey_text.split('\n'):
|
||||
if not line.startswith('\t') and len(line) > 10:
|
||||
parts = line.replace('[', ' ').replace(']', ' ').split()
|
||||
this_record = {
|
||||
'src': parts[0],
|
||||
'dst': parts[2],
|
||||
'automatic': False,
|
||||
'reqid': None
|
||||
}
|
||||
line_num = 0
|
||||
elif this_record is None:
|
||||
continue
|
||||
elif line_num == 1:
|
||||
this_record['direction'] = line.split()[0]
|
||||
elif line.startswith('\tlifetime:') and line.find('ifname=') > 0:
|
||||
this_record['automatic'] = True
|
||||
elif line.find('/unique:') > 0:
|
||||
this_record['reqid'] = line.split('/unique:')[1].split()[0]
|
||||
elif line.startswith('\trefcnt'):
|
||||
if (automatic or not this_record['automatic']) and (req_id is None or req_id == this_record['reqid']):
|
||||
result.append(this_record)
|
||||
line_num += 1
|
||||
|
||||
return result
|
||||
88
src/opnsense/scripts/ipsec/updown_event.py
Executable file
88
src/opnsense/scripts/ipsec/updown_event.py
Executable file
@ -0,0 +1,88 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
"""
|
||||
Copyright (c) 2022 Ad Schellevis <ad@opnsense.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
handle swanctl.conf updown event
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import argparse
|
||||
import tempfile
|
||||
from configparser import ConfigParser
|
||||
from lib import list_spds
|
||||
|
||||
spd_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;'
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--reqid', default=os.environ.get('PLUTO_REQID'))
|
||||
parser.add_argument('--local', default=os.environ.get('PLUTO_ME'))
|
||||
parser.add_argument('--remote', default=os.environ.get('PLUTO_PEER'))
|
||||
parser.add_argument('--action', default=os.environ.get('PLUTO_VERB'))
|
||||
cmd_args = parser.parse_args()
|
||||
# init spd's on up-host[-v6], up-client[-v6]
|
||||
if cmd_args.action and cmd_args.action.startswith('up'):
|
||||
if os.path.exists(spd_filename):
|
||||
cnf = ConfigParser()
|
||||
cnf.read(spd_filename)
|
||||
conf_section = 'spd_%s' % cmd_args.reqid
|
||||
if cnf.has_section(conf_section):
|
||||
spds = {}
|
||||
for opt in cnf.options(conf_section):
|
||||
if opt.count('_') == 1:
|
||||
tmp = opt.split('_')
|
||||
seqid = tmp[1]
|
||||
if seqid not in spds:
|
||||
spds[seqid] = {
|
||||
'reqid': cmd_args.reqid,
|
||||
'local' : cmd_args.local,
|
||||
'remote' : cmd_args.remote,
|
||||
'destination': os.environ.get('PLUTO_PEER_CLIENT')
|
||||
}
|
||||
if cnf.get(conf_section, opt).strip() != '':
|
||||
spds[seqid][tmp[0]] = cnf.get(conf_section, opt).strip()
|
||||
# (re)aaply manual policies if specified
|
||||
cur_spds = list_spds(req_id=cmd_args.reqid, automatic=False)
|
||||
set_key = []
|
||||
for spd in cur_spds:
|
||||
set_key.append('spddelete -n %(src)s %(dst)s any -P %(direction)s;' % spd)
|
||||
for spd in spds.values():
|
||||
if None in spd.values():
|
||||
# incomplete, skip
|
||||
continue
|
||||
spd['ipproto'] = '4' if spd.get('source', '').find(':') == -1 else '6'
|
||||
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)
|
||||
1
src/opnsense/service/templates/OPNsense/IPsec/+TARGETS
Normal file
1
src/opnsense/service/templates/OPNsense/IPsec/+TARGETS
Normal file
@ -0,0 +1 @@
|
||||
reqid_events.conf:/usr/local/etc/swanctl/reqid_events.conf
|
||||
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Automatic generated configuration for IPsec.
|
||||
# Do not edit this file manually.
|
||||
#
|
||||
|
||||
{% set prev_spd = {'reqid' : None } %}
|
||||
{% for spd in helpers.toList('OPNsense.Swanctl.SPDs.SPD', 'reqid', 'int') %}
|
||||
{% if spd.enabled == '1' %}
|
||||
{% if prev_spd.reqid != spd.reqid %}
|
||||
|
||||
[spd_{{spd.reqid}}]
|
||||
{% endif %}
|
||||
protocol_{{loop.index}}={{spd.protocol}}
|
||||
reqid_{{loop.index}}={{spd.reqid}}
|
||||
source_{{loop.index}}={{spd.source}}
|
||||
destination_{{loop.index}}={{spd.destination}}
|
||||
description_{{loop.index}}={{spd.description}}
|
||||
uuid_{{loop.index}}={{spd['uuid']}}
|
||||
{% do prev_spd.update({'reqid': spd.reqid}) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
Loading…
x
Reference in New Issue
Block a user