hello,
m0n0wall is great work. but I have one suggestion: could be advanced
outbound NAT more advanced :-) ? I mean, with ipnat you can do not only:
map fxp0 10.1.0.0/16 -> 0.0.0.0/32
but also:
map fxp0 from 10.1.0.0/16 to 192.168.0.0/16 -> 0.0.0.0/32
or even:
map fxp0 from 10.1.0.0/16 ! to 192.168.0.0/16 -> 0.0.0.0/32
it means: do NAT on packets which goes only to 192.168.0.0/16 network
(resp. do NAT on all packets except those that goes to 192.168.0.0/16 network)
I've already made this changes, so I hope you find it usable:
/etc/inc/filter.inc.diff
=========================================
--- rootfs-pb18r522/etc/inc/filter.inc 2003-10-11 22:46:37.000000000 +0200
+++ patch/etc/inc/filter.inc 2003-10-09 14:42:55.000000000 +0200
@@ -93,11 +93,11 @@
return mwexec("/sbin/ipf -FS");
}
-function filter_nat_rules_generate_if($if, $sa, $sn, $mssclamp) {
+function filter_nat_rules_generate_if($if, $src, $dst, $mssclamp) {
$natrule = <<<EOD
-map $if $sa/$sn -> 0/32 proxy port ftp ftp/tcp $mssclamp
-map $if $sa/$sn -> 0/32 portmap tcp/udp auto $mssclamp
-map $if $sa/$sn -> 0/32 $mssclamp
+map $if $src $dst -> 0/32 proxy port ftp ftp/tcp $mssclamp
+map $if $src $dst -> 0/32 portmap tcp/udp auto $mssclamp
+map $if $src $dst -> 0/32 $mssclamp
EOD;
@@ -136,13 +136,23 @@
/* advanced outbound rules */
if (is_array($config['nat']['advancedoutbound']['rule'])) {
foreach ($config['nat']['advancedoutbound']['rule'] as $obent) {
- list($sa,$sn) = explode("/", $obent['source']);
- $natrules .= filter_nat_rules_generate_if($wanif, $sa, $sn, $mssclamp);
+ $dst = "";
+ $src = "";
+ if (!isset($obent['destination']['any'])) {
+ $src = "from ";
+ if (isset($obent['destination']['not']))
+ $dst = "! to ";
+ else
+ $dst = "to ";
+ $dst .= $obent['destination']['network'];
+ }
+ $src .= $obent['source']['network'];
+ $natrules .= filter_nat_rules_generate_if($wanif, $src, $dst, $mssclamp);
}
}
} else {
/* standard outbound rules (one for each interface) */
- $natrules .= filter_nat_rules_generate_if($wanif, $lansa,
$lancfg['subnet'], $mssclamp);
+ $natrules .= filter_nat_rules_generate_if($wanif,
$lansa."/".$lancfg['subnet'], "", $mssclamp);
/* optional interfaces */
for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
@@ -150,7 +160,7 @@
if (isset($optcfg['enable'])) {
$optsa = gen_subnet($optcfg['ipaddr'], $optcfg['subnet']);
- $natrules .= filter_nat_rules_generate_if($wanif, $optsa,
$optcfg['subnet'], $mssclamp);
+ $natrules .= filter_nat_rules_generate_if($wanif,
$optsa."/".$optcfg['subnet'], "", $mssclamp);
}
}
}
=======================================================
/usr/local/www/firewall_nat_out.php.diff
=======================================================
--- rootfs-pb18r522/usr/local/www/firewall_nat_out.php 2003-10-11
22:46:37.000000000 +0200
+++ patch/usr/local/www/firewall_nat_out.php 2003-10-09 14:53:46.000000000
+0200
@@ -98,7 +98,7 @@
<td width="100%"> </td>
</tr>
<tr>
- <td colspan="4" class="tabcont">
+ <td colspan="6" class="tabcont">
<table width="100%" border="0" cellpadding="6" cellspacing="0">
<tr>
<td class="vtable"><p>
@@ -125,14 +125,25 @@
<br>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
- <td width="30%" class="listhdrr">Internal subnet</td>
- <td width="60%" class="listhdr">Description</td>
+ <td width="20%" class="listhdrr">Internal subnet</td>
+ <td width="20%" class="listhdrr">External subnet</td>
+ <td width="50%" class="listhdr">Description</td>
<td width="10%" class="list"></td>
</tr>
<?php $i = 0; foreach ($a_out as $natent): ?>
<tr>
<td class="listlr">
- <?=$natent['source'];?>
+ <?=$natent['source']['network'];?>
+ </td>
+ <td class="listr">
+ <?php if (isset($natent['destination']['any']))
+ echo "*";
+ else {
+ if (isset($natent['destination']['not']))
+ echo "! ";
+ echo $natent['destination']['network'];
+ } ?>
+
</td>
<td class="listbg">
<?=htmlspecialchars($natent['descr']);?>
@@ -142,7 +153,7 @@
</tr>
<?php $i++; endforeach; ?>
<tr>
- <td class="list" colspan="2"></td>
+ <td class="list" colspan="3"></td>
<td class="list"> <a href="firewall_nat_out_edit.php"><img
src="plus.gif" width="17" height="17" border="0"></a></td>
</tr>
</table>
=========================================================
firewall_nat_out_edit.php.diff
=========================================================
--- rootfs-pb18r522/usr/local/www/firewall_nat_out_edit.php 2003-10-11
22:46:37.000000000 +0200
+++ patch/usr/local/www/firewall_nat_out_edit.php 2003-10-08
12:42:22.000000000 +0200
@@ -41,21 +41,46 @@
if (isset($_POST['id']))
$id = $_POST['id'];
+function network_to_pconfig($adr, &$padr, &$pmask, &$pnot) {
+
+ if (isset($adr['any']))
+ $padr = "any";
+ else if ($adr['network']) {
+ list($padr, $pmask) = explode("/", $adr['network']);
+ if (!$pmask)
+ $pmask = 32;
+ }
+
+ if (isset($adr['not']))
+ $pnot = 1;
+ else
+ $pnot = 0;
+}
+
if (isset($id) && $a_out[$id]) {
- list($pconfig['source'],$pconfig['source_subnet']) = explode('/',
$a_out[$id]['source']);
+ list($pconfig['source'],$pconfig['source_subnet']) = explode('/',
$a_out[$id]['source']['network']);
+ network_to_pconfig($a_out[$id]['destination'], $pconfig['destination'],
$pconfig['destination_subnet'],
+ $pconfig['destination_not']);
$pconfig['descr'] = $a_out[$id]['descr'];
} else {
$pconfig['source_subnet'] = 24;
+ $pconfig['destination'] = "any";
+ $pconfig['destination_subnet'] = 24;
}
if ($_POST) {
+
+ if ($_POST['destination_type'] == "any") {
+ $_POST['destination'] = $_POST['destination_type'];
+ $_POST['destination_subnet'] = 24;
+ }
unset($input_errors);
$pconfig = $_POST;
/* input validation */
- $reqdfields = explode(" ", "source source_subnet");
- $reqdfieldsn = explode(",", "Internal subnet,Internal subnet bit count");
+ $reqdfields = explode(" ", "source source_subnet destination
destination_subnet");
+ $reqdfieldsn = explode(",", "Internal subnet,Internal subnet bit
count,External subnet,External subnet bit count");
do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
@@ -65,22 +90,52 @@
if (($_POST['source_subnet'] && !is_numeric($_POST['source_subnet']))) {
$input_errors[] = "A valid internal subnet bit count must be specified.";
}
+
+ if ($_POST['destination_type'] != "any") {
+ if (($_POST['destination'] &&
!is_ipaddr($_POST['destination']))) {
+ $input_errors[] = "A valid external subnet must be
specified.";
+ }
+ if (($_POST['destination_subnet'] &&
!is_numeric($_POST['destination_subnet']))) {
+ $input_errors[] = "A valid external subnet bit count
must be specified.";
+ }
+ }
+
/* check for existing entries */
$osn = gen_subnet($_POST['source'], $_POST['source_subnet']) . "/" .
$_POST['source_subnet'];
+ if ($_POST['destination_type'] == "any")
+ $ext = "any";
+ else
+ $ext = gen_subnet($_POST['destination'], $_POST['destination_subnet']) .
"/" . $_POST['destination_subnet'];
+
foreach ($a_out as $natent) {
- if (isset($id) && ($a_out[$id]) && ($a_out[$id] === $natent))
+ if (isset($id) && ($a_out[$id]) && ($a_out[$id] == $natent))
continue;
- if ($natent['source'] == $osn) {
- $input_errors[] = "There is already an outbound NAT rule for the specified
internal network.";
- break;
- }
+ if ($natent['source']['network'] == $osn)
+ if (isset($natent['destination']['not']) ==
isset($_POST['destination_not']))
+ if ((isset($natent['destination']['any']) && $ext = "any") ||
+ ($natent['destination']['network'] == $ext)) {
+ $input_errors[] = "There is already an outbound NAT rule for the
specified internal network.";
+ break;
+ }
}
if (!$input_errors) {
$natent = array();
- $natent['source'] = $osn;
+ $natent['source']['network'] = $osn;
+
+ unset($natent['destination']['not']);
+
+ if ($ext == "any") {
+ unset($natent['destination']['network']);
+ $natent['destination']['any'] = true;
+ } else
+ $natent['destination']['network'] = $ext;
+
+ if (isset($_POST['destination_not']) && $ext != "any")
+ $natent['destination']['not'] = true;
+
$natent['descr'] = $_POST['descr'];
if (isset($id) && $a_out[$id])
@@ -103,6 +158,24 @@
<title>m0n0wall webGUI - Firewall: NAT: Edit outbound mapping</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+ switch (document.iform.destination_type.selectedIndex) {
+ case 1: /* network */
+ document.iform.destination.disabled = 0;
+ document.iform.destination_subnet.disabled = 0;
+ break;
+ default:
+ document.iform.destination.value = "";
+ document.iform.destination.disabled = 1;
+ document.iform.destination_subnet.value = 24;
+ document.iform.destination_subnet.disabled = 1;
+ break;
+ }
+}
+//-->
+</script>
</head>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
@@ -126,10 +199,40 @@
<br> <span class="vexpl">Enter the internal subnet for
the outbound NAT mapping.</span></td>
</tr>
<tr>
+ <td width="100" valign="top" class="vncellreq">External
subnet</td>
+ <td class="vtable"><input name="destination_not"
type="checkbox" id="destination_not" value="yes" <?php if
($pconfig['destination_not']) echo "checked"; ?>>
+ <strong>not</strong><br>
+ Use this option to invert the sense of the match.<br>
+ <br>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>Type: </td>
+ <td><select name="destination_type" class="formfld"
onChange="typesel_change()">
+ <option value="any" <?php if
($pconfig['destination'] == "any") echo "selected"; ?>>
+ any</option>
+ <option value="network" <?php if
($pconfig['destination'] != "any") echo "selected"; ?>>
+ Network</option>
+ </select></td>
+ </tr>
+ <tr>
+ <td>Address: </td>
+ <td><input name="destination" type="text" class="formfld"
id="destination" size="20"
value="<?=htmlspecialchars($pconfig['destination']);?>">
+ /
+ <select name="destination_subnet" class="formfld"
id="destination_subnet">
+ <?php for ($i = 32; $i >= 0; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i ==
$pconfig['destination_subnet']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ <br> <span class="vexpl">Enter the external subnet for the outbound
NAT mapping.</span></td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
<td valign="top" class="vncellreq">Description</td>
<td class="vtable"> <input name="descr" type="text"
class="formfld" id="descr" size="40"
value="<?=htmlspecialchars($pconfig['descr']);?>">
- <br> <span class="vexpl">You may enter a description here
- for your reference (not parsed).</span></td>
+ <br> <span class="vexpl">You may enter a description here
for your reference (not parsed).</span></td>
</tr>
<tr>
<td valign="top"> </td>
@@ -141,6 +244,11 @@
</tr>
</table>
</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
<?php include("fend.inc"); ?>
</body>
</html>
======================================================== |