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

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

本期主题: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也会准备好,就可以实现远端通过域名访问了。

3 个帖子 - 3 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文