App-SilverSplash
view release on metacpan or search on metacpan
lib/App/SilverSplash/IPTables.pm view on Meta::CPAN
package App::SilverSplash::IPTables;
use strict;
use warnings;
use base 'App::SilverSplash';
use Data::Dumper qw(Dumper);
use Config::SL ();
use URI::Escape ();
use constant DEBUG => $ENV{SL_DEBUG} || 0;
our (
$Config, $Iptables, $Wan_if, %tables_chains,
$Lan_if, $Perlbal_port, $Mark_op, $Lease_file,
$Gateway_ip, $Wan_ip, $Wan_mac,
);
BEGIN {
$Config = Config::SL->new;
$Iptables = $Config->sl_iptables || die 'oops';
$Perlbal_port = $Config->sl_perlbal_port || die 'oops';
# wan and lan interfaces
$Wan_if = $Config->sl_wan_if || die 'oops';
$Lan_if = $Config->sl_lan_if || die 'oops';
($Gateway_ip) = `/sbin/ifconfig $Lan_if` =~ m/inet addr:(\S+)/;
($Wan_ip) = `/sbin/ifconfig $Wan_if` =~ m/inet addr:(\S+)/;
($Wan_mac) = `/sbin/ifconfig $Wan_if` =~ m/HWaddr\s(\S+)/;
$Mark_op = $Config->sl_mark_op || die 'oops';
$Lease_file = $Config->sl_dhcp_lease_file || die 'oops';
%tables_chains = (
filter => [qw( slAUT slAUTads slNET slRTR )],
mangle => [qw( slBLK slINC slOUT slTRU )],
nat => [qw( slOUT )],
);
}
our $Blocked_mark = '0x100';
our $Trusted_mark = '0x200';
our $Paid_mark = '0x400';
our $Ads_mark = '0x500';
sub load_allows {
my ( $class, $file ) = @_;
my $fh;
open( $fh, '<', $Config->sl_root . "/conf/$file" ) or die $!;
my $ct = do { local $/; <$fh> };
close($fh) or die $!;
my @lines = split( /\n/, $ct );
@lines = grep { $_ =~ m/\S/ }
grep { $_ !~ /#/ } # skip comments
grep { defined $_ } @lines; # skip undef
return \@lines;
}
sub init_firewall {
my $class = shift;
`echo 1 > /proc/sys/net/ipv4/ip_forward`;
# flush the existing firewall
$class->clear_firewall();
# create the chains
foreach my $table ( sort keys %tables_chains ) {
foreach my $chain ( @{ $tables_chains{$table} } ) {
iptables("-t $table -N $chain");
}
}
# walled garden exceptions
my $hosts_allow = $class->load_allows('cp_hosts_allow.txt');
my $sslhosts_allow = $class->load_allows('cp_sslhosts_allow.txt');
my $accept = "slNET -d %s -p tcp -m tcp --dport %d -j ACCEPT";
my $slout = "slOUT -d %s -p tcp -m tcp --dport %d -j ACCEPT";
my $hosts_accept =
join( "\n", map { sprintf( $accept, $_, 80 ) } @{$hosts_allow} );
my $sslhosts_accept =
join( "\n", map { sprintf( $accept, $_, 443 ) } @{$sslhosts_allow} );
my $hosts_slout =
join( "\n", map { sprintf( $slout, $_, 80 ) } @{$hosts_allow} );
my $sslhosts_slout =
join( "\n", map { sprintf( $slout, $_, 443 ) } @{$sslhosts_allow} );
##############################
# add the filter default chains
my $filters = <<"FILTERS";
INPUT -i $Lan_if -j slRTR
FORWARD -i $Lan_if -j slNET
slAUT --protocol tcp --source-port ! 25 -j ACCEPT
slAUTads -m state --state RELATED,ESTABLISHED -j ACCEPT
slAUTads -p tcp -m tcp --dport 22 -j ACCEPT
slAUTads -p tcp -m tcp --dport 80 -j ACCEPT
slAUTads -p tcp -m tcp --dport 110 -j ACCEPT
slAUTads -p tcp -m tcp --dport 143 -j ACCEPT
slAUTads -p tcp -m tcp --dport 443 -j ACCEPT
slAUTads -p tcp -m tcp --dport 465 -j ACCEPT
slAUTads -p udp -m udp --dport 500 -j ACCEPT
slAUTads -p tcp -m tcp --dport 587 -j ACCEPT
slAUTads -p tcp -m tcp --dport 993 -j ACCEPT
slAUTads -p tcp -m tcp --dport 995 -j ACCEPT
slAUTads -p tcp -m tcp --dport 1723 -j ACCEPT
slAUTads -p udp -m udp --dport 1701 -j ACCEPT
slAUTads -p tcp -m tcp --dport 3389 -j ACCEPT
slAUTads -p tcp -m tcp --dport 5050 -j ACCEPT
slAUTads -p tcp -m tcp --dport 5190 -j ACCEPT
slAUTads -p tcp -m tcp --dport 5222 -j ACCEPT
slAUTads -p tcp -m tcp --dport 5223 -j ACCEPT
slNET -m mark --mark $Blocked_mark/0x700 -j DROP
slNET -m state --state INVALID -j DROP
slNET -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
slNET -m mark --mark $Trusted_mark/0x700 -j ACCEPT
slNET -m mark --mark $Paid_mark/0x700 -j slAUT
slNET -m mark --mark $Ads_mark/0x700 -j slAUTads
slNET -p icmp -j REJECT --reject-with icmp-port-unreachable
$hosts_accept
$sslhosts_accept
slNET -j DROP
slRTR -m mark --mark $Blocked_mark/0x700 -j DROP
slRTR -m state --state INVALID -j DROP
slRTR -m state --state RELATED,ESTABLISHED -j ACCEPT
slRTR -p tcp -m tcp ! --tcp-option 2 --tcp-flags SYN SYN -j DROP
slRTR -p tcp -m tcp --dport $Perlbal_port -j ACCEPT
slRTR -m mark --mark $Trusted_mark/0x700 -j ACCEPT
slRTR -p udp -m udp -s 10.69.0.1/16 --dport 53 -j ACCEPT
slRTR -p udp -m udp -s 10.69.0.1/16 --dport 67 -j ACCEPT
slRTR -p udp -m udp -s 10.69.0.1/16 --dport 68 -j ACCEPT
slRTR -p tcp -m tcp -s 10.69.0.1/16 --dport 20022 -j ACCEPT
slRTR -p icmp -s 10.69.0.1/16 -j ACCEPT
FILTERS
add_rules( 'filter', $filters );
#############################
# default mangle chains
my $mangles = <<"MANGLES";
PREROUTING -i $Lan_if -j slOUT
PREROUTING -i $Lan_if -j slBLK
PREROUTING -i $Lan_if -j slTRU
POSTROUTING -o $Lan_if -j slINC
MANGLES
add_rules( 'mangle', $mangles );
#############################
# default nat chains
my $nats = <<"NATS";
PREROUTING -i $Lan_if -j slOUT
POSTROUTING -o $Wan_if -j MASQUERADE
slOUT -m mark --mark $Trusted_mark/0x700 -j ACCEPT
slOUT -m mark --mark $Paid_mark/0x700 -j ACCEPT
slOUT -m mark --mark $Ads_mark/0x700 -j ACCEPT
$hosts_slout
$sslhosts_slout
slOUT -p tcp -m tcp --dport 80 -j DNAT --to-destination $Gateway_ip:$Perlbal_port
slOUT -p tcp -m tcp --dport 443 -j DNAT --to-destination $Gateway_ip:$Perlbal_port
slOUT -p udp --dport 53 -d $Gateway_ip -j ACCEPT
slOUT -p udp --dport 67 -j ACCEPT
slOUT -p udp --dport 68 -j ACCEPT
slOUT -p tcp --dport 20022 -d $Gateway_ip -j ACCEPT
slOUT -p tcp --dport $Perlbal_port -d $Gateway_ip -j ACCEPT
slOUT -j DROP
NATS
add_rules( 'nat', $nats );
# trusted hosts
my $trusted_hosts = $class->load_allows('trusted_hosts.txt');
my $out_rule =
"-t mangle -A slTRU -m mac --mac-source %s -j MARK $Mark_op $Trusted_mark";
# TODO - arp translation
#my $out_rule = "-t mangle -A slTRU -s %s -m mac --mac-source %s -j MARK $Mark_op $Trusted_mark";
#my $in_rule = "-t mangle -A slINC -d %s -j ACCEPT";
foreach my $mac ( @{$trusted_hosts} ) {
# TODO - arp translation
( run in 2.488 seconds using v1.01-cache-2.11-cpan-302cb4679cc )