Actions

Tom 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”.

2007/08/26



Table of Contents

What are Shorewall Actions?
Enabling the Use of Actions
Default Actions (Formerly Common Actions)
Defining your own Actions
Actions and Logging
Creating an Action using an Extension Script

Caution

This article applies to Shorewall 3.0 and later (the information about Shorewall-perl pertains to Shorewall 4.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.

What are Shorewall Actions?

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 /etc/shorewall/rules 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.

Actions can be thought of as templates. When an action is invoked in an /etc/shorewall/rules 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.

There are three types of Shorewall actions:

  1. Built-in Actions. These actions are known by the Shorewall code itself. They are listed in the comments at the top of the file /usr/share/shorewall/actions.std.

  2. Standard Actions. These actions are released as part of Shorewall. They are listed in the file /usr/share/shorewall/actions.std and are defined in the corresponding action.* files in /usr/share/shorewall. Each action.* 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 AllowSMB standard action from Shorewall version 2.2.

    #
    # 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

    If you wish to modify one of the standard actions, do not modify the definition in /usr/share/shorewall. Rather, copy the file to /etc/shorewall (or somewhere else on your CONFIG_PATH) and modify the copy.

    Standard Actions have been largely replaced by macros in Shorewall 3.0 and later major versions.

  3. 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 or in another directory listed in your CONFIG_PATH (defined in /etc/shorewall/shorewall.conf).

Enabling the Use of Actions

In Shorewall version 3.4 and later, to make use of any of the three types of actions you must set the USE_ACTIONS option to Yes in /etc/shorewall/shorewall.conf.

Default Actions (Formerly Common Actions)

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

  1. Relieve log congestion. Default actions typically include rules to silently drop or reject traffic that would otherwise be logged when the policy is enforced.

  2. 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[1].

If you are running Shorewall 3.2 or earlier, then:

Shorewall provides default actions for the REJECT and DROP policies. The default action for REJECT is named Reject and the default action for DROP is named Drop. These associations are made through two entries in /usr/share/shorewall/actions.std:

Drop:DROP       #Default Action for DROP policy
Reject:REJECT   #Default Action for REJECT policy

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

If you are running Shorewall 3.4 or later, then:

Shorewall supports default actions for the ACCEPT, REJECT, DROP and QUEUE policies. These default actions are specified in the /etc/shorewall/shorewall.conf file using the ACCEPT_DEFAULT, REJECT_DEFAULT, DROP_DEFAULT and QUEUE_DEFAULT options respectively. Policies whose default is set to a value of "none" have no default action.

In addition, the default specified in /etc/shorewall/shorewall.conf may be overridden by specifying a different default in the POLICY column of /etc/shorewall/policy.

Warning

Entries in the DROP and REJECT default actions ARE NOT THE CAUSE OF CONNECTION PROBLEMS. Remember — default actions are only invoked immediately before the packet is going to be dropped or rejected anyway!!!

Defining your own Actions

Before defining a new action, you should evaluate whether your goal can be best accomplished using an action or a macro. See this article for details.

To define a new action:

  1. Add a line to /etc/shorewall/actions 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.

    The name of the action may be optionally followed by a colon (“:”) and ACCEPT, DROP or REJECT. When this is done, the named action will become the default action for policies of type ACCEPT, DROP or REJECT respectively. The default 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.

    Shorewall includes pre-defined actions for DROP and REJECT -- see above.

  2. Once you have defined your new action name (ActionName), then copy /usr/share/shorewall/action.template to /etc/shorewall/action.ActionName (for example, if your new action name is “Foo” then copy /usr/share/shorewall/action.template to /etc/shorewall/action.Foo).

  3. Now modify the new file to define the new action.

Columns in the action.template file are as follows:

  • TARGET - Must be ACCEPT, DROP, REJECT, LOG, CONTINUE, QUEUE or <action> where <action> is a previously-defined action (that is, it must precede the action being defined in this file in your /etc/shorewall/actions file). These actions have the same meaning as they do in the /etc/shorewall/rules 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 (“:”) 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 (http://www.netfilter.org/projects/ulogd/index.html).

    You may also use a macro in your action provided that the macro's expansion only results in the ACTIONs ACCEPT, DROP, REJECT, LOG, CONTINUE, or QUEUE. See /usr/share/shorewall/Drop for an example of an action that users macros extensively.

  • 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 “~” and must use “-” as a separator.

    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 (“:”) and an IP/MAC/subnet address as described above (e.g., eth1:192.168.1.5).

  • DEST - Location of Server. Same as above with the exception that MAC addresses are not allowed.

    Unlike in the SOURCE column, you may specify a range of up to 256 IP addresses using the syntax <first ip>-<last ip>.

  • PROTO - Protocol - Must be “tcp”, “udp”, “icmp”, a protocol number, or “all”.

  • DEST PORT(S) - Destination Ports. A comma-separated list of Port names (from /etc/services), port numbers or port ranges; if the protocol is “icmp”, this column is interpreted as the destination icmp-type(s).

    A port range is expressed as <low port>:<high port>.

    This column is ignored if PROTO = "all", but must be entered if any of the following fields are supplied. In that case, it is suggested that this field contain “-”.

    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:

    1. There are 15 or less ports listed.

    2. No port ranges are included.

    Otherwise, a separate rule will be generated for each port.

  • 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.

    If you don't want to restrict client ports but need to specify any of the following fields, then place "-" in this column.

    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:

    1. There are 15 or less ports listed.

    2. No port ranges are included.

    Otherwise, a separate rule will be generated for each port.

  • RATE LIMIT - You may rate-limit the rule by placing a value in this column:

         <rate>/<interval>[:<burst>]

    where <rate> is the number of connections per <interval> (“sec” or “min”) and <burst> is the largest burst permitted. If no <burst> is given, a value of 5 is assumed. There may be no whitespace embedded in the specification.

         Example: 10/sec:20
  • 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:

    [!]<user number>[:]
    [!]<user name>[:]
    [!]:<group number>
    [!]:<group name>
    [!]<user number>:<group number>
    [!]<user name>:<group number>
    [!]<user inumber>:<group name>
    [!]<user name>:<group name>
    [!]+<program name> (Note: support for this form was removed from Netfilter in kernel version 2.6.14).
  • MARK (Added in Shorewall 3.4.4)

    [!]<value>[/<mask>][:C]

    Defines a test on the existing packet or connection mark. The rule will match only if the test returns true.

    If you don’t want to define a test but need to specify anything in the following columns, place a "-" in this field.

    ! — Inverts the test (not equal)
    <value> — Value of the packet or connection mark.
    <mask> —A mask to be applied to the mark before testing.
    :C — Designates a connection mark. If omitted, the packet mark’s value is tested. This option is only supported by Shorewall-perl

Omitted column entries should be entered using a dash ("-").

Example:

/etc/shorewall/actions:

     LogAndAccept

/etc/shorewall/action.LogAndAccept

     LOG:info
     ACCEPT

To use your action, in /etc/shorewall/rules you might do something like:

#ACTION      SOURCE      DEST        PROTO    DEST PORT(S)
LogAndAccept loc         $FW         tcp      22

Actions and Logging

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).

The extent to which logging of action rules occur is governed by the following:

  1. 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.

    Example:

    /etc/shorewall/action.foo

    #TARGET      SOURCE     DEST     PROTO    DEST PORT(S)
    ACCEPT       -          -        tcp      22
    bar:info

    /etc/shorewall/rules:

    #ACTION      SOURCE     DEST     PROTO    DEST PORT(S)
    foo:debug    $FW         net

    Logging in the invoke 'foo' action will be as if foo had been defined as:

    #TARGET      SOURCE     DEST     PROTO    DEST PORT(S)
    ACCEPT:debug -          -        tcp      22
    bar:info
  2. If you follow the log level with "!" then logging will be set at that level for all rules recursively invoked by the action.

    Example:

    /etc/shorewall/action.foo

    #TARGET      SOURCE     DEST     PROTO    DEST PORT(S)
    ACCEPT       -          -        tcp      22
    bar:info

    /etc/shorewall/rules:

    #ACTION      SOURCE     DEST     PROTO    DEST PORT(S)
    foo:debug!   $FW        net

    Logging in the invoke 'foo' action will be as if foo had been defined as:

    #TARGET      SOURCE     DEST     PROTO    DEST PORT(S)
    ACCEPT:debug -          -        tcp      22
    bar:debug

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 /etc/shorewall/acton script then when that script is invoked, the following three variables will be set for use by the script:

  • $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.

  • $LEVEL = Log level. If empty, no logging was specified.

  • $TAG = Log Tag.

Example:

/etc/shorewall/rules:

#ACTION          SOURCE           DEST
acton:info:test  $FW              net

Your /etc/shorewall/acton file will be run with:

  • $CHAIN="%acton1"

  • $LEVEL="info"

  • $TAG="test"

For an example of how to use these variables, see this article.

Creating an Action using an Extension Script

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

If you actually need an action to drop broadcast packets, use the dropBcast standard action rather than create one like this.

Example 1. An action to drop all broadcast packets

/etc/shorewall/actions

DropBcasts

/etc/shorewall/action.DropBcasts

# This file is empty

/etc/shorewall/DropBcasts

[ -n "$LEVEL" ] && log_rule_limit $LEVEL $CHAIN DropBcasts DROP   "" "$TAG" -A
run_iptables -A $CHAIN -m pkttype --pkttype broadcast -j DROP

Example 2. An Example that implements NFQUEUE support

Here's another example that implements support for NFQUEUE.

/etc/shorewall/actions

NFQUEUE

/etc/shorewall/action.NFQUEUE

# This file is empty

/etc/shorewall/NFQUEUE

[ -n "$TAG" ] || TAG=0

if [ -n "$LEVEL" ]; then
    log_rule_limit $LEVEL $CHAIN NFQUEUE $TAG   "" "" -A
fi

run_iptables -A $CHAIN -j NFQUEUE --queue-num $TAG

As you can see in the above code, the $TAG argument is used to specify the queue number rather than as a logging tag. So to invoke the action to direct packets to queue 22, you would have the following in /etc/shorewall/rules:

#ACTION           SOURCE         DEST         PROTO      DEST
#                                                        PORT(S)
NFQUEUE:none:22   fw             net          tcp        9999

Also note that $TAG is being passed as the DISPOSITION argument to log_rule_limit(). Using the default log format, this will produce a log prefix of "<chain>:NFQUEUE:<queue number>:" (e.g., "%NFQUEUE:NFQUEUE:22:"

Beginning with version 4.0.3, Shorewall-perl has builtin support for NFQUEUE; that support is not compatible with what is shown above in that the queue number is specified by following 'NFQUEUE" with a slash ("/") and the queue number (e.g., "NFQUEUE/22").


For another example of defining an action with an extension script, see this article.



[1] AUTH is actually pretty silly on today's internet but it's amazing how many servers still employ it.