==========
tunnel.log
==========

The purpose of Zeek’s :file:`tunnel.log` is to identify encapsulated traffic. A
common use case in modern networks involves encapsulating IPv6 traffic within
IPv4. It’s also entirely possible to tunnel IPv4 over IPv6. This document will
provide a few examples of how Zeek interprets tunneled traffic.

For full details on each field in the :file:`tunnel.log` file, please refer to
:zeek:see:`Tunnel::Info`.

Teredo
======

The following example demonstrates Teredo traffic generated by a Microsoft game
console. Teredo is an encapsulation protocol whereby IPv4 carries IPv6 traffic.

https://learn.microsoft.com/en-us/windows/win32/teredo/portal

:program:`tcpdump` and :program:`tshark`
----------------------------------------

Here is :program:`tcpdump` output for the traffic in question::

  00:55:58.290539 IP 192.168.4.31.3074 > 40.84.25.61.65444: UDP, length 61
  00:55:59.321945 IP 192.168.4.31.3074 > 40.84.25.61.3544: UDP, length 61
  00:55:59.337323 IP 40.84.25.61.3544 > 192.168.4.31.3074: UDP, length 109

Here is :program:`tshark` output for the traffic in question::

    1 192.168.4.31 3074 40.84.25.61  65444 UDP 103 3074 → 65444 Len=61
    2 fe80::ffff:ffff:fffe 3074 ff02::2      3544 ICMPv6 103 Router Solicitation
    3 fe80::8000:f227:d7ab:e6c3 3544 fe80::ffff:ffff:fffe 3074 ICMPv6 151 Router Advertisement

Notice that :program:`tshark` shows frames 2 and 3 as IPv6, whereas
:program:`tcpdump` shows them as IPv4.

Let’s take a closer look at frame 2 to see the encapsulation in detail:

.. literal-emph::

  Frame 2: 103 bytes on wire (824 bits), 103 bytes captured (824 bits)
      Encapsulation type: Ethernet (1)
      Arrival Time: Dec 15, 2020 00:55:59.321945000 UTC
      [Time shift for this packet: 0.000000000 seconds]
      Epoch Time: 1607993759.321945000 seconds
      [Time delta from previous captured frame: 1.031406000 seconds]
      [Time delta from previous displayed frame: 1.031406000 seconds]
      [Time since reference or first frame: 1.031406000 seconds]
      Frame Number: 2
      Frame Length: 103 bytes (824 bits)
      Capture Length: 103 bytes (824 bits)
      [Frame is marked: False]
      [Frame is ignored: False]
      [Protocols in frame: eth:ethertype:ip:udp:teredo:ipv6:icmpv6]
  Ethernet II, Src: bc:83:85:56:2f:67, Dst: fc:ec:da:49:e0:10
      Destination: fc:ec:da:49:e0:10
          Address: fc:ec:da:49:e0:10
          .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
          .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
      Source: bc:83:85:56:2f:67
          Address: bc:83:85:56:2f:67
          .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
          .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
      Type: IPv4 (0x0800)
  **Internet Protocol Version 4, Src: 192.168.4.31, Dst: 40.84.25.61**
      0100 .... = Version: 4
      .... 0101 = Header Length: 20 bytes (5)
      Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
          0000 00.. = Differentiated Services Codepoint: Default (0)
          .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      Total Length: 89
      Identification: 0xbb91 (48017)
      Flags: 0x0000
          0... .... .... .... = Reserved bit: Not set
          .0.. .... .... .... = Don't fragment: Not set
          ..0. .... .... .... = More fragments: Not set
          ...0 0000 0000 0000 = Fragment offset: 0
      Time to live: 128
      Protocol: UDP (17)
      Header checksum: 0x78aa [validation disabled]
      [Header checksum status: Unverified]
      Source: 192.168.4.31
      Destination: 40.84.25.61
  **User Datagram Protocol, Src Port: 3074, Dst Port: 3544**
      Source Port: 3074
      Destination Port: 3544
      Length: 69
      Checksum: 0x7fdc [unverified]
      [Checksum Status: Unverified]
      [Stream index: 1]
  **Teredo IPv6 over UDP tunneling**
      Teredo Authentication header
          Client identifier length: 0
          Authentication value length: 0
          Nonce value: 6aeec3b128884291
          Confirmation byte: 00
  **Internet Protocol Version 6, Src: fe80::ffff:ffff:fffe, Dst: ff02::2**
      **0110 .... = Version: 6**
      .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT)
          .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0)
          .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
      Payload Length: 8
      Next Header: ICMPv6 (58)
      Hop Limit: 255
      Source: fe80::ffff:ffff:fffe
      Destination: ff02::2
  **Internet Control Message Protocol v6**
      Type: Router Solicitation (133)
      Code: 0
      Checksum: 0x7d38 [correct]
      [Checksum Status: Good]
      Reserved: 00000000

The bolded elements show an ICMPv6 message inside an IPv6 packet, inside a UDP
datagram, inside a IPv4 packet. Frame 3 is similar.

:file:`conn.log`
----------------

The :file:`conn.log` for this traffic contains the following:

.. literal-emph::

  {
    "ts": 1607993759.321945,
    **"uid": "CO9T0A3FPac5ig4hud",**
    **"id.orig_h": "192.168.4.31",**
    "id.orig_p": 3074,
    **"id.resp_h": "40.84.25.61",**
    **"id.resp_p": 3544,**
    **"proto": "udp",**
    **"service": "teredo",**
    "duration": 0.015377998352050781,
    "orig_bytes": 61,
    "resp_bytes": 109,
    "conn_state": "SF",
    "missed_bytes": 0,
    "history": "Dd",
    "orig_pkts": 1,
    "orig_ip_bytes": 89,
    "resp_pkts": 1,
    "resp_ip_bytes": 137,
    "ip_proto": 17
  }

This first :file:`conn.log` entry addresses frames 2 and 3 in the original packet
capture. Zeek identifies Teredo as the service within a UDP datagram. Port 3544
UDP appears to be associated with Teredo per Microsoft’s documentation. Port
3074 UDP appears to be associated with Microsoft game consoles as well, perhaps
due to NAT traversal. Note the ``uid`` field. It will appear again
shortly.

.. literal-emph::

  {
    "ts": 1607993758.290539,
    **"uid": "CUqiKk4m6VpWwcaJ4l",**
    **"id.orig_h": "192.168.4.31",**
    "id.orig_p": 3074,
    **"id.resp_h": "40.84.25.61",**
    **"id.resp_p": 65444,**
    **"proto": "udp",**
    "conn_state": "S0",
    "missed_bytes": 0,
    "history": "D",
    "orig_pkts": 1,
    "orig_ip_bytes": 89,
    "resp_pkts": 0,
    "resp_ip_bytes": 0,
    "ip_proto": 17
  }

This second :file:`conn.log` entry refers to frame 1 in the packet capture.
Note the ``uid`` field. It will appear again shortly as well.

.. literal-emph::

  {
    "ts": 1607993759.321945,
    "uid": "CoiibpW4Ov0n1xvj",
    **"id.orig_h": "fe80::ffff:ffff:fffe",**
    "id.orig_p": 133,
    **"id.resp_h": "ff02::2",**
    "id.resp_p": 134,
    **"proto": "icmp",**
    "conn_state": "OTH",
    "missed_bytes": 0,
    "orig_pkts": 1,
    "orig_ip_bytes": 48,
    "resp_pkts": 0,
    "resp_ip_bytes": 0,
    "tunnel_parents": [
      **"CO9T0A3FPac5ig4hud"**
    ],
    "ip_proto": 1
  }

Here Zeek has created a new :file:`conn.log` entry for the ICMPv6 traffic
carried within a tunnel. The UID of the original connection carrying this
traffic appears in the ``tunnel_parents`` field. It refers to the first entry
in the :file:`conn.log`.

.. literal-emph::

  {
    "ts": 1607993758.290539,
    "uid": "C6Gikx4eC6wXR3xOqg",
    **"id.orig_h": "fe80::8000:ffff:ffff:fffe",**
    "id.orig_p": 133,
    **"id.resp_h": "ff02::2",**
    "id.resp_p": 134,
    **"proto": "icmp",**
    "conn_state": "OTH",
    "missed_bytes": 0,
    "orig_pkts": 1,
    "orig_ip_bytes": 48,
    "resp_pkts": 0,
    "resp_ip_bytes": 0,
    "tunnel_parents": [
      "CUqiKk4m6VpWwcaJ4l"
    ]
  }

Similar to the previous :file:`conn.log` entry, here is another tunneled ICMPv6
message. This corresponds to the second :file:`conn.log` entry reviewed earlier.

.. literal-emph::

  {
    "ts": 1607993759.337323,
    "uid": "C8h2gZ3EjWUW5xKh2",
    **"id.orig_h": "fe80::8000:f227:d7ab:e6c3",**
    "id.orig_p": 134,
    **"id.resp_h": "fe80::ffff:ffff:fffe",**
    "id.resp_p": 133,
    **"proto": "icmp",**
    "conn_state": "OTH",
    "missed_bytes": 0,
    "orig_pkts": 1,
    "orig_ip_bytes": 88,
    "resp_pkts": 0,
    "resp_ip_bytes": 0,
    "tunnel_parents": [
      **"CO9T0A3FPac5ig4hud"**
    ]
  }

Zeek creates a final :file:`conn.log` entry for tunneled traffic. This also
corresponds to the first :file:`conn.log` entry by virtue of its
``tunnel_parent`` value.

:file:`tunnel.log`
------------------

Zeek’s :file:`tunnel.log` offers the following entries for this encapsulated
traffic.

.. literal-emph::

  {
    "ts": 1607993758.290539,
    "uid": "CUqiKk4m6VpWwcaJ4l",
    "id.orig_h": "192.168.4.31",
    "id.orig_p": 3074,
    "id.resp_h": "40.84.25.61",
    "id.resp_p": 65444,
    **"tunnel_type": "Tunnel::TEREDO",**
    **"action": "Tunnel::DISCOVER"**
  }
  {
    "ts": 1607993759.321945,
    "uid": "CO9T0A3FPac5ig4hud",
    "id.orig_h": "192.168.4.31",
    "id.orig_p": 3074,
    "id.resp_h": "40.84.25.61",
    "id.resp_p": 3544,
    **"tunnel_type": "Tunnel::TEREDO",**
    **"action": "Tunnel::DISCOVER"**
  }
  {
    "ts": 1607993759.337323,
    "uid": "CO9T0A3FPac5ig4hud",
    "id.orig_h": "192.168.4.31",
    "id.orig_p": 3074,
    "id.resp_h": "40.84.25.61",
    "id.resp_p": 3544,
    **"tunnel_type": "Tunnel::TEREDO",**
    **"action": "Tunnel::CLOSE"**
  }
  {
    "ts": 1607993759.337323,
    "uid": "CUqiKk4m6VpWwcaJ4l",
    "id.orig_h": "192.168.4.31",
    "id.orig_p": 3074,
    "id.resp_h": "40.84.25.61",
    "id.resp_p": 65444,
    **"tunnel_type": "Tunnel::TEREDO",**
    **"action": "Tunnel::CLOSE"**
  }

The ``action`` messages indicate how Zeek is tracking the connections. When it
first identifies a tunnel, it reports ``DISCOVER``. When it assesses that the
tunnel is no longer used, Zeek reports ``CLOSE``.

The take-away from this activity is that Zeek has identified Teredo traffic.
The :file:`tunnel.log` entries abstract the somewhat complicated detailed logs
and produce results that are a bit
friendlier to the analyst. Here we see that the systems involved are opening
and closing Teredo tunnels. If this is not authorized traffic, it is enough to
begin a more detailed investigation.

IP in IP
========

The next example shows transporting IPv4 inside IPv4 traffic. :rfc:`1853` states:

  “The IP in IP encapsulation Protocol/Payload number 4 :rfc:`1700` has long
  been used to bridge portions of the Internet which have disjoint capabilities
  or policies.”

This is another encapsulation method that might surprise an analyst
or network administrator, assuming it is not authorized for use.

:program:`tcpdump` and :program:`tshark`
----------------------------------------

Here is :program:`tcpdump`’s view of the sample traffic:

.. literal-emph::

  12:12:06.059907 **IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request**, id 4, seq 0, length 80 (ipip-proto-4)
  12:12:06.067958 **IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply**, id 4, seq 0, length 80 (ipip-proto-4)
  12:12:06.075906 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 1, length 80 (ipip-proto-4)
  12:12:06.083920 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 1, length 80 (ipip-proto-4)
  12:12:06.091909 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 2, length 80 (ipip-proto-4)
  12:12:06.099922 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 2, length 80 (ipip-proto-4)
  12:12:06.107906 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 3, length 80 (ipip-proto-4)
  12:12:06.116057 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 3, length 80 (ipip-proto-4)
  12:12:06.123910 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 4, length 80 (ipip-proto-4)
  12:12:06.131919 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 4, length 80 (ipip-proto-4)

Here is :program:`tshark`’s view of the first packet:

.. literal-emph::

  Frame 1: 134 bytes on wire (1072 bits), 134 bytes captured (1072 bits)
      Encapsulation type: Ethernet (1)
      Arrival Time: Jun 21, 2008 12:12:06.059907000 UTC
      [Time shift for this packet: 0.000000000 seconds]
      Epoch Time: 1214050326.059907000 seconds
      [Time delta from previous captured frame: 0.000000000 seconds]
      [Time delta from previous displayed frame: 0.000000000 seconds]
      [Time since reference or first frame: 0.000000000 seconds]
      Frame Number: 1
      Frame Length: 134 bytes (1072 bits)
      Capture Length: 134 bytes (1072 bits)
      [Frame is marked: False]
      [Frame is ignored: False]
      [Protocols in frame: eth:ethertype:ip:ip:icmp:data]
  Ethernet II, Src: c2:00:57:75:00:00, Dst: c2:01:57:75:00:00
      Destination: c2:01:57:75:00:00
          Address: c2:01:57:75:00:00
          .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
          .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
      Source: c2:00:57:75:00:00
          Address: c2:00:57:75:00:00
          .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
          .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
      Type: IPv4 (0x0800)
  **Internet Protocol Version 4, Src: 10.0.0.1, Dst: 10.0.0.2**
      0100 .... = Version: 4
      .... 0101 = Header Length: 20 bytes (5)
      Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
          0000 00.. = Differentiated Services Codepoint: Default (0)
          .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      Total Length: 120
      Identification: 0x0014 (20)
      Flags: 0x0000
          0... .... .... .... = Reserved bit: Not set
          .0.. .... .... .... = Don't fragment: Not set
          ..0. .... .... .... = More fragments: Not set
          ...0 0000 0000 0000 = Fragment offset: 0
      Time to live: 255
      Protocol: IPIP (4)
      Header checksum: 0xa76b [validation disabled]
      [Header checksum status: Unverified]
      Source: 10.0.0.1
      Destination: 10.0.0.2
  **Internet Protocol Version 4, Src: 1.1.1.1, Dst: 2.2.2.2**
      0100 .... = Version: 4
      .... 0101 = Header Length: 20 bytes (5)
      Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
          0000 00.. = Differentiated Services Codepoint: Default (0)
          .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      Total Length: 100
      Identification: 0x0014 (20)
      Flags: 0x0000
          0... .... .... .... = Reserved bit: Not set
          .0.. .... .... .... = Don't fragment: Not set
          ..0. .... .... .... = More fragments: Not set
          ...0 0000 0000 0000 = Fragment offset: 0
      Time to live: 255
      **Protocol: ICMP (1)**
      Header checksum: 0xb57f [validation disabled]
      [Header checksum status: Unverified]
      Source: 1.1.1.1
      Destination: 2.2.2.2
  **Internet Control Message Protocol**
      Type: 8 (Echo (ping) request)
      Code: 0
      Checksum: 0x4305 [correct]
      [Checksum Status: Good]
      Identifier (BE): 4 (0x0004)
      Identifier (LE): 1024 (0x0400)
      Sequence number (BE): 0 (0x0000)
      Sequence number (LE): 0 (0x0000)
      Data (72 bytes)

  0000  00 00 00 00 00 09 3b 38 ab cd ab cd ab cd ab cd   ......;8........
  0010  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
  0020  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
  0030  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
  0040  ab cd ab cd ab cd ab cd                           ........
          Data: 0000000000093b38abcdabcdabcdabcdabcdabcdabcdabcd...
          [Length: 72]

Note that both renditions depict the outer and inner IP addresses in use, as
well as the encapsulated ICMP traffic.

:file:`conn.log`
----------------

Zeek creates a single :file:`conn.log` entry for this traffic.

.. literal-emph::

  {
    "ts": 1214050326.059907,
    "uid": "CaG4lb2HwGhNGLo1d2",
    **"id.orig_h": "1.1.1.1",**
    "id.orig_p": 8,
    **"id.resp_h": "2.2.2.2",**
    "id.resp_p": 0,
    **"proto": "icmp",**
    "duration": 0.07201194763183594,
    "orig_bytes": 360,
    "resp_bytes": 360,
    "conn_state": "OTH",
    "missed_bytes": 0,
    "orig_pkts": 5,
    "orig_ip_bytes": 500,
    "resp_pkts": 5,
    "resp_ip_bytes": 500,
    **"tunnel_parents": [**
      **"CllZAw139PBBVBawlj"**
    ]
  }

Notice the only :file:`conn.log` entry lists the encapsulated source and
destination IP addresses for the traffic, i.e., ``1.1.1.1`` and ``2.2.2.2``. To
see the outer IP addresses, we need to look for the ``tunnel_parents``
connection in the :file:`tunnel.log`.

:file:`tunnel.log`
------------------

The :file:`tunnel.log` also contains a single entry:

.. literal-emph::

  {
    "ts": 1214050326.059907,
    "uid": "CllZAw139PBBVBawlj",
    **"id.orig_h": "10.0.0.1",**
    "id.orig_p": 0,
    **"id.resp_h": "10.0.0.2",**
    "id.resp_p": 0,
    **"tunnel_type": "Tunnel::IP",**
    **"action": "Tunnel::DISCOVER"**
  }

Here we learn that the outer IP addresses are ``10.0.0.1`` and ``10.0.0.2``.
The tunnel type is ``IP``. The action of ``Tunnel::DISCOVER`` means that Zeek
has identified a new tunnel or encapsulation.

IP over IP via GRE
==================

Let’s look at a more common variation of IP within IP. This method uses Generic
Routing Encapsulation, or GRE.

:program:`tcpdump` and :program:`tshark`
----------------------------------------

Here is :program:`tcpdump`’s view of the traffic:

.. literal-emph::

  12:06:06.434897 **IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request**, id 2, seq 0, length 80
  12:06:06.442931 **IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply**, id 2, seq 0, length 80
  12:06:06.450900 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 1, length 80
  12:06:06.498938 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 1, length 80
  12:06:06.506904 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 2, length 80
  12:06:06.514914 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 2, length 80
  12:06:06.522905 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 3, length 80
  12:06:06.570925 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 3, length 80
  12:06:06.578905 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 4, length 80
  12:06:06.586923 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 4, length 80

Here is :program:`tshark`’s view of the first packet:

.. literal-emph::

  Frame 1: 138 bytes on wire (1104 bits), 138 bytes captured (1104 bits)
      Encapsulation type: Ethernet (1)
      Arrival Time: Jun 21, 2008 12:06:06.434897000 UTC
      [Time shift for this packet: 0.000000000 seconds]
      Epoch Time: 1214049966.434897000 seconds
      [Time delta from previous captured frame: 0.000000000 seconds]
      [Time delta from previous displayed frame: 0.000000000 seconds]
      [Time since reference or first frame: 0.000000000 seconds]
      Frame Number: 1
      Frame Length: 138 bytes (1104 bits)
      Capture Length: 138 bytes (1104 bits)
      [Frame is marked: False]
      [Frame is ignored: False]
      [Protocols in frame: eth:ethertype:ip:gre:ip:icmp:data]
  Ethernet II, Src: c2:00:57:75:00:00, Dst: c2:01:57:75:00:00
      Destination: c2:01:57:75:00:00
          Address: c2:01:57:75:00:00
          .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
          .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
      Source: c2:00:57:75:00:00
          Address: c2:00:57:75:00:00
          .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
          .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
      Type: IPv4 (0x0800)
  **Internet Protocol Version 4, Src: 10.0.0.1, Dst: 10.0.0.2**
      0100 .... = Version: 4
      .... 0101 = Header Length: 20 bytes (5)
      Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
          0000 00.. = Differentiated Services Codepoint: Default (0)
          .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      Total Length: 124
      Identification: 0x000a (10)
      Flags: 0x0000
          0... .... .... .... = Reserved bit: Not set
          .0.. .... .... .... = Don't fragment: Not set
          ..0. .... .... .... = More fragments: Not set
          ...0 0000 0000 0000 = Fragment offset: 0
      Time to live: 255
      Protocol: Generic Routing Encapsulation (47)
      Header checksum: 0xa746 [validation disabled]
      [Header checksum status: Unverified]
      Source: 10.0.0.1
      Destination: 10.0.0.2
  **Generic Routing Encapsulation (IP)**
      Flags and Version: 0x0000
          0... .... .... .... = Checksum Bit: No
          .0.. .... .... .... = Routing Bit: No
          ..0. .... .... .... = Key Bit: No
          ...0 .... .... .... = Sequence Number Bit: No
          .... 0... .... .... = Strict Source Route Bit: No
          .... .000 .... .... = Recursion control: 0
          .... .... 0000 0... = Flags (Reserved): 0
          .... .... .... .000 = Version: GRE (0)
      Protocol Type: IP (0x0800)
  **Internet Protocol Version 4, Src: 1.1.1.1, Dst: 2.2.2.2**
      0100 .... = Version: 4
      .... 0101 = Header Length: 20 bytes (5)
      Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
          0000 00.. = Differentiated Services Codepoint: Default (0)
          .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      Total Length: 100
      Identification: 0x000a (10)
      Flags: 0x0000
          0... .... .... .... = Reserved bit: Not set
          .0.. .... .... .... = Don't fragment: Not set
          ..0. .... .... .... = More fragments: Not set
          ...0 0000 0000 0000 = Fragment offset: 0
      Time to live: 255
      Protocol: ICMP (1)
      Header checksum: 0xb589 [validation disabled]
      [Header checksum status: Unverified]
      Source: 1.1.1.1
      Destination: 2.2.2.2
  **Internet Control Message Protocol**
      Type: 8 (Echo (ping) request)
      Code: 0
      Checksum: 0xbfd4 [correct]
      [Checksum Status: Good]
      Identifier (BE): 2 (0x0002)
      Identifier (LE): 512 (0x0200)
      Sequence number (BE): 0 (0x0000)
      Sequence number (LE): 0 (0x0000)
      Data (72 bytes)

  0000  00 00 00 00 00 03 be 70 ab cd ab cd ab cd ab cd   .......p........
  0010  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
  0020  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
  0030  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
  0040  ab cd ab cd ab cd ab cd                           ........
          Data: 000000000003be70abcdabcdabcdabcdabcdabcdabcdabcd...
          [Length: 72]

Note that both renditions depict the outer and inner IP addresses in use, as
well as the encapsulated ICMP traffic. This time, in contrast with the previous
example, the inner traffic follows a GRE header.

:file:`conn.log`
----------------

Zeek creates a single :file:`conn.log` entry for this traffic:

.. literal-emph::

  {
    "ts": 1214049966.434897,
    "uid": "Cxg76d2N73I9DhmZ5l",
    **"id.orig_h": "1.1.1.1",**
    "id.orig_p": 8,
    **"id.resp_h": "2.2.2.2",**
    "id.resp_p": 0,
    **"proto": "icmp",**
    "duration": 0.15202593803405762,
    "orig_bytes": 360,
    "resp_bytes": 360,
    "conn_state": "OTH",
    "missed_bytes": 0,
    "orig_pkts": 5,
    "orig_ip_bytes": 500,
    "resp_pkts": 5,
    "resp_ip_bytes": 500,
    "tunnel_parents": [
      **"C2ELkSIprfG0oMEae"**
    ]
  }

As with the previous example, the only :file:`conn.log` entry lists the encapsulated
source and destination IP addresses for the traffic, i.e., ``1.1.1.1`` and
``2.2.2.2``.  To see the outer IP addresses, we need to look for the
``tunnel_parents`` connection in the :file:`tunnel.log`.

:file:`tunnel.log`
------------------

The :file:`tunnel.log` also contains a single entry:

.. literal-emph::

  {
    "ts": 1214049966.434897,
    "uid": "C2ELkSIprfG0oMEae",
    **"id.orig_h": "10.0.0.1",**
    "id.orig_p": 0,
    **"id.resp_h": "10.0.0.2",**
    "id.resp_p": 0,
    **"tunnel_type": "Tunnel::GRE",**
    **"action": "Tunnel::DISCOVER"**
  }

We see again that the outer IP addresses are ``10.0.0.1`` and ``10.0.0.2``. The
tunnel type is ``GRE``, unlike the previous ``IP``. The action of
``Tunnel::DISCOVER`` means that Zeek has identified a new tunnel or
encapsulation.

IPv4 in PPP in GRE in IPv4 in IPv6
==================================

We’ve saved the most complicated example for last.

In this example, we see the following very complicated protocol stack::

  Ethernet II
  802.1Q virtual LAN (VLAN)
  IPv6
  IPv4
  GRE
  Point-to-Point Protocol (PPP)
  IPv4
  UDP
  Domain Name System

I am not sure what created this trace, although I suspect it may be from a
mobile asset.

:program:`tcpdump` and :program:`tshark`
----------------------------------------

Here is :program:`tcpdump`’s view of the sample traffic::

  03:35:03.821897 IP6 2402:f000:1:8e01::5555 > 2607:fcd0:100:2300::b108:2a6b: IP 16.0.0.200 > 192.52.166.154: GREv1, call 6016, seq 430001, ack 539254, length 119: IP 172.16.44.3.40768 > 8.8.8.8.53: 42540+ AAAA? xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678. (71)

  03:35:04.035791 IP6 2607:fcd0:100:2300::b108:2a6b > 2402:f000:1:8e01::5555: IP 192.52.166.154 > 16.0.0.200: GREv1, call 17, seq 539320, length 190: IP 8.8.8.8.53 > 172.16.44.3.40768: 42540 NXDomain 0/1/0 (146)

Here is :program:`tshark`’s view of the first packet:

.. literal-emph::

  Frame 1: 197 bytes on wire (1576 bits), 197 bytes captured (1576 bits)
      Encapsulation type: Ethernet (1)
      Arrival Time: Dec  3, 2014 03:35:03.821897000 UTC
      [Time shift for this packet: 0.000000000 seconds]
      Epoch Time: 1417577703.821897000 seconds
      [Time delta from previous captured frame: 0.000000000 seconds]
      [Time delta from previous displayed frame: 0.000000000 seconds]
      [Time since reference or first frame: 0.000000000 seconds]
      Frame Number: 1
      Frame Length: 197 bytes (1576 bits)
      Capture Length: 197 bytes (1576 bits)
      [Frame is marked: False]
      [Frame is ignored: False]
      [Protocols in frame: eth:ethertype:vlan:ethertype:ipv6:ip:gre:ppp:ip:udp:dns]
  **Ethernet II, Src: 00:12:1e:f2:61:3d, Dst: c5:00:00:00:82:c4**
      Destination: c5:00:00:00:82:c4
          Address: c5:00:00:00:82:c4
          .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
          .... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast)
      Source: 00:12:1e:f2:61:3d
          Address: 00:12:1e:f2:61:3d
          .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
          .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
      Type: 802.1Q Virtual LAN (0x8100)
  **802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 100**
      000. .... .... .... = Priority: Best Effort (default) (0)
      ...0 .... .... .... = DEI: Ineligible
      .... 0000 0110 0100 = ID: 100
      Type: IPv6 (0x86dd)
  **Internet Protocol Version 6, Src: 2402:f000:1:8e01::5555, Dst: 2607:fcd0:100:2300::b108:2a6b**
      0110 .... = Version: 6
      .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT)
          .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0)
          .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
      Payload Length: 139
      Next Header: IPIP (4)
      Hop Limit: 246
      Source: 2402:f000:1:8e01::5555
      Destination: 2607:fcd0:100:2300::b108:2a6b
  **Internet Protocol Version 4, Src: 16.0.0.200, Dst: 192.52.166.154**
      0100 .... = Version: 4
      .... 0101 = Header Length: 20 bytes (5)
      Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
          0000 00.. = Differentiated Services Codepoint: Default (0)
          .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      Total Length: 139
      Identification: 0x8caf (36015)
      Flags: 0x0000
          0... .... .... .... = Reserved bit: Not set
          .0.. .... .... .... = Don't fragment: Not set
          ..0. .... .... .... = More fragments: Not set
          ...0 0000 0000 0000 = Fragment offset: 0
      Time to live: 64
      **Protocol: Generic Routing Encapsulation (47)**
      Header checksum: 0x75fe [validation disabled]
      [Header checksum status: Unverified]
      Source: 16.0.0.200
      Destination: 192.52.166.154
  Generic Routing Encapsulation (PPP)
      Flags and Version: 0x3081
          0... .... .... .... = Checksum Bit: No
          .0.. .... .... .... = Routing Bit: No
          ..1. .... .... .... = Key Bit: Yes
          ...1 .... .... .... = Sequence Number Bit: Yes
          .... 0... .... .... = Strict Source Route Bit: No
          .... .000 .... .... = Recursion control: 0
          .... .... 1... .... = Acknowledgment: Yes
          .... .... .000 0... = Flags (Reserved): 0
          .... .... .... .001 = Version: Enhanced GRE (1)
      Protocol Type: PPP (0x880b)
      Payload Length: 103
      Call ID: 6016
      Sequence Number: 430001
      Acknowledgment Number: 539254
  **Point-to-Point Protocol**
      Address: 0xff
      Control: 0x03
      Protocol: Internet Protocol version 4 (0x0021)
  **Internet Protocol Version 4, Src: 172.16.44.3, Dst: 8.8.8.8**
      0100 .... = Version: 4
      .... 0101 = Header Length: 20 bytes (5)
      Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
          0000 00.. = Differentiated Services Codepoint: Default (0)
          .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
      Total Length: 99
      Identification: 0x0000 (0)
      Flags: 0x4000, Don't fragment
          0... .... .... .... = Reserved bit: Not set
          .1.. .... .... .... = Don't fragment: Set
          ..0. .... .... .... = More fragments: Not set
          ...0 0000 0000 0000 = Fragment offset: 0
      Time to live: 60
      Protocol: UDP (17)
      Header checksum: 0x5667 [validation disabled]
      [Header checksum status: Unverified]
      Source: 172.16.44.3
      Destination: 8.8.8.8
  **User Datagram Protocol, Src Port: 40768, Dst Port: 53**
      Source Port: 40768
      Destination Port: 53
      Length: 79
      Checksum: 0x2d23 [unverified]
      [Checksum Status: Unverified]
      [Stream index: 0]
  **Domain Name System (query)**
      Transaction ID: 0xa62c
      Flags: 0x0100 Standard query
          0... .... .... .... = Response: Message is a query
          .000 0... .... .... = Opcode: Standard query (0)
          .... ..0. .... .... = Truncated: Message is not truncated
          .... ...1 .... .... = Recursion desired: Do query recursively
          .... .... .0.. .... = Z: reserved (0)
          .... .... ...0 .... = Non-authenticated data: Unacceptable
      Questions: 1
      Answer RRs: 0
      Authority RRs: 0
      Additional RRs: 0
      Queries
          xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678: type AAAA, class IN
              Name: xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678
              [Name Length: 53]
              [Label Count: 1]
              Type: AAAA (IPv6 Address) (28)
              Class: IN (0x0001)

Both :program:`tcpdump` and :program:`tshark` show the three levels of IP
addresses used in this complicated frame.

:file:`conn.log`
----------------

Let’s see what Zeek makes of this complicated exchange.

.. literal-emph::

  {
    "ts": 1417577703.821897,
    "uid": "CiJXLc43tlknoHbXH9",
    **"id.orig_h": "172.16.44.3",**
    "id.orig_p": 40768,
    **"id.resp_h": "8.8.8.8",**
    "id.resp_p": 53,
    "proto": "udp",
    "service": "dns",
    "duration": 0.21389389038085938,
    "orig_bytes": 71,
    "resp_bytes": 146,
    "conn_state": "SF",
    "missed_bytes": 0,
    "history": "Dd",
    "orig_pkts": 1,
    "orig_ip_bytes": 99,
    "resp_pkts": 1,
    "resp_ip_bytes": 174,
    **"tunnel_parents": [**
      **"CBvCtfO5sjjyQb2V4"**
    ]
  }

We see Zeek has burrowed all the way down to the innermost IP address,
``172.16.44.3``, making a DNS request to ``8.8.8.8``.

:file:`tunnel.log`
------------------

Zeek’s :file:`tunnel.log` contains two entries for this session.

.. literal-emph::

  {
    "ts": 1417577703.821897,
    "uid": "CPnYZx2edh7O2ueTm4",
    **"id.orig_h": "2402:f000:1:8e01::5555",**
    "id.orig_p": 0,
    **"id.resp_h": "2607:fcd0:100:2300::b108:2a6b",**
    "id.resp_p": 0,
    **"tunnel_type": "Tunnel::IP",**
    **"action": "Tunnel::DISCOVER"**
  }
  {
    "ts": 1417577703.821897,
    "uid": "CBvCtfO5sjjyQb2V4",
    **"id.orig_h": "16.0.0.200",**
    "id.orig_p": 0,
    **"id.resp_h": "192.52.166.154",**
    "id.resp_p": 0,
    **"tunnel_type": "Tunnel::GRE",**
    **"action": "Tunnel::DISCOVER"**
  }

Zeek displays the two outer IP addresses, and ties them to the inner address
using the ``uid`` field. The ``uid`` matches the ``tunnel_parents`` field in
the :file:`conn.log`.

:file:`dns.log`
---------------

For completeness, let’s take a look at the :file:`dns.log` Zeek created for
this activity.

.. literal-emph::

  {
    "ts": 1417577703.821897,
    "uid": "CiJXLc43tlknoHbXH9",
    **"id.orig_h": "172.16.44.3",**
    "id.orig_p": 40768,
    **"id.resp_h": "8.8.8.8",**
    **"id.resp_p": 53,**
    "proto": "udp",
    "trans_id": 42540,
    "query": "xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678",
    "qclass": 1,
    "qclass_name": "C_INTERNET",
    "qtype": 28,
    **"qtype_name": "AAAA",**
    "rcode": 3,
    "rcode_name": "NXDOMAIN",
    "AA": false,
    "TC": false,
    "RD": true,
    "RA": false,
    "Z": 0,
    "rejected": false
  }

Here is a AAAA query, meaning the client wants the IPv6 address for the domain
listed in the query. As you might guess, the DNS server reply (not shown here)
is for a root name server.

Conclusion
==========

Zeek’s :file:`tunnel.log` is a useful way to accomplish two tasks. First, the
presence of a :file:`tunnel.log` in your collection of Zeek outputs means Zeek
has detected and reported on encapsulated traffic. If you do not expect to see
such activity in your environment, it is worth investigating. Second, the
:file:`tunnel.log` provides a means to show the outermost IP addresses
associated with the activity reported in the :file:`conn.log` when
encapsulation is present.
