<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> <article> <!--$Id$--> <articleinfo> <title>Actions</title> <authorgroup> <author> <firstname>Tom</firstname> <surname>Eastep</surname> </author> </authorgroup> <pubdate><?dbtimestamp format="Y/m/d"?></pubdate> <copyright> <year>2005</year> <year>2007</year> <year>2008</year> <year>2009</year> <year>2010</year> <year>2012</year> <holder>Thomas M. Eastep</holder> </copyright> <legalnotice> <para>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 <quote><ulink url="GnuCopyright.htm">GNU Free Documentation License</ulink></quote>.</para> </legalnotice> </articleinfo> <caution> <para><emphasis role="bold">This article applies to Shorewall 4.3 and later. If you are running a version of Shorewall earlier than Shorewall 4.3.5 then please see the documentation for that release.</emphasis></para> </caution> <section id="Intro"> <title>What are Shorewall Actions?</title> <para>Shorewall actions allow a symbolic name to be associated with a series of one or more iptables rules. The symbolic name may appear in the ACTION column of an <filename><ulink url="manpages/shorewall-rules.html">/etc/shorewall/rules</ulink></filename> entry, in a <ulink url="Macros.html">macro</ulink> body and within another action, in which case the traffic matching that rules file entry will be passed to the series of iptables rules named by the action.</para> <para>Actions can be thought of as templates. When an action is invoked in an <filename>/etc/shorewall/rules</filename> entry, it may be qualified by a logging specification (log level and optionally a log tag). The presence of the log level/tag causes a modified series of rules to be generated in which each packet/rule match within the action causes a log message to be generated.</para> <para>For readers familiar with iptables, actions are the way in which you can create your own filter-table chains.</para> <para>There are three types of Shorewall actions:</para> <orderedlist> <listitem> <para>Built-in Actions. These actions are known by the Shorewall code itself. They are listed in the comments at the top of the file <filename>/usr/share/shorewall/actions.std</filename>.</para> </listitem> <listitem> <para>Standard Actions. These actions are released as part of Shorewall. They are listed in the file <filename>/usr/share/shorewall/actions.std</filename> and are defined in the corresponding action.* files in <filename class="directory">/usr/share/shorewall</filename>. Each <filename>action.*</filename> file has a comment at the beginning of the file that describes what the action does. As an example, here is the definition of the <firstterm>AllowSMB</firstterm> standard action from Shorewall version 2.2.</para> <programlisting># # Shorewall 2.2 /usr/share/shorewall/action.AllowSMB # # Allow Microsoft SMB traffic. You need to invoke this action in # both directions. # ###################################################################################### #TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/ # PORT PORT(S) LIMIT GROUP ACCEPT - - udp 135,445 ACCEPT - - udp 137:139 ACCEPT - - udp 1024: 137 ACCEPT - - tcp 135,139,445 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE</programlisting> <para>If you wish to modify one of the standard actions, do not modify the definition in <filename class="directory">/usr/share/shorewall</filename>. Rather, copy the file to <filename class="directory">/etc/shorewall</filename> (or somewhere else on your CONFIG_PATH) and modify the copy.</para> <para>Standard Actions have been largely replaced by <ulink url="Macros.html">macros</ulink> .</para> </listitem> <listitem> <para>User-defined Actions. These actions are created by end-users. They are listed in the file <filename>/etc/shorewall/actions</filename> and are defined in <filename>action.*</filename> files in <filename class="directory">/etc/shorewall</filename> or in another directory listed in your CONFIG_PATH (defined in <filename><ulink url="manpages/shorewall.conf.html">/etc/shorewall/shorewall.conf</ulink></filename>).</para> </listitem> </orderedlist> </section> <section id="Default"> <title>Default Actions (Formerly Common Actions)</title> <para>Shorewall allows the association of a <firstterm>default action</firstterm> with policies. A separate default action may be associated with ACCEPT, DROP, REJECT, QUEUE and NFQUEUE policies. Default actions provide a way to invoke a set of common rules just before the policy is enforced. Default actions accomplish two goals:</para> <orderedlist> <listitem> <para>Relieve log congestion. Default actions typically include rules to silently drop or reject traffic that would otherwise be logged when the policy is enforced.</para> </listitem> <listitem> <para>Ensure correct operation. Default actions can also avoid common pitfalls like dropping connection requests on port TCP port 113. If these connections are dropped (rather than rejected) then you may encounter problems connecting to Internet services that utilize the AUTH protocol of client authentication<footnote> <para>AUTH is actually pretty silly on today's Internet but it's amazing how many servers still employ it.</para> </footnote>.</para> </listitem> </orderedlist> <para>Shorewall supports default actions for the ACCEPT, REJECT, DROP, QUEUE and NFQUEUE policies. These default actions are specified in the <filename>/etc/shorewall/shorewall.conf</filename> file using the ACCEPT_DEFAULT, REJECT_DEFAULT, DROP_DEFAULT, QUEUE_DEFAULT and NFQUEUE_DEFAULT options respectively. Policies whose default is set to a value of <quote>none</quote> have no default action.</para> <para>In addition, the default specified in <filename>/etc/shorewall/shorewall.conf</filename> may be overridden by specifying a different action in the POLICY column of <filename><ulink url="manpages/shorewall-policy.html">/etc/shorewall/policy</ulink></filename>.</para> <important> <para>Entries in the DROP and REJECT default actions <emphasis role="bold">ARE NOT THE CAUSE OF CONNECTION PROBLEMS</emphasis>. Remember — default actions are only invoked immediately before the packet is going to be dropped or rejected anyway!!!</para> </important> <para>Beginning with Shorewall 4.4.21, the standard Drop and Reject options are parameterized. Each has five parameters as follows:</para> <informaltable> <tgroup cols="4"> <tbody> <row> <entry>ACTION</entry> <entry>PARAMETER</entry> <entry>VALUE</entry> <entry>DEFAULT</entry> </row> <row> <entry>Drop</entry> <entry>1</entry> <entry>Either '-' or 'audit'. 'audit' causes auditing by the builtin actions invoked by Drop</entry> <entry>-</entry> </row> <row> <entry>Drop</entry> <entry>2</entry> <entry>Determines what to do with Auth requests</entry> <entry>REJECT or A_REJECT depending on the setting of parameter 1</entry> </row> <row> <entry>Drop</entry> <entry>3</entry> <entry>Determines what to do with SMB</entry> <entry>DROP or A_DROP depending on the setting of parameter 1</entry> </row> <row> <entry>Reject</entry> <entry>1</entry> <entry>Either '-' or 'audit'. 'audit' causes auditing by the builtin actions invoked by Drop</entry> <entry>-</entry> </row> <row> <entry>Reject</entry> <entry>2</entry> <entry>Determines what to do with Auth requests</entry> <entry>REJECT or A_REJECT depending on the setting of parameter 1</entry> </row> <row> <entry>Reject</entry> <entry>3</entry> <entry>Determines what to do with SMB</entry> <entry>REJECT or A_REJECT depending on the setting of parameter 1</entry> </row> <row> <entry>Both</entry> <entry>4</entry> <entry>Determines what to do with accepted critical ICMP packets.</entry> <entry>ACCEPT or A_ACCEPT depending on the setting of parameter 1</entry> </row> <row> <entry>Both</entry> <entry>5</entry> <entry>Determines what to do with late-arriving DNS replies (source port 53) or UPnP (udp port 1900).</entry> <entry>DROP or A_DROP depending on the setting of parameter 1.</entry> </row> </tbody> </tgroup> </informaltable> <para>The parameters may be specified in either shorewall.conf (e.g., DROP_DEFAULT=<emphasis role="bold">Drop(-,DROP)</emphasis> or in the POLICY column of <ulink url="manpages/shorewall-policy.html">shorewall-policy</ulink>(5) (e.g., DROP:<emphasis role="bold">Drop(audit)</emphasis>:audit).</para> </section> <section id="Defining"> <title>Defining your own Actions</title> <para>Before defining a new action, you should evaluate whether your goal can be best accomplished using an action or a <firstterm>macro</firstterm>. See <ulink url="Macros.html">this article</ulink> for details.</para> <para>To define a new action:</para> <orderedlist> <listitem> <para>Add a line to <filename>/etc/shorewall/actions</filename> that names your new action. Action names must be valid shell variable names (must begin with a letter and be composed of letters, digits and underscore characters) as well as valid Netfilter chain names. If you intend to log from the action, the name must have a maximum of 11 characters. It is recommended that the name you select for a new action begins with a capital letter; that way, the name won't conflict with a Shorewall-defined chain name.</para> <para>Normally. the rules in an action are placed in a separate chain. Beginning with Shorewall 4.5.10, the action rules can be expanded inline in a manner similar to a macro by specifying <option>inline</option> in the OPTIONS column of <filename>/etc/shorewall/actions</filename>.</para> <para>Beginning in Shorewall 4.5.11, the <option>nolog</option> option may be specified; see the <link linkend="Logging">logging section</link> below for details.</para> <para>Shorewall includes pre-defined actions for DROP and REJECT -- see above.</para> </listitem> <listitem> <para>Once you have defined your new action name (ActionName), then copy <filename>/usr/share/shorewall/action.template</filename> to <filename>/etc/shorewall/action.ActionName</filename> (for example, if your new action name is <quote>Foo</quote> then copy <filename>/usr/share/shorewall/action.template</filename> to <filename>/etc/shorewall/action.Foo</filename>).</para> </listitem> <listitem> <para>Now modify the new file to define the new action.</para> </listitem> </orderedlist> <section> <title>Shorewall 4.4.16 and Later.</title> <para>Beginning with Shorewall 4.4.16, the columns in action.template are the same as those in shorewall-rules (5). The first non-commentary line in the template must be</para> <programlisting>FORMAT 2</programlisting> <para>Beginning with Shorewall 4.5.11, the preferred format is as shown below, and the above format is deprecated.</para> <programlisting>?FORMAT 2</programlisting> <para>When using Shorewall 4.4.16 or later, there are no restrictions regarding which targets can be used within your action.</para> <para>The SOURCE and DEST columns in the action file may not include zone names; those are given when the action is invoked.</para> <para>Additionally, it is possible to pass parameters to an action, when it is invoked in the rules file or in another action.</para> <para>Here's a trivial example:</para> <para>/etc/shorewall/action.A:</para> <programlisting>#TARGET SOURCE DEST PROTO DEST SOURCE ORIGINAL # PORT(S) PORT(S) DEST FORMAT 2 $1 - - tcp 80 - 1.2.3.4</programlisting> <para>/etc/shorewall/rules:</para> <programlisting>#TARGET SOURCE DEST PROTO DEST SOURCE ORIGINAL # PORT(S) PORT(S) DEST A(REDIRECT) net fw</programlisting> <para>The above is equivalent to this rule:</para> <programlisting>#TARGET SOURCE DEST PROTO DEST SOURCE ORIGINAL # PORT(S) PORT(S) DEST REDIRECT net - tcp 80 - 1.2.3.4</programlisting> <para>You can 'omit' parameters by using '-'.</para> <para>Example: ACTION(REDIRECT,-,info)</para> <para>In the above example, $2 would expand to nothing.</para> <para>If you want to make '-' a parameter value, use '--' (e.g., ACTION(REDIRECT,--.info)).</para> <para>Beginning with Shorewall 4.4.21, you can specify the default values of your FORMAT-2 actions:</para> <programlisting>DEFAULTS <replaceable>def1</replaceable>,<replaceable>def2</replaceable>,...</programlisting> <para>where <replaceable>def1</replaceable> is the default value for the first parameter, <replaceable>def2</replaceable> is the default value for the second parameter and so on. You can specify an empty default using '-' (e.g. DEFAULTS DROP,-,audit).</para> <para>The DEFAULTS directive also determines the maximum number of parameters that an action may have. If more parameters are passed than have default values, an error message is issued.</para> <para>For additional information about actions, see the <ulink url="configuration_file_basics.htm#ActionVariables">Action Variables section</ulink> of the Configuration Basics article.</para> </section> <section> <title>Shorewall 4.4.15 and Earlier.</title> <para>Prior to 4.4.16, columns in the <filename>action.template</filename> file were as follows:</para> <itemizedlist> <listitem> <para>TARGET - Must be ACCEPT, DROP, REJECT, LOG, CONTINUE, QUEUE or an <<emphasis>action</emphasis>> where <<emphasis>action</emphasis>> is a previously-defined action (that is, it must precede the action being defined in this file in your <filename>/etc/shorewall/actions</filename> file). These actions have the same meaning as they do in the <filename>/etc/shorewall/rules</filename> file (CONTINUE terminates processing of the current action and returns to the point where that action was invoked). The TARGET may optionally be followed by a colon (<quote>:</quote>) and a syslog log level (e.g, REJECT:info or ACCEPT:debugging). This causes the packet to be logged at the specified level. You may also specify ULOG (must be in upper case) as a log level. This will log to the ULOG target for routing to a separate log through use of ulogd (<ulink url="http://www.netfilter.org/projects/ulogd/index.html">http://www.netfilter.org/projects/ulogd/index.html</ulink>).</para> <para>You may also use a <ulink url="Macros.html">macro</ulink> in your action provided that the macro's expansion only results in the ACTIONs ACCEPT, DROP, REJECT, LOG, CONTINUE, or QUEUE. See <filename>/usr/share/shorewall/action.Drop</filename> for an example of an action that users macros extensively.</para> </listitem> <listitem> <para>SOURCE - Source hosts to which the rule applies. A comma-separated list of subnets and/or hosts. Hosts may be specified by IP or MAC address; MAC addresses must begin with <quote>~</quote> and must use <quote>-</quote> as a separator.</para> <para>Alternatively, clients may be specified by interface name. For example, eth1 specifies a client that communicates with the firewall system through eth1. This may be optionally followed by another colon (<quote>:</quote>) and an IP/MAC/subnet address as described above (e.g., eth1:192.168.1.5).</para> </listitem> <listitem> <para>DEST - Location of Server. Same as above with the exception that MAC addresses are not allowed.</para> </listitem> <listitem> <para>PROTO - Protocol - Must be <quote>tcp</quote>, <quote>udp</quote>, <quote>icmp</quote>, a protocol number, or <quote>all</quote>.</para> </listitem> <listitem> <para>DEST PORT(S) - Destination Ports. A comma-separated list of Port names (from <filename>/etc/services</filename>), port numbers or port ranges; if the protocol is <quote>icmp</quote>, this column is interpreted as the destination icmp-type(s).</para> <para>A port range is expressed as <<emphasis>low port</emphasis>>:<<emphasis>high port</emphasis>>.</para> <para>This column is ignored if PROTO = <quote>all</quote>, but must be entered if any of the following fields are supplied. In that case, it is suggested that this field contain <quote>-</quote>.</para> </listitem> <listitem> <para>SOURCE PORT(S) - Port(s) used by the client. If omitted, any source port is acceptable. Specified as a comma-separated list of port names, port numbers or port ranges.</para> <para>If you don't want to restrict client ports but need to specify any of the subsequent fields, then place <quote>-</quote> in this column.</para> </listitem> <listitem> <para>RATE LIMIT - You may rate-limit the rule by placing a value in this column:</para> <para><programlisting> <<emphasis>rate</emphasis>>/<<emphasis>interval</emphasis>>[:<<emphasis>burst</emphasis>>]</programlisting>where <<emphasis>rate</emphasis>> is the number of connections per <<emphasis>interval</emphasis>> (<quote>sec</quote> or <quote>min</quote>) and <<emphasis>burst</emphasis>> is the largest burst permitted. If no <<emphasis>burst</emphasis>> is given, a value of 5 is assumed. There may be no whitespace embedded in the specification.</para> <para><programlisting> Example: 10/sec:20</programlisting></para> </listitem> <listitem> <para>USER/GROUP - For output rules (those with the firewall as their source), you may control connections based on the effective UID and/or GID of the process requesting the connection. This column can contain any of the following:</para> <simplelist> <member>[!]<<emphasis>user number</emphasis>>[:]</member> <member>[!]<<emphasis>user name</emphasis>>[:]</member> <member>[!]:<<emphasis>group number</emphasis>></member> <member>[!]:<<emphasis>group name</emphasis>></member> <member>[!]<<emphasis>user number</emphasis>>:<<emphasis>group number</emphasis>></member> <member>[!]<<emphasis>user name</emphasis>>:<<emphasis>group number</emphasis>></member> <member>[!]<<emphasis>user inumber</emphasis>>:<<emphasis>group name</emphasis>></member> <member>[!]<<emphasis>user name</emphasis>>:<<emphasis>group name</emphasis>></member> <member>[!]+<<emphasis>program name</emphasis>> (Note: support for this form was removed from Netfilter in kernel version 2.6.14).</member> </simplelist> </listitem> <listitem> <para>MARK</para> <para><simplelist> <member>[!]<<emphasis>value</emphasis>>[/<<emphasis>mask</emphasis>>][:C]</member> </simplelist></para> <para>Defines a test on the existing packet or connection mark. The rule will match only if the test returns true.</para> <para>If you don’t want to define a test but need to specify anything in the subsequent columns, place a <quote>-</quote> in this field.<simplelist> <member>! — Inverts the test (not equal)</member> <member><<emphasis>value</emphasis>> — Value of the packet or connection mark.</member> <member><<emphasis>mask</emphasis>> —A mask to be applied to the mark before testing.</member> <member>:C — Designates a connection mark. If omitted, the packet mark’s value is tested. This option is only supported by Shorewall-perl</member> </simplelist></para> </listitem> </itemizedlist> <para>Omitted column entries should be entered using a dash (<quote>-</quote>).</para> <para>Example:</para> <para><filename>/etc/shorewall/actions</filename>:</para> <para><programlisting> #ACTION COMMENT (place '# ' below the 'C' in comment followed by # v a comment describing the action) LogAndAccept # LOG and ACCEPT a connection</programlisting><emphasis role="bold">Note:</emphasis> If your <filename>/etc/shorewall/actions</filename> file doesn't have an indication where to place the comment, put the <quote>#</quote> in column 21.</para> <para><phrase><filename>/etc/shorewall/action.LogAndAccept</filename></phrase><programlisting> LOG:info ACCEPT</programlisting></para> <para>Placing a comment on the line causes the comment to appear in the output of the <command>shorewall show actions</command> command.</para> <para>To use your action, in <filename>/etc/shorewall/rules</filename> you might do something like:</para> <programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S) LogAndAccept loc $FW tcp 22</programlisting> </section> </section> <section id="Logging"> <title>Actions and Logging</title> <para>Specifying a log level in a rule that specifies a user-defined or Shorewall-defined action will cause each rule in the action to be logged with the specified level (and tag), unless the <option>nolog</option> option is specified in the action's entry in <filename>/etc/shorewall/actions</filename>.</para> <para>The extent to which logging of action rules occur is governed by the following:</para> <orderedlist> <listitem> <para>When you invoke an action and specify a log level, only those rules in the action that have no log level will be changed to log at the level specified at the action invocation.</para> <para>Example:</para> <para>/etc/shorewall/action.foo</para> <programlisting>#TARGET SOURCE DEST PROTO DEST PORT(S) ACCEPT - - tcp 22 bar:info</programlisting> <para>/etc/shorewall/rules:</para> <programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S) foo:debug $FW net</programlisting> <para>Logging in the invoke <quote>foo</quote> action will be as if foo had been defined as:</para> <programlisting>#TARGET SOURCE DEST PROTO DEST PORT(S) ACCEPT:debug - - tcp 22 bar:info</programlisting> </listitem> <listitem> <para>If you follow the log level with <quote>!</quote> then logging will be set at that level for all rules recursively invoked by the action.</para> <para>Example:</para> <para>/etc/shorewall/action.foo</para> <programlisting>#TARGET SOURCE DEST PROTO DEST PORT(S) ACCEPT - - tcp 22 bar:info</programlisting> <para>/etc/shorewall/rules:</para> <programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S) foo:debug! $FW net</programlisting> <para>Logging in the invoke <quote>foo</quote> action will be as if foo had been defined as:</para> <programlisting>#TARGET SOURCE DEST PROTO DEST PORT(S) ACCEPT:debug - - tcp 22 bar:debug</programlisting> </listitem> </orderedlist> </section> <section id="Embedded"> <title>Using Embedded Perl in an Action</title> <para>There may be cases where you wish to create a chain with rules that can't be constructed using the tools defined in the <filename>action.template</filename>. Such rules can be constructed using <ulink url="configuration_file_basics.htm#Embedded">Embedded Perl.</ulink> For those who are comfortable using Perl, embedded Perl is more efficient that using complicated conditional entries. The Perl compiler is invoked only once for a BEGIN PERL...END PERL block; it is invoked most times that an expression is evaluated in an ?IF, ?ELSEIF or ?SET directive.</para> <para>The Shorewall compiler provides a set of services that are available to Perl code embedded in an action file. These services are not available in in-line actions.</para> <variablelist> <varlistentry> <term>Shorewall::Config::get_action_params( <replaceable>$howmany</replaceable> )</term> <listitem> <para>This function returns an array containing the functions parameters. The scalar argument <replaceable>$howmany</replaceable> is the number of parameters that you expect to be passed. You can ensure that at least this many parameters are passed by including a DEFAULTS line prior to the embedded Perl.</para> </listitem> </varlistentry> <varlistentry> <term>Shorewall::Config::set_action_param( <replaceable>$ordinal</replaceable>, <replaceable>$value</replaceable> )</term> <listitem> <para>Set the value of parameter <replaceable>$ordinal</replaceable> to <replaceable>$value</replaceable>. Care must be take when using this function such that for a given set of parameters actually passed to the action, the same rules are created. That is because the compiler assumes that all invocations of an action with the same parameters, log level and log tag can share the same action chain.</para> </listitem> </varlistentry> <varlistentry> <term>Shorewall::Config::get_action_chain()</term> <listitem> <para>This function returns a reference to the chain table entry for the current action chain.</para> </listitem> </varlistentry> <varlistentry> <term>Shorewall::Config::get_action_logging()</term> <listitem> <para>Returns a two-element list containing the the log level and log tag specified when the action was invoked. Note that you must use this function rather than @loglevel and @logtag within embedded Perl, as the compiler does not expand <ulink url="configuration_file_basics.htm#ShorewallVariables">Shorewall Variables</ulink> within embedded Perl (or embedded shell).</para> </listitem> </varlistentry> <varlistentry> <term>Shorewall::Chains::add_rule( <replaceable>$chainre</replaceable>f, <replaceable>$rule</replaceable> [, <replaceable>$expandports</replaceable> ] )</term> <listitem> <para>This function adds a rule to a chain. Arguments are:</para> <variablelist> <varlistentry> <term><replaceable>$chainref</replaceable></term> <listitem> <para>Normally, you get this from get_action_chain() described above.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$rule</replaceable></term> <listitem> <para>The matches and target for the rule that you want added.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$expandports</replaceable> (optional)</term> <listitem> <para>This optional argument is for compiler-internal use only. Either omit it or pass a false value.</para> </listitem> </varlistentry> </variablelist> </listitem> </varlistentry> <varlistentry> <term>Shorewall::Chains::log_rule_limit( <replaceable>$level</replaceable>, $<replaceable>chainref</replaceable>, <replaceable>$chain</replaceable>, <replaceable>$disposition</replaceable>, <replaceable>$limit</replaceable>, <replaceable>$tag</replaceable>, <replaceable>$command</replaceable>, <replaceable>$matches</replaceable> )</term> <listitem> <para>This function adds a logging rule to a chain. Arguments are:</para> <variablelist> <varlistentry> <term><replaceable>$level</replaceable></term> <listitem> <para>Either a syslog level or a ULOG or NFLOG target expression (e.g., "NFLOG(1,0,1)"). Specifies how you want the logging done.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$chainref</replaceable></term> <listitem> <para>Normally, you get this from get_action_chain() described above.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$chain</replaceable></term> <listitem> <para>The value you want substituted for the first %s formatting directive in the LOGFORMAT setting in <filename>/etc/shorewall/shorewall.conf</filename>.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$disposition</replaceable></term> <listitem> <para>This is the value substituted for the second '%s' formatting directive in the LOGFORMAT setting in <filename>/etc/shorewall/shorewall.conf</filename>.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$limit</replaceable></term> <listitem> <para>If you want to use the default limit set in LOGLIMIT (<filename>/etc/shorewall/shorewall.conf</filename>), you can specify your own '-limit' match. Otherwise, if you want to use the default, pass 0 or "". If you want the rule to be unlimited, pass '-'.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$tag</replaceable></term> <listitem> <para>Log tag.</para> </listitem> </varlistentry> <varlistentry> <term><replaceable>$command</replaceable></term> <listitem> <para>Pass 'add' here, unless you want the rule to be inserted at the front of the chain.</para> </listitem> </varlistentry> <varlistentry> <term><firstterm>$matches</firstterm></term> <listitem> <para>Zero or more iptables matches that limit when logging will occur. If this parameter is other than the empty string, the last character must be a space.</para> </listitem> </varlistentry> </variablelist> </listitem> </varlistentry> <varlistentry> <term>Shorewall::Chains::allow::optimize( <replaceable>chainref</replaceable> )</term> <listitem> <para>This allows the passed action chain to be optimized away (jumps to the chain are replaced by the chain's rule(s)). The <replaceable>chainref</replaceable> argument is usually obtained from get_action_chain() described above.</para> </listitem> </varlistentry> </variablelist> <para>For an example of using these services, look at the standard action <filename>/usr/share/shorewall/action.Broadcast</filename>.</para> </section> <section id="Extension"> <title>Creating an Action using an Extension Script (deprecated in favor of BEGIN PERL ... END PERL)</title> <para>There may be cases where you wish to create a chain with rules that can't be constructed using the tools defined in the <filename>action.template</filename>. In that case, you can use an <ulink url="shorewall_extension_scripts.htm">extension script</ulink>.<note> <para>If you actually need an action to drop broadcast packets, use the <command>dropBcast</command> standard action rather than create one like this.</para> </note></para> <example id="Example"> <title>An action to drop all broadcast packets</title> <para>If you define an action <quote>acton</quote> and you have an <filename>/etc/shorewall/acton</filename> script, the rules compiler sets lexical variables as follows:</para> <itemizedlist> <listitem> <para><emphasis role="bold">$chainref</emphasis> is a reference to the chain-table entry for the chain where your rules are to be placed.</para> </listitem> <listitem> <para><emphasis role="bold">$level</emphasis> is the log level. If false, no logging was specified.</para> </listitem> <listitem> <para><emphasis role="bold">$tag</emphasis> is the log tag.</para> </listitem> <listitem> <para><emphasis role="bold">@params</emphasis> is the list of parameter values (Shorewall 4.4.16 and later). 'Omitted' parameters contain '-'.</para> </listitem> </itemizedlist> <para>Example:</para> <para>/etc/shorewall/actions<programlisting>DropBcasts</programlisting></para> <para>/etc/shorewall/action.DropBcasts<programlisting># This file is empty</programlisting>/etc/shorewall/DropBcasts<programlisting>use Shorewall::Chains; if ( $level ne '' ) { log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -m addrtype --dst-type BROADCAST '; log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d 224.0.0.0/4 '; } add_rule $chainref, '-m addrtype --dst-type BROADCAST -j DROP'; add_rule $chainref, '-d 224.0.0.0/4 -j DROP'; 1;</programlisting></para> </example> <para>For a richer example, see the next section.</para> </section> <section id="Limit"> <title>Limiting Per-IP Connection Rate using the Limit Action</title> <para>Shorewall supports a <quote>Limit</quote> built-in action. Prior to Shorewall 4.4.16, Limit is invoked with a comma-separated list in place of a logging tag. Beginning in Shorewall 4.4.16, it may also be invoked with a list of three parameters enclosed in parentheses. The list has three elements:</para> <orderedlist> <listitem> <para>The name of a <quote>recent</quote> list. You select the list name which must conform to the rules for a valid chain name. Different rules that specify the same list name will use the same set of counters.</para> </listitem> <listitem> <para>The number of connections permitted in a specified time period.</para> </listitem> <listitem> <para>The time period, expressed in seconds.</para> </listitem> </orderedlist> <para>Connections that exceed the specified rate are dropped.</para> <para>For example, to use a recent list name of <emphasis role="bold">SSHA</emphasis>, and to limit SSH connections to 3 per minute, use this entry in <filename>/etc/shorewall/rules</filename>:</para> <programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S) Limit:none:SSHA,3,60 net $FW tcp 22</programlisting> <para>Using Shorewall 4.4.16 or later, you can also invoke the action this way:</para> <programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S) Limit(SSHA,3,60):none net $FW tcp 22</programlisting> <para>If you want dropped connections to be logged at the info level, use this rule instead:</para> <programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S) Limit:info:SSHA,3,60 net $FW tcp 22</programlisting> <para>Shorewall 4.4.16 and later:<programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S) Limit(SSH,3,60):info net $FW tcp 22</programlisting></para> <para>To summarize, you pass four pieces of information to the Limit action:</para> <itemizedlist> <listitem> <para>The log level. If you don't want to log, specify <quote>none</quote>.</para> </listitem> <listitem> <para>The name of the recent list that you want to use (<quote>SSHA</quote> in this example).</para> </listitem> <listitem> <para>The maximum number of connections to accept (3 in this example).</para> </listitem> <listitem> <para>The number of seconds over which you are willing to accept that many connections (60 in this example).</para> </listitem> </itemizedlist> <section id="LimitImp"> <title>How Limit is Implemented</title> <para>For those who are curious, the Limit action in Shorewall 4.4.16 is implemented as follows:</para> <programlisting>use Shorewall::Chains; @params = split( /,/, $tag ), $tag='' unless @params; fatal_error 'Limit rules must include <list name>,<max connections>,<interval> as the log tag or params' unless @params == 3; my $list = $params[0]; for ( @params[1,2] ) { fatal_error 'Max connections and interval in Limit rules must be numeric (' . $_ . ')' unless /^\d+$/ } my $count = $params[1] + 1; add_rule $chainref, "-m recent --name $list --set"; if ( $level ) { my $xchainref = new_chain 'filter' , "$chainref->{name}%"; log_rule_limit $level, $xchainref, $params[0], 'DROP', $tag, '', 'add', ''; add_rule $xchainref, '-j DROP'; add_rule $chainref, "-m recent --name $list --update --seconds $params[2] --hitcount $count -j $xchainref->{name}"; } else { add_rule $chainref, "-m recent --update --name $list --seconds $params[2] --hitcount $count -j DROP"; } add_rule $chainref, '-j ACCEPT'; 1; </programlisting> </section> </section> </article>