Add support for condition match in the rules file

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2011-09-21 08:13:44 -07:00
parent 7978993d2b
commit e8f51150dd
10 changed files with 123 additions and 21 deletions

View File

@ -169,6 +169,7 @@ our %EXPORT_TAGS = (
do_connbytes
do_helper
do_headers
do_condition
have_ipset_rules
record_runtime_address
conditional_rule
@ -3736,6 +3737,20 @@ sub do_headers( $ ) {
"-m ipv6header ${invert}--header ${headers} ${soft}";
}
#
# Generate a -m condition match
#
sub do_condition( $ ) {
my $condition = shift;
return '' if $condition eq '-';
require_capability 'CONDITION_MATCH', 'A non-empty CONDITION column', 's';
fatal_error "Invalid condition name ($condition)" unless $condition =~ /^[a-zA-Z]\w*$/;
"-m condition --condition $condition"
}
#
# Match Source Interface
#

View File

@ -280,6 +280,7 @@ my %capdesc = ( NAT_ENABLED => 'NAT',
ACCOUNT_TARGET => 'ACCOUNT Target',
AUDIT_TARGET => 'AUDIT Target',
RAWPOST_TABLE => 'Rawpost Table',
CONDITION_MATCH => 'Condition Match',
CAPVERSION => 'Capability Version',
KERNELVERSION => 'Kernel Version',
);
@ -444,7 +445,7 @@ sub initialize( $ ) {
STATEMATCH => '-m state --state',
UNTRACKED => 0,
VERSION => "4.4.22.1",
CAPVERSION => 40423 ,
CAPVERSION => 40424 ,
);
#
# From shorewall.conf file
@ -664,6 +665,7 @@ sub initialize( $ ) {
HEADER_MATCH => undef,
ACCOUNT_TARGET => undef,
AUDIT_TARGET => undef,
CONDITION_MATCH => undef,
CAPVERSION => undef,
KERNELVERSION => undef,
);
@ -2671,6 +2673,10 @@ sub Account_Target() {
}
}
sub Condition_Match() {
qt1( "$iptables -m condition --condition foo" );
}
sub Audit_Target() {
qt1( "$iptables -A $sillyname -j AUDIT --type drop" );
}
@ -2680,6 +2686,7 @@ our %detect_capability =
AUDIT_TARGET => \&Audit_Target,
ADDRTYPE => \&Addrtype,
CLASSIFY_TARGET => \&Classify_Target,
CONDITION_MATCH => \&Condition_Match,
COMMENTS => \&Comments,
CONNLIMIT_MATCH => \&Connlimit_Match,
CONNMARK => \&Connmark,
@ -2853,6 +2860,7 @@ sub determine_capabilities() {
$capabilities{ACCOUNT_TARGET} = detect_capability( 'ACCOUNT_TARGET' );
$capabilities{AUDIT_TARGET} = detect_capability( 'AUDIT_TARGET' );
$capabilities{IPSET_V5} = detect_capability( 'IPSET_V5' );
$capabilities{CONDITION_MATCH} = detect_capability( 'CONDITION_MATCH' );
qt1( "$iptables -F $sillyname" );

View File

@ -1382,7 +1382,7 @@ sub process_actions() {
}
sub process_rule1 ( $$$$$$$$$$$$$$$$ );
sub process_rule1 ( $$$$$$$$$$$$$$$$$ );
#
# Populate an action invocation chain. As new action tuples are encountered,
@ -1415,14 +1415,14 @@ sub process_action( $) {
while ( read_a_line ) {
my ($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers );
my ($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition );
if ( $format == 1 ) {
($target, $source, $dest, $proto, $ports, $sports, $rate, $user, $mark ) = split_line1 1, 9, 'action file', $rule_commands;
$origdest = $connlimit = $time = $headers = '-';
$origdest = $connlimit = $time = $headers = $condition = '-';
} else {
($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers )
= split_line1 1, 13, 'action file', $action_commands;
($target, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition )
= split_line1 1, 14, 'action file', $action_commands;
}
if ( $target eq 'COMMENT' ) {
@ -1456,6 +1456,7 @@ sub process_action( $) {
$connlimit,
$time,
$headers,
$condition,
0 );
}
@ -1485,8 +1486,8 @@ sub use_policy_action( $ ) {
#
# Expand a macro rule from the rules file
#
sub process_macro ( $$$$$$$$$$$$$$$$$ ) {
my ($macro, $chainref, $target, $param, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $wildcard ) = @_;
sub process_macro ( $$$$$$$$$$$$$$$$$$ ) {
my ($macro, $chainref, $target, $param, $source, $dest, $proto, $ports, $sports, $origdest, $rate, $user, $mark, $connlimit, $time, $headers, $condition, $wildcard ) = @_;
my $nocomment = no_comment;
@ -1504,13 +1505,13 @@ sub process_macro ( $$$$$$$$$$$$$$$$$ ) {
while ( read_a_line ) {
my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders );
my ( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition );
if ( $format == 1 ) {
( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $mrate, $muser ) = split_line1 1, 8, 'macro file', $rule_commands;
( $morigdest, $mmark, $mconnlimit, $mtime, $mheaders ) = qw/- - - - -/;
( $morigdest, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition ) = qw/- - - - - -/;
} else {
( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders ) = split_line1 1, 13, 'macro file', $rule_commands;
( $mtarget, $msource, $mdest, $mproto, $mports, $msports, $morigdest, $mrate, $muser, $mmark, $mconnlimit, $mtime, $mheaders, $mcondition ) = split_line1 1, 14, 'macro file', $rule_commands;
}
if ( $mtarget eq 'COMMENT' ) {
@ -1586,6 +1587,7 @@ sub process_macro ( $$$$$$$$$$$$$$$$$ ) {
merge_macro_column( $mconnlimit, $connlimit) ,
merge_macro_column( $mtime, $time ),
merge_macro_column( $mheaders, $headers ),
merge_macro_column( $mcondition, $condition ),
$wildcard
);
@ -1618,7 +1620,7 @@ sub verify_audit($;$$) {
# Similarly, if a new action tuple is encountered, this function is called recursively for each rule in the action
# body. In this latter case, a reference to the tuple's chain is passed in the first ($chainref) argument.
#
sub process_rule1 ( $$$$$$$$$$$$$$$$ ) {
sub process_rule1 ( $$$$$$$$$$$$$$$$ $) {
my ( $chainref, #reference to Action Chain if we are being called from process_action(); undef otherwise
$target,
$current_param,
@ -1634,6 +1636,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$ ) {
$connlimit,
$time,
$headers,
$condition,
$wildcard ) = @_;
my ( $action, $loglevel) = split_action $target;
@ -1685,6 +1688,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$ ) {
$connlimit,
$time,
$headers,
$condition,
$wildcard );
$macro_nest_level--;
@ -1925,6 +1929,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$ ) {
do_connlimit( $connlimit ),
do_time( $time ) ,
do_headers( $headers ) ,
do_condition( $condition ) ,
);
} else {
$rule = join( '',
@ -1934,7 +1939,8 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$ ) {
do_test( $mark , $globals{TC_MASK} ) ,
do_connlimit( $connlimit ),
do_time( $time ) ,
do_headers( $headers )
do_headers( $headers ) ,
do_condition( $condition ) ,
);
}
@ -2313,8 +2319,8 @@ sub build_zone_list( $$$\$\$ ) {
# Process a Record in the rules file
#
sub process_rule ( ) {
my ( $target, $source, $dest, $protos, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, $headers )
= split_line1 1, 13, 'rules file', $rule_commands;
my ( $target, $source, $dest, $protos, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, $headers, $condition )
= split_line1 1, 14, 'rules file', $rule_commands;
process_comment, return 1 if $target eq 'COMMENT';
process_section( $source ), return 1 if $target eq 'SECTION';
@ -2367,6 +2373,7 @@ sub process_rule ( ) {
$connlimit,
$time,
$headers,
$condition,
$wild );
}
}

View File

@ -6,8 +6,8 @@
# The manpage is also online at
# http://www.shorewall.net/manpages/shorewall-rules.html
#
####################################################################################################################################################################
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK CONNLIMIT TIME HEADERS
######################################################################################################################################################################################
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK CONNLIMIT TIME HEADERS CONDITION
# PORT PORT(S) DEST LIMIT GROUP
#SECTION ALL
#SECTION ESTABLISHED

View File

@ -28,7 +28,7 @@
#
SHOREWALL_LIBVERSION=40407
SHOREWALL_CAPVERSION=40421
SHOREWALL_CAPVERSION=40424
[ -n "${VARDIR:=/var/lib/shorewall}" ]
[ -n "${SHAREDIR:=/usr/share/shorewall}" ]

View File

@ -1731,6 +1731,7 @@ determine_capabilities() {
HEADER_MATCH=
ACCOUNT_TARGET=
AUDIT_TARGET=
CONDITION_MATCH=
chain=fooX$$
@ -1881,6 +1882,7 @@ determine_capabilities() {
qt $IPTABLES -A $chain -j MARK --set-mark 5 && MARK_ANYWHERE=Yes
qt $IPTABLES -A $chain -j ACCOUNT --addr 192.168.1.0/29 --tname $chain && ACCOUNT_TARGET=Yes
qt $IPTABLES -A $chain -j AUDIT --type drop && AUDIT_TARGET=Yes
qt $IPTABLES -A $chain -m condition --condition foo && CONDITION_MATCH=Yes
qt $IPTABLES -F $chain
qt $IPTABLES -X $chain
qt $IPTABLES -F $chain1
@ -1975,6 +1977,7 @@ report_capabilities() {
report_capability "ACCOUNT Target" $ACCOUNT_TARGET
report_capability "AUDIT Target" $AUDIT_TARGET
report_capability "ipset V5" $IPSET_V5
report_capability "Condition Match" $CONDITION_MATCH
fi
[ -n "$PKTTYPE" ] || USEPKTTYPE=
@ -2045,6 +2048,7 @@ report_capabilities1() {
report_capability1 ACCOUNT_TARGET
report_capability1 AUDIT_TARGET
report_capability1 IPSET_V5
report_capability1 CONDITION_MATCH
echo CAPVERSION=$SHOREWALL_CAPVERSION
echo KERNELVERSION=$KERNELVERSION

View File

@ -32,7 +32,7 @@
#
SHOREWALL_LIBVERSION=40407
SHOREWALL_CAPVERSION=40423
SHOREWALL_CAPVERSION=40424
[ -n "${VARDIR:=/var/lib/shorewall6}" ]
[ -n "${SHAREDIR:=/usr/share/shorewall6}" ]

View File

@ -1558,6 +1558,7 @@ determine_capabilities() {
ACCOUNT_TARGET=
AUDIT_TARGET=
IPSET_V5=
CONDITION_MATCH=
chain=fooX$$
@ -1709,6 +1710,7 @@ determine_capabilities() {
qt $IP6TABLES -A $chain -m ipv6header --header 255 && HEADER_MATCH=Yes
qt $IP6TABLES -A $chain -j ACCOUNT --addr 1::/122 --tname $chain && ACCOUNT_TARGET=Yes
qt $IP6TABLES -A $chain -j AUDIT --type drop && AUDIT_TARGET=Yes
qt $IP6TABLES -A $chain -m condition --condition foo && CONDITION_MATCH=Yes
qt $IP6TABLES -F $chain
@ -1802,6 +1804,7 @@ report_capabilities() {
report_capability "ACCOUNT Target" $ACCOUNT_TARGET
report_capability "AUDIT Target" $AUDIT_TARGET
report_capability "ipset V5" $IPSET_V5
report_capability "Condition Match" $CONDITION_MATCH
fi
[ -n "$PKTTYPE" ] || USEPKTTYPE=
@ -1869,6 +1872,7 @@ report_capabilities1() {
report_capability1 ACCOUNT_TARGET
report_capability1 AUDIT_TARGET
report_capability1 IPSET_V5
report_capability1 CONDITION_MATCH
echo CAPVERSION=$SHOREWALL_CAPVERSION
echo KERNELVERSION=$KERNELVERSION

View File

@ -1267,6 +1267,30 @@
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">HEADERS</emphasis></term>
<listitem>
<para>Added in Shorewall 4.4.15. Not used in IPv4 configurations. If
you with to supply a value for one of the later columns, enter '-'
in this column.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">CONDITION -
[!]<replaceable>condition-name</replaceable></emphasis></term>
<listitem>
<para>Added in Shorewall 4.4.24. Matches if the value stored in
<filename>/proc/net/nf_condition/<replaceable>condition-name</replaceable></filename>
is 1. Does not match if that file contains 0 (the default). If '!'
is supplied, the test is inverted such that there is a match if the
file contains 0. The condition-name must begin with a letter and be
composed of letters, decimal digits or underscores.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -1457,6 +1481,19 @@
SSH(ACCEPT) net all - - - - s:1/min:3</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Example 12:</term>
<listitem>
<para>Forward port 80 to dmz host $BACKUP if condition
'primary_down' is set.</para>
<programlisting> #ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK CONNLIMIT TIME HEADERS CONDITION
# PORT(S) PORT(S) DEST LIMIT GROUP
DNAT net dmz:$BACKUP tcp 80 - - - - - - - - primary_down</programlisting>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -1102,6 +1102,20 @@
role="bold">!</emphasis> is omitted.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">CONDITION -
[!]<replaceable>condition-name</replaceable></emphasis></term>
<listitem>
<para>Added in Shorewall6 4.4.24. Matches if the value stored in
<filename>/proc/net/nf_condition/<replaceable>condition-name</replaceable></filename>
is 1. Does not match if that file contains 0 (the default). If '!'
is supplied, the test is inverted such that there is a match if the
file contains 0. The condition-name must begin with a letter and be
composed of letters, decimal digits or underscores.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -1148,6 +1162,19 @@
SSH(ACCEPT) net all - - - - s:1/min:3</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Example 6:</term>
<listitem>
<para>Forward port 80 to dmz host $BACKUP if condition
'primary_down' is set.</para>
<programlisting> #ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK CONNLIMIT TIME HEADERS CONDITION
# PORT(S) PORT(S) DEST LIMIT GROUP
DNAT net dmz:$BACKUP tcp 80 - - - - - - - - primary_down</programlisting>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -1162,8 +1189,8 @@
<para>shorewall6(8), shorewall6-accounting(5), shorewall6-actions(5),
shorewall6-blacklist(5), shorewall6-hosts(5), shorewall6-interfaces(5),
shorewall6-maclist(5), shoewall6-netmap(5),shorewall6-params(5), shorewall6-policy(5),
shorewall6-providers(5), shorewall6-route_rules(5),
shorewall6-maclist(5), shoewall6-netmap(5),shorewall6-params(5),
shorewall6-policy(5), shorewall6-providers(5), shorewall6-route_rules(5),
shorewall6-routestopped(5), shorewall6.conf(5), shorewall6-secmarks(5),
shorewall6-tcclasses(5), shorewall6-tcdevices(5), shorewall6-tcrules(5),
shorewall6-tos(5), shorewall6-tunnels(5), shorewall6-zones(5)</para>