1

I'm trying to use tcpdump to explore what on my computer talks with whom on the world wide web.

I've came this far as of yet:

lan_hosts="(hosts || to || exclude)"
local_hosts="(127.0.0.1 || ips_of_my_nics || localhost || local_hostname)"
excused_local_ports="(ssh || https || domain || $(netstat -ap | egrep -h '/(processes|I_dont|want|to_see|traffic_of)' | tr -s ' ' | cut -d ' ' -f 4 | rev | cut -d ':' -sf 1 | rev | sort | sed ':a; N; $!ba; s/\n/ \|\| /g'))"
tcpdump -vi any "ip && ! icmp && ! arp && (src ! $local_hosts || dst ! $local_hosts) && (src $local_hosts || dst $local_hosts) && (src ! $local_hosts || src port ! $excused_local_ports) && (dst ! $local_hosts || dst port ! $excused_local_ports) && host ! $lan_hosts"

Now the reason I'm posting this here as question: I don't understand why / how these packets still show up in the output:

tcpdump: listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
14:49:30.660109 IP (tos 0x0, ttl 64, id 23067, offset 0, flags [DF], proto UDP (17), length 71)
    localhost.38976 > localhost.domain: 26002+ [1au] A? lan_host.lan. (43)
14:49:30.686174 IP (tos 0x0, ttl 64, id 23110, offset 0, flags [DF], proto UDP (17), length 80)
    localhost.47181 > localhost.domain: 45895+ [1au] PTR? some_ip.in-addr.arpa. (52)
14:49:30.686219 IP (tos 0x0, ttl 64, id 2440, offset 0, flags [DF], proto UDP (17), length 103)
    localhost.domain > localhost.47181: 45895 1/0/1 some_ip.in-addr.arpa. PTR localhost. (75)

I thought that the segment (src ! $local_hosts || dst ! $local_hosts) of my filter declaration, which is only concatenated with && logic to other filter parts should exclude those? And even if I didn't have that part in the filter, they should again be excluded because of the inclusion of domain in my excused_local_ports variable.

Let's unpack the filter declaration a bit and try to explain what I wanted to achieve with each part:

  • ip -> only look at ipv4 packets, since this machine doesn't have an ipv6 path to the internet I am not concerned with ipv6 here.
  • ! icmp -> don't care about ping requests / replies and other icmp routing metadata.
  • ! arp -> filter out adress resolution protocol packets
  • (src ! $local_hosts || dst ! $local_hosts) -> hide packets of the localhost talking to itself
  • (src $local_hosts || dst $local_hosts) -> hide broadcasts from other hosts
  • (src ! $local_hosts || src port ! $excused_local_ports) -> hide packets my host has sent from one of the ports of the programs I don't want to look at right now.
  • (dst ! $local_hosts || dst port ! $excused_local_ports) -> hide packets my host has received on one of the ports of the programs I don't want to look at right now.
  • (host ! $lan_hosts) -> hide communication with the defined hosts
3
  • 1
    What is the actual commandline to tcpdump? The best way to filter out localhost is to only listen on the interfaces that is relevant, that is not lo - it is also related to performance.
    – NiKiZe
    Aug 17, 2021 at 9:24
  • It's the 4th line of my first code-block. The first 3 lines are extracted bash variables to make it a bit more readable. Yes I understand, but sadly it seems one can either look at a single interface, or at all of them at once. If I could I would just listen to the two that provide a path to the internet. But that would requiring running two separate tcpdump processes.
    – xogoxec344
    Aug 18, 2021 at 19:25
  • Dumping each interface should take less CPU, but will run in promiscuous mode.
    – NiKiZe
    Aug 18, 2021 at 19:52

0

You must log in to answer this question.