<?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>Shorewall Traffic Accounting</title>

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

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

    <pubdate>2004-04-19</pubdate>

    <copyright>
      <year>2003-2004</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>

  <para>Shorewall Traffic Accounting support was added in Shorewall release
  1.4.7.</para>

  <para>Shorewall accounting rules are described in the file
  /etc/shorewall/accounting. By default, the accounting rules are placed in a
  chain called <quote>accounting</quote> and can thus be displayed using
  <quote>shorewall show accounting</quote>. All traffic passing into, out of
  or through the firewall traverses the accounting chain including traffic
  that will later be rejected by interface options such as <quote>tcpflags</quote>
  and <quote>maclist</quote>. If your kernel doesn&#39;t support the
  connection tracking match extension (Kernel 2.4.21) then some traffic
  rejected under <quote>norfc1918</quote> will not traverse the accounting
  chain.</para>

  <para>The columns in the accounting file are as follows:</para>

  <itemizedlist>
    <listitem>
      <para><emphasis role="bold">ACTION </emphasis>- What to do when a match
      is found. Possible values are:</para>

      <itemizedlist>
        <listitem>
          <para>COUNT- Simply count the match and continue trying to match the
          packet with the following accounting rules</para>
        </listitem>

        <listitem>
          <para>DONE- Count the match and don&#39;t attempt to match any
          following accounting rules.</para>
        </listitem>

        <listitem>
          <para><emphasis>&#60;chain&#62;</emphasis> - The name of a chain to
          jump to. Shorewall will create the chain automatically. If the name
          of the chain is followed by <quote>:COUNT</quote> then a COUNT rule
          matching this rule will automatically be added to &#60;chain&#62;.
          Chain names must start with a letter, must be composed of letters
          and digits, and may contain underscores (<quote>_</quote>) and
          periods (<quote>.</quote>). Beginning with Shorewall version 1.4.8,
          chain names man also contain embedded dashes (<quote>-</quote>) and
          are not required to start with a letter.</para>
        </listitem>
      </itemizedlist>
    </listitem>

    <listitem>
      <para><emphasis role="bold">CHAIN</emphasis> - The name of the chain
      where the accounting rule is to be added. If empty or <quote>-</quote>
      then the <quote>accounting</quote> chain is assumed.</para>
    </listitem>

    <listitem>
      <para><emphasis role="bold">SOURCE</emphasis> - Packet Source. The name
      of an interface, an address (host or net) or an interface name followed
      by <quote>:</quote> and a host or net address.</para>
    </listitem>

    <listitem>
      <para><emphasis role="bold">DESTINATION</emphasis> - Packet Destination
      Format the same as the SOURCE column.</para>
    </listitem>

    <listitem>
      <para><emphasis role="bold">PROTOCOL</emphasis> - A protocol name (from
      <filename>/etc/protocols</filename>) or a protocol number.</para>
    </listitem>

    <listitem>
      <para><emphasis role="bold">DEST PORT</emphasis> - Destination Port
      number. Service name from <filename>/etc/services</filename> or port
      number. May only be specified if the protocol is TCP or UDP (6 or 17).</para>
    </listitem>

    <listitem>
      <para><emphasis role="bold">SOURCE PORT</emphasis>- Source Port number.
      Service name from /etc/services or port number. May only be specified if
      the protocol is TCP or UDP (6 or 17).</para>
    </listitem>
  </itemizedlist>

  <para>In all columns except ACTION and CHAIN, the values <quote>-</quote>,<quote>any</quote>
  and <quote>all</quote> are treated as wild-cards.</para>

  <para>The accounting rules are evaluated in the Netfilter <quote>filter</quote>
  table. This is the same environment where the <quote>rules</quote> file
  rules are evaluated and in this environment, DNAT has already occurred in
  inbound packets and SNAT has not yet occurred on outbound ones.</para>

  <para>Accounting rules are not stateful -- each rule only handles traffic in
  one direction. For example, if eth0 is your internet interface and you have
  a web server in your DMZ connected to eth1 then to count HTTP traffic in
  both directions requires two rules:</para>

  <programlisting>        #ACTION CHAIN   SOURCE  DESTINATION     PROTOCOL        DEST            SOURCE
        #                                                       PORT            PORT
        DONE    -       eth0    eth1            tcp             80
        DONE    -       eth1    eth0            tcp             -               80</programlisting>

  <para>Associating a counter with a chain allows for nice reporting. For
  example:</para>

  <programlisting>        #ACTION         CHAIN   SOURCE  DESTINATION     PROTOCOL        DEST            SOURCE
        #                                                               PORT            PORT
        web:COUNT       -       eth0    eth1            tcp             80
        web:COUNT       -       eth1    eth0            tcp             -               80
        web:COUNT       -       eth0    eth1            tcp             443
        web:COUNT       -       eth1    eth0            tcp             -               443
        DONE            web</programlisting>

  <para>Now <quote>shorewall show web</quote> will give you a breakdown of
  your web traffic:</para>

  <programlisting>     [root@gateway shorewall]# shorewall show web
     Shorewall-1.4.6-20030821 Chain web at gateway.shorewall.net - Wed Aug 20 09:48:56 PDT 2003
     
     Counters reset Wed Aug 20 09:48:00 PDT 2003

     Chain web (4 references)
     pkts bytes target     prot opt in     out     source               destination
       11  1335            tcp  --  eth0   eth1    0.0.0.0/0            0.0.0.0/0          tcp dpt:80
       18  1962            tcp  --  eth1   eth0    0.0.0.0/0            0.0.0.0/0          tcp spt:80
        0     0            tcp  --  eth0   eth1    0.0.0.0/0            0.0.0.0/0          tcp dpt:443
        0     0            tcp  --  eth1   eth0    0.0.0.0/0            0.0.0.0/0          tcp spt:443
       29  3297 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0
       [root@gateway shorewall]#</programlisting>

  <para>Here is a slightly different example:</para>

  <programlisting>        #ACTION         CHAIN   SOURCE  DESTINATION     PROTOCOL        DEST            SOURCE
        #                                                               PORT            PORT
        web             -       eth0    eth1            tcp             80
        web             -       eth1    eth0            tcp             -               80
        web             -       eth0    eth1            tcp             443
        web             -       eth1    eth0            tcp             -               443
        COUNT           web     eth0    eth1
        COUNT           web     eth1    eth0</programlisting>

  <para>Now <quote>shorewall show web</quote> simply gives you a breakdown by
  input and output:</para>

  <programlisting>     [root@gateway shorewall]# shorewall show accounting web
     Shorewall-1.4.6-20030821 Chains accounting web at gateway.shorewall.net - Wed Aug 20 10:27:21 PDT 2003

     Counters reset Wed Aug 20 10:24:33 PDT 2003

     Chain accounting (3 references)
         pkts bytes target     prot opt in     out     source               destination
         8767  727K web        tcp  --  eth0   eth1    0.0.0.0/0            0.0.0.0/0          tcp dpt:80
            0     0 web        tcp  --  eth0   eth1    0.0.0.0/0            0.0.0.0/0          tcp dpt:443
        11506   13M web        tcp  --  eth1   eth0    0.0.0.0/0            0.0.0.0/0          tcp spt:80
            0     0 web        tcp  --  eth1   eth0    0.0.0.0/0            0.0.0.0/0          tcp spt:443

     Chain web (4 references)
         pkts bytes target     prot opt in     out     source               destination
         8767  727K            all  --  eth0   eth1    0.0.0.0/0            0.0.0.0/0
        11506   13M            all  --  eth1   eth0    0.0.0.0/0            0.0.0.0/0
     [root@gateway shorewall]#</programlisting>

  <para>Here&#39;s how the same example would be constructed on an HTTP server
  with only one interface (eth0).</para>

  <caution>
    <para>READ THE ABOVE CAREFULLY -- IT SAYS <emphasis role="bold">SERVER</emphasis>.
    If you want to account for web browsing, you have to reverse the rules
    below.</para>
  </caution>

  <programlisting>        #ACTION         CHAIN   SOURCE  DESTINATION     PROTOCOL        DEST            SOURCE
        #                                                               PORT            PORT
        web             -       eth0    -               tcp             80
        web             -       -       eth0            tcp             -               80
        web             -       eth0    -               tcp             443
        web             -       -       eth0            tcp             -               443
        COUNT           web     eth0
        COUNT           web     -       eth0</programlisting>

  <para>Note that with only one interface, only the SOURCE (for input rules)
  or the DESTINATION (for output rules) is specified in each rule.</para>

  <para>Here&#39;s the output:</para>

  <programlisting>     [root@mail shorewall]# shorewall show accounting web Shorewall-1.4.7
     Chains accounting web at mail.shorewall.net - Sun Oct 12 10:27:21 PDT 2003

     Counters reset Sat Oct 11 08:12:57 PDT 2003

     Chain accounting (3 references)
      pkts bytes target     prot opt in     out     source               destination
      8767  727K web        tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0          tcp dpt:80
     11506   13M web        tcp  --  *      eth0    0.0.0.0/0            0.0.0.0/0          tcp spt:80
         0     0 web        tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0          tcp dpt:443
         0     0 web        tcp  --  *      eth0    0.0.0.0/0            0.0.0.0/0          tcp spt:443

     Chain web (4 references)
      pkts bytes target     prot opt in     out     source               destination
      8767  727K            all  --  eth0   *       0.0.0.0/0            0.0.0.0/0
     11506   13M            all  --  *      eth0    0.0.0.0/0            0.0.0.0/0
     [root@mail shorewall]#</programlisting>

  <para>For an example of integrating Shorewall Accounting with MRTG, see
  <ulink url="http://www.nightbrawler.com/code/shorewall-stats/">http://www.nightbrawler.com/code/shorewall-stats/</ulink>.</para>
</article>