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