9

I have two network segments connected using a IPSEC-VPN tunnel :

  • NET#1: a.b.0.0/16 with LAN gateway a.b.0.1
  • NET#2: x.y.0.0/16 with LAN gateway x.y.130.1

I initiate a ping from a.b.0.1 to x.y.130.100 and started a tcpdump. This later shows echo replies packets but it doesn't show echo request packets.

Is it normal? How can I get the echo request packets too?

Here is a sample tests session:

The PING:

# ping x.y.130.100
PING x.y.130.100 56(84) bytes of data.
64 bytes from x.y.130.100: icmp_seq=1 ttl=63 time=1.87 ms
64 bytes from x.y.130.100: icmp_seq=2 ttl=63 time=1.38 ms
64 bytes from x.y.130.100: icmp_seq=3 ttl=63 time=1.27 ms
64 bytes from x.y.130.100: icmp_seq=4 ttl=63 time=3.93 ms
64 bytes from x.y.130.100: icmp_seq=5 ttl=63 time=1.15 ms
64 bytes from x.y.130.100: icmp_seq=6 ttl=63 time=1.16 ms

The TCPDUMP:

# tcpdump -nn 'icmp and (src a.b.0.1 or dst a.b.0.1)'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:54:27.607103 IP x.y.130.100 > a.b.0.1: ICMP echo reply, id 22607, seq 1, length 64
13:54:28.608433 IP x.y.130.100 > a.b.0.1: ICMP echo reply, id 22607, seq 2, length 64
13:54:29.610167 IP x.y.130.100 > a.b.0.1: ICMP echo reply, id 22607, seq 3, length 64
13:54:30.614716 IP x.y.130.100 > a.b.0.1: ICMP echo reply, id 22607, seq 4, length 64
13:54:31.613417 IP x.y.130.100 > a.b.0.1: ICMP echo reply, id 22607, seq 5, length 64
13:54:32.615054 IP x.y.130.100 > a.b.0.1: ICMP echo reply, id 22607, seq 6, length 64
Younes
  • 233
  • 2
  • 6

2 Answers2

15

This answer assumes Linux as OS.

The output cannot be captured as plaintext by tcpdump: it's already encrypted before tcpdump has a chance to see it and its icmp filter will not match. The input, which arrives encrypted is looped back as plaintext payload: tcpdump captures both, but its icmp filter will match on the second passage.

The Packet flow in Netfilter and General Networking gives clues about this (you'll have to click for details):

Packet flow in Netfilter and General Networking

on the right side (output):

  • plaintext packet reaches xfrm lookup and is looped back as encrypted payload through xfrm encode

  • tcpdump captures later the final result at AF_PACKET. This doesn't match ICMP, nothing will be displayed by the filter

on the left side (input):

  • the encrypted payload arrives and is captured at AF_PACKET by tcpdump: this doesn't match an ICMP and won't be displayed
  • the packet reaches xfrm/socket lookup and undergoes decoding through xfrm decode
  • the now decoded plaintext payload is specifically sent through AF_PACKET: this time tcpdump will see an ICMP packet
  • the plaintext payload follows the now usual routing

Actually in some cases (when IPSec compression is enabled and the packet is a short packet) there can be yet-an-other loop with the intermediate internal packet as ipip protocol.

If you want to get the outgoing traffic, here are some suggestions:

  • you'll have to add something like or esp, but of course it won't be decoded, unless a proper -E option with the adequate secrets is set (which I wouldn't know much about). I don't know if tcpdump can also decode NAT-T (udp port 4500) this way.
  • use iptables or nftables to duplicate packets to a dummy interface. tcpdump can capture on this interface instead.
  • use iptables or nftables to log entire packets to the nflog facility. tcpdump can capture on this pseudo-interface instead.
A.B
  • 11,090
  • 2
  • 24
  • 45
  • 1
    Many thanks @A.B. Everything is clear now in my head. I'm using strongswan and its wiki explains very well the third solution proposed by A.B. Here is the link: https://wiki.strongswan.org/projects/strongswan/wiki/CorrectTrafficDump. – Younes Nov 11 '20 at 17:16
2

Is there a chance that the replies are going out on a different interface (perhaps one for IPSec?) from the one (eth0) that you are running tcpdump on?

JamesHannah
  • 1,731
  • 2
  • 11
  • 24
  • 1
    No, it doesn't. I have run `tcpdump -i eth1 -nn` and I got nothing. I have `lo`, `eth0` and `eth1` interfaces and `eth1` is the one that holds `a.b.0.0/16`. – Younes Nov 11 '20 at 14:28