目前,我sudo tcpflow -i lo
必须根用户,我想将lo
接口授予TCP port range 3000-3999 of all interfaces
给用户1,该怎么做?
答案1
您需要以 root 身份执行 tcpflow 和 tcpdump 执行的监听操作。因此,您需要sudo
一个 setuid root 包装器。
好吧,从技术上讲,你只需要这个CAP_NET_RAW
功能。如果你安装libcap2-bin
包¹,您可以使用setcap
命令在 周围创建一个“setcap- CAP_NET_RAW
”包装器tcpflow
,而不是 setuid 包装器。但这只能帮助减少包装器中的安全漏洞造成的危害(获得CAP_NET_RAW
访问权限的用户可能可以轻松获得 root 权限)。
您可以使用sudo
或 setuid root 包装器让 user1 运行类似 的命令tcpflow -i eth0 tcp and \( src host 1.2.3.4 and src port 3000 or dst host 1.2.3.4 and src port 3000 \)
。请注意,您不能只让 user1 运行任意命令:这将允许 user1以 root 权限tcpflow
运行tcpflow -r … -r /path/to/foo
和读取(至少部分)之类的命令。/path/to/foo
我认为您无法让用户指定表达式来匹配数据包。tcpflow
我建议不要授予运行的额外权限,而是授予运行固定tcpdump
命令的额外权限(写入 stdout,让用户在必要时重定向到文件)。然后用户可以运行tcpflow -r
来分析tcpdump
输出(即使是实时的,通过管道)。
现在lo
,允许用户 1 运行此命令:
tcpdump -i lo tcp
对于其他接口,我认为以下命令选择 tcp 端口 3000–3999(但要进行大量测试以确保无误):
tcpdump -i eth0 tcp and \( \
\( src host 1.2.3.4 and 'tcp[0:2] >= 3000' and 'tcp[0:2] <= 3999' \) or
\( dst host 1.2.3.4 and 'tcp[2:2] >= 3000' and 'tcp[2:2] <= 3999' \) \)
将 1.2.3.4 替换为与接口关联的 IP 地址。如果 IP 地址不固定,我没有好的解决方案:如果您从ifconfig
输出或包装器脚本开头读取它,则容易出现竞争条件。
我对包装器的建议是不要使用 shell 脚本(我不知道 Debian 中是否有任何 shell 适合编写 setuid 脚本 — shell 往往会使用很多环境变量),而是使用 Perl(明确支持这种东西),如下所示:
#!/usr/bin/perl -T
exec '/usr/sbin/tmpdump', '-i', 'lo', 'tcp'
使脚本成为普通的可执行文件(模式 755),并允许用户 1 通过 sudo 运行它。
¹
对于其他 Linux 发行版:您需要内核 2.6.24 或更高版本和命令setcap
。