【超详细】手机搭建服务器 · 第 六 期

Semmering 2026-05-27 18:47 1

本期主题:termux永久唤醒 & ubuntu环境自启动 & 实现sshd


前五期回顾:


【超详细】手机搭建服务器 · 第 一 期

【超详细】手机搭建服务器 · 第 二 期

【超详细】手机搭建服务器 · 第 三 期

【超详细】手机搭建服务器 · 第 四 期

【超详细】手机搭建服务器 · 第 五 期


一、termux永久唤醒:



1. 打开MT管理器,进入/data/adb/service.d/文件夹,创建60-termux-wake-keeper.sh开机脚本:



#!/system/bin/sh

# ============================================================
# 60-termux-wake-keeper.sh
#
# 功能:
# 1. 手机开机后自动启动 termux-wake-keeper.sh
# 2. 定时执行 termux-wake-lock,保持 wake lock
#
# 注意:
# - 这个脚本只负责“开机拉起守护脚本”
# - 真正循环执行 termux-wake-lock 的逻辑在:
# /data/local/termux-wake-keeper/termux-wake-keeper.sh
# ============================================================

BASE_DIR="/data/local/termux-wake-keeper"

SCRIPT="$BASE_DIR/termux-wake-keeper.sh"
LOG="$BASE_DIR/termux-wake-keeper-start.log"

mkdir -p "$BASE_DIR"

log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG"
}

log "============================================================"
log "===== termux wake keeper auto start | START ====="
log "BASE_DIR=$BASE_DIR"
log "SCRIPT=$SCRIPT"
log "LOG=$LOG"

# ------------------------------------------------------------
# 1. 等待 Android 系统启动完成
# ------------------------------------------------------------
while [ "$(getprop sys.boot_completed)" != "1" ]; do
sleep 5
done

log "Android boot completed"

# ------------------------------------------------------------
# 2. 再额外等待一会儿
# 避免刚开机时 /data/data、Termux、ZeroTermux 相关环境还没完全稳定
# ------------------------------------------------------------
sleep 30

# ------------------------------------------------------------
# 3. 检查主守护脚本是否存在
# ------------------------------------------------------------
if [ ! -x "$SCRIPT" ]; then
log "ERROR: script not found or not executable: $SCRIPT"
log "Please check file path and chmod 755."
log "===== termux wake keeper auto start | FAILED ====="
exit 1
fi

# ------------------------------------------------------------
# 4. 启动守护脚本
# 守护脚本内部有 PID 判断,重复启动不会产生多个实例
# ------------------------------------------------------------
nohup "$SCRIPT" >> "$LOG" 2>&1 &

log "termux wake keeper started"
log "===== termux wake keeper auto start | DONE ====="
log "============================================================"


2.在/data/local/termux-wake-keeper/文件夹中创建termux-wake-keeper.sh脚本



#!/system/bin/sh

# ============================================================
# termux-wake-keeper.sh
#
# 功能:
# 1. 定时执行 termux-wake-lock
# 2. 防止 wake lock 失效
# 3. 不依赖 Ubuntu
# 4. 不启动 sshd / nginx
#
# 日志:
# /data/local/termux-wake-keeper/termux-wake-keeper.log
# ============================================================

BASE_DIR="/data/local/termux-wake-keeper"
LOG="$BASE_DIR/termux-wake-keeper.log"

RUN_DIR="/dev/.termux-wake-keeper"
PIDFILE="$RUN_DIR/termux-wake-keeper.pid"

# 每隔多少秒重新执行一次 termux-wake-lock
INTERVAL="60"

mkdir -p "$BASE_DIR"
mkdir -p "$RUN_DIR"

log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG"
}

is_running() {
OLD_PID="$1"

if [ -z "$OLD_PID" ]; then
return 1
fi

if [ ! -d "/proc/$OLD_PID" ]; then
return 1
fi

tr '\0' ' ' < "/proc/$OLD_PID/cmdline" 2>/dev/null | grep -q "termux-wake-keeper.sh"
}

find_wake_lock_cmd() {
for p in \
/data/data/com.termux/files/usr/bin/termux-wake-lock \
/data/data/com.zerotermux/files/usr/bin/termux-wake-lock \
/data/data/com.termux.zero/files/usr/bin/termux-wake-lock
do
if [ -x "$p" ]; then
echo "$p"
return 0
fi
done

find /data/data -path '*/files/usr/bin/termux-wake-lock' -type f -perm -111 2>/dev/null | head -n 1
}

find_wake_unlock_cmd() {
for p in \
/data/data/com.termux/files/usr/bin/termux-wake-unlock \
/data/data/com.zerotermux/files/usr/bin/termux-wake-unlock \
/data/data/com.termux.zero/files/usr/bin/termux-wake-unlock
do
if [ -x "$p" ]; then
echo "$p"
return 0
fi
done

find /data/data -path '*/files/usr/bin/termux-wake-unlock' -type f -perm -111 2>/dev/null | head -n 1
}

# 防止重复启动
if [ -f "$PIDFILE" ]; then
OLD_PID="$(cat "$PIDFILE" 2>/dev/null)"

if is_running "$OLD_PID"; then
log "already running, pid=$OLD_PID"
exit 0
else
log "stale pidfile found, overwrite"
fi
fi

echo "$$" > "$PIDFILE"

WAKE_LOCK_CMD="$(find_wake_lock_cmd)"
WAKE_UNLOCK_CMD="$(find_wake_unlock_cmd)"

log "============================================================"
log "===== termux wake keeper | START ====="
log "PID=$$"
log "BASE_DIR=$BASE_DIR"
log "LOG=$LOG"
log "INTERVAL=$INTERVAL"
log "WAKE_LOCK_CMD=$WAKE_LOCK_CMD"
log "WAKE_UNLOCK_CMD=$WAKE_UNLOCK_CMD"

if [ -z "$WAKE_LOCK_CMD" ]; then
log "ERROR: termux-wake-lock not found"
log "Please check: find /data/data -path '*/files/usr/bin/termux-wake-lock'"
rm -f "$PIDFILE"
exit 1
fi

release_lock() {
log "release termux wake lock"

if [ -n "$WAKE_UNLOCK_CMD" ] && [ -x "$WAKE_UNLOCK_CMD" ]; then
"$WAKE_UNLOCK_CMD" >> "$LOG" 2>&1
log "termux-wake-unlock executed"
else
log "WARN: termux-wake-unlock not found, skip unlock"
fi

rm -f "$PIDFILE"
}

trap 'release_lock; exit 0' INT TERM

# 启动时先执行一次
"$WAKE_LOCK_CMD" >> "$LOG" 2>&1
RESULT="$?"

if [ "$RESULT" = "0" ]; then
log "termux-wake-lock executed at startup"
else
log "ERROR: termux-wake-lock startup failed, result=$RESULT"
fi

# 循环续保
while true; do
sleep "$INTERVAL"

"$WAKE_LOCK_CMD" >> "$LOG" 2>&1
RESULT="$?"

if [ "$RESULT" = "0" ]; then
log "termux-wake-lock refresh ok"
else
log "ERROR: termux-wake-lock refresh failed, result=$RESULT"
fi
done


[!note]如何手动停止唤醒

如果需要手动停止唤醒,可以用下面这个脚本,如果不需要,可以忽略,一般是不需要的

stop-termux-wake-keeper.sh:



#!/system/bin/sh

# ============================================================
# stop-termux-wake-keeper.sh
#
# 功能:
# 1. 停止 termux-wake-keeper.sh 守护脚本
# 2. 执行 termux-wake-unlock
#
# 日志:
# /data/local/termux-wake-keeper/termux-wake-keeper.log
# ============================================================

BASE_DIR="/data/local/termux-wake-keeper"
LOG="$BASE_DIR/termux-wake-keeper.log"

RUN_DIR="/dev/.termux-wake-keeper"
PIDFILE="$RUN_DIR/termux-wake-keeper.pid"

mkdir -p "$BASE_DIR"

log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG"
}

find_wake_unlock_cmd() {
for p in \
/data/data/com.termux/files/usr/bin/termux-wake-unlock \
/data/data/com.zerotermux/files/usr/bin/termux-wake-unlock \
/data/data/com.termux.zero/files/usr/bin/termux-wake-unlock
do
if [ -x "$p" ]; then
echo "$p"
return 0
fi
done

find /data/data -path '*/files/usr/bin/termux-wake-unlock' -type f -perm -111 2>/dev/null | head -n 1
}

log "============================================================"
log "===== stop termux wake keeper | START ====="

if [ -f "$PIDFILE" ]; then
PID="$(cat "$PIDFILE" 2>/dev/null)"

if [ -n "$PID" ] && [ -d "/proc/$PID" ]; then
kill -TERM "$PID"
log "sent TERM to termux-wake-keeper pid=$PID"
sleep 1
else
log "pid not running: $PID"
fi

rm -f "$PIDFILE"
else
log "pidfile not found: $PIDFILE"
fi

WAKE_UNLOCK_CMD="$(find_wake_unlock_cmd)"
log "WAKE_UNLOCK_CMD=$WAKE_UNLOCK_CMD"

if [ -n "$WAKE_UNLOCK_CMD" ] && [ -x "$WAKE_UNLOCK_CMD" ]; then
"$WAKE_UNLOCK_CMD" >> "$LOG" 2>&1
RESULT="$?"

if [ "$RESULT" = "0" ]; then
log "termux-wake-unlock executed"
else
log "ERROR: termux-wake-unlock failed, result=$RESULT"
fi
else
log "WARN: termux-wake-unlock not found"
fi

log "===== stop termux wake keeper | DONE ====="
log "============================================================"


[!warning]提醒

上面的脚本一定要记得给足权限



二、实现ubuntu开机自启



1. 打开MT管理器,进入/data/adb/service.d/文件夹,新建文件90-ubuntu-sshd.sh,代码如下:



#!/system/bin/sh

# ============================================================
# 90-ubuntu-sshd.sh
#
# 功能:
# 1. 开机后调用 Magisk 版 chroot-distro
# 2. 自动准备 ubuntu chroot 环境
# 3. 自动启动 ubuntu 里的 sshd
#
# 说明:
# - 不处理 wake lock
# - 不依赖 Termux 路径
# - 不在脚本里写死 SSH 端口
# - SSH 端口以 Ubuntu 的 /etc/ssh/sshd_config 为准
# ============================================================

# 日志目录
LOG_DIR="/data/local/chroot-distro/logs"

# 日志文件
LOG="$LOG_DIR/ubuntu-sshd-start.log"

# 你平时是 chroot-distro login ubuntu
# 所以这里发行版名称就是 ubuntu
DISTRO="ubuntu"

# 开机后额外等待时间
BOOT_WAIT="25"

# 设置 Android / Magisk 常见命令路径
# 这个不是 Termux PATH,只是为了让 service.d 脚本能找到系统命令
export PATH="/system/bin:/system/xbin:/vendor/bin:/odm/bin:/data/adb/magisk:/data/adb/ksu/bin:$PATH"

# 确保日志目录存在
mkdir -p "$LOG_DIR"

log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG"
}

log "============================================================"
log "===== Ubuntu sshd auto start via chroot-distro | START ====="
log "DISTRO=$DISTRO"
log "BOOT_WAIT=$BOOT_WAIT"
log "LOG=$LOG"

# ------------------------------------------------------------
# 1. 等待 Android 开机完成
# ------------------------------------------------------------
while [ "$(getprop sys.boot_completed)" != "1" ]; do
sleep 5
done

log "Android boot completed"

sleep "$BOOT_WAIT"

# ------------------------------------------------------------
# 2. 查找 chroot-distro
# ------------------------------------------------------------
CHROOT_DISTRO="$(command -v chroot-distro 2>/dev/null)"

if [ -z "$CHROOT_DISTRO" ]; then
if [ -x /system/bin/chroot-distro ]; then
CHROOT_DISTRO="/system/bin/chroot-distro"
elif [ -x /system/xbin/chroot-distro ]; then
CHROOT_DISTRO="/system/xbin/chroot-distro"
else
log "ERROR: chroot-distro command not found"
log "Please run: command -v chroot-distro"
log "===== FAILED ====="
exit 1
fi
fi

log "CHROOT_DISTRO=$CHROOT_DISTRO"

# ------------------------------------------------------------
# 3. 让 chroot-distro 准备 Ubuntu 环境
# ------------------------------------------------------------
log "mount distro: $DISTRO"
"$CHROOT_DISTRO" mount "$DISTRO" >> "$LOG" 2>&1

# ------------------------------------------------------------
# 4. 在 Ubuntu 环境里启动 sshd
# ------------------------------------------------------------
log "start sshd inside Ubuntu"

"$CHROOT_DISTRO" command "$DISTRO" '
mkdir -p /run/sshd
chmod 755 /run/sshd

ssh-keygen -A >/dev/null 2>&1 || true

/usr/sbin/sshd -t
if [ $? -ne 0 ]; then
echo "ERROR: sshd config test failed"
exit 1
fi

echo "effective sshd config:"
/usr/sbin/sshd -T | awk "/^(port|addressfamily|listenaddress|permitrootlogin|passwordauthentication|pubkeyauthentication) / {print}"

if pgrep -x sshd >/dev/null 2>&1; then
echo "sshd already running"
else
/usr/sbin/sshd
echo "sshd started"
fi
' >> "$LOG" 2>&1

RESULT="$?"

if [ "$RESULT" != "0" ]; then
log "ERROR: chroot-distro command failed, result=$RESULT"
log "===== Ubuntu sshd auto start via chroot-distro | FAILED ====="
exit 1
fi

log "chroot-distro command finished"

# ------------------------------------------------------------
# 5. 输出监听状态
# 不写死端口,直接看 sshd 实际监听了什么
# ------------------------------------------------------------
log "listening status:"
ss -lntp 2>/dev/null | grep sshd >> "$LOG" 2>&1

log "process status:"
ps -A 2>/dev/null | grep sshd >> "$LOG" 2>&1

log "===== Ubuntu sshd auto start via chroot-distro | DONE ====="
log "============================================================"



[!warning]权限提醒

脚本同样记得给足权限



三、如何在ubuntu中实现sshd



1.修改 sshd 配置

打开mt管理器/data/local/chroot-distro/ubuntu/etc/ssh/sshd_config

修改 sshd_config文件:

找到这段代码:



#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

改成


Port 2222
AddressFamily any
ListenAddress 0.0.0.0
ListenAddress ::

再找到


# PasswordAuthentication yes

改成


PasswordAuthentication yes
PubkeyAuthentication yes

也就是密码和允许使用 SSH 密钥登录



2.创建 sshd 运行目录



sudo mkdir -p /run/sshd
sudo chmod 755 /run/sshd


3.启动 sshd



如果有旧的ssh,就先停掉旧的 sshd:


sudo pkill sshd 2>/dev/null

再启动:


sudo /usr/sbin/sshd

确认是否监听成功:


ss -lntp | grep sshd

正常应该看到类似:


LISTEN 0 128 [::]:2222 [::]:* users:(("sshd",pid=xxxx,fd=3))

这说明 Ubuntu 已经在 IPv6 的 2222 端口上等待外部连接。


给几个常用的命令:


查看sshd状态:


ss -lntp | grep sshd

停止:


pkill -TERM -x sshd

启动:


mkdir -p /run/sshd && chmod 755 /run/sshd && /usr/sbin/sshd

重启:


/usr/sbin/sshd -t && pkill -TERM -x sshd && sleep 1 && mkdir -p /run/sshd && chmod 755 /run/sshd && /usr/sbin/sshd


[!warning]远端ssh报错问题

如果远端ssh访问时,有下面这张报错问题:



-bash: /etc/bash.bashrc: Required key not available
-bash: /home/semmering/.profile: Required key not available
-bash-5.2$

解决办法是:


用MT管理器,把/data/local/chroot-distro/ubuntu/etc/pam.d/sshd这句话注销就不会报错了。

# session optional pam_keyinit.so force revoke


也就是在这句话前面加上#号,或者删除这句话。


这个报错问题非常不好解决,网络上的信息非常少。非常幸运再github上找到了方法。



[!success]

按照上面的教程来一步一步操作。脚本记得给足权限,然后重新开关机,termux会永久唤醒,然后ubuntu环境也会准备好,然后sshd也会准备好,就可以实现远端通过域名访问了。


最新回复 (16)
  • 𝐴𝐼𝐺𝐶𝐹𝑅𝐸𝐸 05-27 18:49
    1

    佬的教程太给力了,狠狠学习收藏了!

  • Lucifer Morningstar 05-27 18:51
    2

    目前我搜索到有个更好的方案,在你的第一期的基础上直接刷入postmarketos,这个是linux框架的os,能直接在手机上运行docker,相当于直接将Android环境改成linux

  • herring 05-27 19:47
    3

    这个系统感觉硬件支持的不多吧 ,前两天看他的wiki说我的老手机网卡和蓝牙什么的都不支持。

  • Semmering 楼主 05-27 19:49
    4

    这这个应该不是所以机型都通用吧。支持的机型列表有吗?

  • Semmering 楼主 05-27 19:50
    5

    感谢支持。有问题可以随时沟通。看到后一一解答

  • Lucifer Morningstar 05-27 22:33
    6

    可以去postmarkeros的官网查看下

  • dvdbv 05-28 01:13
    7

    佬,全部做完后发现linux内无法访问外网,佬有遇到过吗,不知道是不是我哪一步做错了,我正在让ai试试,不确定能不能解决

  • Semmering 楼主 05-28 14:08
    8

    Linux内无法访问外网?你仔细看报错了嘛,可以把报错贴出来。关于网络问题我记得第五期也说过如何解决。不知道你注意到没。

  • Atlas Zhang 05-28 14:11
    9

    很详细的教程,虽然现在用不上,不过先收藏一波

  • Semmering 楼主 05-28 14:11
    10

    好,感谢佬的支持。有问题及时沟通

  • dvdbv 05-28 14:25
    11

    解决了,是一些配置问题,我是让手机和我服务器组内网的,所以有些没走教程

  • Semmering 楼主 05-28 14:56
    12

    牛逼,解决了就好。有问题再及时沟通

  • 春风得意王大帅 06-04 00:42
    13



    感谢佬,在佬的教程和GenericAgent的帮助下,搞定了

  • 春风得意王大帅 06-04 22:33
    14



    这对吗,佬。我一加6

  • wofortune 06-08 20:52
    15

    涉及到嵌套虚拟化的问题可以试试droidspaces,这个是专门为安卓设计的linux容器,比chroot方案好很多

  • 春风得意王大帅 06-08 21:12
    16

    哦哦,要的。谢谢佬,已经让ai给我装起了

* 帖子来源Linux.do
返回