<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<article>
  <!--$Id$-->

  <articleinfo>
    <title>Actions</title>

    <authorgroup>
      <author>
        <firstname>Tom</firstname>

        <surname>Eastep</surname>
      </author>
    </authorgroup>

    <pubdate>2005-01-19</pubdate>

    <copyright>
      <year>2005</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>

  <section>
    <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="Documentation.htm#Rules">/etc/shorewall/rules</ulink></filename> file
    entry 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>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.</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 /usr/share/shorewall. Rather, copy the file to
        <filename class="directory">/etc/shorewall</filename> (or somewhere
        else on your CONFIG_PATH) and modify the copy.</para>
      </listitem>

      <listitem>
        <para>User-defined Actions. These actions are created by end-users.
        They are listed in the file /etc/shorewall/actions and are defined in
        action.* files in /etc/shorewall/actions or in another directory
        listed in your CONFIG_PATH (defined in <ulink
        url="Documentation.htm#Conf">/etc/shorewall/shorewall.conf</ulink>).</para>
      </listitem>
    </orderedlist>
  </section>

  <section>
    <title>Common Actions</title>

    <para>Shorewall allows the association of a <firstterm>common
    action</firstterm> with policies. A separate common action may be
    associated with ACCEPT, DROP and REJECT policies. Common actions provide a
    way to invoke a set of common rules just before the policy is enforced.
    Common actions accomplish two goals:</para>

    <orderedlist>
      <listitem>
        <para>Relieve log congestion. Common 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. Common 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 provides common actions for the REJECT and DROP policies.
    The common action for REJECT is named <firstterm>Reject</firstterm> and
    the common action for DROP is named <firstterm>Drop</firstterm>. These
    associations are made through two entries in
    /usr/share/shorewall/actions.std:</para>

    <programlisting>Drop:DROP       #Common Action for DROP policy
Reject:REJECT   #Common Action for REJECT policy</programlisting>

    <para>These may be overridden by entries in your /etc/shorewall/actions
    file.</para>

    <warning>
      <para>Entries in the DROP and REJECT common actions <emphasis
      role="bold">ARE NOT THE CAUSE OF CONNECTION PROBLEMS</emphasis>.
      Remember — common actions are only invoked immediately before the packet
      is going to be dropped or rejected anyway!!!</para>
    </warning>
  </section>

  <section>
    <title> Defining your own Actions</title>

    <para>To define a new action:</para>

    <orderedlist>
      <listitem>
        <para>Add a line to
        <filename><filename>/etc/shorewall/actions</filename></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 with a capital letter; that way, the name won't
        conflict with a Shorewall-defined chain name.</para>

        <para>Beginning with Shorewall-2.0.0-Beta1, the name of the action may
        be optionally followed by a colon (<quote>:</quote>) and ACCEPT, DROP
        or REJECT. When this is done, the named action will become the
        <emphasis>common action </emphasis>for policies of type ACCEPT, DROP
        or REJECT respectively. The common action is applied immediately
        before the policy is enforced (before any logging is done under that
        policy) and is used mainly to suppress logging of uninteresting
        traffic which would otherwise clog your logs. The same policy name can
        appear in multiple actions; the last such action for each policy name
        is the one which Shorewall will use.</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 /usr/share/shorewall/action.template 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>

    <para>Columns in the action.template file are as follows:</para>

    <itemizedlist>
      <listitem>
        <para>TARGET - Must be ACCEPT, DROP, REJECT, LOG, CONTINUE, QUEUE or
        &lt;<emphasis>action</emphasis>&gt; where
        &lt;<emphasis>action</emphasis>&gt; 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.gnumonks.org/projects/ulogd">http://www.gnumonks.org/projects/ulogd</ulink>).</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>

        <para>Unlike in the SOURCE column, you may specify a range of up to
        256 IP addresses using the syntax &lt;<emphasis>first
        ip</emphasis>&gt;-&lt;<emphasis>last ip</emphasis>&gt;.</para>
      </listitem>

      <listitem>
        <para>PROTO - Protocol - Must be <quote>tcp</quote>,
        <quote>udp</quote>, <quote>icmp</quote>, a 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 &lt;<emphasis>low
        port</emphasis>&gt;:&lt;<emphasis>high port</emphasis>&gt;.</para>

        <para>This column is ignored if PROTOCOL = all but must be entered if
        any of the following ields are supplied. In that case, it is suggested
        that this field contain <quote>-</quote>.</para>

        <para>If your kernel contains multi-port match support, then only a
        single Netfilter rule will be generated if in this list and in the
        CLIENT PORT(S) list below:</para>

        <orderedlist>
          <listitem>
            <para>There are 15 or less ports listed.</para>
          </listitem>

          <listitem>
            <para>No port ranges are included.</para>
          </listitem>
        </orderedlist>

        <para>Otherwise, a separate rule will be generated for each
        port.</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
        an ADDRESS in the next column, then place "-" in this column.</para>

        <para>If your kernel contains multi-port match support, then only a
        single Netfilter rule will be generated if in this list and in the
        DEST PORT(S) list above:</para>

        <orderedlist>
          <listitem>
            <para>There are 15 or less ports listed.</para>
          </listitem>

          <listitem>
            <para>No port ranges are included.</para>
          </listitem>
        </orderedlist>

        <para>Otherwise, a separate rule will be generated for each
        port.</para>
      </listitem>

      <listitem>
        <para>RATE LIMIT - You may rate-limit the rule by placing a value in
        this column:</para>

        <para><programlisting>     &lt;<emphasis>rate</emphasis>&gt;/&lt;<emphasis>interval</emphasis>&gt;[:&lt;<emphasis>burst</emphasis>&gt;]</programlisting>where
        &lt;<emphasis>rate</emphasis>&gt; is the number of connections per
        &lt;<emphasis>interval</emphasis>&gt; (<quote>sec</quote> or
        <quote>min</quote>) and &lt;<emphasis>burst</emphasis>&gt; is the
        largest burst permitted. If no &lt;<emphasis>burst</emphasis>&gt; 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>[!]&lt;<emphasis>user number</emphasis>&gt;[:]</member>

          <member>[!]&lt;<emphasis>user name</emphasis>&gt;[:]</member>

          <member>[!]:&lt;<emphasis>group number</emphasis>&gt;</member>

          <member>[!]:&lt;<emphasis>group name</emphasis>&gt;</member>

          <member>[!]&lt;<emphasis>user
          number</emphasis>&gt;:&lt;<emphasis>group
          number</emphasis>&gt;</member>

          <member>[!]&lt;<emphasis>user
          name</emphasis>&gt;:&lt;<emphasis>group
          number</emphasis>&gt;</member>

          <member>[!]&lt;<emphasis>user
          inumber</emphasis>&gt;:&lt;<emphasis>group
          name</emphasis>&gt;</member>

          <member>[!]&lt;<emphasis>user
          name</emphasis>&gt;:&lt;<emphasis>group name</emphasis>&gt;</member>
        </simplelist>
      </listitem>
    </itemizedlist>

    <para>Omitted column entries should be entered using a dash ("-:).</para>

    <para>Example:</para>

    <para><filename>/etc/shorewall/actions</filename>:</para>

    <para><programlisting>     LogAndAccept</programlisting><phrase><filename>/etc/shorewall/action.LogAndAccept</filename></phrase><programlisting>     LOG:info
     ACCEPT</programlisting></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>
    <title>Actions and Logging</title>

    <para>Prior to Shorewall 2.1.2, specifying a log level (and optionally a
    log tag) on a rule that specified a user-defined (or Shorewall-defined)
    action would log all traffic passed to the action. Beginning with
    Shorewall 2.1.2, specifying a log level in a rule that specifies a user-
    or Shorewall-defined action will cause each rule in the action to be
    logged with the specified level (and tag).</para>

    <para>The extent to which logging of action rules occur is goverend 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 'foo' 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 "!" then logging will be 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 'foo' 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>

    <para>The change in Shorewall 2.1.2 has an effect on extension scripts
    used with user-defined actions. If you define an action 'acton' and you
    have an <filename>/etc/shorewall/acton</filename> script then when that
    script is invoked, the following three variables will be set for use by
    the script:</para>

    <itemizedlist>
      <listitem>
        <para>$CHAIN = the name of the chain where your rules are to be
        placed. When logging is used on an action invocation, Shorewall
        creates a chain with a slightly different name from the action
        itself.</para>
      </listitem>

      <listitem>
        <para>$LEVEL = Log level. If empty, no logging was specified.</para>
      </listitem>

      <listitem>
        <para>$TAG = Log Tag.</para>
      </listitem>
    </itemizedlist>

    <para>Example:</para>

    <para><filename>/etc/shorewall/rules</filename>:</para>

    <programlisting>#ACTION          SOURCE           DEST
acton:info:test  fw               net</programlisting>

    <para>Your /etc/shorewall/acton file will be run with:</para>

    <itemizedlist>
      <listitem>
        <para>$CHAIN="%acton1"</para>
      </listitem>

      <listitem>
        <para>$LEVEL="info"</para>
      </listitem>

      <listitem>
        <para>$TAG="test"</para>
      </listitem>
    </itemizedlist>
  </section>

  <section id="Extension">
    <title>Creating an Action using an Extension Script</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 action.template. In
    that case, you can use an extension script.<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>
      <title>An action to drop all broadcast packets</title>

      <para>/etc/shorewall/actions<programlisting>DropBcasts</programlisting></para>

      <para>/etc/shorewall/action.DropBcasts<programlisting># This file is empty</programlisting></para>

      <para>/etc/shorewall/DropBcasts<programlisting>run_iptables -A DropBcasts -m pkttype --pkttype broadcast -j DROP</programlisting></para>
    </example>
  </section>
</article>