dump tcp connections without tcpdump
On a centos box, I like to dump tcp connections - I would like to see if a server tries to send requests to a certain IP. Usually tcpdump would do the trick - but tcpdump is not installed, and installing software is not an option (because of company policy). I am afraid netstat will not show me a single request.
So I was wondering what other options I have. I do have root access on the server.
Solution 1:
Surely you have python
?
from socket import *
from struct import unpack
import sys
INTERFACE = "eth0"
TARGET = "8.8.8.8"
if __name__ == "__main__":
sock = socket(AF_PACKET, SOCK_DGRAM, 0x0800)
sock.bind((INTERFACE, 0x0800))
while True:
data = sock.recvfrom(1500, 0)[0]
ip = inet_ntop(AF_INET, data[12:16])
if ip == TARGET:
print "GOT TARGET"
sys.exit(1)
This will exit with "GOT TARGET" providing the IP address coming back matches. Since TCP has to send something back during a handshake, this should catch anything from a specific target address. It doesn't care if the protocol is TCP or UDP though (nor do I check).
Dont forget to change TARGET and INTERFACE.
Solution 2:
I'd really try to get tcpdump. That being said, some alternatives to see if a certain connection exists for an IP are:
strace:
[kbrandt@ny-kbrandt01: ~] strace -e trace=network nc 1.2.3.4 1234
...
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("1.2.3.4")}, 16) = -1 EINPROGRESS (Operation now in progress)
lsof:
[kbrandt@ny-kbrandt01: ~] nc 1.2.3.4 1234 &
[1] 11434
[kbrandt@ny-kbrandt01: ~] lsof -p 11434
....
nc 11434 kbrandt 3u IPv4 4543149 0t0 TCP 10.7.0.78:58886->1.2.3.4:search-agent (SYN_SENT)
netstat:
[kbrandt@ny-kbrandt01: ~] nc 1.2.3.4 1234 &
[1] 11486
[kbrandt@ny-kbrandt01: ~] sudo netstat -a -p | grep 11486
tcp 0 1 10.7.0.78:58891 1.2.3.4:search-agent SYN_SENT 11486/nc
Solution 3:
Iptables has a debug capability and that can be used for traffic analysis too.
The solution is described on the URL below.
Debugging rules in Iptables
It's also worth reading the following URL to set up the logging of trace output to a file of your choice.
http://backreference.org/2010/06/11/iptables-debugging/
I would not consider this solution equal to tcpdump, but it can be done using a minimal install of Centos. You need to be careful not to fill up the disk with the logs, because tcpdump is much more efficient in disk use. Turn off the logging when it is not required.
You can use the following as a basic template in your script.
# Logging
log(){
SOURCE=a.b.c.d (IP address)
$IPT -A INPUT -s $SOURCE -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "In: "
$IPT -A OUTPUT -s $SOURCE -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "Out: "
$IPT -A FORWARD -s $SOURCE -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "Fw: "
$IPT -t nat -A POSTROUTING -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "Nat: "
}
#log (remove comment to enable)
trace(){
iptables -t raw -A PREROUTING -p tcp -j TRACE
iptables -t raw -A OUTPUT -p tcp -j TRACE
}
#trace (remove comment to enable)