From: tom <tom@t0mb.net>
To: Joris Dobbelsteen <Joris@familiedobbelsteen.nl>
Cc: netfilter@lists.netfilter.org
Subject: Re: Traffic auditing per user
Date: Sun, 10 Dec 2006 14:52:10 +0000 [thread overview]
Message-ID: <457C1F1A.6070201@t0mb.net> (raw)
In-Reply-To: <73427AD314CC364C8DF0FFF9C4D693FF544D@nehemiah.joris2k.local>
/proc/net/tcp and udp both have a column for the UID of any particular
connection. The last column is the inode of the socket, and you can
resolve this to a prticular program by searching through all the
/proc/[0-9]+/fd/ folders. There will be symbolic links to sockets and
one of them will have the inode. Here's an example from /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt
uid timeout inode
7: CAF01B52:CD14 5DC20B55:1A0B 01 00000000:00000000 02:000855AB 00000000
666 0 11007 2 f6780a00 815 40 30 2 100
as you can see, my UID is 666
I wrote this code for a netstat plugin for an app i'm working on. (it's
python btw)
def get_connections(self):
temp_inodes = {}
cdict = {}
try:
procnettcp_f = open('/proc/net/tcp')
except IOError:
raise
procnettcp_f.readline()
while 1:
cdict = {}
line = procnettcp_f.readline()
if line == '': break
spline = line.split()
inode = spline[9]
[lhost, lport] = spline[1].split(':', 1)
[rhost, rport] = spline[2].split(':', 1)
status = spline[3]
if int(status,16) == 0x01:
cdict['status'] = "ESTABLISHED"
elif int(status,16) == 0x0A:
cdict['status'] = "LISTENING"
elif int(status, 16) == 0x100:
cdict['status'] = "WAITING"
else:
cdict['status'] = '-'
continue
lhost = int(lhost, 16)
rhost = int(rhost, 16)
cdict['lport'] = str(int(lport,16))
cdict['rport'] = str(int(rport,16))
cdict['lhost'] = ".".join(map(str,(lhost & 0xff, (lhost >> 8) & 0xff,
(lhost >> 16) & 0xff, (lhost >> 24) & 0xff)))
cdict['rhost'] = ".".join(map(str,(rhost & 0xff, (rhost >> 8) & 0xff,
(rhost >> 16) & 0xff, (rhost >> 24) & 0xff)))
temp_inodes[inode] = cdict
for iknowd, pid, prog_name in self.resolve_inodes(temp_inodes):
temp_inodes[iknowd]['pid'] = pid
temp_inodes[iknowd]['prog_name'] = prog_name
print temp_inodes
return temp_inodes
def resolve_inodes(self, inodes):
for file in glob.glob('/proc/[0-9]*/fd/*'):
try:
fdno = os.readlink(file)
if fdno[0:8] == 'socket:[':
this_inode = fdno[8:-1]
if this_inode in inodes:
pid = file.split('/')[2]
try:
pid_status = open(''.join(['/proc/', pid, '/status']))
name = pid_status.readline().split()[-1].rstrip()
pid_status.close()
except IOError:
name = '?'
yield this_inode, pid, name
except os.error:
pass
This code doesn't do anything with the UID, but it's there in
/proc/net/tcp, so easy to get to. I don't think netfilter itself really
has what you're looking for. Hope this helps you out. Another thing
worth mentioning actually is /proc/net/ip_conntrack, which has lines
like. This would be useful in conjunction with the corresponding lines
from /proc/net/tcp etc...
tcp 6 431482 ESTABLISHED src=82.27.240.202 dst=213.171.192.50
sport=34571 dport=143 packets=274 bytes=15668 src=213.171.192.50
dst=82.27.240.202 sport=143 dport=34571 packets=268 bytes=153509
[ASSURED] mark=0 use=1
Joris Dobbelsteen wrote:
> I'm looking for a solution to audit network traffic usage per user.
> After a long enough search I was not able to find a solution that suited
> my needs.
>
> It must fit the following requirements:
> * The traffic must be logged on a uid basis.
> * Some traffic should not be counted, which is protocol (i.e. non-IP)
> and IP address based (i.e. no local network).
> * Of course not have a dramatic effect on performance
>
> Hopefully its not to hard for me, thus the tool has some (decent)
> instructions/documentation.
> Further I want to keep using my stock application. The platform is
> Ubuntu 6.06 LTS, and I prefer to have the packages from the
> repositories, rather than my own complications. Mostly for reasons of
> testing and maintenance.
>
> I would guess this is not directly a netfilter question, but it should
> be close enough.
>
> - Joris
>
>
next prev parent reply other threads:[~2006-12-10 14:52 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-03 23:11 Traffic auditing per user Joris Dobbelsteen
2006-12-10 14:52 ` tom [this message]
-- strict thread matches above, loose matches on Subject: below --
2006-12-12 16:55 Joris Dobbelsteen
2006-12-12 23:42 ` tom
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=457C1F1A.6070201@t0mb.net \
--to=tom@t0mb.net \
--cc=Joris@familiedobbelsteen.nl \
--cc=netfilter@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.