mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-09 18:45:54 +02:00
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:
@@ -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;
|
||||
|
||||
@@ -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"};
|
||||
|
||||
@@ -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'});
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user