Linux的Capabilities机制可以对root身份进行更加精细的控制。在研究tcpdump如何在android上运行时,遇到了一个难题:You don't have permission to capture on that device,(socket: Operation not permitted)
,可是我明明已经把tcpdump文件权限设置成了777,按道理不应该出现这个问题。后来查到,tcpdump运行时需要捕获网络数据包,这个权限默认只有root用户才有,用libcap工具可以让普通用户也能访问到网络数据包。
还有一个工具叫libpcap,差一个字母,但是这两个工具的用途完全不一样。libcap才是管理权限的
那么问题来了,android平台把libcap阉割掉了,只能用libcap源码自己编译,下面简单描述下怎么编译libcap可执行文件
第一步:下载NDK,用 Android Studio 的 SDK Manager 可以下载,比较方便
第二步:下载源码,Elder-Wu/libcap-for-android。这个项目是从kernel-googlesource-libcapfork过来的。并添加了几个文件。/libcap/Android.mk(这个mk生成libcap.so)、/progs/Android.mk(这个mk生成setcap和getcap等可执行文件),根目录的Android.mk(引用另外两个mk文件)。还有一个Application.mk,是用来配置参数的。至于其他的makefile,不是android平台要考虑的,可以忽略。根目录的build.sh用来启动编译。在kernel-googlesource-libcap的基础上多了这5个文件,可以查看代码提交记录。一般情况下,直接用编译好的文件,避免麻烦。想要最新的文件,就自己去下载kernel-googlesource-libcap的源码然后根据代码提交记录迁移那5个文件。
第三步:编译生成可执行文件。找到根目录的build.sh脚本,把里面的NDK_BUILD填写一下,比如:~/Library/Android/sdk/ndk/28.0.12433566/ndk-build
,保存并执行build.sh。需要注意的是,下载的NDK是什么平台的,就要在什么平台编译。举个例子,我最开始下载了macos的NDK,但是我又开了个unbuntu-docker容器,在unbuntu里面用macos的NDK编译源码,一直报错Unknown host CPU architecture: aarch64
其实就是NDK和系统不匹配导致的。
运行可能会报错
➜ ~/Downloads/test2/libcap-for-Android git:(master) ✗ ./build.sh
[arm64-v8a] Compile : cap <= cap_alloc.c
In file included from libcap/cap_alloc.c:8:
libcap/libcap.h:27:10: fatal error: 'cap_names.h' file not found
27 | #include "cap_names.h"
| ^~~~~~~~~~~~~
1 error generated.
make: *** [~/Library/Android/sdk/ndk/28.0.12433566/build/core/build-binary.mk:421: obj/local/arm64-v8a/objs/cap/cap_alloc.o] Error 1
执行build.sh之前要先执行一下make命令,忽略报错。
编译后产生几个可执行文件和1个so库,so库放到android系统里/system/lib或/system/lib64,根据你的系统来。如果系统的lib目录里已经有了对应的so库,做好备份
相关指令:
# 设置权限
./setcap cap_dac_override,cap_net_raw,cap_net_admin=eip /system/bin/tcpdump
# 查看权限
./getcap /system/bin/tcpdump
相关资料:
- https://askubuntu.com/questions/530920/tcpdump-permissions-problem
- https://web.archive.org/web/20160403142820/http://peternixon.net/news/2012/01/28/configure-tcpdump-work-non-root-user-opensuse-using-file-system-capabilities/
- https://stackoverflow.com/questions/4566435/how-to-get-libcap-linux-capabilities-library-for-android