用手機Termux建立chroot Ubuntu 22.04環境

注意:需要Root權限。

緣由:Linux Deploy雖然介面直觀,但已經有點老舊,尤其是下載的發行版rootfs。預設下載腳本寫的不好容易斷線,一些細部設定也不是讓人很滿意。

因此拋棄Linux Deploy,直接使用Termux手動建立chroot環境吧。下面以Ubuntu 22.04為範例,建立一個帶有XFCE桌面環境的chroot,用VNC連線。

手機為Android 12版本的Sony Xperia 5 II。

1. Android 12安裝Busybox

Busybox仍然是必備工具,因為Termux在切換到su之後就會無法使用自身的套件,得安裝Busybox補齊基本的Linux工具。

鑑於Android 11以後對system分區嚴苛的限制,最好的方法是用Magisk模塊安裝。

  1. 安裝這個新版本Magisk模塊管理器:FoxMagisk Module Manager

  2. 從裡面搜尋"Builtn Busybox",安裝Magisk模塊,重開機。

2. 安裝Ubuntu chroot環境

Linux Deploy預設是把檔案系統存放成映像檔掛載,但這裡我們直接把Ubuntu的檔案系統解壓縮到適當的位置。

  1. 開啟Termux,安裝tsu和pulseaudio:
1
2
pkg update
pkg install tsu pulseaudio
  1. 切換到su,選擇/data/local/tmp這個目錄比較不會有權限問題。首先新增存放檔案系統的目錄:
1
2
3
su
mkdir /data/local/tmp/chrootubuntu
cd /data/local/tmp/chrootubuntu
  1. 下載最新Ubuntu 22.04 base檔案系統。你可以到Ubuntu官網查看每日建構的最新版本。
1
wget https://cdimage.ubuntu.com/ubuntu-base/releases/22.04/release/ubuntu-base-22.04-base-arm64.tar.gz
  1. 解壓縮,再新增一個當作掛載點的sdcard目錄
1
2
tar xpvf ubuntu-base-22.04-base-arm64.tar.gz --numeric-owner
mkdir sdcard
  1. 用vi在/data/local/tmp新增啟動chroot的腳本start.sh,填入以下內容。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
busybox mount --bind /dev /data/local/tmp/chrootubuntu/dev
busybox mount --bind /sys /data/local/tmp/chrootubuntu/sys
busybox mount --bind /proc /data/local/tmp/chrootubuntu/proc
busybox mount -t devpts devpts /data/local/tmp/chrootubuntu/dev/pts

# 將手機內部儲存空間掛載到chroot的/sdcard目錄
busybox mount --bind /sdcard /data/local/tmp/chrootubuntu/sdcard

# 進入chroot
busybox chroot /data/local/tmp/chrootubuntu /bin/su - root

# 退出chroot後自動取消掛載
busybox umount /data/local/tmp/chrootubuntu/dev/pts
busybox umount /data/local/tmp/chrootubuntu/dev
busybox umount /data/local/tmp/chrootubuntu/proc
busybox umount /data/local/tmp/chrootubuntu/sys
busybox umount /data/local/tmp/chrootubuntu/sdcard
  1. 賦予執行權限
1
chmod +x start.sh
  1. 進入chroot,這樣就可以開始安裝VNC server和SSH等服務了。此腳本在輸入exit之後會自動取消掛載目錄。如果退出後chroot行程沒有中止,那麼就強制停止Termux。
1
sh start.sh

3. 安裝常用軟體和桌面環境

在下載套件前,先修正DNS和新增本機名稱:

1
2
3
# 使用Google的DNS
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "127.0.0.1 localhost" > /etc/hosts

然後解決"Download is performed unsandboxed as root"警告,並讓root能存取Android的網路:

1
2
3
4
5
groupadd -g 3003 aid_inet
groupadd -g 3004 aid_net_raw
groupadd -g 1003 aid_graphics
usermod -g 3003 -G 3003,3004 -a _apt
usermod -G 3003 -a root

再來更新APT儲存庫:

1
2
apt update
apt upgrade

安裝常用工具:

1
apt install vim net-tools sudo git

3.1. 安裝SSH

  1. 安裝openSSH:
1
sudo apt install openssh-client openssh-server
  1. 啟動SSH server daemon:
1
2
mkdir /run/sshd
/usr/sbin/sshd -D &
  1. 手機的IP位址可以用以下指令查看:
1
ifconfig

3.2. 安裝XFCE4和VNC伺服器

  1. 安裝XFCE4:
1
2
3
apt install xfce4 xfce4-goodies
# 輸入XFCE終端機的號碼設定預設終端機
update-alternatives --config x-terminal-emulator
  1. 安裝VNC server:
1
apt install tigervnc-standalone-server tigervnc-xorg-extension
  1. 設定6位數字密碼:
1
vncpasswd
  1. 用vim編輯~/.vnc/xstartup,設定VNC啟動腳本:
1
2
3
4
5
6
7
#!/bin/bash
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADRESS
# 設定PulseAudio音效
export PULSE_SERVER=127.0.0.1 && pulseaudio --start --disable-shm=1 --exit-idle-time=-1
# 執行XFCE4
exec startxfce4
  1. 賦予執行權限
1
chmod +x ~/.vnc/xstartup
  1. 執行VNC server(注意螢幕上顯示的埠號),再使用AVNC新增localhost:5901進行連線。此外也可以用電腦的VNC Viewer進行區域連線。
1
vncserver -localhost no
  1. 如果終端機開不起來,試著重新掛載pts:
1
mount -t devpts devpts /dev/pts
  1. VNC server斷線後要記得關閉:
1
vncserver -kill :1

3.3. 設定PulseAudio

Termux本身有用PulseAudio → OpenGL ES發出音效的功能。

如果啟動VNC server後沒聲音,Termux左邊滑出來,開第二個終端機,在Termux(非chroot)執行以下指令。

1
2
pulseaudio --start --load="module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1" --exit-idle-time=-1
pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1

3.4. 新增一般使用者和中文化

  1. 設定時區為台灣台北
1
ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime
  1. 新增一般使用者並設定密碼
1
2
3
groupadd wheel
useradd -m -g users -G wheel,audio,video,storage -s /bin/bash ivon
passwd ivon
  1. 用vim編輯/etc/sudoers,在"root ALL=(ALL) ALL"的下一行加入以下內容:
1
ivon ALL=(ALL) ALL
  1. 一般使用者也要新增VNC server的設定檔,請參考上面root的設定方法。

  2. 安裝locales套件並產生正體中文:

1
2
apt install locales
locale-gen zh_TW.UTF-8
  1. 編輯/etc/environment,加入以下內容。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
LANG=zh_TW.UTF-8
LC_CTYPE="zh_TW.UTF-8"
LC_NUMERIC="zh_TW.UTF-8"
LC_TIME="zh_TW.UTF-8"
LC_COLLATE="zh_TW.UTF-8"
LC_MONETARY="zh_TW.UTF-8"
LC_MESSAGES="zh_TW.UTF-8"
LC_PAPER="zh_TW.UTF-8"
LC_NAME="zh_TW.UTF-8"
LC_ADDRESS="zh_TW.UTF-8"
LC_TELEPHONE="zh_TW.UTF-8"
LC_MEASUREMENT="zh_TW.UTF-8"
LC_IDENTIFICATION="zh_TW.UTF-8"
LC_ALL=
  1. 之後使用su ivon登入一般使用者。或者修改chroot的啟動腳本,將chroot . /bin/su - root改成chroot . /bin/su - ivon

3.5. 移除Snap和安裝瀏覽器

現在Ubuntu不論安裝Firefox還是Chrmoium都會重新導向到用Snap安裝,偏偏chroot環境Snap又跑不起來,所以只好將他封鎖了。

  1. 解除安裝Snap:
1
apt-get autopurge snapd
  1. 執行此指令防止以後自動安裝Snap,請一次全複製然後執行:
1
2
3
4
5
6
7
8
cat <<EOF | sudo tee /etc/apt/preferences.d/nosnap.pref
# To prevent repository packages from triggering the installation of Snap,
# this file forbids snapd from being installed by APT.
# For more information: https://linuxmint-user-guide.readthedocs.io/en/latest/snap.html
Package: snapd
Pin: release a=*
Pin-Priority: -10
EOF
  1. 移除Snap之後會有很多套件無法安裝,於是就只能額外取得deb檔來安裝。以Firefox來說,可以改從Mozilla官方軟體庫安裝:
1
2
3
sudo add-apt-repository ppa:mozillateam/ppa
sudo apt-get update
sudo apt-get install firefox-esr

參考資料

chroot啟動腳本參考自mjuned47/Termux-Ubuntu

系統設定部份參考在Android 上创建GNU/Linux 容器- 约伊兹的萌狼乡手札

移除Snap參考How to remove Snap completely without losing Firefox? - AskUbuntu