natlog - source-nat logging tool


natlog [OPTIONS] command


Firewalls like iptables(1) may offer POSTROUTING (source network address translation, snat) facilities changing the source address of a host behind the firewall to the address of the host connected to the outer world. With snat the following combinations of IP addresses and port numbers are encountered:

. )

Source natting usually uses sport for fwport, but fwport may already be in use, in which case the firewalling host must use another, available port to forward communication from IPsrc, sport to IPdst, dport.

The general scheme that applies to source natting, therefore, looks like this:

    IPsrc:sport is translated by the firewall to IPfw:fwport;
    IPfw:fwport is used when communicating with IPdst:dport.
From the perspective of the destination host the communication originates at IPfw::fwport and consequently all communication (e.g., incident reports) sent by the systems administrator maintaining IPdst to IPfw's systems administrator will refer to IPfw:fwport, rather than to IPsrc::sport.

Relating IPfw:fwport to IPsrc:sport is difficult when merely using the standard log facilities provided by iptables and natlog was developed to fill in that particular niche.

Natlog provides data about source natting in various forms. The standard logging mode consists of messages sent to the syslog daemon (cf., rsyslogd(1)) and/or to the standard output stream showing the essential characteristics of connections using source natting. Here is an example of a logged message (log-entries occupy single lines; the line-breaks below are to enhance readability):

    NATLOG: from 1338990672:55588 thru 1338990747:807100 (UTC): tcp (via: to 
        to; sent: 802, received: 7669
The values 1338990672:55588 and 1338990747:807100 are time stamps showing the begin- and end-times in seconds:microseconds of a tcp connection since the beginning of the epoch (Jan 1, 1970, 0:00 UTC). Natlog offers the --time option for requesting human-readable time specifications like Nov 2 13:29:11 rather than time representations using seconds and micro seconds.

The next value ( represents IPsrc::sport. This is followed by, representing IPfw:fwport. The third pair of values ( represents IPdst:dport.

In this example, host, using port 4467, connected to host, port 443. To this latter host the connection appears to have originated from port 4467. The log message allows us to associate this with the `real' host and port from which the connection originated:

The final entries show the number of bytes that were sent by the source-host (IPsrc) and received from the destination-host (IPdst).

When natlog is terminated it can no longer track connections that are still open. If natlog was terminated (by a SIGINT or SIGTERM signal), then it logs a `terminating' line, followed by an overview of all (potentially) still open connections. Those connections are flagged with a trailing '(EOP)' (end of program) log-element, and their end-times show natlog's termination time. Incomplete connections show (EXPIRED).

In addition to the standard logs the option --log-data is available. This option requires the path to a file where information is logged in tabular form, which can easily be processed by statistical software like R(1). When specifying this option information will be appended to an existing file. When the log file does not yet exist it is created. The first line of the thus written log files names the columns of the table. The column names are (all on one line):

    type, srcNr, srcIP, srcPort, dstNr, dstIP, dstPort, 
        sent, recvd, begin,  end, beginTime, endTime, status 
Most column labels will be self-explanatory. Type indicates the connection type, logged as icmp, tcp, or udp; srcNr and dstNr are the 32 bit numeric values of, respectively, the source host's IP address and the destination host's IP address (decimal representations); begin and end are the times in seconds since the beginning of the epoch, corresponding to the times displayed at, respectively, beginTime and endTime; status indicates the status of the logged connection information: ok indicates a connection that was normally completed; expired indicates that the connection was recognized, but was not normally completed; eop is used for connections that were still active by the time natlog terminates. When the status equals expired, the time entries show the times of receiving the first and last packets of that connection; when eop, then the end and endTime entries show natlog's termination time.

Log entries look like this (each entry occupies one line, header line and logged data lines are right-aligned):

    tcp, 101820608,,        48886, 
        4012145084,,           80,       
               430,            2266,   1517387644,    1517387644, 
        Jan 31 08:34:04:318340, Jan 31 08:34:04:383170,  ok



See also section SYSTEMD.


An annoying characteristic of systemd(1) is that environment variables containing blanks are passed as single arguments to the program being called by their .service files. As a consequence, it is very hard to provide an environment variable in, e.g., /etc/default/natlog specifying natlog's arguments: in practice the number of arguments varies, and so even constructions like ARG1=value1, ARG2=value2, etc. are awkward at best.

As a stopgap for this unwelcome characteristic of systemd the option -S is provided. When used it must be specified as natlog's first argument. Natlog will then inspect all remaining arguments, splitting arguments containing blanks into separate arguments, which are then processed by natlog as intended. Be aware that, to limit the complexity of the splitting-procedure, it is not full-proof: double- or single-quote delimited string-arguments will also be split into separate arguments. Unless filenames themselves containing blanks are passed as arguments to natlog this limitation is probably not very serious.

As an example, here is an example of systemd's ExecStart specification:

    ExecStart=/usr/bin/natlog -S -p ${PIDFILE} ${DAEMON_ARGS}
where DAEMON_ARGS might have been specified in /etc/default/natlog as

    DAEMON_ARGS=--log /tmp/natlog.log --log-data /dev/null conntrack


When using rsyslogd(1) property based filters may be used to filter syslog messages and write them to a file of your choice. E.g., to filter messages starting with the syslog message tag (e.g., NATLOG) use

:syslogtag, isequal, "NATLOG:"   /var/log/natlog.log
:syslogtag, isequal, "NATLOG:"   stop
Note that the colon is part of the tag, but is not specified with the syslog-tag option.

This causes all messages having the NATLOG: tag to be written on /var/log/natlog.log after which they are discarded. More extensive filtering is also supported, see, e.g., and


Examples of natlog activations:

Here is natlog's default configuration file. Empty lines and lines starting with hash-marks (#) are ignored. Options adhere to the following syntax:

option  value 
Option and value are separated by white space, a colon may be appended to option names:

# This configuration file shows the default option values.

# all options and values are case sensitive
# see `man natlog' for further details

    # the path and options of the conntrack program:
    # when no filtering options are specified, the tcp
    # protocol is monitored
    # the default command is shown:
#conntrack-command:  /usr/sbin/conntrack -p tcp -E -n -o timestamp \
                                                        -e NEW,DESTROY"

    # the device used by conntrack
#conntrack-device:  /proc/net/nf_conntrack

    # correction for the IP header size 
    # (standard IP header size is 20 bytes)
#conntrack-ip-header-size:  0

    # max. number of conntrack restarts
#conntrack-restart: 10

    # data file for tabular logs (specify path, default: 
    # data file is not used)

    # flush the log-data file after writing log-data-flush lines
#log-data-flush: 32

    # do not run as a daemon (by default: natlog runs as a daemon)

    # do not write messages handled by syslog

    # the path to the pid-file of natlog's daemon process
#pid-file: /run/

    # the protocols that are scanned with the 'conntrack' command:
    #   protocol: all       - monitors tcp, udp, icmp
    #   protocol: udp:tcp   - monitors upd and tcp (any non-empty subset, 
    #                         possibly including icmp is OK)
    # ignored when conntrack-command is specified
#protocol: tcp

    # write messages to stdout (ignored by daemons)

    # the default syslog facility:
#syslog-facility: DAEMON

    # the default syslog priority:
#syslog-priority: NOTICE

    # the default syslog tag:
#syslog-tag: NATLOG

    # the time specification:
#time: raw

    # ttl: time to live (seconds) for udp/icmp connections
#ttl: 60

# end of the configuration file



conntrack(1), ifconfig(1), iptables(1), pcap-filter(7), ping(1), R(1), rsyslogd(1), syslog(3), systemd(1), tcpdump(1)


Natlog currently may process tcp, udp and icmp layer four protocols.


Frank B. Brokken (