## Shorewall Logging

### Tom Eastep

### Bill Shirley

Copyright © 2001 - 2016 Thomas M. Eastep, Bill Shirley

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

2017/09/19

### Caution

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.

## How to Log Traffic Through a Shorewall Firewall

The disposition of packets entering a Shorewall firewall is determined by one of a number of Shorewall facilities. Only some of these facilities permit logging.

1. The packet is part of an established connection. While the packet can be logged using LOG rules in the ESTABLISHED section of /etc/shorewall/rules, that is not recommended because of the large amount of information that may be logged.

2. The packet represents a connection request that is related to an established connection (such as a data connection associated with an FTP control connection). These packets may be logged using LOG rules in the RELATED section of /etc/shorewall/rules.

3. The packet is rejected because of an option in /etc/shorewall/shorewall.conf or /etc/shorewall/interfaces. These packets can be logged by setting the appropriate logging-related option in /etc/shorewall/shorewall.conf.

4. The packet matches a rule in /etc/shorewall/rules. By including a syslog level (see below) in the ACTION column of a rule (e.g., “ACCEPT:info net $FW tcp 22”), the connection attempt will be logged at that level.

5. The packet doesn't match a rule so it is handled by a policy defined in /etc/shorewall/policy. These may be logged by specifying a syslog level in the LOG LEVEL column of the policy's entry (e.g., “loc net ACCEPT info”).

## Where the Traffic is Logged and How to Change the Destination

By default, Shorewall directs Netfilter to log using syslog (8). Syslog classifies log messages by a facility and a priority (using the notation facility.priority).

The facilities defined by syslog are auth, authpriv, cron, daemon, kern, lpr, mail, mark, news, syslog, user, uucp and local0 through local7.

Throughout the Shorewall documentation, I will use the term level rather than priority since level is the term used by Netfilter. The syslog documentation uses the term priority.

### Syslog Levels

Syslog levels are a method of describing to syslog (8) the importance of a message. A number of Shorewall parameters have a syslog level as their value.

Valid levels are:

7 - debug (Debug-level messages)
6 - info (Informational)
5 - notice (Normal but significant Condition)
4 - warning (Warning Condition)
3 - err (Error Condition)
2 - crit (Critical Conditions)
1 - alert (must be handled immediately)
0 - emerg (System is unusable)

For most Shorewall logging, a level of 6 (info) is appropriate. Shorewall log messages are generated by Netfilter and are logged using the kern facility and the level that you specify. If you are unsure of the level to choose, 6 (info) is a safe bet. You may specify levels by name or by number.

Beginning with Shorewall 4.5.5, the `level` name or number may be optionally followed by a comma-separated list of one or more`log options`. The list is enclosed in parentheses. Log options cause additional information to be included in each log message.

Valid log options are:

ip_options

  Log messages will include the option settings from the IP header.

macdecode

  Decode the MAC address and protocol.

tcp_sequence

  Include TCP sequence numbers.

tcp_options

  Include options from the TCP header.

uid

  Include the UID of the sending program; only valid for packets originating on the firewall itself.

Example: info(tcp_options,tcp_sequence)

Syslogd writes log messages to files (typically in `/var/log/`*) based on their facility and level. The mapping of these facility/level pairs to log files is done in /etc/syslog.conf (5). If you make changes to this file, you must restart syslogd before the changes can take effect.

Syslog may also write to your system console. See Shorewall FAQ 16 for ways to avoid having Shorewall messages written to the console.

### Configuring a Separate Log for Shorewall Messages (ulogd)

There are a couple of limitations to syslogd-based logging:

1. If you give, for example, kern.info its own log destination then that destination will also receive all kernel messages of levels 5 (notice) through 0 (emerg).

2. All kernel.info messages will go to that destination and not just those from Netfilter.

If your kernel has NFLOG target support (and most vendor-supplied kernels do), you may also specify a log level of NFLOG (must be all caps). When NFLOG is used, Shorewall will direct Netfilter to log the related messages via the ULOG target which will send them to a process called “ulogd”. The ulogd program is included in most distributions and is also available from http://www.netfilter.org/projects/ulogd/index.html. Ulogd can be configured to log all Shorewall messages to their own log file.

### Note

The NFLOG logging mechanism is completely separate from syslog. Once you switch to ULOG, the settings in `/etc/syslog.conf` have absolutely no effect on your Shorewall logging (except for Shorewall status messages which still go to syslog).

You will need to change all instances of log levels (usually “info”) in your Shorewall configuration files to “NFLOG” - this includes entries in the policy, rules and shorewall.conf files. If you initially installed using Shorewall 5.1.2 or later, you can simply change the setting of LOG_LEVEL in shorewall.conf.

Otherwise, you must search for all instances of log levels in your configuration and change them accordingly. If you currently run Shorewall 5.1.2 or later, then change them to $LOG_LEVEL and set LOG_LEVEL accordingly. If you are running an earlier release, using a shell variable simplifies future changes. Here's what I had at one time:

    gateway:/etc/shorewall# grep -v ^\# * | egrep '\$LOG|ULOG|LOGFILE'
    params:LOG=NFOG
    policy:loc              $FW             REJECT          $LOG
    policy:net              all             DROP            $LOG            10/sec:40
    policy:all              all             REJECT          $LOG
    rules:REJECT:$LOG       loc                             net                     tcp     25
    rules:REJECT:$LOG       loc                             net                     udp     1025:1031
    rules:REJECT:$LOG       dmz                             net                     udp     1025:1031
    rules:ACCEPT:$LOG       dmz                             net                     tcp     1024:                                   20
    rules:REJECT:$LOG       $FW                             net                     udp     1025:1031
    shorewall.conf:LOGFILE=/var/log/shorewall
    shorewall.conf:LOGUNCLEAN=$LOG
    shorewall.conf:MACLIST_LOG_LEVEL=$LOG
    shorewall.conf:TCP_FLAGS_LOG_LEVEL=$LOG
    shorewall.conf:RFC1918_LOG_LEVEL=$LOG
    gateway:/etc/shorewall#

Finally edit `/etc/shorewall/shorewall.conf` and set LOGFILE=<file that you wish to log to>. This tells the `/sbin/shorewall` program where to look for the log when processing its “show log”, “logwatch” and “dump” commands.

The NFLOG target is a successor to ULOG. Both ULOG and NFLOG may be followed by a list of up to three numbers in parentheses.

- The first number specifies the netlink group (0-65535). If omitted (e.g., NFLOG(,0,10)) then a value of 0 is assumed.

- The second number specifies the maximum number of bytes to copy. If omitted, 0 (no limit) is assumed.

- The third number specifies the number of log messages that should be buffered in the kernel before they are sent to user space. The default is 1.

Examples:

`/etc/shorewall/shorewall.conf`:

    MACLIST_LOG_LEVEL=NFLOG(1,0,1)

`/etc/shorewall/rules`:

    #ACTION             SOURCE     DEST     PROTO     DPORT
    ACCEPT:NFLOG(1,0,1) vpn        fw       tcp       ssh,time,631,8080

### Important

Shorewall considers ULOG(...) and NFLOG(...) to be log levels, just like info, debug, etc. even though they are not defined by syslog.

Here is a copy of a ulogd.conf file that logs to /var/log/firewall. It was contributed by a Shorewall user on IRC:

    [global]
    user="ulogd"
    logfile="/var/log/ulogd/ulogd.log"
    loglevel=7

    plugin="/usr/lib64/ulogd/ulogd_inppkt_NFLOG.so"
    plugin="/usr/lib64/ulogd/ulogd_filter_IFINDEX.so"
    plugin="/usr/lib64/ulogd/ulogd_filter_IP2STR.so"
    plugin="/usr/lib64/ulogd/ulogd_filter_PRINTPKT.so"
    plugin="/usr/lib64/ulogd/ulogd_output_LOGEMU.so"
    plugin="/usr/lib64/ulogd/ulogd_raw2packet_BASE.so"

    stack=log:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,firewall:LOGEMU

    [firewall]
    file="/var/log/firewall"
    sync=1

### Note

This sample config file assumes that NFLOG is being used in logging rules and policies.

## Log Backends

Netfilter logging allows configuration of multiple backends. Logging backends provide the The low-level forward of log messages. There are currently three backends:

LOG (ipt_LOG and ip6t_LOG).

  Normal kernel-based logging to a syslog daemon.

ULOG (ipt_ULOG)

  ULOG logging as described ablve. Only available for IPv4.

netlink (nfnetlink_log)

  The logging backend behind NFLOG, defined above.

The currently-available and currently-selected IPv4 and IPv6 backends are shown in /proc/sys/net/netfilter/nf_log:

    cat /proc/net/netfilter/nf_log
     0 NONE (nfnetlink_log)
     1 NONE (nfnetlink_log)
     2 ipt_ULOG (ipt_ULOG,ipt_LOG,nfnetlink_log)
     3 NONE (nfnetlink_log)
     4 NONE (nfnetlink_log)
     5 NONE (nfnetlink_log)
     6 NONE (nfnetlink_log)
     7 NONE (nfnetlink_log)
     8 NONE (nfnetlink_log)
     9 NONE (nfnetlink_log)
    10 ip6t_LOG (ip6t_LOG,nfnetlink_log)
    11 NONE (nfnetlink_log)
    12 NONE (nfnetlink_log)

The magic numbers (0-12) are Linux address family numbers (AF_INET is 2 and AF_INET6 is 10).

The name immediately following the number is the currently-selected backend, and the ones in parantheses are the ones that are available. You can change the currently selected backend by echoing it's name into /proc/net/netfilter/nf_log.`number`.

Example - change the IPv4 backend to LOG:

    sysctl net.netfilter.nf_log.2=ipt_LOG

Beginning with Shorewall 4.6.4, you can configure the backend using the LOG_BACKEND option in shorewall.conf(5) and shorewall6.conf(5).

## Syslog-ng

Here is a post describing configuring syslog-ng to work with Shorewall. Recent SUSE™ releases come preconfigured with syslog-ng with Netfilter messages (including Shorewall's) are written to `/var/log/firewall`.

## Understanding the Contents of Shorewall Log Messages

For general information on the contents of Netfilter log messages, see http://logi.cc/en/2010/07/netfilter-log-format/.

For Shorewall-specific information, see FAQ #17.

## Customizing the Content of Shorewall Log Messages

In addition to the options mentioned above, a certain amount of customization of the Netfilter-generated messages is allowed.

### Log Tags

In a Shorewall logging rule, the log level can be followed by a log tag as in "DROP:NFLOG:junk". The generated log message will include "chain-name junk DROP".

### LOGTAGONLY

By setting the LOGTAGONLY option to Yes in shorewall.conf(5) or shorewall6.conf(5), the disposition ('DROP' in the above example) will be omitted. Consider the following rule:

    #ACTION                                    SOURCE          DEST           PROTO
    REJECT(icmp-proto-unreachable):notice:IPv6 loc             net            41      # who's using IPv6 tunneling

This rule generates the following warning at compile time:

WARNING: Log Prefix shortened to "Shorewall:IPv6:REJECT(icmp-p " /etc/shorewall/rules (line 212)

and produces the rather ugly prefix "Shorewall:IPv6:REJECT(icmp-p ".

Now consider this similar rule:

    #ACTION                                              SOURCE          DEST           PROTO
    REJECT(icmp-proto-unreachable):notice:IPv6,tunneling loc             net            41      # who's using IPv6 tunneling

With LOGTAGONLY=Yes, no warning is generated and the prefix becomes "Shorewall:IPv6:tunneling:"

See the shorewall[6].conf man page for further information about how LOGTAGONLY=Yes can be used.

### Log Levels in shorewall[6].conf

shorewall.conf(5) and shorewall6.conf(5) have a number of options whose values are log levels. Beginning with Shorewall 5.0.0, these specifcations may include a log tag as described above.

## Some Additional Thoughts on Logging (by Bill Shirley)

As a side note to the LOGTAGONLY example above, i recommend blocking all tunneling because it bypasses the firewall rules:

    #ACTION                                              SOURCE          DEST           PROTO      DPORT
    ?COMMENT tunneling
    REJECT(icmp-proto-unreachable):notice:IPv6,tunneling loc             net            41                   # who's using IPv6 tunneling
    REJECT(icmp-port-unreachable)                        loc             net            tcp,udp    teredo
    REJECT(icmp-port-unreachable)                        loc             net            tcp,udp    isakmp,ipsec-nat-t

Here is an example of logging traffic only once:

`/etc/shorewall/init:`

    ipset -exist create IPv4 hash:ip timeout 86400
    ipset -exist create IPv4-port hash:ip,port timeout 14400

`/etc/shorewall/rules` (at the top):

    #ACTION             SOURCE                         DEST           PROTO
    ?SECTION NEW
    # ------------------
    ?COMMENT drop previously flagged
    DROP                net:+IPv4[src]                 fw
    DROP                net:+IPv4-port[src,dst]        fw

After all the rules have been checked, at the bottom of `/etc/shorewall/rules`:

    # =============================================================================
    # =============================== H@ck0rz =====================================
    # =============================================================================
    ?COMMENT dont whack myself
    REJECT:notice           inet:$ME_NET           fw

    ?COMMENT not public
    ADD(+IPv4-port:src,dst) net                     fw      tcp,udp  domain
    ADD(+IPv4-port:src,dst) net                     fw      tcp      ldap,ldaps
    ADD(+IPv4-port:src,dst) net                     fw      tcp,udp  ipp

    ?COMMENT H@ck0rz
    ADD(+IPv4:src)          net                     fw      tcp      ssh
    ADD(+IPv4:src)          net                     fw      tcp      ftp,ftps,sftp,telnet,telnets,exec,login,shell,sunrpc
    ADD(+IPv4:src)          net                     fw      tcp,udp  ms-sql-s,ms-sql-m

    ?COMMENT drop if added
    DROP:info:BAN,IPv4      net:+IPv4[src]          fw
    DROP:info:BAN,IPv4-port net:+IPv4-port[src,dst] fw

One final note: I wanted less firewall messages in /var/log/messages so I added to rsyslog.conf:

    #### RULES #### <-- find this
    if $msg contains 'Shorewall' then {
      action(type="omfile" file="/var/log/shorewall.log")
    #  if ($syslogfacility == 0 and $syslogseverity >= 4) then stop    # warning
    #  if ($syslogfacility == 0 and $syslogseverity >= 5) then stop    # notice
      if ($syslogfacility == 0 and $syslogseverity >= 6) then stop  # info
    }

I log at 'notice' log level if I want the message in `/var/log/messages` and everything goes to `/var/log/shorewall.log`. Don't forget to add /var/log/shorewall.log to logrotate.