Extension Scripts and Default Actions
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 3.0 and
later. If you are running a version of Shorewall earlier than Shorewall
3.0.0 then please see the documentation for that
release.
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:
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.
started -- invoked after the firewall has been marked as
'running'.
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.
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 -- (Added in Shorewall version 3.2.5) 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).
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.
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).
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 versions 3.0.x and earlier
only. If you run commands other than
iptables that must be re-run in order to restore the
firewall to its current state then you must save the commands to the
restore file. The restore file is a temporary
file in /var/lib/shorewall that
will be renamed /var/lib/shorewall/restore-base at
the successful completion of the Shorewall command. The
shorewall save command combines
/var/lib/shorewall/restore-base with the output of
iptables-save to produce the
/var/lib/shorewall/restore script.
Here are three functions that are useful when running commands
other than iptables:
save_command() -- saves the
passed command to the restore file.
Example: save_command echo Operation Complete
That command would simply write "echo Operation Complete" to
the restore file.
run_and_save_command() --
saves the passed command to the restore file then executes it. The
return value is the exit status of the command. Example:
run_and_save_command "echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all"
Note that as in this example, when the command involves file
redirection then the entire command must be enclosed in quotes. This
applies to all of the functions described here.
ensure_and_save_command() --
runs the passed command. If the command fails, the firewall is
restored to its prior saved state and the operation is terminated.
If the command succeeds, the command is written to the restore
file
Shorewall version 3.2.0 - 3.2.8
only. 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 during compilation and
copied into the compiled script as just described. 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.
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 version 3.2.9 (3.4.0 RC2) and
later (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
initdone
clear
continue
maclog
initdone
Per-chain (including those associated with
actions)
start
started
stop
stopped
tcclear
refresh
refreshed
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.
All 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' );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
two 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
);Some run-time scripts have been converted to
compile time scripts:
initdone
maclog
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.
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. This script was designed to allow you to
add special temporary rules during [re]start. Shorewall-perl doesn't
need such rules.