83

I've searched quite extensively for this, but cannot seem to come up with a working example.

My objective is to monitor TCP traffic on a specific port to see incoming connections and write them to a text file. The catch is I also need a timestamp on each row to show exactly when the client connected down to the second.

I've already exhausted netstat, nmap, and tcptrack, but none support timestamp.

I was thinking a linux shell script might work if I monitored a specific local port and wrote text to a file when a connection is made then just concatenate the date on each line.

I was playing with this:

netstat -ano|grep 443|grep ESTABLISHED

as well as this:

tcptrack -i eth0 port 443

but neither suit my needs as I need the time the connection comes in at.

If you have any suggestions or could point me in the right direction it would be greatly appreciated.

Thanks. :)

1
  • Haha migrated from stackoverflow but needs to migrate to unix/linux Sep 21, 2016 at 20:24

7 Answers 7

105

edit: I'm still getting upvotes for this years later. Please don't go for this answer, the answer using iptables here is far superior in my opinion.


tcpdump port 443 and '(tcp-syn|tcp-ack)!=0'

or only tcp-syn, or only tcp-ack (my guess would be that one), depending on what you need.

8
  • Instead of showing the hostname for each connection, is there a way to override it with the IP?
    – tajonny07
    Jun 7, 2013 at 16:20
  • Yep, add -n after tcpdump (man tcpdump: -n Don't convert addresses (i.e., host addresses, port numbers, etc.) to names.)
    – Wrikken
    Jun 8, 2013 at 0:33
  • 9
    I’d argue that spamming the kernel log isn’t really superior. ;)
    – Daniel B
    May 23, 2017 at 19:57
  • 1
    Ah, but I would, provided one properly configures where which logs should go of course :P But hey, this answer is still here if that's a deal breaker :)
    – Wrikken
    May 23, 2017 at 21:09
  • 6
    @Wrikken the problem with using the kernel log for this is that, using your solution when you ctrl+c out of tcpdump everything remains as before. The iptables solution means leaving a "surprise" behind if you don't remove the rule manually. This surprise can translate in having a full root disk in no time. Sorry, but I'm upvoting this (: Oct 30, 2018 at 14:40
55

You can use the iptables support in the Linux kernel for this. The upside is that it doesn't require any extra software to be moderately useful. The downside is that it requires root privileges to set up (but given that you are talking about port 443, which is a privileged port, you probably need root privileges with most solutions).

Add an iptables rule with something like:

sudo iptables -I INPUT -p tcp --dport 443 --syn -j LOG --log-prefix "HTTPS SYN: "

(Adjust the -I INPUT part to suit your taste.)

When the rule is triggered, a syslog entry will be emitted by the kernel. For example, with an input rule, the log entry may look something like:

Dec 5 09:10:56 hostname kernel: [1023963.185332] HTTPS SYN: IN=ifX OUT= MAC=80:80:80:80:80:80:80:80:80:80:80:80:08:00 SRC=A.B.C.D DST=W.X.Y.Z LEN=52 TOS=0x00 PREC=0x20 TTL=119 ID=11901 DF PROTO=TCP SPT=37287 DPT=443 WINDOW=8192 RES=0x00 SYN URGP=0

You can then use any run-of-the-mill log monitoring tool to do something useful with this information. If your syslog implementation supports it, you can even direct these into a separate log file, effectively fulfilling your requirement to write the connection data to a file timestamped to the second with no additional software.

Note that the LOG target is a non-terminating target, which means that any rules following it will still be evaluated, and the packet will not be either rejected or accepted by the LOG rule itself. This makes the LOG target useful also for debugging firewall rules.

To avoid flooding your log, consider using the limit module in conjunction with this. See the iptables(8) man page for details.

2
  • is it possible to execute a python script triggering this? Oct 26, 2018 at 14:56
  • 6
    Don't forget to delete these IP tables rules once you are done, otherwise they'll spam the logs quite heavily depending on the rule. digitalocean.com/community/tutorials/…
    – Mo Beigi
    Oct 20, 2019 at 14:35
35

Micro-Second Resolution

By default, the tcpdump utility will report time with micro-second resolution. For example:

$ sudo tcpdump -i any port 443

will show output similar to the following:

12:08:14.028945 IP localhost.33255 > localhost.https: Flags [S], seq 1828376761, win 43690, options [mss 65495,sackOK,TS val 108010971 ecr 0,nop,wscale 7], length 0
12:08:14.028959 IP localhost.https > localhost.33255: Flags [R.], seq 0, ack 1828376762, win 0, length 0

See tcpdump(8) for a full list of tcpdump options, and pcap-filter(7) for the complete syntax of the filters you can use.

5

443 is encrypted traffic - so difficult to make heads or tails of traffic on this port anyhow:

you can do

yum install ngrep or apt-get install ngrep

then run

ngrep -W byline -d any port 443 -q
3

You may require this also to monitor the incoming and outgoing packets from other machines.

tcpflow -i eth0 -c port 7891

(option -i for mentioning the network, option -c to print the packets in console)

1
1

You can use tcpdump or Wireshark.

0

If you need a permanent solution that will always monitor traffic on ports of interest, I suggest to use QoS (the tc command in linux). tc is a bit cryptic and undocumented, so I use FireQoS to setup QoS and netdata for real-time monitoring it.

Check this for more information: https://github.com/firehol/netdata/wiki/You-should-install-QoS-on-all-your-servers

2
  • I'd say this is a bit over kill simply for logging connections, where iPTables + --log will work. May 26, 2017 at 12:07
  • You are right, it is overkill if you need to log the connections. I use this solution not to monitor which clients connected, but how much bandwidth the service uses. May 26, 2017 at 15:12

You must log in to answer this question.