在 Android 上 chroot 一个 ArchLinux
https://haruue.moe/blog/2017/05/02/android-chroot-archlinux/
翻知乎看到初春静流的 这条回答 ,刚好手边有闲置的 Android 机,不妨来试试 chroot 。
创建 root 目录
首先手机必须破解了 root 权限,然后到 /data
下面建一个用作 rootfs 的目录,比如我用的是 /data/local/archlinux
。
获取合适的 ArchLinuxARM 镜像
虽然现在 ArchLinux 只对 x86_64 架构提供支持,但是有 ArchLinuxARM 项目对 arm 平台也提供了完善的支持,去源里找一个支持你手机平台的镜像,比如我用的是 ArchLinuxARM-odroid。
把镜像安装到手机
把镜像下载下来,解压到 /data/local/archlinux
,先别急着 chroot ,把必要的目录 rbind 过去
busybox mount --rbind /dev /data/local/archlinux/dev
busybox mount --rbind /sys /data/local/archlinux/sys
busybox mount --rbind /proc /data/local/archlinux/proc
busybox mount -t tmpfs tmpfs /data/local/archlinux/tmp
切换到 chroot 环境
现在就是切换到 chroot 环境的时候了,使用这条命令就好
chroot /data/local/archlinux bash
不出所料的话, bash 会出现在你的眼前。
联网
讲道理网络本来应该是配好的,不过 Android 内核有个蛋疼的网络权限机制,所以还需要做一些魔改
groupadd -g 3001 aid_bt
groupadd -g 3002 aid_bt_net
groupadd -g 3003 aid_inet
groupadd -g 3004 aid_net_raw
groupadd -g 3005 aid_admin
usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin root
newgrp aid_inet # 切换到 aid_inet 组,获取联网权限
然后是解析,Arch Linux 的网络和解析默认都是由 systemd 管着的,然而在 chroot 环境下,systemd 不能正常工作,所以手动设置一下吧。
rm /etc/resolv.conf # 先删掉之前的符号链接
echo 'nameserver ip.of.name.server' > /etc/resolv.conf
pacman
清华和科大都提供了 ArchLinuxARM 的开源镜像,把这两行放到 /etc/pacman.d/mirrorlist
顶上
Server = http://mirrors.ustc.edu.cn/archlinuxarm/$arch/$repo
Server = http://mirrors.tuna.tsinghua.edu.cn/archlinuxarm/$arch/$repo
然后配置 pacman 使用 curl 进行下载,在 /etc/pacman.conf
中取消注释下面一行
XferCommand = /usr/bin/curl -C - -f %u > %o
完成之后 pacman 应该就能正常工作了。
坑
服务
由于 systemd 在 chroot 环境下不能工作,所以需要使用 nohup
启动服务。
例如启动 sshd 服务使用
nohup /bin/sshd -D > sshd.log &
要提示没有 host key 就 gen 一个
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
用户与权限
大部分手机在挂载 /data 时使用了 nosuid ,比如我这部手机的
/dev/block/mmcblk0p21 /data ext4 rw,seclabel,nosuid,nodev,noatime,journal_checksum,journal_async_commit,noauto_da_alloc,data=ordered 0 0
这使得需要 suid 的东西都无法工作,比如 sudo ,要解决这个问题,有三种方案:
- 直接使用 root 用户,有需要时使用 sudo 降低权限(可能不安全)
- 把整个 rootfs 放到一个 img 文件里,然后挂载
-
在手机上使用 suid 选项重新挂载 /data
busybox mount -o remount,suid /data