mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 16:44:39 +00:00
VPN: IPsec: Security Policy Database - refactor to MVC and extend functionality.
o add a remove button hooking spddelete to remove entries when not cleanedup correctly for some reason to ease maintenance o add reqid to IPsec phase 2 tunnel view for clarity so we can easily inspect if traffic is trying to pass the right policy o show Ikeid and Reqid including optional phase[1|2] description when provided o extend fields with data provided from setkey -DP, but keep them deselected in the default view (e.g. Upperspec, Mode, Type, ..)
This commit is contained in:
parent
9b7073d3b0
commit
434a0a80e8
@ -627,60 +627,6 @@ function ipsec_phase1_status($ipsec_status, $ikeid)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return dump of SPD table
|
||||
*/
|
||||
function ipsec_dump_spd()
|
||||
{
|
||||
$fd = @popen("/sbin/setkey -DP", "r");
|
||||
$spd = array();
|
||||
if ($fd) {
|
||||
$i = 0;
|
||||
while (!feof($fd)) {
|
||||
$line = chop(fgets($fd));
|
||||
if (!$line) {
|
||||
continue;
|
||||
}
|
||||
if ($line == "No SPD entries.") {
|
||||
break;
|
||||
}
|
||||
if ($line[0] != "\t") {
|
||||
if (isset($cursp)) {
|
||||
$spd[] = $cursp;
|
||||
}
|
||||
$cursp = array();
|
||||
$linea = explode(" ", $line);
|
||||
$cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
|
||||
$cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
|
||||
$i = 0;
|
||||
} elseif (isset($cursp)) {
|
||||
$linea = explode(" ", trim($line));
|
||||
switch ($i) {
|
||||
case 1:
|
||||
if ($linea[1] == "none") { /* don't show default anti-lockout rule */
|
||||
unset($cursp);
|
||||
} else {
|
||||
$cursp['dir'] = $linea[0];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
$upperspec = explode("/", $linea[0]);
|
||||
$cursp['proto'] = $upperspec[0];
|
||||
list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
|
||||
$cursp['reqid'] = substr($upperspec[3], strpos($upperspec[3], "#") + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (isset($cursp) && count($cursp)) {
|
||||
$spd[] = $cursp;
|
||||
}
|
||||
pclose($fd);
|
||||
}
|
||||
|
||||
return $spd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return dump of SAD table
|
||||
|
||||
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Deciso B.V.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace OPNsense\IPsec\Api;
|
||||
|
||||
use OPNsense\Base\ApiControllerBase;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
/**
|
||||
* Class SpdController
|
||||
* @package OPNsense\IPsec\Api
|
||||
*/
|
||||
class SpdController extends ApiControllerBase
|
||||
{
|
||||
/**
|
||||
* Search SPD entrys
|
||||
* @return array
|
||||
*/
|
||||
public function searchAction()
|
||||
{
|
||||
$this->sessionClose();
|
||||
$data = json_decode((new Backend())->configdRun('ipsec list spd'), true);
|
||||
$records = (!empty($data) && !empty($data['records'])) ? $data['records'] : [];
|
||||
|
||||
// link IPsec phase1/2 references
|
||||
$config = Config::getInstance()->object();
|
||||
$reqids = [];
|
||||
$phase1s = [];
|
||||
if (!empty($config->ipsec->phase1)) {
|
||||
foreach ($config->ipsec->phase1 as $p1) {
|
||||
if (!empty((string)$p1->ikeid)) {
|
||||
$phase1s[(string)$p1->ikeid] = $p1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($config->ipsec->phase2)) {
|
||||
foreach ($config->ipsec->phase2 as $p2) {
|
||||
if (!empty((string)$p2->reqid) && !empty($phase1s[(string)$p2->ikeid])) {
|
||||
$p1 = $phase1s[(string)$p2->ikeid];
|
||||
$reqids[(string)$p2->reqid] = [
|
||||
"ikeid" => (string)$p2->ikeid,
|
||||
"phase1desc" => (string)$p1->descr,
|
||||
"phase2desc" => (string)$p2->descr
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($records as &$record) {
|
||||
if (!empty($record['reqid']) && !empty($reqids[$record['reqid']])) {
|
||||
$record = array_merge($record, $reqids[$record['reqid']]);
|
||||
} else {
|
||||
$record['ikeid'] = null;
|
||||
$record['phase1desc'] = null;
|
||||
$record['phase2desc'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $this->searchRecordsetBase($records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an SPD entry
|
||||
* @param string $id md 5 hash to identify the spd entry
|
||||
* @return array
|
||||
*/
|
||||
public function deleteAction($id)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$this->sessionClose();
|
||||
$data = json_decode((new Backend())-> configdpRun('ipsec spddelete', [$id]), true);
|
||||
if ($data) {
|
||||
$data['result'] = "ok";
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
return ["result" => "failed"];
|
||||
}
|
||||
}
|
||||
@ -29,7 +29,6 @@
|
||||
namespace OPNsense\IPsec\Api;
|
||||
|
||||
use OPNsense\Base\ApiControllerBase;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
/**
|
||||
@ -238,6 +237,7 @@ class TunnelController extends ApiControllerBase
|
||||
"id" => $p2idx,
|
||||
"uniqid" => (string)$p2->uniqid, // XXX: a bit convoluted, should probably replace id at some point
|
||||
"ikeid" => $ikeid,
|
||||
"reqid" => (string)$p2->reqid,
|
||||
"enabled" => empty((string)$p2->disabled) ? "1" : "0",
|
||||
"protocol" => $p2->protocol == "esp" ? "ESP" : "AH",
|
||||
"mode" => $p2mode,
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Deciso B.V.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace OPNsense\IPsec;
|
||||
|
||||
/**
|
||||
* Class SpdController
|
||||
* @package OPNsense\IPsec
|
||||
*/
|
||||
class SpdController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/IPsec/spd');
|
||||
}
|
||||
}
|
||||
@ -70,7 +70,8 @@
|
||||
<page-status-ipsec-spd>
|
||||
<name>Status: IPsec: SPD</name>
|
||||
<patterns>
|
||||
<pattern>diag_ipsec_spd.php*</pattern>
|
||||
<pattern>ui/ipsec/spd</pattern>
|
||||
<pattern>api/ipsec/spd/*</pattern>
|
||||
</patterns>
|
||||
</page-status-ipsec-spd>
|
||||
<page-status-systemlogs-ipsecvpn>
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
</Status>
|
||||
<Leases order="70" VisibleName="Lease Status" url="/diag_ipsec_leases.php"/>
|
||||
<SAD order="80" VisibleName="Security Association Database" url="/diag_ipsec_sad.php"/>
|
||||
<SPD order="90" VisibleName="Security Policy Database" url="/diag_ipsec_spd.php"/>
|
||||
<SPD order="90" VisibleName="Security Policy Database" url="/ui/ipsec/spd"/>
|
||||
<LogFile order="100" VisibleName="Log File" url="/ui/diagnostics/log/core/ipsec"/>
|
||||
</IPsec>
|
||||
</VPN>
|
||||
|
||||
120
src/opnsense/mvc/app/views/OPNsense/IPsec/spd.volt
Normal file
120
src/opnsense/mvc/app/views/OPNsense/IPsec/spd.volt
Normal file
@ -0,0 +1,120 @@
|
||||
{#
|
||||
# Copyright (c) 2022 Deciso B.V.
|
||||
# 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.
|
||||
#}
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
$( document ).ready(function() {
|
||||
let grid_spd = $("#grid-spd").UIBootgrid({
|
||||
search:'/api/ipsec/spd/search',
|
||||
del:'/api/ipsec/spd/delete/',
|
||||
options:{
|
||||
formatters:{
|
||||
commands: function (column, row) {
|
||||
return '<button type="button" class="btn btn-xs btn-default command-delete bootgrid-tooltip" title="{{ lang._('Drop') }}" data-row-id="' + row.id + '"><span class="fa fa-trash-o fa-fw"></span></button>';
|
||||
},
|
||||
direction: function (column, row) {
|
||||
if (row[column.id] == 'out') {
|
||||
return "<span class=\"fa fa-arrow-left\" title=\"{{lang._('out')}}\" data-toggle=\"tooltip\"></span>";
|
||||
} else {
|
||||
return "<span class=\"fa fa-arrow-right\" title=\"{{lang._('in')}}\" data-toggle=\"tooltip\"></span>";
|
||||
}
|
||||
},
|
||||
address: function (column, row) {
|
||||
let addr_txt = row[column.id];
|
||||
if (row[column.id+"_port"]) {
|
||||
addr_txt = addr_txt + "[" + row[column.id+"_port"] + "]";
|
||||
}
|
||||
return addr_txt;
|
||||
},
|
||||
tunnel: function (column, row) {
|
||||
if (Array.isArray(row[column.id])) {
|
||||
return row[column.id].join('->');
|
||||
}
|
||||
return "";
|
||||
},
|
||||
tunnel_info: function (column, row) {
|
||||
let txt = "";
|
||||
let lbl_field = column.id == "reqid" ? "phase2desc" : "phase1desc";
|
||||
if (row[column.id] != null) {
|
||||
txt += row[column.id];
|
||||
if (row[lbl_field]) {
|
||||
let label = row[lbl_field].replace('"', "'");
|
||||
txt += "<span class=\"fa fa-fw fa-info-circle\" title=\""+label+"\" data-toggle=\"tooltip\"></span>";
|
||||
}
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
grid_spd.on('loaded.rs.jquery.bootgrid', function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="tab-content content-box">
|
||||
<table id="grid-spd" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogEdit">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="id" data-type="string" data-sortable="false" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="direction" data-type="string" data-width="4em" data-formatter="direction">{{ lang._('Dir') }}</th>
|
||||
<th data-column-id="src" data-type="string" data-formatter="address">{{ lang._('Source') }}</th>
|
||||
<th data-column-id="dst" data-type="string" data-formatter="address">{{ lang._('Destination') }}</th>
|
||||
<th data-column-id="upperspec" data-type="string" data-visible="false">{{ lang._('Upperspec') }}</th>
|
||||
<th data-column-id="type" data-type="string" data-visible="false">{{ lang._('Type') }}</th>
|
||||
<th data-column-id="src-dst" data-formatter="tunnel" data-sortable="false" data-type="string">{{ lang._('Tunnel endpoints') }}</th>
|
||||
<th data-column-id="level" data-type="string" data-visible="false">{{ lang._('Level') }}</th>
|
||||
<th data-column-id="ikeid" data-type="string" data-formatter="tunnel_info">
|
||||
{{ lang._('Ikeid') }}
|
||||
<span class="fa fa-fw fa-info-circle" title="{{ lang._('Tunnel phase 1 definition') }}" data-toggle="tooltip"></span>
|
||||
</th>
|
||||
<th data-column-id="reqid" data-type="string" data-formatter="tunnel_info">
|
||||
{{ lang._('Reqid') }}
|
||||
<span class="fa fa-fw fa-info-circle" title="{{ lang._('Tunnel phase 2 definition') }}" data-toggle="tooltip"></span>
|
||||
</th>
|
||||
<th data-column-id="proto" data-type="string">{{ lang._('Protocol') }}</th>
|
||||
<th data-column-id="mode" data-type="string" data-visible="false">{{ lang._('Mode') }}</th>
|
||||
<th data-column-id="type" data-type="string" data-visible="false">{{ lang._('Type') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o fa-fw"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
@ -277,9 +277,10 @@
|
||||
<table id="grid-phase2" class="table table-condensed table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle" data-sortable="false">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="id" data-type="numeric" data-identifier="true" data-visible="false">ID</th>
|
||||
<th data-column-id="uniqid" data-type="string" data-visible="false">{{ lang._('uniqid') }}</th>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle" data-sortable="false">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="reqid" data-type="string" data-width="6em">{{ lang._('Reqid') }}</th>
|
||||
<th data-column-id="type" data-width="8em" data-type="string" data-formatter="mode_type" data-sortable="false">{{ lang._('Type') }}</th>
|
||||
<th data-column-id="local_subnet" data-width="18em" data-type="string">{{ lang._('Local Subnet') }}</th>
|
||||
<th data-column-id="remote_subnet" data-width="18em" data-type="string">{{ lang._('Remote Subnet') }}</th>
|
||||
|
||||
85
src/opnsense/scripts/ipsec/list_spd.py
Executable file
85
src/opnsense/scripts/ipsec/list_spd.py
Executable file
@ -0,0 +1,85 @@
|
||||
#!/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.
|
||||
|
||||
"""
|
||||
import hashlib
|
||||
import subprocess
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = {'records': []}
|
||||
sp = subprocess.run(['/sbin/setkey', '-DP'], capture_output=True, text=True)
|
||||
line_no = 0
|
||||
spd_rec = None
|
||||
spec_line = ""
|
||||
for line in sp.stdout.split("\n"):
|
||||
line_no += 1
|
||||
parts = line.split()
|
||||
if not line.startswith("\t") and line.count('/') == 2:
|
||||
line_no = 0
|
||||
spec_line = line.strip()
|
||||
spd_rec = {
|
||||
'src': parts[0].split('[')[0],
|
||||
'dst': parts[1].split('[')[0]
|
||||
}
|
||||
if parts[0].find('[') > 0:
|
||||
spd_rec['src_port'] = parts[0].split('[')[1].split(']')[0]
|
||||
if parts[1].find('[') > 0:
|
||||
spd_rec['dst_port'] = parts[1].split('[')[1].split(']')[0]
|
||||
spd_rec['upperspec'] = parts[2]
|
||||
elif spd_rec and line_no == 1 and len(parts) >= 2:
|
||||
spd_rec['dir'] = parts[0]
|
||||
spd_rec['type'] = parts[1]
|
||||
# the spd record (used for spddelete) identities itself by the spec {first row} + direction
|
||||
ident = "%s %s" % (spec_line, parts[0])
|
||||
spd_rec['id'] = hashlib.md5(ident.encode()).hexdigest()
|
||||
elif spd_rec and line_no == 2 and line.count('/') >= 3:
|
||||
parts = line.strip().split('/')
|
||||
spd_rec['proto'] = parts[0]
|
||||
spd_rec['mode'] = parts[1]
|
||||
spd_rec['src-dst'] = parts[2].split('-')
|
||||
spd_rec['level'] = parts[3].split('#')[0].split(':')[0]
|
||||
if parts[3].find(':') > -1:
|
||||
spd_rec['reqid'] = parts[3].split(':')[-1]
|
||||
elif spd_rec and line.find('=') > 0:
|
||||
for attr in parts:
|
||||
if attr.find('=') > -1:
|
||||
tmp = attr.split('=')
|
||||
spd_rec[tmp[0]] = tmp[1]
|
||||
if line.startswith('\trefcnt'):
|
||||
result['records'].append(spd_rec)
|
||||
|
||||
# make sure all records are formatted equally in terms of available fields
|
||||
all_keys = set()
|
||||
for record in result['records']:
|
||||
all_keys = all_keys.union(record.keys())
|
||||
for record in result['records']:
|
||||
for key in all_keys:
|
||||
if key not in record:
|
||||
record[key] = None
|
||||
|
||||
print(ujson.dumps(result))
|
||||
59
src/opnsense/scripts/ipsec/spddelete.py
Executable file
59
src/opnsense/scripts/ipsec/spddelete.py
Executable file
@ -0,0 +1,59 @@
|
||||
#!/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.
|
||||
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import subprocess
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('id', help='record id (md5 hash)')
|
||||
cmd_args = parser.parse_args()
|
||||
|
||||
result = {'status': 'not_found'}
|
||||
sp = subprocess.run(['/sbin/setkey', '-DP'], capture_output=True, text=True)
|
||||
spec_line = None
|
||||
for line in sp.stdout.split("\n"):
|
||||
if not line.startswith("\t") and line.count('/') == 2:
|
||||
spec_line = line.strip()
|
||||
elif spec_line:
|
||||
ident = "%s %s" % (spec_line, line.strip().split()[0])
|
||||
if hashlib.md5(ident.encode()).hexdigest() == cmd_args.id:
|
||||
result['status'] = 'found'
|
||||
parts = ident.split()
|
||||
result['src_range'] = parts[0]
|
||||
result['dst_range'] = parts[1]
|
||||
result['upperspec'] = parts[2]
|
||||
result['direction'] = parts[3]
|
||||
policy = "spddelete -n %(src_range)s %(dst_range)s %(upperspec)s -P %(direction)s;" % result
|
||||
p = subprocess.run(['/sbin/setkey', '-c'], capture_output=True, text=True, input=policy)
|
||||
|
||||
spec_line = None
|
||||
|
||||
print(ujson.dumps(result))
|
||||
@ -10,6 +10,12 @@ parameters:
|
||||
type:script_output
|
||||
message:IPsec list ip address pools
|
||||
|
||||
[list.spd]
|
||||
command:/usr/local/opnsense/scripts/ipsec/list_spd.py
|
||||
parameters:
|
||||
type:script_output
|
||||
message:List SPD entries
|
||||
|
||||
[connect]
|
||||
command:/usr/local/opnsense/scripts/ipsec/connect.py
|
||||
parameters:%s
|
||||
@ -22,6 +28,12 @@ parameters:%s
|
||||
type:script
|
||||
message:IPsec disconnect %s
|
||||
|
||||
[spddelete]
|
||||
command:/usr/local/opnsense/scripts/ipsec/spddelete.py
|
||||
parameters:%s
|
||||
type:script_output
|
||||
message:List SPD entry %s
|
||||
|
||||
[status]
|
||||
command:/usr/local/etc/rc.d/strongswan onestatus 2> /dev/null && echo "ipsec is running" || echo "ipsec is not running"; exit 0
|
||||
parameters:
|
||||
|
||||
@ -1,96 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Deciso B.V.
|
||||
* Copyright (C) 2004-2009 Scott Ullrich <sullrich@gmail.com>
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
require_once("guiconfig.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("plugins.inc.d/ipsec.inc");
|
||||
|
||||
$service_hook = 'strongswan';
|
||||
|
||||
include("head.inc");
|
||||
|
||||
$spd = ipsec_dump_spd();
|
||||
legacy_html_escape_form_data($spd);
|
||||
|
||||
?>
|
||||
<body>
|
||||
|
||||
<?php include("fbegin.inc"); ?>
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<section class="col-xs-12">
|
||||
<div class="tab-content content-box col-xs-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<?php if (count($spd)): ?>
|
||||
<tr>
|
||||
<td><?= gettext("Source"); ?></td>
|
||||
<td><?= gettext("Destination"); ?></td>
|
||||
<td><?= gettext("Direction"); ?></td>
|
||||
<td><?= gettext("Protocol"); ?></td>
|
||||
<td><?= gettext("Tunnel endpoints"); ?></td>
|
||||
</tr>
|
||||
<?php foreach ($spd as $sp): ?>
|
||||
<tr>
|
||||
<td><?=$sp['srcid'];?></td>
|
||||
<td><?=$sp['dstid'];?></td>
|
||||
<td>
|
||||
<i class="fa fa-arrow-<?= $sp['dir'] == 'in' ? 'right' : 'left' ?> fa-fw" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><?=strtoupper($sp['proto']);?></td>
|
||||
<td><?=$sp['src'];?> -> <?=$sp['dst'];?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr>
|
||||
<td colspan="2"></td>
|
||||
<td colspan="3">
|
||||
<span class="fa fa-arrow-right fa-fw" aria-hidden="true"></span>
|
||||
<?= gettext("incoming (as seen by firewall)"); ?> <br/>
|
||||
<span class="fa fa-arrow-left fa-fw" aria-hidden="true"></span>
|
||||
<?= gettext("outgoing (as seen by firewall)"); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td>
|
||||
<p><strong><?= gettext("No IPsec security policies."); ?></strong></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php include("foot.inc"); ?>
|
||||
Loading…
x
Reference in New Issue
Block a user