forked from extern/shorewall_code
New IPSET MATCH extensions
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
48ceed9ecb
commit
b4847d6a01
@ -448,7 +448,22 @@ use constant { NO_RESTRICT => 0, # FORWARD chain rule - Both -i an
|
||||
ALL_RESTRICT => 12, # fw->fw rule - neither -i nor -o allowed
|
||||
DESTIFACE_DISALLOW => 32, # Don't allow dest interface. Similar to INPUT_RESTRICT but generates a more relevant error message
|
||||
};
|
||||
|
||||
#
|
||||
# Possible IPSET options
|
||||
#
|
||||
our %ipset_extensions = (
|
||||
'nomatch' => '--return-nomatch ',
|
||||
'no-update-counters' => '! --update-counters ',
|
||||
'no-update-subcounters' => '! --update-subcounters ',
|
||||
'pkts-eq' => '--packets-eq = ',
|
||||
'pkts-neq' => '! --packets-eq = ',
|
||||
'pkts-lt' => '--packets-lt = ',
|
||||
'pkts-gt' => '--packets-gt = ',
|
||||
'bytes-eq' => '--bytes-eq = ',
|
||||
'bytes-neq' => '! --bytes-eq = ',
|
||||
'bytes-lt' => '--bytes-lt = ',
|
||||
'bytes-gt' => '--bytes-gt = ',
|
||||
);
|
||||
#
|
||||
# See initialize() below for additional comments on these variables
|
||||
#
|
||||
@ -4403,6 +4418,11 @@ sub do_proto( $$$;$ )
|
||||
|
||||
if ( $ports ne '' ) {
|
||||
$invert = $ports =~ s/^!// ? '! ' : '';
|
||||
|
||||
if ( $ports =~ /^\+/ ) {
|
||||
$output .= $invert;
|
||||
$output .= get_set_flags( $ports, 'dst' );
|
||||
} else {
|
||||
$sports = '', require_capability( 'MULTIPORT', "'=' in the SOURCE PORT(S) column", 's' ) if ( $srcndst = $sports eq '=' );
|
||||
|
||||
if ( $multiport || $ports =~ tr/,/,/ > 0 || $sports =~ tr/,/,/ > 0 ) {
|
||||
@ -4424,6 +4444,7 @@ sub do_proto( $$$;$ )
|
||||
$ports = validate_portpair $pname , $ports;
|
||||
$output .= ( $srcndst ? "-m multiport ${invert}--ports ${ports} " : "${invert}--dport ${ports} " );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$multiport ||= ( $sports =~ tr/,/,/ ) > 0 ;;
|
||||
}
|
||||
@ -4434,9 +4455,13 @@ sub do_proto( $$$;$ )
|
||||
|
||||
if ( $sports ne '' ) {
|
||||
fatal_error "'=' in the SOURCE PORT(S) column requires one or more ports in the DEST PORT(S) column" if $sports eq '=';
|
||||
$invert = $sports =~ s/^!// ? '! ' : '';
|
||||
if ( $multiport ) {
|
||||
|
||||
$invert = $sports =~ s/^!// ? '! ' : '';
|
||||
|
||||
if ( $ports =~ /^\+/ ) {
|
||||
$output .= $invert;
|
||||
$output .= get_set_flags( $ports, 'dst' );
|
||||
} elsif ( $multiport ) {
|
||||
if ( port_count( $sports ) > 15 ) {
|
||||
if ( $restricted ) {
|
||||
fatal_error "A port list in this file may only have up to 15 ports";
|
||||
@ -5424,6 +5449,7 @@ sub iprange_match() {
|
||||
sub get_set_flags( $$ ) {
|
||||
my ( $setname, $option ) = @_;
|
||||
my $options = $option;
|
||||
my $extensions = '';
|
||||
|
||||
require_capability( 'IPSET_MATCH' , 'ipset names in Shorewall configuration files' , '' );
|
||||
|
||||
@ -5431,6 +5457,28 @@ sub get_set_flags( $$ ) {
|
||||
|
||||
$setname =~ s/^!//; # Caller has already taken care of leading !
|
||||
|
||||
if ( $setname =~ s/\((.+)\)$// ) {
|
||||
fatal_error "Your iptables and/or kernel are too old to support an IPSET option list" if have_capability 'OLD_IPSET_MATCH';
|
||||
my @extensions = split_list($1, 'ipset option');
|
||||
|
||||
for ( @extensions ) {
|
||||
my ($extension, $value) = split ' ', $_;
|
||||
my $match = $ipset_extensions{$extension};
|
||||
fatal_error "Unknown ipset option ($extension)" unless $match;
|
||||
|
||||
if ( $match =~ /= $/ ) {
|
||||
my $val;
|
||||
fatal_error "The $extension option requires a value" unless supplied $value;
|
||||
fatal_error "Invalid number ($value)" unless defined ( $val = numeric_value($value) );
|
||||
$match =~ s/= $/$value /;
|
||||
} else {
|
||||
fatal_error "The $extension option does not require a value" if supplied $value;
|
||||
}
|
||||
|
||||
$extensions = join( '', $extensions, $match );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $setname =~ /^(.*)\[([1-6])\]$/ ) {
|
||||
$setname = $1;
|
||||
my $count = $2;
|
||||
@ -5463,7 +5511,7 @@ sub get_set_flags( $$ ) {
|
||||
|
||||
fatal_error "Invalid ipset name ($setname)" unless $setname =~ /^(6_)?[a-zA-Z][-\w]*/;
|
||||
|
||||
have_capability( 'OLD_IPSET_MATCH' ) ? "--set $setname $options " : "--match-set $setname $options ";
|
||||
have_capability( 'OLD_IPSET_MATCH' ) ? "--set $setname $options " : "--match-set $setname $options $extensions";
|
||||
|
||||
}
|
||||
|
||||
|
@ -327,6 +327,10 @@ our %capdesc = ( NAT_ENABLED => 'NAT',
|
||||
=> 'Owner Name Match',
|
||||
IPSET_MATCH => 'Ipset Match',
|
||||
OLD_IPSET_MATCH => 'Old Ipset Match',
|
||||
IPSET_MATCH_NOMATCH
|
||||
=> 'Ipset Match nomatch',
|
||||
IPSET_MATCH_COUNTERS
|
||||
=> 'Ipset Match counters',
|
||||
IPSET_V5 => 'Version 5 ipsets',
|
||||
CONNMARK => 'CONNMARK Target',
|
||||
XCONNMARK => 'Extended CONNMARK Target',
|
||||
@ -904,6 +908,8 @@ sub initialize( $;$$) {
|
||||
OWNER_NAME_MATCH => undef,
|
||||
IPSET_MATCH => undef,
|
||||
OLD_IPSET_MATCH => undef,
|
||||
IPSET_MATCH_NOMATCH => undef,
|
||||
IPSET_MATCH_COUNTERS => undef,
|
||||
IPSET_V5 => undef,
|
||||
CONNMARK => undef,
|
||||
XCONNMARK => undef,
|
||||
@ -4077,11 +4083,15 @@ sub IPSet_Match() {
|
||||
|
||||
$ipset = which $ipset unless $ipset =~ '/';
|
||||
|
||||
$capabilities{IPSET_MATCH_NOMATCH} = $capabilities{IPSET_MATCH_COUNTERS} = 0;
|
||||
|
||||
if ( $ipset && -x $ipset ) {
|
||||
qt( "$ipset -X $sillyname" );
|
||||
|
||||
if ( qt( "$ipset -N $sillyname iphash" ) || qt( "$ipset -N $sillyname hash:ip family $fam") ) {
|
||||
if ( qt1( "$iptables $iptablesw -A $sillyname -m set --match-set $sillyname src -j ACCEPT" ) ) {
|
||||
$capabilities{IPSET_MATCH_NOMATCH} = qt1( "$iptables $iptablesw -A $sillyname -m set --match-set $sillyname src --return-nomatch -j ACCEPT" );
|
||||
$capabilities{IPSET_MATCH_COUNTERS} = qt1( "$iptables $iptablesw -A $sillyname -m set --match-set $sillyname src --packets-lt 100 -j ACCEPT" );
|
||||
qt1( "$iptables $iptablesw -F $sillyname" );
|
||||
$result = ! ( $capabilities{OLD_IPSET_MATCH} = 0 );
|
||||
} else {
|
||||
@ -4095,6 +4105,14 @@ sub IPSet_Match() {
|
||||
$result;
|
||||
}
|
||||
|
||||
sub IPSet_Match_Nomatch() {
|
||||
have_capability 'IPSET_MATCH' && $capabilities{IPSET_MATCH_NOMATCH};
|
||||
}
|
||||
|
||||
sub IPSet_Match_Counters() {
|
||||
have_capability 'IPSET_MATCH' && $capabilities{IPSET_MATCH_COUNTGERS};
|
||||
}
|
||||
|
||||
sub IPSET_V5() {
|
||||
my $ipset = $config{IPSET} || 'ipset';
|
||||
my $result = 0;
|
||||
@ -4383,6 +4401,8 @@ our %detect_capability =
|
||||
IPP2P_MATCH => \&Ipp2p_Match,
|
||||
IPRANGE_MATCH => \&IPRange_Match,
|
||||
IPSET_MATCH => \&IPSet_Match,
|
||||
IPSET_MATCH_NOMATCH => \&IPSet_Match_Nomatch,
|
||||
IPSET_MATCH_COUNTERS => \&IPSet_Match_Counters,
|
||||
IRC_HELPER => \&IRC_Helper,
|
||||
IRC0_HELPER => \&IRC0_Helper,
|
||||
OLD_IPSET_MATCH => \&Old_IPSet_Match,
|
||||
|
Loading…
Reference in New Issue
Block a user