Termux SSH 锁屏断开详解:为什么 MIUI 会杀掉 untrusted_app 进程

很多 Android 用户在手机上使用 Termux 运行 SSH Server,希望在局域网内远程访问。然而在 MIUI / 澎湃 OS 等系统中,即便开启前台通知和 wakelock,SSH 仍会在锁屏或后台运行一段时间后断开。这不是 sshd 的 bug,而是系统机制决定的行为。


问题现象

logcat 可以看到典型日志:

12-28 02:07:52.217 W/sshd-session(27491): type=1400 audit(0.0:26364388): avc:  granted  { execute } for  name="login" ... scontext=u:r:untrusted_app_27 ...
12-28 02:07:52.221 I/sshd-session(27493): Read error from remote host 192.168.1.100 port 24483: Software caused connection abort
12-28 02:07:52.217 W/bash    (27494): type=1400 audit(0.0:26364389): avc:  denied  { ioctl } for path=/dev/pts/... scontext=u:r:untrusted_app_27 ...
12-28 02:07:45.518 I/VRI[TermuxActivity]: DisplayState - old: 1, new: 3

关键点分析:

  • avc: denied → SELinux 拒绝了 untrusted_app_27 的 ioctl 操作
  • Software caused connection abort → sshd 的 socket 被系统杀掉
  • DisplayState 变化 → Termux Activity 后台化,触发系统冻结
点击展开详细日志
12-28 02:07:39.950 I/Termux:TerminalView(21261): IME: finishComposingText()
12-28 02:07:39.950 I/Termux:TerminalView(21261): onKeyDown(keyCode=66, isSystem()=false, event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_ENTER, scanCode=0, metaState=0, flags=0x16, repeatCount=0, eventTime=1552220598000000, downTime=1552220598000000, deviceId=-1, source=0x0, displayId=-1 })
12-28 02:07:39.951 I/Termux:TerminalView(21261): handleKeyCode() took key event
12-28 02:07:39.951 I/Termux:TerminalView(21261): onKeyUp(keyCode=66, event=KeyEvent { action=ACTION_UP, keyCode=KEYCODE_ENTER, scanCode=0, metaState=0, flags=0x16, repeatCount=0, eventTime=1552220598000000, downTime=1552220598000000, deviceId=-1, source=0x0, displayId=-1 })
12-28 02:07:44.942 I/Termux:TerminalView(21261): IME: finishComposingText()
12-28 02:07:44.942 W/WindowOnBackDispatcher(21261): sendCancelIfRunning: isInProgress=false callback=ImeCallback=ImeOnBackInvokedCallback@159169589 Callback=android.window.IOnBackInvokedCallback$Stub$Proxy@52b7d62
12-28 02:07:44.950 E/ImeBackDispatcher(21261): Ime callback not found. Ignoring unregisterReceivedCallback. callbackId: 159169589
12-28 02:07:45.166 I/ContentCatcher(21261): SettingTrigger : unregister status observer com.termux.app.TermuxActivity
12-28 02:07:45.172 D/VRI[TermuxActivity](21261): visibilityChanged oldVisibility=true newVisibility=false
12-28 02:07:45.177 I/ContentCatcher(21261): SettingTrigger : unregisterUIAgentListener com.termux.app.TermuxActivity, uid:10280
12-28 02:07:45.203 I/ImeTracker(21261): system_server:3de7fccc: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:45.205 W/com.termux(21261): Binder 0x75680336e0 destroyed after setInheritRt before being parceled.
12-28 02:07:45.205 D/BLASTBufferQueue(21261): [VRI[TermuxActivity]#4](f:0,a:2) destructor()
12-28 02:07:45.205 D/BufferQueueConsumer(21261): [VRI[TermuxActivity]#4(BLAST Consumer)4](id:530d00000004,api:0,p:-1,c:21261) disconnect
12-28 02:07:45.207 D/Termux:TermuxActivity(21261): onStop
12-28 02:07:45.207 D/SoundPool(21261): native_release called
12-28 02:07:45.207 D/SoundPool(21261): native_release end
12-28 02:07:45.208 I/VRI[TermuxActivity](21261): DisplayState - old: 2, new: 1
12-28 02:07:45.436 I/ImeTracker(21261): system_server:28a1ae12: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:45.439 I/ImeTracker(21261): system_server:942707c: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:45.449 I/ImeTracker(21261): system_server:bc953bfe: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:45.462 I/ImeTracker(21261): system_server:9d43eee0: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:45.490 I/ImeTracker(21261): system_server:edcc13d7: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:45.516 I/ImeTracker(21261): system_server:23bff0f: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:45.518 I/VRI[TermuxActivity](21261): DisplayState - old: 1, new: 3
12-28 02:07:45.732 I/ImeTracker(21261): system_server:61fbe98b: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:46.188 I/ImeTracker(21261): system_server:727d5067: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:48.512 I/VRI[TermuxActivity](21261): DisplayState - old: 3, new: 4
12-28 02:07:48.573 I/ImeTracker(21261): system_server:8b12cd72: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:49.966 I/VRI[TermuxActivity](21261): DisplayState - old: 4, new: 3
12-28 02:07:50.003 I/ImeTracker(21261): system_server:cd8f694d: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:50.011 I/VRI[TermuxActivity](21261): DisplayState - old: 3, new: 1
12-28 02:07:50.011 I/ImeTracker(21261): system_server:e68ad4aa: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:50.240 I/ImeTracker(21261): system_server:244e2a4c: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:52.217 W/sshd-session(27491): type=1400 audit(0.0:26364388): avc:  granted  { execute } for  name="login" dev="dm-85" ino=742816 scontext=u:r:untrusted_app_27:s0:c24,c257,c512,c768 tcontext=u:object_r:app_data_file:s0:c24,c257,c512,c768 tclass=file app=com.termux.api
12-28 02:07:52.221 I/sshd-session(27493): Read error from remote host 192.168.1.100 port 24483: Software caused connection abort
12-28 02:07:52.217 W/bash    (27494): type=1400 audit(0.0:26364389): avc:  denied  { ioctl } for  path=2F6465762F7074732F31202864656C6574656429 dev="devpts" ino=4 ioctlcmd=0x540a scontext=u:r:untrusted_app_27:s0:c24,c257,c512,c768 tcontext=u:object_r:untrusted_app_all_devpts:s0:c24,c257,c512,c768 tclass=chr_file permissive=0 app=com.termux.api
12-28 02:07:52.225 I/VRI[TermuxActivity](21261): DisplayState - old: 1, new: 2
12-28 02:07:52.395 I/ImeTracker(21261): system_server:c05d3ed5: onCancelled at PHASE_CLIENT_ON_CONTROLS_CHANGED
12-28 02:07:52.859 D/AppScoutStateMachine(21261): 21261-ScoutStateMachinecreated
12-28 02:07:52.861 D/ViewRootImpl(21261): Skipping stats log for color mode
12-28 02:07:52.861 D/Termux:TermuxActivity(21261): onStart
12-28 02:07:52.862 D/Activity(21261): Activity = ActivityInfo{e8c328 com.termux.app.TermuxActivity}, Resume onConfigurationChanged = {1.0 460mcc11mnc [zh_CN] ldltr sw394dp w394dp h806dp 520dpi nrml long hdr widecg port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1280, 2772) mAppBounds=Rect(0, 152 - 1280, 2772) mMaxBounds=Rect(0, 0 - 1280, 2772) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0 mInSplitScreen=false letterBoxed=false foScaled=false isSpecificEmbedded=false} as.3 s.2 fontWeightAdjustment=0/dc themeChanged=3 themeChangedFlags=8 display=0 extraData = Bundle[{key_var_font_scale=50}] screenType=0c}
12-28 02:07:52.863 D/SecurityManager(21261): checkAccessControl flag1
12-28 02:07:52.863 I/ContentCatcher(21261): SettingTrigger : register screen QA status observer com.termux.app.TermuxActivity
12-28 02:07:52.864 I/ContentCatcher(21261): SettingTrigger : register global collect status observer com.termux.app.TermuxActivity
12-28 02:07:52.864 I/ContentCatcher(21261): SettingTrigger : registerUIAgentListener com.termux.app.TermuxActivity, uid:10280
12-28 02:07:52.871 D/MediaCodec(21261): CreateByType: pid -1(21261)
12-28 02:07:52.871 D/MediaCodec(21261): CreateByType: mime audio/vorbis, encoder 0 pid -1
12-28 02:07:52.871 D/MediaCodecList(21261): processName: com.termux , mime: audio/vorbis
12-28 02:07:52.874 D/MediaCodecList(21261): codecHandlesFormat: no format, so no extra checks

断开过程分析

结合日志和 Android 系统机制,可以推导 SSH 被杀的过程:

  1. 锁屏 / 后台触发系统策略

    • Android 对后台应用进行资源回收
    • MIUI / 澎湃 OS 的电池优化会冻结或 kill 非系统应用
  2. SELinux 安全限制

    • Termux 进程域为 u:r:untrusted_app_27:s0:c24,c257,c512,c768
    • sshd 对 /dev/pts 的操作被拒绝 (ioctl denied)
  3. 前台通知和 wakelock无法完全阻止

    • Termux 前台通知可提升优先级,但 MIUI 冻结机制仍会在锁屏或低内存时杀进程
  4. SSH socket 被中断

    • 进程暂停或 kill → TCP socket 异常 → 客户端报告 Software caused connection abort
  5. 终端 Activity 后台化

12-28 02:07:45.518 I/VRI[TermuxActivity]: DisplayState - old: 1, new: 3
  • Activity 后台化是系统判断可冻结应用的条件之一

核心原因总结

  • 系统层面限制:MIUI / 澎湃 OS 会冻结或杀掉后台 untrusted_app
  • SELinux 安全策略:Termux 属于 untrusted_app_27,操作 /dev/pts 受限
  • 锁屏和后台触发条件:屏幕熄灭或 Activity 不可见 → 系统认为进程可回收
  • 结果:sshd 进程被系统暂停或终止 → 远程客户端断开连接

结论:SSH 断开是系统设计行为,而非 Termux 或 sshd 的 bug。


日志解读细节

日志 含义
avc: denied { ioctl } for path=/dev/pts/... sshd 操作伪终端被 SELinux 拒绝
Read error from remote host ... Software caused connection abort sshd socket 被系统 kill
DisplayState - old: 1, new: 3 Activity 后台化 → 系统可能冻结进程

SSH 断开流程示意图

flowchart LR A[锁屏或后台] --> B[系统冻结 untrusted_app 进程] B --> C[sshd 被暂停或 kill] C --> D[TCP socket 失效] D --> E[客户端收到断开]
  • 锁屏或后台是触发点
  • SELinux 限制 + 系统后台回收 → sshd 断开

总结

  1. SSH 断开是 Android 系统(尤其是 MIUI 电池优化 + SELinux)决定的行为
  2. 通过更改设置无法根本解决此问题,或许只能root ?

我找到了新的解决方法: 《驯服 HyperOS 3:Android 16 下 Termux SSH 永不断连的极简方案 》


posted @ 2025-12-28 03:22  雨中遐想  阅读(54)  评论(0)    收藏  举报