You need to be root to do the kind of snooping that tcpflow and tcpdump do. So you either need
sudo or a setuid root wrapper.
Well, technically all you need the
CAP_NET_RAW capability. If you install the
libcap2-bin package¹, you can use the
setcap command to create a “setcap-
CAP_NET_RAW” wrapper around
tcpflow, rather than a setuid wrapper. But that only helps make a security hole in the wrapper be a little less damaging (a user who obtains
CAP_NET_RAW access can probably gain root with little effort).
You can use
sudo or a setuid root wrapper to let user1 run a command like
tcpflow -i eth0 tcp and \( src host 184.108.40.206 and src port 3000 or dst host 220.127.116.11 and src port 3000 \). Note that you can't just let user1 run an arbitrary
tcpflow command: that would allow user1 to run things like
tcpflow -r … -r /path/to/foo and read (at least partially)
/path/to/foo with root permissions.
I don't think you'll be decently able to allow the user to specify an expression to match packets. Rather than give extra permissions to run
tcpflow, I suggest giving extra permissions to run a fixed
tcpdump command (writing to stdout, let the user redirect into a file if necessary). Then the user can run
tcpflow -r to analyze
tcpdump output (even in real time, through a pipe).
lo, allow user1 to run this exact command:
tcpdump -i lo tcp
For other interfaces, I think the following command selects tcp ports 3000–3999 (but make extensive tests to be sure):
tcpdump -i eth0 tcp and \( \
\( src host 18.104.22.168 and 'tcp[0:2] >= 3000' and 'tcp[0:2] <= 3999' \) or
\( dst host 22.214.171.124 and 'tcp[2:2] >= 3000' and 'tcp[2:2] <= 3999' \) \)
Replace 126.96.36.199 by the IP address associated with the interface. I don't have a good solution to offer if the IP address isn't fixed: if you read it from
ifconfig output or otherwise at the beginning of the wrapper script, it's open to a race condition.
My recommendation for a wrapper is not to use a shell script (I don't know if any of the shells in Debian is suitable for writing setuid scripts — shells tend to use a lot of environment variables), but rather Perl (where this kind of thing is explicitly supported), like this:
exec '/usr/sbin/tmpdump', '-i', 'lo', 'tcp'
Make the script an ordinary executable (mode 755), and allow user1 to run it through sudo.
For other Linux distributions: you need kernel 2.6.24 or above and the