Extension Scripts
Tom
Eastep
2001-2007
Thomas M. Eastep
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License, Version
1.2 or any later version published by the Free Software Foundation; with
no Invariant Sections, with no Front-Cover, and with no Back-Cover
Texts. A copy of the license is included in the section entitled
GNU Free Documentation
License
.
This article applies to Shorewall 4.0 and later. If you are running
a version of Shorewall earlier than Shorewall 4.0.0 then please see the
documentation for that release.
Extension Scripts
Extension scripts are user-provided scripts that are invoked at
various points during firewall start, restart, stop and clear. The scripts
are placed in /etc/shorewall and are processed using the Bourne shell
source
mechanism.
Be sure that you actually need to use an extension script to
do what you want. Shorewall has a wide range of features that cover
most requirements.
DO NOT SIMPLY COPY RULES THAT YOU FIND ON THE NET INTO AN
EXTENSION SCRIPT AND EXPECT THEM TO WORK AND TO NOT BREAK SHOREWALL.
TO USE SHOREWALL EXTENSION SCRIPTS YOU MUST KNOW WHAT YOU ARE DOING
WITH RESPECT TO iptables/Netfilter AND SHOREWALL.
The following scripts can be supplied:
compile -- (Added in Shorewall-perl version
4.0.6). Invoked by the Shorewall-perl compiler early in the
compilation process. Must be written in Perl.
init -- invoked early in shorewall
start
and shorewall restart
initdone -- invoked after Shorewall has
flushed all existing rules but before any rules have been added to the
builtin chains.
start -- invoked after the firewall has
been started or restarted. The script is also invoked by
Shorewall-shell after a successful 'restore'.
started -- invoked after the firewall has
been marked as 'running'. The script is also invoked by
Shorewall-shell after a successful 'restore'.
stop -- invoked as a first step when the
firewall is being stopped.
stopped -- invoked after the firewall has
been stopped.
clear -- invoked after the firewall has
been cleared.
tcclear -- invoked to clear traffic shaping
when CLEAR_TC=Yes in shorewall.conf.
refresh -- invoked while the firewall is
being refreshed but before the blacklst chains have been
rebuilt.
refreshed -- invoked after the firewall has
been refreshed.
continue -- invoked to allow you to insert
special rules to allow traffic while Shorewall is [re]starting. Any
rules added in this script should be deleted in your
start script. This script is invoked earlier in
the [re]start process than is the initdone script
described above (Not used by Shorewall Perl).
maclog -- invoked while mac filtering rules
are being created. It is invoked once for each interface having
'maclist' specified and it is invoked just before the logging rule is
added to the current chain (the name of that chain will be in
$CHAIN).
isusable -- (Added in Shorewall-perl
version 4.0.3) invoked when Shorewall is trying to determine the
usability of the network interface associated with an optional entry
in /etc/shorewall/providers. $1 is the name of
the interface which will have been determined to be up and configured
before the script is invoked. The return value from the script
indicates whether or not the interface is usable (0 = usable, other =
unusable).
Example:# Ping a gateway through the passed interface
case $1 in
eth0)
ping -c 4 -t 1 -I eth0 206.124.146.254 > /dev/null 2>&1
return
;;
eth1)
ping -c 4 -t 1 -I eth1 192.168.12.254 > /dev/null 2>&1
return
;;
*)
# No additional testing of other interfaces
return 0
;;
esac
We recommend that this script only be used with
ADMINISABSENTMINDED=Yes.
The firewall state when this script is invoked is
indeterminate. So if you have ADMINISABSENTMINDED=No in shorewall.conf(8) and
output on an interface is not allowed by routestopped(8) then
the isuasable script must blow it's own holes in the firewall
before probing.
save -- (Added in Shorewall version 4.2.0
Beta2). This script is invoked during execution of the
shorewall save and shorewall-lite
save commands.
restored -- (Added in Shorewall-perl
version 4.2.6). This script is invoked at the completion of a
successful shorewall restore and
shorewall-lite restore.
If your version of Shorewall doesn't have the
file that you want to use from the above list, you can simply create the
file yourself. You can also supply a script with the same name
as any of the filter chains in the firewall and the script will be invoked
after the /etc/shorewall/rules file has been processed but before the
/etc/shorewall/policy file has been processed.
The following table indicate which commands invoke the various
scripts.
script
Shorewall-shell
Shorewall-perl
clear
clear
clear
compile
-
check, compile, export, load, refresh, reload, restart,
restore,start
continue
load, refresh, reload, restart, restore, start
init
load, refresh, reload, restart, restore, start
load, refresh, reload, restart restore, start
initdone
refresh, restart, restore, start
check, compile, export, refresh, restart, start
isusable
refresh, restart, restore, start
refresh, restart, restore, start
maclog
load, refresh, reload, restart, restore, start
check, compile, export, refresh, restart, start
refresh
refresh
refresh
refreshed
refresh
refresh
restored
-
restore
save
save
save
start
load, reload, restart, restore, start
load, reload, restart, start
started
load, reload, restart, restore, start
load, reload, restart, start
stop
stop, clear
stop, clear
stopped
stop, clear
stop, clear
tcclear
load, reload, restart, restore, start
load, reload, restart, restore, start
There are a couple of special considerations for commands in
extension scripts:
When you want to run iptables, use the
command run_iptables instead.
run_iptables will run the iptables utility passing
the arguments to run_iptables and if the command
fails, the firewall will be stopped (or restored from the last
save command, if any). Note that when
Shorewall-shell invokes this script during restore,
The run_iptables function does nothing; calls to
that function are effectively ignored. run_iptables
should not be called from the started or
restored scripts.
If you wish to generate a log message, use log_rule_limit. Parameters are:
Log Level
Chain to insert the rule into
Chain name to display in the message (this can be different
from the preceding argument — see the Port Knocking article for an
example of how to use this).
Disposition to report in the message (ACCEPT, DROP,
etc)
Rate Limit (if passed as "" then $LOGLIMIT is assumed — see
the LOGLIMIT option in /etc/shorewall/shorewall.conf)
Log Tag ("" if none)
Command (-A or -I for append or insert).
The remaining arguments are passed "as is" to
iptables
Many of the extension scripts get executed for both the
shorewall start and shorewall restart commands. You can determine
which command is being executed using the contents of $COMMAND.
if [ $COMMAND = start ]; then
...
Shorewall-shell
When compiling your firewall configuration, Shorewall copies most
extension scripts directly into the "compiled" program where they are
executed in-line during processing of the start, restart and restore
commands. When copying a script, Shorewall indents the script to match
the surrounding code; if you have 'awk' installed on the system where
the configuration is being compiled, Shorewall can correctly handle line
continuation in your script ("\" as the last character on a line). If
you do not have awk, you may not use line continuation in your scripts.
Also beware that quoted strings continued from one line to another will
have extra whitespace inserted as a result of indentation.
The /etc/shorewall/params script is
processed only during compilation if EXPORTPARAMS=No in
shorewall.conf. So shell variables set in that
file may be used in Shorewall configuration files only. Any variables
that your extension scripts require at run-time on the firewall system
should be set in the init extension script (if
you need variable values in the stop or
stopped scripts, you will need to set their value
in stop since init is not
invoked when processing the stop and
clear commands).
When EXPORTPARAMS=Yes (the default), the
/etc/shorewall/params script is processed during
compilation and copied into the
compiled script as described above. So shell variables set during
compilation may be used in Shorewall configuration files while those
set at run-time are available to your other extension scripts.Note
that if you assign dynamic values to variables, there is no guarantee
that the value calculated at compile time will be the same as what is
calculated at run time. This is particularly true if you use the
shorewall compile command to compile a program then
run that program at a later time or if you use Shorewall Lite.
Extension scripts associated with a particular chain or action
are not copied into the compiled script; they are rather processed
directly by the compiler using the Bourne shell "." command. For
example, if A is an action then if /etc/shorewall/A exists then it will be
processed by the compiler rather than copied into the compiled
script.
Shorewall-perl
Because the compiler is written in Perl, some of your extension
scripts from earlier versions will no longer work because Shorewall-perl
runs those extension scripts at compile-time rather than at
run-time.
The following table summarizes when the various extension scripts
are run:
Compile-time
Run-time
Eliminated
compile
clear
continue
initdone
init
maclog
isusable
Per-chain (including those associated with
actions)
start
started
stop
stopped
tcclear
refresh
refreshed
restored
Compile-time extension scripts are executed using the Perl 'eval
`cat <file>`' mechanism. Be sure that each
script returns a 'true' value; otherwise, the compiler will assume that
the script failed and will abort the compilation.
Beginning with Shorewall version 4.0.6, each compile-time script
is implicitly prefaced with:
package Shorewall::User;
Most scripts will need to begin with the following
line:use Shorewall::Chains;For more
complex scripts, you may need to 'use' other Shorewall Perl modules --
browse /usr/share/shorewall-perl/Shorewall/ to see
what's available.
When a script is invoked, the $chainref scalar variable will hold a reference
to a chain table entry.
$chainref->{name}
contains the name of the chain
$chainref->{table} holds
the table name
To add a rule to the chain:add_rule( $chainref, <the rule> );Where
<the rule> is a scalar argument
holding the rule text. Do not include "-A <chain
name>"
Example:add_rule( $chainref, '-j ACCEPT' );
Beginning with Shorewall 4.0.5, add_rule() accepts an optional
third argument; If that argument evaluates to true and the passed rule
contains a --dports list with more than
15 ports (a port range counts as two ports), the rule will be split into
multiple rules where each resulting rule has 15 or fewer ports in its
--dports list.
To insert a rule into the chain: insert_rule( $chainref, <rulenum>, <the rule> );The
log_rule_limit() function works like it
does in the shell compiler with three exceptions:
You pass the chain reference rather than the name of the
chain.
The commands are 'add' and 'insert' rather than '-A' and
'-I'.
There is only a single "pass as-is to iptables" argument (so
you must quote that part).
Example:log_rule_limit(
'info' ,
$chainref ,
$chainref->{name},
'DROP' ,
'', #Limit
'' , #Log tag
'add', #Command
'-p tcp' #Pass as-is
);Note that in the 'initdone' script, there is
no default chain ($chainref). You can
obtain a reference to a standard chain by:my $chainref = $chain_table{<table>}{<chain name>};Example:my $chainref = $chain_table{filter}{INPUT};
You can also use the hash references $filter_table, $mangle_table and $nat_table to access chain references in the
three main tables.
Example:
my $chainref = $filter_table->{INPUT}; #Same as above with a few less keystrokes; runs faster too
The 'continue' script has been eliminated because it no longer
make any sense under Shorewall-perl. That script was designed to allow
you to add special temporary rules during [re]start. Shorewall-perl
doesn't need such rules since the rule set is instantiated atomically by
table.