Firewall: make DNAT only accessible from selected source network

We added RED to the standard networks and now portforwardings are only
useable from the selected source. If selected "all" the portforwarding
can be used from any internal network. Else the access is only grnated
from the selected source network.
This commit is contained in:
Alexander Marx
2014-07-18 08:44:45 +02:00
parent d7636b6fa3
commit 48f07c1957
4 changed files with 63 additions and 24 deletions

View File

@@ -217,7 +217,7 @@ sub get_std_net_ip
}elsif($val eq 'BLUE'){
return "$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}";
}elsif($val eq 'RED'){
return "0.0.0.0/0 -o $con";
return "0.0.0.0/0";
}elsif($val =~ /OpenVPN/i){
return "$ovpnsettings{'DOVPN_SUBNET'}";
}elsif($val =~ /IPsec/i){
@@ -226,6 +226,23 @@ sub get_std_net_ip
return ;
}
}
sub get_interface
{
my $net=shift;
if($net eq "$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}"){
return "$netsettings{'GREEN_DEV'}";
}
if($net eq "$netsettings{'ORANGE_NETADDRESS'}/$netsettings{'ORANGE_NETMASK'}"){
return "$netsettings{'ORANGE_DEV'}";
}
if($net eq "$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}"){
return "$netsettings{'BLUE_DEV'}";
}
if($net eq "0.0.0.0/0"){
return "$netsettings{'RED_DEV'}";
}
return "";
}
sub get_net_ip
{
my $val=shift;
@@ -305,9 +322,9 @@ sub get_address
# address. Otherwise, we assume that it is an IP address.
if ($key ~~ ["src_addr", "tgt_addr"]) {
if (&General::validmac($value)) {
push(@ret, "-m mac --mac-source $value");
push(@ret, ["-m mac --mac-source $value", ""]);
} else {
push(@ret, $value);
push(@ret, [$value, ""]);
}
# If a default network interface (GREEN, BLUE, etc.) is selected, we
@@ -316,88 +333,90 @@ sub get_address
my $external_interface = &get_external_interface();
my $network_address = &get_std_net_ip($value, $external_interface);
if ($network_address) {
push(@ret, $network_address);
my $interface = &get_interface($network_address);
push(@ret, [$network_address, $interface]);
}
# Custom networks.
} elsif ($key ~~ ["cust_net_src", "cust_net_tgt", "Custom Network"]) {
my $network_address = &get_net_ip($value);
if ($network_address) {
push(@ret, $network_address);
push(@ret, [$network_address, ""]);
}
# Custom hosts.
} elsif ($key ~~ ["cust_host_src", "cust_host_tgt", "Custom Host"]) {
my $host_address = &get_host_ip($value, $type);
if ($host_address) {
push(@ret, $host_address);
push(@ret, [$host_address, ""]);
}
# OpenVPN networks.
} elsif ($key ~~ ["ovpn_net_src", "ovpn_net_tgt", "OpenVPN static network"]) {
my $network_address = &get_ovpn_net_ip($value, 1);
if ($network_address) {
push(@ret, $network_address);
push(@ret, [$network_address, ""]);
}
# OpenVPN hosts.
} elsif ($key ~~ ["ovpn_host_src", "ovpn_host_tgt", "OpenVPN static host"]) {
my $host_address = &get_ovpn_host_ip($value, 33);
if ($host_address) {
push(@ret, $host_address);
push(@ret, [$host_address, ""]);
}
# OpenVPN N2N.
} elsif ($key ~~ ["ovpn_n2n_src", "ovpn_n2n_tgt", "OpenVPN N-2-N"]) {
my $network_address = &get_ovpn_n2n_ip($value, 11);
if ($network_address) {
push(@ret, $network_address);
push(@ret, [$network_address, ""]);
}
# IPsec networks.
} elsif ($key ~~ ["ipsec_net_src", "ipsec_net_tgt", "IpSec Network"]) {
my $network_address = &get_ipsec_net_ip($value, 11);
if ($network_address) {
push(@ret, $network_address);
push(@ret, [$network_address, ""]);
}
# The firewall's own IP addresses.
} elsif ($key ~~ ["ipfire", "ipfire_src"]) {
# ALL
if ($value eq "ALL") {
push(@ret, "0/0");
push(@ret, ["0/0", ""]);
# GREEN
} elsif ($value eq "GREEN") {
push(@ret, $netsettings{"GREEN_ADDRESS"});
push(@ret, [$netsettings{"GREEN_ADDRESS"}, ""]);
# BLUE
} elsif ($value eq "BLUE") {
push(@ret, $netsettings{"BLUE_ADDRESS"});
push(@ret, [$netsettings{"BLUE_ADDRESS"}, ""]);
# ORANGE
} elsif ($value eq "ORANGE") {
push(@ret, $netsettings{"ORANGE_ADDRESS"});
push(@ret, [$netsettings{"ORANGE_ADDRESS"}, ""]);
# RED
} elsif ($value ~~ ["RED", "RED1"]) {
my $address = &get_external_address();
if ($address) {
push(@ret, $address);
push(@ret, [$address, ""]);
}
# Aliases
} else {
my $alias = &get_alias($value);
if ($alias) {
push(@ret, $alias);
push(@ret, [$alias, ""]);
}
}
# If nothing was selected, we assume "any".
} else {
push(@ret, "0/0");
push(@ret, ["0/0", ""]);
}
return @ret;

View File

@@ -291,24 +291,28 @@ sub buildrules {
foreach my $src (@sources) {
# Skip invalid source.
next unless ($src);
next unless (@$src[0]);
# Sanitize source.
my $source = $src;
my $source = @$src[0];
if ($source ~~ @ANY_ADDRESSES) {
$source = "";
}
my $source_intf = @$src[1];
foreach my $dst (@destinations) {
# Skip invalid rules.
next if (!$dst || ($dst eq "none"));
next if (!@$dst[0] || (@$dst[0] eq "none"));
# Sanitize destination.
my $destination = $dst;
my $destination = @$dst[0];
if ($destination ~~ @ANY_ADDRESSES) {
$destination = "";
}
my $destination_intf = @$dst[1];
# Array with iptables arguments.
my @options = ();
@@ -325,12 +329,20 @@ sub buildrules {
push(@source_options, ("-s", $source));
}
if ($source_intf) {
push(@source_options, ("-i", $source_intf));
}
# Prepare destination options.
my @destination_options = ();
if ($destination) {
push(@destination_options, ("-d", $destination));
}
if ($destination_intf) {
push(@destination_options, ("-o", $destination_intf));
}
# Add time constraint options.
push(@options, @time_options);
@@ -364,7 +376,7 @@ sub buildrules {
# Make port-forwardings useable from the internal networks.
my @internal_addresses = &fwlib::get_internal_firewall_ip_addresses(1);
unless ($nat_address ~~ @internal_addresses) {
&add_dnat_mangle_rules($nat_address, @nat_options);
&add_dnat_mangle_rules($nat_address, $source_intf, @nat_options);
}
push(@nat_options, @source_options);
@@ -681,6 +693,7 @@ sub get_dnat_target_port {
sub add_dnat_mangle_rules {
my $nat_address = shift;
my $interface = shift;
my @options = @_;
my $mark = 0;
@@ -691,6 +704,8 @@ sub add_dnat_mangle_rules {
next unless (exists $defaultNetworks{$zone . "_NETADDRESS"});
next unless (exists $defaultNetworks{$zone . "_NETMASK"});
next if ($interface && $interface ne $defaultNetworks{$zone . "_DEV"});
my @mangle_options = @options;
my $netaddress = $defaultNetworks{$zone . "_NETADDRESS"};

View File

@@ -1064,7 +1064,6 @@ print<<END;
END
foreach my $network (sort keys %defaultNetworks)
{
next if($defaultNetworks{$network}{'NAME'} eq "RED" && $srctgt eq 'src');
next if($defaultNetworks{$network}{'NAME'} eq "IPFire");
print "<option value='$defaultNetworks{$network}{'NAME'}'";
print " selected='selected'" if ($fwdfwsettings{$fwdfwsettings{$grp}} eq $defaultNetworks{$network}{'NAME'});

View File

@@ -1644,7 +1644,10 @@ sub getcolor
$tdcolor="<font style='color: $Header::colourblue;'>$c</font>";
return $tdcolor;
}
if ("$sip/$scidr" eq "0.0.0.0/0"){
$tdcolor="<font style='color: $Header::colourred;'>$c</font>";
return $tdcolor;
}
#Check if IP is part of OpenVPN N2N subnet
foreach my $key (sort keys %ccdhost){
if ($ccdhost{$key}[3] eq 'net'){
@@ -2501,6 +2504,9 @@ sub getipforgroup
&General::readhash("${General::swroot}/vpn/settings",\%hash);
return $hash{'RW_NET'};
}
if ($name eq 'RED'){
return "0.0.0.0/0";
}
}
}
sub decrease