ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Termux 非 root 环境下 sudo 与 FakeRoot 配置实战指南

Termux 非 root 环境下 sudo 与 FakeRoot 配置实战指南 安卓手机上折腾 Linux 环境这件事Termux 算是目前最省心的入口。但很多人装完 Termux、跑起 Ubuntu 或者 Kali 之后第一个卡住的地方不是网络、不是源而是——为什么我执行 sudo 它说找不到命令为什么我 su 之后提示权限拒绝明明在电脑上敲sudo apt install顺得不行到了手机上就处处碰壁。这篇就来把这件事讲透在不 root 手机的前提下怎么让 Termux 里的 sudo 真正能用FakeRoot 到底做了什么以及配置过程中那些文档里不会写的坑。先说结论省得你带着错误预期往下看Termux 里的 sudo 不是真正的 root 提权它是一层模拟身份的包装。你的手机系统分区依然是只读的你动不了/system也改不了内核参数。但在 Termux 自己的 PRoot 容器里你可以拥有一个看起来像 root的身份能装包、能改文件属主、能跑那些检测 root 的脚本。理解这个边界后面所有操作你都不会迷惑。1. 先搞清楚 Termux 里root到底是什么东西1.1 安卓的权限模型和桌面 Linux 的根本差异桌面 Linux 上root 是内核层面承认的超级用户UID 为 0拥有绕过一切 DAC 检查的能力。安卓虽然内核也是 Linux但它的权限体系被改造成了应用沙箱 SELinux的双层结构。每个 App 跑在自己的 UID 下互相隔离普通应用连别的应用的数据目录都读不到。你从应用商店装的 Termux本质上就是一个普通 App它的 UID 是类似u0_a123这样的普通用户它根本没有能力去调用真正的 setuid 提权。这就是为什么你在 Termux 里敲su要么提示su: command not found要么提示权限拒绝。不是你没装对是这条路在非 root 设备上从系统层面就被堵死了。很多人第一次遇到这个会去搜Termux 怎么 root然后被引到一堆刷机、解锁 Bootloader 的教程上那完全是另一回事风险也高得多。1.2 PRoot 提供的伪 root能力边界Termux 生态里真正让普通用户能玩转 Linux 发行版的是PRoot。它的原理是用ptrace系统调用拦截程序发出的系统调用把路径、UID 这些信息在用户态做一层翻译。比如你在 PRoot 容器里是 root程序调用getuid()返回 0调用chown看起来成功了但实际上这些操作都被 PRoot 重定向到了容器内的虚拟文件系统里碰不到真实的系统分区。所以 PRoot 给你的 root 是容器内的 root能力范围仅限容器内部。这既是限制也是安全边界——你不可能因为玩 Termux 把手机搞砖。FakeRoot 就是在这个基础上进一步把我是 root这个身份伪装做得更完整让那些会主动检测 root 的程序也认账。1.3 为什么有些命令在 PRoot 里看起来成功了这里有个反直觉的点值得单独说。你在 PRoot 里执行chown root:root somefile它不报错ls -l一看属主真的变成 root 了。但如果你退出容器在 Termux 原生环境里看同一个文件属主还是你原来的普通用户。原因就是 PRoot 维护了一套映射表容器内看到的元数据是它伪造出来的。理解这一点非常关键你在容器里做的权限操作只在容器生命周期内、容器视角下有效。一旦容器销毁或者你从外部访问这些root 痕迹就消失了。所以别指望用这种方式去改手机系统里的东西那是不可能的。2. FakeRoot 到底解决了哪些实际问题2.1 那些检测到非 root 就罢工的脚本有一类工具和安装脚本开头就写一句if [ $(id -u) ! 0 ]; then echo 请用 root 运行; exit 1; fi。你在 Termux 里跑直接就被拦下了。这类检测在渗透测试工具、某些服务端软件的安装脚本里特别常见。FakeRoot 的核心价值之一就是让id -u返回 0骗过这类前置检查。但要注意骗过检查不等于功能真的能用。有些脚本检测完 root 之后接下来会去操作/etc下的真实系统配置或者绑定 1024 以下的特权端口。前者在 PRoot 里会被重定向到容器内的/etc没问题后者则要看 PRoot 有没有做端口映射很多时候是失败的。所以 FakeRoot 能解决入口检查问题但解决不了底层特权操作问题这个区分要拎清。2.2 包管理器对 root 身份的依赖apt、dpkg这类包管理器在安装软件时需要写入/var/lib/dpkg、/usr/bin这些目录并且会检查当前用户是否有权限。在 PRoot 容器里如果你不是 root 身份apt install会报一堆权限错误。把容器内的身份切成 root这些操作就顺畅了。这也是为什么很多人装完 Ubuntu 容器后第一件事就是proot-distro login ubuntu默认进去就是 root。但如果你用的是某些精简镜像或者手动配置的容器默认用户可能不是 root这时候就需要 FakeRoot 来补上这一环。2.3 文件属主和权限位的实际影响开发过程中经常遇到的情况从电脑传过来的项目文件属主是某个特定 UID在容器里跑构建脚本时因为属主不对导致失败。或者某个程序硬性要求配置文件权限是600且属主为 root。这些场景下FakeRoot 配合 PRoot 的映射能力能让你在容器内把这些元数据摆平。我自己的经验是做 Python 项目时遇到过pip因为缓存目录属主问题报错切到 root 身份后重装就好了。这类问题不致命但很烦FakeRoot 能省下不少排查时间。3. 从零配置 FakeRoot 的完整操作链路3.1 环境准备Termux 基础配置不能省动手之前先把 Termux 的基础环境弄利索。第一步是换源默认源在国内访问经常超时termux-change-repo执行后会弹出选择界面选一个国内镜像比如清华或中科大。换完源执行pkg update pkg upgrade -y这一步别偷懒很多后续报错都是因为包版本太旧。然后装核心依赖pkg install proot proot-distro git curl -yproot是底层工具proot-distro是管理发行版容器的高层封装两个都要。装完之后proot-distro list能看到支持的发行版列表。提示Termux 从 Google Play 装的版本已经停止更新建议从 F-Droid 或者官方 GitHub Release 获取。版本差异会导致部分命令行为不一致这个坑我踩过。3.2 安装一个带 root 身份的发行版容器以 Ubuntu 为例proot-distro install ubuntu装完之后登录proot-distro login ubuntu默认情况下proot-distro登录进去就是 root 身份whoami返回root。如果你只是想用 sudo 命令到这里其实已经能用了——因为你就是 root不需要 sudo。但很多人的需求是以普通用户身份登录需要时用 sudo 提权这就涉及到下一步的配置。3.3 在容器内创建普通用户并配置 sudo先装 sudoapt update apt install sudo -y创建普通用户假设叫 devuseradd -m -s /bin/bash dev passwd dev把 dev 加入 sudo 组usermod -aG sudo dev这时候退出容器用指定用户重新登录proot-distro login ubuntu --user dev进去之后whoami是 dev执行sudo apt update会提示输入密码。输入你刚设的密码命令就能跑。这就是最干净的普通用户 sudo方案不需要 FakeRoot 做额外伪装因为 PRoot 本身已经把容器内的权限体系搭好了。3.4 FakeRoot 的介入时机和配置方式那 FakeRoot 什么时候用主要两种情况一是你用的容器默认用户不是 root且没有 sudo 可用二是某些程序在 PRoot 环境下id -u检测异常需要额外伪装。FakeRoot 本质上是一个编译好的libfakeroot.so通过LD_PRELOAD注入拦截getuid、getgid、stat等函数调用返回伪造的 root 身份。配置方式pkg install fakeroot -y然后在需要伪装的环境里fakeroot -- bash进入这个 bash 后id -u返回 0whoami返回 root。但注意fakeroot 的伪装只对通过它启动的进程树有效而且它伪造的是文件操作看起来是 root 做的对真正的权限检查比如能不能写某个系统文件没有帮助。我实测下来fakeroot 在 Termux 原生环境里跑一些打包脚本比如dpkg-deb --build特别有用因为打包过程需要设置文件属主为 rootfakeroot 能让这个操作看起来成功。4. 配置过程中最容易翻车的几个点4.1 换源之后 update 报错 GPG 签名问题换源后第一次pkg update有时会报GPG error或者NO_PUBKEY。这不是源坏了是密钥没同步。解决办法pkg install gnupg -y apt-key update如果还不行把$PREFIX/etc/apt/sources.list里的源地址检查一遍确认没有拼写错误。我遇到过把mirrors.tuna写成mirror.tuna的情况排查了半小时。4.2 proot-distro login 卡住或黑屏登录容器时卡在[rootlocalhost ~]#之前不动或者进去之后终端没反应。常见原因有三个一是容器没装完整重装一次二是 Termux 的存储权限没给执行termux-setup-storage授权三是终端模拟器的问题换个终端 App 试试。还有一种情况是登录后执行图形程序黑屏那是 X11 转发没配好跟 sudo 无关需要额外装termux-x11或者 VNC。这个坑很多人会混淆以为是权限问题。4.3 sudo 提示 a terminal is required这个报错长这样sudo: a terminal is required to read the password原因是 sudo 需要交互式终端输入密码但当前环境没有分配 TTY。解决办法有两个一是用sudo -S从标准输入读密码二是配置免密码。免密码配置echo dev ALL(ALL) NOPASSWD:ALL /etc/sudoers或者更规范地visudo在文件末尾加上面那行。改 sudoers 一定要用 visudo它会做语法检查直接编辑文件写错了会导致 sudo 彻底不可用那时候就只能靠 root 身份进去救了。4.4 容器内改了 root 密码却登录不上有人在容器里执行passwd root改了密码然后退出重登发现进不去。这是因为proot-distro login默认不走密码验证它直接以 root 身份进入密码改了也不影响登录逻辑。如果你是用su root切换那密码才生效。搞清楚你用的是哪种登录方式别自己把自己绕进去。5. 几个真实场景下的实操验证5.1 跑一个检测 root 的安装脚本拿一个典型的检测脚本测试。写个check.sh#!/bin/bash if [ $(id -u) ! 0 ]; then echo 需要 root 权限 exit 1 fi echo root 检查通过在普通用户下执行输出需要 root 权限。用sudo bash check.sh执行输出root 检查通过。这说明 sudo 提权后id -u确实返回 0检测被绕过。5.2 验证文件属主操作的实际效果在容器内以 root 身份touch /tmp/testfile chown root:root /tmp/testfile ls -l /tmp/testfile看到属主是 root。然后退出容器在 Termux 原生环境找这个文件路径在$PREFIX/var/lib/proot-distro/installed-rootfs/ubuntu/tmp/testfilels -l一看属主是 Termux 的普通用户。这直接证明了 PRoot 的映射是容器内视角的伪造非常有教育意义。5.3 免密码 sudo 的完整验证配置完 NOPASSWD 后执行sudo -k sudo whoamisudo -k是清掉之前缓存的凭证强制下次重新验证。如果配置正确第二条命令直接返回 root不提示输密码。这个验证步骤很重要能确认你的 sudoers 配置真的生效了而不是靠之前缓存的凭证蒙混过关。6. 关于真 root和伪 root的取舍建议6.1 什么需求必须真 rootTermux 满足不了有些操作是 PRoot 和 FakeRoot 无论如何都做不到的修改系统分区文件、调整内核参数、访问其他 App 的私有数据、绑定特权端口部分情况、加载内核模块。如果你的需求落在这几类里那 Termux 方案直接出局得考虑其他路径。我见过有人想在 Termux 里改 hosts 文件做本地域名映射结果发现改的是容器内的 hosts对手机系统网络栈没影响。这种预期错位很常见动手前先想清楚你的操作作用在哪一层。6.2 大多数开发和学习场景伪 root 完全够用反过来说学 Linux 命令、跑 Python/Node 项目、搭本地数据库、做网络编程练习、玩渗透测试工具在授权环境下这些场景 PRoot 容器 sudo 完全能覆盖。你获得的是一个隔离、可销毁、不影响手机系统的实验环境这比真 root 更安全也更省心。6.3 性能和维护成本的现实考量PRoot 因为要拦截系统调用性能有损耗大概比原生慢 10% 到 30%跑重 IO 的任务会明显。另外容器文件系统占空间装几个发行版几个 G 就没了。维护上容器出问题最省事的办法往往是删了重装所以重要数据别只放容器里做好备份。7. 一些文档里不会写的经验配置 sudoers 的时候永远用visudo而不是直接vim /etc/sudoers。我有一次手快直接编辑多打了个字符结果 sudo 直接报语法错误罢工最后是靠proot-distro login ubuntu以 root 身份进去才修好。visudo 会在保存时做语法校验写错了会提示你这个保护机制能救命。关于密码容器内的 root 密码和 sudo 密码是两套东西。passwd root改的是 root 账户密码passwd dev改的是 dev 账户密码sudo 验证用的是当前用户的密码也就是 dev 的密码不是 root 密码。这个混淆点新手特别容易搞错输半天 root 密码发现不对。还有一点Termux 的会话在后台被系统杀掉后容器内的进程也会一起没。如果你在容器里跑着长任务记得用tmux或者nohup挂起来不然切个 App 回来发现任务没了白跑。装 tmux 很简单pkg install tmux -y然后tmux new -s work开一个会话CtrlB然后D脱离tmux attach -t work回来。最后说个存储路径的事。容器内的文件实际存在$PREFIX/var/lib/proot-distro/installed-rootfs/发行版名/下面想从 Termux 原生环境访问容器文件直接去这个路径找。反过来想把手机存储里的文件给容器用先termux-setup-storage然后在容器里访问/sdcard或者通过--bind参数挂载。这个双向访问的路径关系理清楚了传文件就不用靠scp绕圈子了。
返回列表