shorewall_code/Shorewall-docs2/Macros.xml

508 lines
19 KiB
XML
Raw Normal View History

<?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 lang="en" status="">
<!--$Id$-->
<articleinfo>
<title>Macros</title>
<authorgroup>
<author>
<firstname>Tom</firstname>
<surname>Eastep</surname>
</author>
<author>
<firstname>Cristian</firstname>
<surname>Rodríguez</surname>
</author>
</authorgroup>
<pubdate>2005-11-02</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>
<caution>
<para><emphasis role="bold">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.</emphasis></para>
</caution>
<section>
<title>Overview of Shorewall Macros?</title>
<para>Shorewall macros 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 and in the TARGET column of an action in which case, the traffic
matching that rules file entry will be passed to the series of iptables
rules named by the macro.</para>
<para>Macros can be thought of as templates. When a macro 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 macro causes a log message to be
generated.</para>
<para>There are two types of Shorewall macros:</para>
<orderedlist>
<listitem>
<para>Standard Macros. These macros are released as part of Shorewall.
They are defined in macros.* files in <filename
class="directory">/usr/share/shorewall</filename>. Each
<filename>macros.*</filename> file has a comment at the beginning of
the file that describes what the macro does. As an example, here is
the definition of the <firstterm>SMB</firstterm> standard
macro.</para>
<programlisting>#
# Shorewall 3.0 /usr/share/shorewall/macro.SMB
#
# Handle Microsoft SMB traffic. You need to invoke this macro in
# both directions.
#
######################################################################################
#TARGET SOURCE DEST PROTO DEST SOURCE RATE USER/
# PORT PORT(S) LIMIT GROUP
PARAM - - udp 135,445
PARAM - - udp 137:139
PARAM - - udp 1024: 137
PARAM - - 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 macros, 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 Macros. These macros are created by end-users. They
are defined in macros.* files in /etc/shorewall or in another
directory listed in your CONFIG_PATH (defined in <ulink
url="Documentation.htm#Conf">/etc/shorewall/shorewall.conf</ulink>).</para>
</listitem>
</orderedlist>
<para>Most Standard Macros are <firstterm>parameterized</firstterm>. That
means that you specify what you want to do (ACCEPT, DROP, REJECT, etc.)
when you invoke the macro. The SMB macro shown above is parameterized
(note PARAM in the TARGET column). When invoking a parameterized macro,
you follow the name of the macro with a slash ("/") and the action that
you want to substitute for PARAM.</para>
<para>Example:</para>
<blockquote>
<para>/etc/shorewall/rules:</para>
<programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S)
SMB/ACCEPT loc fw </programlisting>
<para>The above is equivalent to coding the following series of
rules:</para>
<programlisting>#TARGET SOURCE DEST PROTO DEST PORT(s)
ACCEPT loc fw udp 135,445
ACCEPT loc fw udp 137:139
ACCEPT loc fw udp 1024: 137
ACCEPT loc fw tcp 135,139,445</programlisting>
</blockquote>
<para>Logging is covered in <link linkend="Logging">a following
section</link>. The other columns are treated as follows:</para>
<variablelist>
<varlistentry>
<term>SOURCE and DEST</term>
<listitem>
<para>If the rule in the macro file specifies a value and the
invocation of the rule also specifies a value then the value in the
invocation is appended to the value in the rule using ":" as a
separator.</para>
<para>Example:</para>
<blockquote>
<para>/etc/shorewall/macro.SMTP</para>
<programlisting>#TARGET SOURCE DEST PROTO DEST PORT(S)
PARAM - loc tcp 25</programlisting>
<para>/etc/shorewall/rules</para>
<programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S)
SMTP/DNAT:info net 192.168.1.5</programlisting>
<para>This would be equivalent to coding the following directly in
/etc/shorewall/rules</para>
<programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S)
DNAT:info net loc:192.168.1.5 tcp 25</programlisting>
</blockquote>
</listitem>
</varlistentry>
<varlistentry>
<term>Remaining columns</term>
<listitem>
<para>Any value in the invocation replaces the value in the rule in
the macro.</para>
</listitem>
</varlistentry>
</variablelist>
<para>One remaining restriction must be mentioned: macros that are invoked
from actions cannot themselves invoke other actions.</para>
</section>
<section>
<title>Defining your own Macros</title>
<para>To define a new macro:</para>
<orderedlist>
<listitem>
<para>Macro 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.</para>
</listitem>
<listitem>
<para>Copy /usr/share/shorewall/macro.template to
<filename>/etc/shorewall/macro.MacroName</filename> (for example, if
your new macro name is <quote>Foo</quote> then copy
<filename>/usr/share/shorewall/macro.template</filename> to
<filename>/etc/shorewall/macro.Foo</filename>).</para>
</listitem>
<listitem>
<para>Now modify the new file to define the new macro.</para>
</listitem>
</orderedlist>
<para>Columns in the macro.template file are as follows:</para>
<itemizedlist>
<listitem>
<para>ACTION - ACCEPT, DROP, REJECT, DNAT, DNAT-, REDIRECT, CONTINUE,
LOG, QUEUE, PARAM or an action name. Note that a macro may not invoke
another macro.</para>
<simplelist>
<member>ACCEPT - allow the connection request</member>
<member>ACCEPT+ - like ACCEPT but also excludes the connection from
any subsequent DNAT[-] or REDIRECT[-] rules.</member>
<member>NONAT - Excludes the connection from any subsequent DNAT[-]
or REDIRECT[-] rules but doesn't generate a rule to accept the
traffic.</member>
<member>DROP - ignore the request</member>
<member>REJECT - disallow the request and return an icmp unreachable
or an RST packet.</member>
<member>DNAT - Forward the request to another address (and
optionally another port).</member>
<member>DNAT- - Advanced users only. Like DNAT but only generates
the DNAT iptables rule and not the companion ACCEPT rule.</member>
<member>SAME - Similar to DNAT except that the port may not be
remapped and when multiple server addresses are listed, all requests
from a given remote system go to the same server.</member>
<member>SAME- - Advanced users only. Like SAME but only generates
the SAME iptables rule and not the companion ACCEPT rule.</member>
<member>REDIRECT - Redirect the request to a local port on the
firewall.</member>
<member>REDIRECT- - Advanced users only. Like REDIRECT but only
generates the REDIRECT iptables rule and not the companion ACCEPT
rule.</member>
<member>CONTINUE - (For experts only). Do not process any of the
following rules for this (source zone,destination zone). If The
source and/or destination If the address falls into a zone defined
later in /etc/shorewall/zones, this connection request will be
passed to the rules defined for that (those) zone(s).</member>
<member>LOG - Simply log the packet and continue.</member>
<member>QUEUE - Queue the packet to a user-space application such as
ftwall (http://p2pwall.sf.net).</member>
</simplelist>
<para>The ACTION may optionally be followed by ":" and a syslog log
level (e.g, REJECT:info or DNAT:debug). This causes the packet to be
logged at the specified level.</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 fields 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>
<member>[!]+&lt;<emphasis>program name</emphasis>&gt; (Note: support
for this form was removed from Netfilter in kernel version
2.6.14).</member>
</simplelist>
</listitem>
</itemizedlist>
<para>Omitted column entries should be entered using a dash ("-:).</para>
<para>Example:</para>
<para><phrase><filename>/etc/shorewall/macro.LogAndAccept</filename></phrase><programlisting> LOG:info
ACCEPT</programlisting></para>
<para>To use your macro, 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 id="Logging">
<title>Macros and Logging</title>
<para>Specifying a log level in a rule that invokes a user- or
Shorewall-defined action will cause each rule in the macro to be logged
with the specified level (and tag).</para>
<para>The extent to which logging of macro rules occur is governed by the
following:</para>
<orderedlist>
<listitem>
<para>When you invoke a macro and specify a log level, only those
rules in the macro 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/macro.foo</para>
<programlisting>#ACTION 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 invoked 'foo' macro will be as if foo had been
defined as:</para>
<programlisting>#ACTION 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 macro.</para>
<para>Example:</para>
<para>/etc/shorewall/macro.foo</para>
<programlisting>#ACTION 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 invoked 'foo' macro will be as if foo had been
defined as:</para>
<programlisting>#ACTION SOURCE DEST PROTO DEST PORT(S)
ACCEPT:debug - - tcp 22
bar:debug</programlisting>
</listitem>
</orderedlist>
</section>
<section>
<title>How do I know if I should create an Action or a Macro?</title>
<para>While actions and macros perform similar functions, in any given
case you will generally find that one is more appropriate than the
other.</para>
<orderedlist>
<listitem>
<para>You can not associate an Extension Script with a macro <ulink
url="Actions.html#Extension">the way that you can with an
Action</ulink>. So if you need access to iptables features not
directly supported by Shorewall then you must use an action.</para>
</listitem>
<listitem>
<para>Macros are expanded in-line while each action is it's own chain.
So if there are a lot of rules involved in your new action/macro then
it is generally better to use an action than a macro. Only the packets
selected when you invoke the action are directed to the corresponding
chain. On the other hand, if there are only one or two rules involved
in what you want to do then a macro is more efficient.</para>
</listitem>
</orderedlist>
</section>
</article>