Project

General

Profile

Taking traffic dumps on Linux

Abstract

This is a short tutorial on how to get correct IPsec traffic dumps on Linux.

Many users are not aware of the packet capture anomaly that occurs when capturing with default
settings using Wireshark and tcpdump. This article will explain how to take correct traffic dumps
of ...
  • ingress IPsec and IKE traffic
  • egress IPsec and IKE traffic
  • decapsulated IPsec traffic
  • IPsec traffic that is destined for the local host (iptables INPUT chain)
  • IPsec traffic that is destined for a remote host (iptables FORWARD chain)
  • IPsec traffic that is outgoing (iptables OUTPUT chain)

Warning

In the course of the tutorial, firewall rules will be modified. This approach only works with
kernel processing of IPsec traffic.

If you do not exactly know what you are doing, then stop here and read material about the topic.

Traffic dumps are generally not useful for debugging of IKE, because charon optionally logs the complete
structure of the IKE packets. However, the graphical interface provided by Wireshark could be helpful.

If you're debugging problems with ESP or AH encoding or other fancy things, it is useful, though.

This method can only capture traffic before *nat POSTROUTING. *nat POSTROUTING is the last chain before IPsec processing of outgoing packets happen.
To check if packets match the SPs, check the traffic counters of the CHILD_SA. You can see them in the output of ipsec statusall and swanctl -l.

The problem

Capturing traffic with tcpdump or wireshark by listening on a normal network interface shows encapslated
and decapsulated IPsec traffic only for inbound traffic. For outbound traffic only the encrypted traffic is seen.
This is because of how the capturing socket used by the aforementioned tools (or rather libpcap) work.

IPsec processing is usually done in the kernel. strongSwan only handles IKE. If you're using libipsec, then
a plugin in charon handles that traffic.

The solution

The solution to the problem is to use the nflog interface in the iptables framework to get exactly the
packets we are interested in. Taking a look at the netfilter graph gives a list of possible places to dump traffic at.

nflog rules log to a kernel internal multicast group, which is identified by an integer in the 0 - 2^16-1 range.
Only the part of the datagram that the framework sees will be captured. For iptables that is an IPv4 packet.
For ip6tables that is an IPv6 packet. If you use it in ebtables that is an Ethernet frame.

Using nflog to dump packets forces you to use a special interface syntax for tcpdump and wireshark.
You must use nflog:groupnumber as interface.

Example: tcpdump -s 0 -n -i nflog:5

Rules

Because nflog rules are normal iptables rules, the rules need a proper match and target part so you
get exactly the traffic you want. You also must put the rule into the correct place for it to get the packets
you're interested in. The policy match module of iptables enables you to match packets with a
matching IPsec policy.

Following are the parameters for the nflog target in iptables:

NFLOG
    This target provides logging of matching packets. When this  target  is
    set  for  a  rule,  the Linux kernel will pass the packet to the loaded
    logging backend to log the packet. This is usually used in  combination
    with  nfnetlink_log as logging backend, which will multicast the packet
    through a netlink socket to the specified multicast group. One or  more
    userspace  processes may subscribe to the group to receive the packets.
    Like LOG, this is a non-terminating target, i.e. rule traversal contin‐
    ues at the next rule.

    --nflog-group nlgroup
           The netlink group (0 - 2^16-1) to which packets are (only appli‐
           cable for nfnetlink_log). The default value is 0.

    --nflog-prefix prefix
           A prefix string to include in the log message, up to 64  charac‐
           ters long, useful for distinguishing messages in the logs.

    --nflog-range size
           The  number  of bytes to be copied to userspace (only applicable
           for nfnetlink_log). nfnetlink_log instances  may  specify  their
           own range, this option overrides it.

    --nflog-threshold size
           Number of packets to queue inside the kernel before sending them
           to userspace (only applicable for nfnetlink_log). Higher  values
           result in less overhead per packet, but increase delay until the
           packets reach userspace. The default value is 1.
Source: man page of iptables-extensions. iptables version 1.4.21 Licence: GPLv2

And the man page of the policy match module for iptables.

policy
    This modules matches the policy used by IPsec for handling a packet.

    --dir {in|out}
           Used  to  select  whether  to  match the policy used for decapsulation or the policy that will be used for encapsulation.  in is valid in the PREROUTING, INPUT and FORWARD
           chains, out is valid in the POSTROUTING, OUTPUT and FORWARD chains.

    --pol {none|ipsec}
           Matches if the packet is subject to IPsec processing. --pol none cannot be combined with --strict.

    --strict
           Selects whether to match the exact policy or match if any rule of the policy matches the given policy.

    For each policy element that is to be described, one can use one or more of the following options. When --strict is in effect, at least one must be used per element.

    [!] --reqid id
           Matches the reqid of the policy rule. The reqid can be specified with setkey(8) using unique:id as level.

    [!] --spi spi
           Matches the SPI of the SA.

    [!] --proto {ah|esp|ipcomp}
           Matches the encapsulation protocol.

    [!] --mode {tunnel|transport}
           Matches the encapsulation mode.

    [!] --tunnel-src addr[/mask]
           Matches the source end-point address of a tunnel mode SA.  Only valid with --mode tunnel.

    [!] --tunnel-dst addr[/mask]
           Matches the destination end-point address of a tunnel mode SA.  Only valid with --mode tunnel.

    --next Start the next element in the policy specification. Can only be used with --strict.
Source: manpage of iptables-extensions. iptables version 1.4.21 Licence: GPLv2

Examples

The following rules use nflog group 5. Adjust the value for whatever group you're using.

ingress IPsec and IKE Traffic rule

iptables -t filter -I INPUT -p esp -j NFLOG --nflog-group 5
iptables -t filter -I INPUT -p ah -j NFLOG --nflog-group 5
iptables -t filter -I INPUT -p udp -m multiport --dports 500,4500 -j NFLOG --nflog-group 5

egress IPsec and IKE traffic

iptables -t filter -I OUTPUT -p esp -j NFLOG --nflog-group 5
iptables -t filter -I OUTPUT -p ah -j NFLOG --nflog-group 5
iptables -t filter -I OUTPUT -p udp -m multiport --dports 500,4500 -j NFLOG --nflog-group 5

decapsulated IPsec traffic

iptables -t mangle -I PREROUTING -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5
iptables -t mangle -I POSTROUTING -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5

IPsec traffic that is destinated for the local host (iptables INPUT chain)

iptables -t filter -I INPUT -m addrtype --dst-type LOCAL -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5

IPsec traffic that is destinated for a remote host (iptables FORWARD chain)

iptables -t filter -I INPUT -m addrtype ! --dst-type LOCAL -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5

IPsec traffic that is outgoing (iptables OUTPUT chain)

iptables -t filter -I OUTPUT -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5

Getting the traffic

tcpdump -s 0 -n -i nflog:5

Or use Wireshark. The nflog group appears in the interface list.

Special case: libipsec

If you're using libipsec, then simply make tcpdump listen on the tun interface to get decapsulated traffic.
If you want IKE and the IPsec traffic, just listen on the interface that is used to communicate with the peers.

Decrypting IKE/ESP traffic in Wireshark

It is possible to configure encryption and authenticaton keys in Wireshark in order to decrypt and
verify IKE and ESP traffic. However, it depends on the Wireshark version how well this works.
For instance, to decrypt ISAKMP (IKEv1) traffic only 3DES was supported until 1.12.0, which added
support for AES. Similarly, versions before 1.10.9 only supported ISAKMP with PSK authentication.

The IKE encryption and authentication keys can be extracted from the log if the log level is
increased to 4 for the ike subsystem (when using IKEv1 look for SKEYID_, or Ka to get the final
encryption key, with IKEv2 look for Sk_). The ESP keys are logged on level 4 in the chd subsystem,
but they can also be extracted via ip xfrm state.

To debug IKEv2 it is also possible to use NULL encryption via the openssl plugin.