%PDF- %PDF-
| Direktori : /proc/thread-self/root/backups/router/usr/local/www/ |
| Current File : //proc/thread-self/root/backups/router/usr/local/www/firewall_rules.php |
<?php
/*
* Copyright (C) 2014-2015 Deciso B.V.
* Copyright (C) 2005 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("filter.inc");
require_once("system.inc");
/***********************************************************************************************************
* format functions for this page
***********************************************************************************************************/
function firewall_rule_item_proto($filterent)
{
// construct line ipprotocol
if (isset($filterent['ipprotocol'])) {
switch($filterent['ipprotocol']) {
case "inet":
$record_ipprotocol = "IPv4 ";
break;
case "inet6":
$record_ipprotocol = "IPv6 ";
break;
case "inet46":
$record_ipprotocol = "IPv4+6 ";
break;
}
} else {
// when ipprotocol is not set, pf would normally figure out the ip proto itself.
// reconstruct ipproto depending on source/destination address.
if (!empty($filterent['from']) && is_ipaddr(explode("/", $filterent['from'])[0])) {
$record_ipprotocol = strpos($filterent['from'], ":") === false ? "IPv4 " : "IPv6 ";
} elseif (!empty($filterent['to']) && is_ipaddr(explode("/", $filterent['to'])[0])) {
$record_ipprotocol = strpos($filterent['to'], ":") === false ? "IPv4 " : "IPv6 ";
} elseif (isset($filterent['source']['address'])
&& is_ipaddr(explode("/", $filterent['source']['address'])[0])) {
$record_ipprotocol = strpos($filterent['source']['address'], ":") === false ? "IPv4 " : "IPv6 ";
} elseif (isset($filterent['destination']['address'])
&& is_ipaddr(explode("/", $filterent['destination']['address'])[0])) {
$record_ipprotocol = strpos($filterent['destination']['address'], ":") === false ? "IPv4 " : "IPv6 ";
} else {
$record_ipprotocol = "IPv4+6 ";
}
}
$icmptypes = array(
"" => gettext("any"),
"echoreq" => gettext("Echo Request"),
"echorep" => gettext("Echo Reply"),
"unreach" => gettext("Destination Unreachable"),
"squench" => gettext("Source Quench (Deprecated)"),
"redir" => gettext("Redirect"),
"althost" => gettext("Alternate Host Address (Deprecated)"),
"routeradv" => gettext("Router Advertisement"),
"routersol" => gettext("Router Solicitation"),
"timex" => gettext("Time Exceeded"),
"paramprob" => gettext("Parameter Problem"),
"timereq" => gettext("Timestamp"),
"timerep" => gettext("Timestamp Reply"),
"inforeq" => gettext("Information Request (Deprecated)"),
"inforep" => gettext("Information Reply (Deprecated)"),
"maskreq" => gettext("Address Mask Request (Deprecated)"),
"maskrep" => gettext("Address Mask Reply (Deprecated)")
);
$icmp6types = array(
"" => gettext("any"),
"unreach" => gettext("Destination unreachable"),
"toobig" => gettext("Packet too big"),
"timex" => gettext("Time exceeded"),
"paramprob" => gettext("Invalid IPv6 header"),
"echoreq" => gettext("Echo service request"),
"echorep" => gettext("Echo service reply"),
"groupqry" => gettext("Group membership query"),
"listqry" => gettext("Multicast listener query"),
"grouprep" => gettext("Group membership report"),
"listenrep" => gettext("Multicast listener report"),
"groupterm" => gettext("Group membership termination"),
"listendone" => gettext("Multicast listener done"),
"routersol" => gettext("Router solicitation"),
"routeradv" => gettext("Router advertisement"),
"neighbrsol" => gettext("Neighbor solicitation"),
"neighbradv" => gettext("Neighbor advertisement"),
"redir" => gettext("Shorter route exists"),
"routrrenum" => gettext("Route renumbering"),
"fqdnreq" => gettext("FQDN query"),
"niqry" => gettext("Node information query"),
"wrureq" => gettext("Who-are-you request"),
"fqdnrep" => gettext("FQDN reply"),
"nirep" => gettext("Node information reply"),
"wrurep" => gettext("Who-are-you reply"),
"mtraceresp" => gettext("mtrace response"),
"mtrace" => gettext("mtrace messages")
);
if (isset($filterent['protocol']) && $filterent['protocol'] == 'icmp') {
$result = $record_ipprotocol;
$icmplabel = $icmptypes[$filterent['icmptype'] ?? ''] ?? $filterent['icmptype'];
$result .= sprintf(
'<span data-toggle="tooltip" title="ICMP type: %s">%s</span>',
html_safe($icmplabel),
isset($filterent['protocol']) ? strtoupper($filterent['protocol']) : '*'
);
return $result;
} elseif (isset($filterent['protocol']) && $filterent['protocol'] == 'ipv6-icmp') {
$result = $record_ipprotocol;
$icmplabel = $icmp6types[$filterent['icmp6-type'] ?? ''] ?? $filterent['icmp6-type'];
$result .= sprintf(
'<span data-toggle="tooltip" title="ICMP6 type: %s">%s</span>',
html_safe($icmplabel),
isset($filterent['protocol']) ? strtoupper($filterent['protocol']) : '*'
);
return $result;
} else {
return $record_ipprotocol . (isset($filterent['protocol']) ? strtoupper($filterent['protocol']) : "*");
}
}
function firewall_rule_item_icons($filterent)
{
$result = "";
if (empty($filterent['direction']) || $filterent['direction'] == "in") {
$result .= sprintf(
"<i class=\"fa fa-long-arrow-right fa-fw text-info\" data-toggle=\"tooltip\" title=\"%s\"></i>",
gettext("in")
);
} elseif (!empty($filterent['direction']) && $filterent['direction'] == "out") {
$result .= sprintf(
"<i class=\"fa fa-long-arrow-left fa-fw\" data-toggle=\"tooltip\" title=\"%s\"></i>",
gettext("out")
);
} else {
$result .= sprintf(
"<i class=\"fa fa-exchange fa-fw\" data-toggle=\"tooltip\" title=\"%s\"></i>",
gettext("any")
);
}
if (empty($filterent['floating']) && !isset($filterent['quick'])){
$is_quick = true;
} elseif (!empty($filterent['floating']) && !isset($filterent['quick'])) {
$is_quick = false;
} else {
$is_quick = $filterent['quick'];
}
if ($is_quick) {
$result .= sprintf(
"<i class=\"fa fa-flash fa-fw text-warning\" data-toggle=\"tooltip\" title=\"%s\"></i>",
gettext('first match')
);
} else {
$result .= sprintf(
"<i class=\"fa fa-flash fa-fw text-muted\" data-toggle=\"tooltip\" title=\"%s\"></i>",
gettext('last match')
);
}
return $result;
}
function firewall_rule_item_action($filterent)
{
if (!isset($filterent['type']) && empty($filterent['disabled'])) {
return "fa fa-play fa-fw text-success";
} elseif (!isset($filterent['type']) && !empty($filterent['disabled'])) {
return "fa fa-play fa-fw text-muted";
} elseif ($filterent['type'] == "block" && empty($filterent['disabled'])) {
return "fa fa-times fa-fw text-danger";
} elseif ($filterent['type'] == "block" && !empty($filterent['disabled'])) {
return "fa fa-times fa-fw text-muted";
} elseif ($filterent['type'] == "reject" && empty($filterent['disabled'])) {
return "fa fa-times-circle fa-fw text-danger";
} elseif ($filterent['type'] == "reject" && !empty($filterent['disabled'])) {
return "fa fa-times-circle fa-fw text-muted";
} elseif (empty($filterent['disabled'])) {
return "fa fa-play fa-fw text-success";
} else {
return "fa fa-play fa-fw text-muted";
}
}
function firewall_rule_item_log($filterent)
{
if (!empty($filterent['log'])) {
return "fa fa-info-circle fa-fw text-info";
} else {
return "fa fa-info-circle fa-fw text-muted";
}
}
function filter_rule_item_alias_tooltip($alias_name)
{
$alias_descr = htmlspecialchars(get_alias_description($alias_name));
$alias_name = htmlspecialchars($alias_name);
$result = "<span title=\"{$alias_descr}\" data-toggle=\"tooltip\" data-html=\"true\">";
$result .= $alias_name . " ";
$result .= "</span>";
$result .= "<a href=\"/ui/firewall/alias/index/{$alias_name}\"";
$result .= " title=\"". gettext("edit alias") ."\" data-toggle=\"tooltip\">";
$result .= "<i class=\"fa fa-list\"></i>";
$result .= "</a>";
return $result;
}
/***********************************************************************************************************
*
***********************************************************************************************************/
$a_filter = &config_read_array('filter', 'rule');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_GET['if'])) {
$current_if = htmlspecialchars($_GET['if']);
} else {
$current_if = "FloatingRules";
}
$pconfig = $_POST;
if (isset($pconfig['id']) && isset($a_filter[$pconfig['id']])) {
// id found and valid
$id = $pconfig['id'];
}
if (isset($pconfig['act']) && $pconfig['act'] == "apply") {
system_cron_configure();
filter_configure();
clear_subsystem_dirty('filter');
$savemsg = get_std_save_message();
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'del' && isset($id)) {
// delete single item
if (!empty($a_filter[$id]['associated-rule-id'])) {
// unlink nat entry
if (isset($config['nat']['rule'])) {
$a_nat = &config_read_array('nat', 'rule');
foreach ($a_nat as &$natent) {
if ($natent['associated-rule-id'] == $a_filter[$id]['associated-rule-id']) {
$natent['associated-rule-id'] = '';
}
}
}
}
unset($a_filter[$id]);
write_config();
mark_subsystem_dirty('filter');
header(url_safe('Location: /firewall_rules.php?if=%s', array($current_if)));
exit;
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'del_x' && isset($pconfig['rule']) && count($pconfig['rule']) > 0) {
// delete selected rules
foreach ($pconfig['rule'] as $rulei) {
// unlink nat entry
if (isset($config['nat']['rule'])) {
$a_nat = &config_read_array('nat', 'rule');
foreach ($a_nat as &$natent) {
if ($natent['associated-rule-id'] == $a_filter[$rulei]['associated-rule-id']) {
$natent['associated-rule-id'] = '';
}
}
}
unset($a_filter[$rulei]);
}
write_config();
mark_subsystem_dirty('filter');
header(url_safe('Location: /firewall_rules.php?if=%s', array($current_if)));
exit;
} elseif (isset($pconfig['act']) && in_array($pconfig['act'], array('toggle_enable', 'toggle_disable')) && isset($pconfig['rule']) && count($pconfig['rule']) > 0) {
foreach ($pconfig['rule'] as $rulei) {
$a_filter[$rulei]['disabled'] = $pconfig['act'] == 'toggle_disable';
}
write_config();
mark_subsystem_dirty('filter');
header(url_safe('Location: /firewall_rules.php?if=%s', array($current_if)));
exit;
} elseif ( isset($pconfig['act']) && $pconfig['act'] == 'move' && isset($pconfig['rule']) && count($pconfig['rule']) > 0) {
// move selected rules
if (!isset($id)) {
// if rule not set/found, move to end
$id = count($a_filter);
}
$a_filter = legacy_move_config_list_items($a_filter, $id, $pconfig['rule']);
write_config();
mark_subsystem_dirty('filter');
header(url_safe('Location: /firewall_rules.php?if=%s', array($current_if)));
exit;
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'toggle' && isset($id)) {
// toggle item
if(isset($a_filter[$id]['disabled'])) {
unset($a_filter[$id]['disabled']);
} else {
$a_filter[$id]['disabled'] = true;
}
write_config();
mark_subsystem_dirty('filter');
$response = array("id" => $id);
$response["new_label"] = !isset($a_filter[$id]['disabled']) ? gettext("Disable Rule") : gettext("Enable Rule");
$response["new_state"] = !isset($a_filter[$id]['disabled']) ;
echo json_encode($response);
exit;
} elseif (isset($pconfig['act']) && $pconfig['act'] == 'log' && isset($id)) {
// toggle logging
if(isset($a_filter[$id]['log'])) {
unset($a_filter[$id]['log']);
} else {
$a_filter[$id]['log'] = true;
}
write_config();
mark_subsystem_dirty('filter');
$response = array("id" => $id);
$response["new_label"] = isset($a_filter[$id]['log']) ? gettext("Disable Log") : gettext("Enable Log");
$response["new_state"] = isset($a_filter[$id]['log']) ;
echo json_encode($response);
exit;
}
}
$selected_if = 'FloatingRules';
if (isset($_GET['if'])) {
$selected_if = htmlspecialchars($_GET['if']);
}
include("head.inc");
$a_filter_raw = config_read_array('filter', 'rule');
legacy_html_escape_form_data($a_filter);
?>
<body>
<script>
$( document ).ready(function() {
// link delete buttons
$(".act_delete").click(function(event){
event.preventDefault();
var id = $(this).attr("id").split('_').pop(-1);
if (id != 'x') {
// delete single
BootstrapDialog.show({
type:BootstrapDialog.TYPE_DANGER,
title: "<?= gettext("Rules");?>",
message: "<?=gettext("Do you really want to delete this rule?");?>",
buttons: [{
label: "<?= gettext("No");?>",
action: function(dialogRef) {
dialogRef.close();
}}, {
label: "<?= gettext("Yes");?>",
action: function(dialogRef) {
$("#id").val(id);
$("#action").val("del");
$("#iform").submit()
}
}]
});
} else {
// delete selected
BootstrapDialog.show({
type:BootstrapDialog.TYPE_DANGER,
title: "<?= gettext("Rules");?>",
message: "<?=gettext("Do you really want to delete the selected rules?");?>",
buttons: [{
label: "<?= gettext("No");?>",
action: function(dialogRef) {
dialogRef.close();
}}, {
label: "<?= gettext("Yes");?>",
action: function(dialogRef) {
$("#id").val("");
$("#action").val("del_x");
$("#iform").submit()
}
}]
});
}
});
// enable/disable selected
$(".act_toggle_enable").click(function(event){
event.preventDefault();
BootstrapDialog.show({
type:BootstrapDialog.TYPE_DANGER,
title: "<?= gettext("Rules");?>",
message: "<?=gettext("Enable selected rules?");?>",
buttons: [{
label: "<?= gettext("No");?>",
action: function(dialogRef) {
dialogRef.close();
}}, {
label: "<?= gettext("Yes");?>",
action: function(dialogRef) {
$("#id").val("");
$("#action").val("toggle_enable");
$("#iform").submit()
}
}]
});
});
$(".act_toggle_disable").click(function(event){
event.preventDefault();
BootstrapDialog.show({
type:BootstrapDialog.TYPE_DANGER,
title: "<?= gettext("Rules");?>",
message: "<?=gettext("Disable selected rules?");?>",
buttons: [{
label: "<?= gettext("No");?>",
action: function(dialogRef) {
dialogRef.close();
}}, {
label: "<?= gettext("Yes");?>",
action: function(dialogRef) {
$("#id").val("");
$("#action").val("toggle_disable");
$("#iform").submit()
}
}]
});
});
// link move buttons
$(".act_move").click(function(event){
event.preventDefault();
var id = $(this).attr("id").split('_').pop(-1);
$("#id").val(id);
$("#action").val("move");
$("#iform").submit();
});
// link apply button
$("#btn_apply").click(function(event){
event.preventDefault();
$("#action").val("apply");
$("#iform").submit();
});
// link toggle buttons
$(".act_toggle").click(function(event){
event.preventDefault();
let target = $(this);
target.addClass('fa-spinner fa-pulse');
let id = target.attr("id").split('_').pop(-1);
$.ajax("firewall_rules.php",{
type: 'post',
cache: false,
dataType: "json",
data: {'act': 'toggle', 'id': id},
success: function(response) {
target.prop('title', response['new_label']).tooltip('fixTitle').tooltip('hide');
target.removeClass('fa-spinner fa-pulse');
if (response['new_state']) {
target.removeClass('text-muted').addClass(target.hasClass('fa-play') ? 'text-success' : 'text-danger');
} else {
target.removeClass('text-success text-danger').addClass('text-muted');
}
$("#fw-alert-box").removeClass("hidden");
$(".fw-alert-messages").addClass("hidden");
$("#fw-alert-changes").removeClass("hidden");
},
error: function () {
target.removeClass('fa-spinner fa-pulse');
}
});
});
// link log buttons
$(".act_log").click(function(event){
event.preventDefault();
let target = $(this);
target.removeClass('fa-info-circle').addClass('fa-spinner fa-pulse');
let id = target.attr("id").split('_').pop(-1);
$.ajax("firewall_rules.php",{
type: 'post',
cache: false,
dataType: "json",
data: {'act': 'log', 'id': id},
success: function(response) {
target.prop('title', response['new_label']).tooltip('fixTitle').tooltip('hide');
target.removeClass('fa-spinner fa-pulse').addClass('fa-info-circle');
if (response['new_state']) {
target.removeClass('text-muted').addClass('text-info');
} else {
target.removeClass('text-info').addClass('text-muted');
}
$("#fw-alert-box").removeClass("hidden");
$(".fw-alert-messages").addClass("hidden");
$("#fw-alert-changes").removeClass("hidden");
},
error: function () {
target.removeClass('fa-spinner fa-pulse').addClass('fa-info-circle');
}
});
});
// watch scroll position and set to last known on page load
watchScrollPosition();
// select All
$("#selectAll").click(function(){
$(".rule_select:not(:disabled)").prop("checked", $(this).prop("checked"));
});
// move category block
$("#category_block").detach().appendTo($(".page-content-head > .container-fluid > .list-inline"));
$("#category_block").addClass("pull-right");
$("#btn_inspect").click(function(){
let mode = $(this).data('mode');
if (mode === 'stats') {
$(".view-stats").hide();
$(".view-info").show();
$(this).removeClass('active');
$(this).data('mode', 'info');
} else {
$(".view-stats").show();
$(".view-info").hide();
$(this).addClass('active');
$(this).data('mode', 'stats');
$.ajax('api/firewall/filter_util/rule_stats', {
success: function(response) {
if (response.status == 'ok') {
let fileSizeTypes = ["", "K", "M", "G", "T", "P", "E", "Z", "Y"];
$.each(response.stats, function(index, value) {
$("#" + index + "_evaluations").text(value.evaluations);
$("#" + index + "_states").text(value.states);
$("#" + index + "_packets").text(value.packets);
if (value.bytes > 0) {
let ndx = Math.floor(Math.log(value.bytes) / Math.log(1000));
$("#" + index + "_bytes").text(
(value.bytes / Math.pow(1000, ndx)).toFixed(2) + ' ' + fileSizeTypes[ndx]
);
} else {
$("#" + index + "_bytes").text("0");
}
});
}
}
});
}
$(this).blur();
});
// hook category functionality
hook_firewall_categories();
// our usual zebra striping doesn't respect hidden rows, hook repaint on .opnsense-rules change() and fire initially
$(".opnsense-rules > tbody > tr").each(function(){
// save zebra color
let tr_color = $(this).children(0).css("background-color");
if (tr_color != 'transparent' && !tr_color.includes('(0, 0, 0')) {
$("#fw_category").data('stripe_color', tr_color);
}
});
$(".opnsense-rules").removeClass("table-striped");
$(".opnsense-rules").change(function(){
$(".opnsense-rules > tbody > tr:visible").each(function (index) {
$(this).css("background-color", "inherit");
if ( index % 2 == 0) {
$(this).css("background-color", $("#fw_category").data('stripe_color'));
}
});
$(".expand_type").each(function(){
let tmp = $(this).data('type');
if ($("tr."+tmp+"-rule").length > 0) {
$("#expand-"+tmp+"-rules").show();
$("#"+tmp+"-rule-count").text($("tr."+tmp+"-rule").length);
}
if ($(this).hasClass('is_collapsed')) {
$("tr."+tmp+"-rule").hide();
}
});
});
$(".expand_type").each(function(){
$("#expand-"+$(this).data('type')).click(function(event){
event.preventDefault();
$(this).parent().parent().toggleClass('is_collapsed');
// trigger category change as this will show/hide all "rule" rows (and fires an event on .opnsense-rules )
$("#fw_category").change();
});
});
// tooltip interface list
$(".interface_tooltip").tooltip({
html: true,
placement: 'bottom',
title: function(){
<?php
$iflist = [];
foreach (legacy_config_get_interfaces() as $intf => $payload) {
$iflist[$intf] = $payload['descr'];
}
echo " let descriptions = JSON.parse('". json_encode($iflist) . "');";?>
let this_interfaces = [];
$.each($(this).data('interfaces').split(','), function(idx, intf) {
if (descriptions[intf]) {
this_interfaces.push(descriptions[intf]);
} else {
// strikeout non existing interface (show, but mark)
this_interfaces.push('<s>'+intf+'</s>');
}
});
return this_interfaces.join('<br/>');
}
});
//
});
</script>
<style>
.view-stats {
display: none;
}
.button-th {
width: 150px;
}
.opnsense-rules > tbody > tr > td {
padding-left:5px;
padding-right:5px;
}
.expand_type {
font-style: italic;
}
</style>
<?php include("fbegin.inc"); ?>
<div class="hidden">
<div id="category_block" style="z-index:-100;">
<select class="selectpicker hidden-xs hidden-sm hidden-md" data-live-search="true" data-size="5" multiple title="<?=gettext("Select category");?>" id="fw_category">
</select>
<button id="btn_inspect" class="btn btn-default">
<i class="fa fa-eye" aria-hidden="true"></i>
<?=gettext("Inspect");?>
</button>
</div>
</div>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php print_firewall_banner() ?>
<div id="fw-alert-box" class="col-xs-12 <?=!is_subsystem_dirty('filter') && !isset($savemsg) ? "hidden":"";?>">
<div class="alert alert-info" role="alert">
<div id="fw-alert-changes" class="fw-alert-messages <?=!is_subsystem_dirty('filter') ? "hidden":"";?>">
<label for="btn_apply">
<?=gettext("The firewall rule configuration has been changed.<br />You must apply the changes in order for them to take effect.");?>
</label>
<button id="btn_apply" class="btn btn-primary pull-right" value="Apply changes"><?=gettext("Apply changes");?></button>
</div>
<div id="fw-alert-message" class="fw-alert-messages <?=!isset($savemsg) ? "hidden":"";?>">
<?=isset($savemsg) ? $savemsg : "";?>
</div>
</div>
</div>
<?php
$interface_has_rules = false;
foreach ($a_filter as $i => $filterent) {
if ((!isset($filterent['floating']) && $selected_if == $filterent['interface']) ||
((isset($filterent['floating']) || empty($filterent['interface'])) && $selected_if == 'FloatingRules')) {
$interface_has_rules = true;
break;
}
} ?>
<?php if (!$interface_has_rules): ?>
<?php if ($selected_if == 'FloatingRules'): ?>
<?php print_info_box(gettext('No floating rules are currently defined. Floating rules are ' .
'not bound to a single interface and can therefore be used to span ' .
'policies over multiple networks at the same time.')) ?>
<?php else: ?>
<?php print_info_box(sprintf(gettext('No %s rules are currently defined. All incoming connections ' .
'on this interface will be blocked until you add a pass rule. Exceptions for automatically generated ' .
'rules may apply.'),
!empty($config['interfaces'][$selected_if]['descr']) ?
$config['interfaces'][$selected_if]['descr'] : strtoupper($selected_if))) ?>
<?php endif ?>
<?php endif ?>
<section class="col-xs-12">
<div class="content-box">
<form action="firewall_rules.php?if=<?=$selected_if;?>" method="post" name="iform" id="iform">
<input type="hidden" id="id" name="id" value="" />
<input type="hidden" id="action" name="act" value="" />
<div class="table-responsive">
<table class="table table-condensed table-striped opnsense-rules">
<tbody>
<tr>
<td><input type="checkbox" id="selectAll"></td>
<td> </td>
<td class="view-info"><strong><?= gettext('Protocol') ?></strong></td>
<td class="view-info"><strong><?= gettext('Source') ?></strong></td>
<td class="view-info hidden-xs hidden-sm"><strong><?= gettext('Port') ?></strong></td>
<td class="view-info hidden-xs hidden-sm"><strong><?= gettext('Destination') ?></strong></td>
<td class="view-info hidden-xs hidden-sm"><strong><?= gettext('Port') ?></strong></td>
<td class="view-info hidden-xs hidden-sm"><strong><?= gettext('Gateway') ?></strong></td>
<td class="view-info hidden-xs hidden-sm"><strong><?= gettext('Schedule') ?></strong></td>
<td class="view-info">
<i class="fa fa-fw fa-sitemap" data-toggle="tooltip" title="<?= html_safe(gettext('Number of interfaces this rule applies to'));?>"></i>
</td>
<td class="view-stats hidden-xs hidden-sm"><strong><?= gettext('Evaluations') ?></strong></td>
<td class="view-stats hidden-xs hidden-sm"><strong><?= gettext('States') ?></strong></td>
<td class="view-stats"><strong><?= gettext('Packets') ?></strong></td>
<td class="view-stats"><strong><?= gettext('Bytes') ?></strong></td>
<td class="text-nowrap">
<strong><?= gettext('Description') ?></strong>
<i class="fa fa-question-circle" data-toggle="collapse" data-target=".rule_md5_hash" ></i>
</td>
<td class="text-nowrap button-th">
<a href="<?= url_safe('firewall_rules_edit.php?if=%s', array($selected_if)) ?>" class="btn btn-primary btn-xs" data-toggle="tooltip" title="<?= html_safe(gettext('Add')) ?>" aria-label="<?= html_safe(gettext('Add')) ?>">
<i class="fa fa-plus fa-fw"></i>
</a>
<button id="move_<?= count($a_filter) ?>" name="move_<?= count($a_filter) ?>_x" data-toggle="tooltip" title="<?= html_safe(gettext('Move selected rules to end')) ?>" class="act_move btn btn-default btn-xs" aria-label="<?=gettext("Move selected rules to end"); ?>">
<i class="fa fa-arrow-left fa-fw"></i>
</button>
<button id="del_x" title="<?= html_safe(gettext('Delete selected')) ?>" data-toggle="tooltip" class="act_delete btn btn-default btn-xs" aria-label="<?=gettext("delete selected"); ?>">
<i class="fa fa-trash fa-fw"></i>
</button>
<button title="<?= html_safe(gettext('Enable selected')) ?>" data-toggle="tooltip" class="act_toggle_enable btn btn-default btn-xs" aria-label="<?=gettext("Enable selected"); ?>">
<i class="fa fa-check-square-o fa-fw"></i>
</button>
<button title="<?= html_safe(gettext('Disable selected')) ?>" data-toggle="tooltip" class="act_toggle_disable btn btn-default btn-xs">
<i class="fa fa-square-o fa-fw"></i>
</button>
</td>
</tr>
<?php
$ifgroups = [];
foreach (config_read_array('ifgroups', 'ifgroupentry') as $ifgroup) {
if (!empty($ifgroup['members']) && in_array($selected_if, preg_split('/[ |,]+/', $ifgroup['members']))) {
$ifgroups[] = $ifgroup['ifname'];
}
}
$fw = filter_core_get_initialized_plugin_system();
filter_core_bootstrap($fw);
plugins_firewall($fw);
filter_core_rules_user($fw);
$prev_origin = null;
$origin_texts = [
'internal' => gettext('Automatically generated rules'),
'floating' => gettext('Floating rules'),
'group' => gettext('Group rules'),
'internal2' => gettext('Automatically generated rules (end of ruleset)'),
'automation' => gettext('Rules from Automation'),
];
foreach ($fw->iterateFilterRules() as $rule):
$is_selected = false;
if (empty($ifgroups) && $rule->ruleOrigin() == 'group'){
// group view, skip group section (groups can't be nested)
$is_selected = false;
} elseif ($rule->getInterface() == $selected_if && empty($rule->getRawRule()['interfacenot'])) {
// interface view and this interface is selected
$is_selected = true;
} elseif ($selected_if == "FloatingRules" && $rule->ruleOrigin() == 'floating') {
// floating view, skip floating
$is_selected = false;
} elseif (!empty($rule->getRawRule()['interfacenot'])) {
// inverted interface, all but selected
if (!in_array($selected_if, explode(',', $rule->getInterface()))) {
$is_selected = true;
}
} elseif (($rule->getInterface() == "" || strpos($rule->getInterface(), ",") !== false) && $selected_if == "FloatingRules") {
// floating type of rule and "floating" view
$is_selected = true;
} elseif ($rule->getInterface() == "" || !empty(array_intersect(array_merge([$selected_if], $ifgroups), explode(',', $rule->getInterface())))) {
// rule is floating or of group type and matches this interface
$is_selected = true;
}
if ($rule->isEnabled() && $is_selected && $rule->ruleOrigin() != 'interface'):
$intf_count = empty($rule->getInterface()) ? '*' : count(explode(',', $rule->getInterface()));
$filterent = $rule->getRawRule();
$filterent['quick'] = !isset($filterent['quick']) || $filterent['quick'];
legacy_html_escape_form_data($filterent);
?>
<?php
if ($prev_origin != $rule->ruleOrigin()):?>
<tr id="expand-<?=$rule->ruleOrigin();?>-rules" class="expand_type is_collapsed" data-type="<?=$rule->ruleOrigin();?>" style="display: none;">
<td><i class="fa fa-folder-o text-muted"></i></td>
<td></td>
<td class="view-info" colspan="2"> </td>
<td class="view-info hidden-xs hidden-sm" colspan="5"> </td>
<td colspan="2" class="view-stats hidden-xs hidden-sm"></td>
<td colspan="2" class="view-stats"></td>
<td class="view-info"></td>
<td><?= $origin_texts[$rule->ruleOrigin()] ?></td>
<td>
<button class="btn btn-default btn-xs" id="expand-<?=$rule->ruleOrigin();?>">
<i class="fa fa-chevron-circle-down" aria-hidden="true"></i>
<span class="badge">
<span id="<?=$rule->ruleOrigin();?>-rule-count"><span>
</span>
</button>
</td>
</tr>
<?php
endif;?>
<tr class="rule <?=$rule->ruleOrigin();?>-rule" style="display: none;" data-category="<?=!empty($filterent['category']) ? $filterent['category'] : "";?>">
<td><i class="fa fa-magic"></i></td>
<td>
<span class="<?=firewall_rule_item_action($filterent);?>"></span>
<?=firewall_rule_item_icons($filterent);?>
<i class="<?=firewall_rule_item_log($filterent);?>"></i>
</td>
<td class="view-info">
<?=firewall_rule_item_proto($filterent);?>
</td>
<td class="view-info">
<?=$rule->isUIFromNot() ? '!' : '';?>
<?= is_alias($rule->getUIFromAddress()) ? filter_rule_item_alias_tooltip($rule->getUIFromAddress()) : htmlspecialchars($rule->getUIFromAddress());?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?= is_alias($rule->getUIFromPort()) ? filter_rule_item_alias_tooltip($rule->getUIFromPort()) : htmlspecialchars(pprint_port($rule->getUIFromPort()));?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?=$rule->isUIToNot() ? '!' : '';?>
<?= is_alias($rule->getUIToAddress()) ? filter_rule_item_alias_tooltip($rule->getUIToAddress()) : htmlspecialchars($rule->getUIToAddress());?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?= is_alias($rule->getUIToPort()) ? filter_rule_item_alias_tooltip($rule->getUIToPort()) : htmlspecialchars(pprint_port($rule->getUIToPort()));?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?= $rule->getUIGateway();?>
</td>
<td class="view-info hidden-xs hidden-sm">*</td>
<td class="view-info">
<?php if ($intf_count == '*'):?>
<a style="cursor: pointer;" title="<?=html_safe(gettext('Affects all interfaces'));?>" data-placement='bottom' data-toggle="tooltip">
<?=$intf_count;?>
</a>
<?php elseif ($intf_count != '1' || $selected_if != $rule->getInterface() || $selected_if == 'FloatingRules'): ?>
<?= !empty($rule->getRawRule()['interfacenot']) ? '!' : '';?>
<a style="cursor: pointer;" class='interface_tooltip' data-interfaces="<?=$rule->getInterface();?>">
<?=$intf_count;?>
</a>
<?php endif; ?>
</td>
<td class="view-stats hidden-xs hidden-sm" id="<?=$rule->getLabel();?>_evaluations"><?= gettext('N/A') ?></td>
<td class="view-stats hidden-xs hidden-sm">
<a href="/ui/diagnostics/firewall/states#<?=html_safe($rule->getLabel());?>" id="<?=$rule->getLabel();?>_states" data-toggle="tooltip" title="<?=html_safe("open states view");?>" ><?= gettext('N/A');?></a>
<td class="view-stats" id="<?=$rule->getLabel();?>_packets"><?= gettext('N/A') ?></td>
<td class="view-stats" id="<?=$rule->getLabel();?>_bytes"><?= gettext('N/A') ?></td>
<td class="rule-description">
<?=$rule->getDescr();?>
<div class="collapse rule_md5_hash">
<small><?=$filterent['label'];?></small>
</div>
</td>
<td>
<?php if (!empty($rule->getRef())): ?>
<a href="firewall_rule_lookup.php?rid=<?=html_safe($rule->getLabel());?>" class="btn btn-default btn-xs"><i class="fa fa-fw fa-search"></i></a>
<?php endif ?>
</td>
</tr>
<?php
$prev_origin = $rule->ruleOrigin();
endif;
endforeach;?>
<?php
foreach ($a_filter as $i => $filterent):
if (
(!isset($filterent['floating']) && $selected_if == $filterent['interface']) ||
(
(isset($filterent['floating']) || empty($filterent['interface'])) &&
$selected_if == 'FloatingRules'
)
):
// calculate a hash so we can track these records in the ruleset, new style (mvc) code will
// automatically provide us with a uuid, this is a workaround to provide some help with tracking issues.
$rule_hash = OPNsense\Firewall\Util::calcRuleHash($a_filter_raw[$i]);
$intf_count = empty($filterent['interface']) ? '*' : count(explode(',', $filterent['interface']));
?>
<tr class="rule <?=isset($filterent['disabled'])?"text-muted":"";?>" data-category="<?=!empty($filterent['category']) ? $filterent['category'] : "";?>">
<td>
<input class="rule_select" type="checkbox" name="rule[]" value="<?=$i;?>" />
</td>
<td>
<i class="act_toggle <?=firewall_rule_item_action($filterent);?>" style="cursor: pointer;" id="toggle_<?=$i;?>" data-toggle="tooltip" title="<?= html_safe(empty($filterent['disabled']) ? gettext('Disable rule') : gettext('Enable rule')) ?>"></i>
<?=firewall_rule_item_icons($filterent);?>
<i class="act_log <?= firewall_rule_item_log($filterent) ?>" style="cursor: pointer;" id="toggle_<?=$i;?>" data-toggle="tooltip" title="<?= html_safe(empty($filterent['log']) ? gettext('Enable logging') : gettext('Disable logging')) ?>"></i>
</td>
<td class="view-info">
<?=firewall_rule_item_proto($filterent);?>
</td>
<td class="view-info">
<?php if (isset($filterent['source']['address']) && is_alias($filterent['source']['address'])): ?>
<?=!empty($filterent['source']['not']) ? '!' : '';?>
<?=filter_rule_item_alias_tooltip($filterent['source']['address']);?>
<?php else: ?>
<?=htmlspecialchars(pprint_address($filterent['source']));?>
<?php endif; ?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?php if (isset($filterent['source']['port']) && is_alias($filterent['source']['port'])): ?>
<?=filter_rule_item_alias_tooltip($filterent['source']['port']);?>
<?php else: ?>
<?=htmlspecialchars(pprint_port(isset($filterent['source']['port']) ? $filterent['source']['port'] : null)); ?>
<?php endif; ?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?php if (isset($filterent['destination']['address']) && is_alias($filterent['destination']['address'])): ?>
<?=!empty($filterent['destination']['not']) ? '!' : '';?>
<?=filter_rule_item_alias_tooltip($filterent['destination']['address']);?>
<?php else: ?>
<?=htmlspecialchars(pprint_address($filterent['destination'])); ?>
<?php endif; ?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?php if (isset($filterent['destination']['port']) && is_alias($filterent['destination']['port'])): ?>
<?=filter_rule_item_alias_tooltip($filterent['destination']['port']);?>
<?php else: ?>
<?=htmlspecialchars(pprint_port(isset($filterent['destination']['port']) ? $filterent['destination']['port'] : null)); ?>
<?php endif; ?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?php
if (isset($filterent['gateway'])):?>
<?=isset($config['interfaces'][$filterent['gateway']]['descr']) ? htmlspecialchars($config['interfaces'][$filterent['gateway']]['descr']) : htmlspecialchars(pprint_port($filterent['gateway'])); ?>
<?php
else: ?>
*
<?php endif; ?>
</td>
<td class="view-info hidden-xs hidden-sm">
<?php
if (!empty($filterent['sched'])):?>
<?php
$schedule_descr = "";
if (isset($config['schedules']['schedule']))
{
foreach ($config['schedules']['schedule'] as $schedule)
{
if ($schedule['name'] == $filterent['sched'])
{
$schedule_descr = (isset($schedule['descr'])) ? $schedule['descr'] : "";
break;
}
}
}
?>
<span title="<?=htmlspecialchars($schedule_descr);?>" data-toggle="tooltip">
<?=htmlspecialchars($filterent['sched']);?>
</span>
<a href="/firewall_schedule_edit.php?name=<?=htmlspecialchars($filterent['sched']);?>"
title="<?= html_safe(gettext('Edit')) ?>" data-toggle="tooltip">
<?php
if (filter_get_time_based_rule_status($schedule)):?>
<i class="fa fa-calendar text-success"></i>
<?php
else:?>
<i class="fa fa-calendar text-muted"></i>
<?php
endif;?>
</a>
<?php
else: ?>
*
<?php
endif;?>
</td>
<td class="view-info">
<?php if ($intf_count == '*'):?>
<a style="cursor: pointer;" title="<?=html_safe(gettext('Affects all interfaces'));?>" data-placement='bottom' data-toggle="tooltip">
<?=$intf_count;?>
</a>
<?php elseif ($intf_count != '1' || $selected_if == 'FloatingRules'): ?>
<?= !empty($filterent['interfacenot']) ? '!' : '';?>
<a style="cursor: pointer;" class='interface_tooltip' data-interfaces="<?=$filterent['interface'];?>">
<?=$intf_count;?>
</a>
<?php endif; ?>
</td>
<td class="view-stats hidden-xs hidden-sm" id="<?=$rule_hash;?>_evaluations"><?= gettext('N/A') ?></td>
<td class="view-stats hidden-xs hidden-sm">
<a href="/ui/diagnostics/firewall/states#<?=html_safe($rule_hash);?>" id="<?=$rule_hash;?>_states" data-toggle="tooltip" title="<?=html_safe("open states view");?>" ><?= gettext('N/A') ?></a>
</td>
<td class="view-stats" id="<?=$rule_hash;?>_packets"><?= gettext('N/A') ?></td>
<td class="view-stats" id="<?=$rule_hash;?>_bytes"><?= gettext('N/A') ?></td>
<td class="rule-description">
<?= $filterent['descr'] ?? '' ?>
<div class="collapse rule_md5_hash">
<small><?=$rule_hash;?></small>
</div>
</td>
<td>
<button id="move_<?=$i;?>" name="move_<?=$i;?>_x" data-toggle="tooltip" title="<?= html_safe(gettext("Move selected rules before this rule")) ?>" class="act_move btn btn-default btn-xs" aria-label="<?= html_safe(gettext("Move selected rules before this rule")) ?>">
<i class="fa fa-arrow-left fa-fw"></i>
</button>
<?php if (empty($filterent['associated-rule-id'])): ?>
<a href="firewall_rules_edit.php?if=<?=$selected_if;?>&id=<?=$i;?>" data-toggle="tooltip" title="<?= html_safe(gettext('Edit')) ?>" aria-label="<?= html_safe(gettext('Edit')) ?>" class="btn btn-default btn-xs">
<i class="fa fa-pencil fa-fw"></i>
</a>
<a href="firewall_rules_edit.php?if=<?=$selected_if;?>&dup=<?=$i;?>" class="btn btn-default btn-xs" data-toggle="tooltip" title="<?= html_safe(gettext('Clone')) ?>" aria-label="<?= html_safe(gettext('Clone')) ?>">
<i class="fa fa-clone fa-fw"></i>
</a>
<?php endif ?>
<a id="del_<?=$i;?>" title="<?= html_safe(gettext('Delete')) ?>" data-toggle="tooltip" class="act_delete btn btn-default btn-xs" aria-label="<?= html_safe(gettext('Delete')) ?>">
<i class="fa fa-trash fa-fw"></i>
</a>
</td>
</tr>
<?php
endif;
endforeach;
$i++;
?>
</tbody>
</table>
<table class="table table-condensed table-striped opnsense-rules">
<tbody>
<tr class="hidden-xs hidden-sm">
<td>
<table style="width:100%; border:0;">
<tr>
<td style="width:16px"><span class="fa fa-play text-success"></span></td>
<td style="width:100px"><?=gettext("pass");?></td>
<td style="width:14px"></td>
<td style="width:16px"><span class="fa fa-times text-danger"></span></td>
<td style="width:100px"><?=gettext("block");?></td>
<td style="width:14px"></td>
<td style="width:16px"><span class="fa fa-times-circle text-danger"></span></td>
<td style="width:100px"><?=gettext("reject");?></td>
<td style="width:14px"></td>
<td style="width:16px"><span class="fa fa-info-circle text-info"></span></td>
<td style="width:100px"><?=gettext("log");?></td>
<td style="width:16px"><span class="fa fa-long-arrow-right text-info"></span></td>
<td style="width:100px"><?=gettext("in");?></td>
<td style="width:16px"><span class="fa fa-flash text-warning"></span></td>
<td style="width:100px"><?=gettext("first match");?></td>
</tr>
<tr>
<td><span class="fa fa-play text-muted"></span></td>
<td class="nowrap"><?=gettext("pass (disabled)");?></td>
<td> </td>
<td><span class="fa fa-times text-muted"></span></td>
<td class="nowrap"><?=gettext("block (disabled)");?></td>
<td> </td>
<td><span class="fa fa-times-circle text-muted"></span></td>
<td class="nowrap"><?=gettext("reject (disabled)");?></td>
<td> </td>
<td style="width:16px"><span class="fa fa-info-circle text-muted"></span></td>
<td class="nowrap"><?=gettext("log (disabled)");?></td>
<td style="width:16px"><span class="fa fa-long-arrow-left"></span></td>
<td style="width:100px"><?=gettext("out");?></td>
<td style="width:16px"><span class="fa fa-flash text-muted"></span></td>
<td style="width:100px"><?=gettext("last match");?></td>
</tr>
</table>
</td>
</tr>
<tr class="hidden-xs hidden-sm">
<td>
<i class="fa fa-calendar fa-fw text-success"></i>
<i class="fa fa-calendar fa-fw text-muted"></i>
<?= gettext('Active/Inactive Schedule (click to view/edit)') ?></td>
</td>
</tr>
<tr class="hidden-xs hidden-sm">
<td>
<i class="fa fa-list fa-fw text-primary"></i>
<?= gettext('Alias (click to view/edit)') ?>
</td>
</tr>
<tr class="hidden-xs hidden-sm">
<td>
<?php if ('FloatingRules' != $selected_if): ?>
<?= sprintf(gettext('%s rules are evaluated on a first-match basis by default (i.e. ' .
'the action of the first rule to match a packet will be executed). ' .
'This means that if you use block rules, you will have to pay attention ' .
'to the rule order. Everything that is not explicitly passed is blocked ' .
'by default.'), !empty($config['interfaces'][$selected_if]['descr']) ?
$config['interfaces'][$selected_if]['descr'] : strtoupper($selected_if)) ?>
<?php else: ?>
<?= gettext('Floating rules are evaluated on a first-match basis (i.e. ' .
'the action of the first rule to match a packet will be executed) only ' .
'if the "quick" option is checked on a rule. Otherwise they will only apply if no ' .
'other rules match. Pay close attention to the rule order and options ' .
'chosen. If no rule here matches, the per-interface or default rules are used.') ?>
<?php endif ?>
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc"); ?>