forked from extern/shorewall_code
Implement user-defined address variables.
- Also correct handling of ${0} & ${chain} in a SWITCH column. Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
2b9af94c59
commit
df7785f2e9
@ -209,6 +209,7 @@ our %EXPORT_TAGS = (
|
||||
do_dscp
|
||||
have_ipset_rules
|
||||
record_runtime_address
|
||||
verify_address_variables
|
||||
conditional_rule
|
||||
conditional_rule_end
|
||||
match_source_dev
|
||||
@ -389,6 +390,7 @@ my $idiotcount1;
|
||||
my $warningcount;
|
||||
my $hashlimitset;
|
||||
my $global_variables;
|
||||
my %address_variables;
|
||||
my $ipset_rules;
|
||||
|
||||
#
|
||||
@ -654,6 +656,7 @@ sub initialize( $$$ ) {
|
||||
%interfacebcasts = ();
|
||||
%interfaceacasts = ();
|
||||
%interfacegateways = ();
|
||||
%address_variables = ();
|
||||
|
||||
$global_variables = 0;
|
||||
$idiotcount = 0;
|
||||
@ -4887,6 +4890,13 @@ sub get_interface_address( $ );
|
||||
|
||||
sub record_runtime_address( $$;$ ) {
|
||||
my ( $addrtype, $interface, $protect ) = @_;
|
||||
|
||||
if ( $interface =~ /^{([a-zA-Z_]\w*)}$/ ) {
|
||||
fatal_error "Mixed required/optional usage of address variable $1" if ( $address_variables{$1} || $addrtype ) ne $addrtype;
|
||||
$address_variables{$1} = $addrtype;
|
||||
return '$' . "$1 ";
|
||||
}
|
||||
|
||||
fatal_error "Unknown interface address variable (&$interface)" unless known_interface( $interface );
|
||||
fatal_error "Invalid interface address variable (&$interface)" if $interface =~ /\+$/;
|
||||
|
||||
@ -4913,6 +4923,7 @@ sub conditional_rule( $$ ) {
|
||||
|
||||
if ( $address =~ /^!?([&%])(.+)$/ ) {
|
||||
my ($type, $interface) = ($1, $2);
|
||||
|
||||
if ( my $ref = known_interface $interface ) {
|
||||
if ( $ref->{options}{optional} ) {
|
||||
my $variable;
|
||||
@ -4927,7 +4938,13 @@ sub conditional_rule( $$ ) {
|
||||
incr_cmd_level $chainref;
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
} elsif ( $type eq '%' && $interface =~ /^{([a-zA-Z_]\w*)}$/ ) {
|
||||
fatal_error "Mixed required/optional usage of address variable $1" if ( $address_variables{$1} || $type ) ne $type;
|
||||
$address_variables{$1} = $type;
|
||||
add_commands( $chainref , "if [ \$$1 != " . NILIP . ' ]; then' );
|
||||
incr_cmd_level $chainref;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
0;
|
||||
@ -5873,6 +5890,27 @@ sub set_global_variables( $ ) {
|
||||
}
|
||||
}
|
||||
|
||||
sub verify_address_variables() {
|
||||
while ( my ( $variable, $type ) = ( each %address_variables ) ) {
|
||||
my $address = "\$$variable";
|
||||
|
||||
if ( $type eq '&' ) {
|
||||
emit( qq([ -n "$address" ] || startup_error "Address variable $variable had not been assigned an address") ,
|
||||
q() ,
|
||||
qq(if qt \$g_tool -A INPUT -s $address; then) );
|
||||
} else {
|
||||
emit( qq(if [ -z "$address" ]; then) ,
|
||||
qq( $variable=) . NILIP ,
|
||||
qq(elif qt \$g_tool -A INPUT -s $address; then) );
|
||||
}
|
||||
|
||||
emit( qq( qt \$g_tool -D INPUT -s $address),
|
||||
q(else),
|
||||
qq( startup_error "Invalid value ($address) for address variable $variable"),
|
||||
qq(fi\n) );
|
||||
}
|
||||
}
|
||||
|
||||
############################################################################################
|
||||
# Helpers for expand_rule()
|
||||
############################################################################################
|
||||
@ -5990,7 +6028,7 @@ sub isolate_source_interface( $ ) {
|
||||
if ( $source =~ /^(.+?):(.+)$/ ) {
|
||||
$iiface = $1;
|
||||
$inets = $2;
|
||||
} elsif ( $source =~ /^!?(?:\+|&|~|\^|\d+\.)/ ) {
|
||||
} elsif ( $source =~ /^!?(?:\+|&|~|%|\^|\d+\.)/ ) {
|
||||
$inets = $source;
|
||||
} else {
|
||||
$iiface = $source;
|
||||
@ -5998,6 +6036,7 @@ sub isolate_source_interface( $ ) {
|
||||
} elsif ( $source =~ /^(.+?):<(.+)>\s*$/ ||
|
||||
$source =~ /^(.+?):\[(.+)\]\s*$/ ||
|
||||
$source =~ /^(.+?):(!?\+.+)$/ ||
|
||||
$source =~ /^(.+?):(!?[&%].+)$/ ||
|
||||
$source =~ /^(.+?):(\[.+\]\/(?:\d+))\s*$/
|
||||
) {
|
||||
$iiface = $1;
|
||||
@ -6107,6 +6146,7 @@ sub isolate_dest_interface( $$$$ ) {
|
||||
} elsif ( $dest =~ /^(.+?):<(.+)>\s*$/ ||
|
||||
$dest =~ /^(.+?):\[(.+)\]\s*$/ ||
|
||||
$dest =~ /^(.+?):(!?\+.+)$/ ||
|
||||
$dest =~ /^(.+?):(!?[&%].+)$/ ||
|
||||
$dest =~ /^(.+?):(\[.+\]\/(?:\d+))\s*$/
|
||||
) {
|
||||
$diface = $1;
|
||||
|
@ -365,8 +365,8 @@ sub generate_script_3($) {
|
||||
'fi',
|
||||
'' );
|
||||
|
||||
verify_address_variables;
|
||||
save_dynamic_chains;
|
||||
|
||||
mark_firewall_not_started;
|
||||
|
||||
emit ( '',
|
||||
@ -394,6 +394,7 @@ sub generate_script_3($) {
|
||||
'fi',
|
||||
'' );
|
||||
|
||||
verify_address_variables;
|
||||
save_dynamic_chains;
|
||||
mark_firewall_not_started;
|
||||
|
||||
|
@ -1840,7 +1840,7 @@ sub split_line1( $$;$$ ) {
|
||||
# Found it -- be sure there wasn't more than one.
|
||||
#
|
||||
fatal_error "Only one semicolon (';') allowed on a line" if defined $rest;
|
||||
} elsif ( $currentline =~ /(.*){(.*)}$/ ) {
|
||||
} elsif ( $currentline =~ /^(\s*|.*[^&@%]){(.*)}$/ ) {
|
||||
#
|
||||
# Pairs are enclosed in curly brackets.
|
||||
#
|
||||
|
@ -196,12 +196,16 @@ sub process_one_masq( )
|
||||
} else {
|
||||
my $addrlist = '';
|
||||
for my $addr ( split_list $addresses , 'address' ) {
|
||||
if ( $addr =~ /^&(.+)$/ ) {
|
||||
if ( $addr =~ /^([&%])(.+)$/ ) {
|
||||
my ( $type, $interface ) = ( $1, $2 );
|
||||
$target = 'SNAT ';
|
||||
if ( $conditional = conditional_rule( $chainref, $addr ) ) {
|
||||
$addrlist .= '--to-source ' . get_interface_address $1;
|
||||
if ( $interface =~ /^{([a-zA-Z_]\w*)}$/ ) {
|
||||
$conditional = conditional_rule( $chainref, $addr );
|
||||
$addrlist .= '--to-source ' . "\$$1 ";
|
||||
} elsif ( $conditional = conditional_rule( $chainref, $addr ) ) {
|
||||
$addrlist .= '--to-source ' . get_interface_address $interface;
|
||||
} else {
|
||||
$addrlist .= '--to-source ' . record_runtime_address( '&', $1 );
|
||||
$addrlist .= '--to-source ' . record_runtime_address( $type, $interface );
|
||||
}
|
||||
} elsif ( $addr =~ /^.*\..*\..*\./ ) {
|
||||
$target = 'SNAT ';
|
||||
|
@ -1366,6 +1366,66 @@ SHELL cat /etc/shorewall/rules.d/*.rules 2> /dev/null || true</programlisting
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>Beginning with Shorewall 4.5.11, you can define your own address
|
||||
variables by using this syntax:</para>
|
||||
|
||||
<simplelist>
|
||||
<member>&{<replaceable>variable</replaceable>}</member>
|
||||
</simplelist>
|
||||
|
||||
<para>where <replaceable>variable</replaceable> is a valid shell variable
|
||||
name. The generated script will verify that the
|
||||
<replaceable>variable</replaceable> contains a valid host or network
|
||||
address, either from the environment or from it being assigned in your
|
||||
<emphasis>init</emphasis> <ulink
|
||||
url="shorewall_extension_scripts.htm">extension script</ulink>, and will
|
||||
raise an error if it does not. In the error case, the state of the
|
||||
firewall will remain unchanged.</para>
|
||||
|
||||
<para>Example:</para>
|
||||
|
||||
<para>/etc/shorewall/init:</para>
|
||||
|
||||
<programlisting><emphasis role="bold">SMC_ADDR</emphasis>=10.1.10.11</programlisting>
|
||||
|
||||
<para>/etc/shorewall/rules:</para>
|
||||
|
||||
<programlisting>test:debug net:<emphasis role="bold">&{SMC_ADDR}</emphasis> fw</programlisting>
|
||||
|
||||
<para>A second form is also available beginning with Shorewall
|
||||
4.5.11</para>
|
||||
|
||||
<simplelist>
|
||||
<member>%{<replaceable>variable</replaceable>}</member>
|
||||
</simplelist>
|
||||
|
||||
<para>Unlike with the first form, this form does not require the variable
|
||||
to be set. If the variable is empty, the generated script will supply the
|
||||
all-zeros address (0.0.0.0 in IPv4 and :: in IPv6). In most cases, the
|
||||
compiler simply omits rules containing matches on the all-zeros
|
||||
address.</para>
|
||||
|
||||
<para>Example:</para>
|
||||
|
||||
<para>/etc/shorewall/init:</para>
|
||||
|
||||
<programlisting><emphasis role="bold">SMC_ADDR</emphasis>=10.1.10.11</programlisting>
|
||||
|
||||
<para>/etc/shorewall/rules:</para>
|
||||
|
||||
<programlisting>test:debug net:<emphasis role="bold">%{SMC_ADDR}</emphasis> fw</programlisting>
|
||||
|
||||
<important>
|
||||
<para>For a particular address variable, all references must use the
|
||||
same prefix character ('&' or '%'). Otherwise, the following error
|
||||
message is raised:</para>
|
||||
|
||||
<simplelist>
|
||||
<member>ERROR: Mixed required/optional usage of address variable
|
||||
<replaceable>variable</replaceable></member>
|
||||
</simplelist>
|
||||
</important>
|
||||
|
||||
<para>Run-time address variables may be used in the SOURCE and DEST column
|
||||
of the following configuration files:</para>
|
||||
|
||||
@ -1566,7 +1626,7 @@ SHELL cat /etc/shorewall/rules.d/*.rules 2> /dev/null || true</programlisting
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>@0 and @chain</term>
|
||||
<term>@0 and @chain (@{0} and @{chain})</term>
|
||||
|
||||
<listitem>
|
||||
<para>Expands to the name of the current chain. Unlike $0, @0 has
|
||||
@ -1577,7 +1637,7 @@ SHELL cat /etc/shorewall/rules.d/*.rules 2> /dev/null || true</programlisting
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>@loglevel</term>
|
||||
<term>@loglevel (@{loglevel})</term>
|
||||
|
||||
<listitem>
|
||||
<para>Expands to the log level specified when the action was
|
||||
@ -1586,7 +1646,7 @@ SHELL cat /etc/shorewall/rules.d/*.rules 2> /dev/null || true</programlisting
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>@logtag</term>
|
||||
<term>@logtag (@{logtag})</term>
|
||||
|
||||
<listitem>
|
||||
<para>Expands to the log tag specified when the action was
|
||||
|
Loading…
Reference in New Issue
Block a user