使用 USB tty 控制你的 Linux 主机
使用 USB tty 控制你的 Linux 主机
之所以有这个小需求,是遇到了两件事情。
一个是朋友的 PVE 在配置坏了网络、没有屏幕可用的时候,需要一种能控制系统的方式;另一个是在打 CTF 线下赛的时候,因为自己现在主力是 macOS 了,所以整了个 x86_64 的小机器来调试 x86 的程序,而现场的网络环境不一定可以直接使用 DHCP 或者其他方式打通网络,然后走 SSH 交互——所以为了这个无显示器配置网络的需求,就有了这个需求。
需要什么硬件
- 2 * USB 转 TTL 的串口线
- 一些杜邦线
这个硬件来说基本就是不超过 10 块钱就能搞定的水平,为的是能不直接走串口接线的情况下,能够在 USB 上直接使用串口终端。
一般来说也会被别人讲是 “刷机线” 之类的,之所以需要两个,是因为控制设备和被控制设备都需要一个。
要通讯需要至少连接 GND
、RX
、TX
三个引脚,如果是需要控制电源的话,还需要 VCC
引脚。
连接方式是两个 USB 转 TTL 的串口线的 RX
和 TX
两个引脚交叉连接,也即两端的 “收发” 引脚互相连接,然后 GND
引脚连接在一起,VCC
引脚连接在一起。
连接好之后插到终端上就能看到类似于 /dev/tty.usbserial-xxxx
或者 /dev/ttyUSBx
的设备了。
使用 USB tty 进行交互
这里主要描述的是 Linux 作为受控端的情况,其他类型的话这里不涉及了。
实现方式的话是基于 systemd 的,对于不使用 systemd 的发行版,这里也不涉及了——不过现在跑在物理机上的 Linux 应该没有人不用 systemd 了吧。
在 Linux 上接入 USB 转 TTL 的串口线后,通过 ls /dev/ttyUSB*
可以看到类似于 /dev/ttyUSB0
的设备。
需要注明的是,下文中出现的设备名都会使用 ttyUSB0
代替。确认有设备之后使用如下指令来创建一个 systemd 的服务:
sudo systemctl enable [email protected] --now
这样就能在 /dev/ttyUSB0
上暴露一个 getty 服务了,之后我们在另一个终端上使用 screen
来连接这个设备。
需要注意的是这一侧的设备需要自己查找一下,在 macOS 上的话是 /dev/tty.usbserial-xxxx
,Windows 上的话应该(可能)是 COMx
。下面的例子中使用的是 *unix 系统进行,如需 Windows 的话可能需要安装一些额外软件,比如 PuTTY 之类的(Copilot 说的)。
screen /dev/tty.usbserial-xxxx 9600
按几下回车之后如果能正常看到登陆提示的话,就说明串口连接成功了。
你可能会需要的小知识:
退出 screen
的话可以使用 Ctrl + A
然后再按 k
,然后再按 y
确认退出。
不过这样的串口通讯是不持久的,拔掉 USB 转 TTL 的串口线之后,这个 getty 服务也会被关闭,再次插入的时候也不会自动启用,并且波特率的协商可能会使用最低的 9600,这样的话在交互的时候会有延迟,所以我们需要做一些额外的配置。
使用 systemd 管理 USB tty
我们可以使用 systemctl edit
来编辑一个服务的配置,生成一个 Drop-in file 来覆盖默认的配置,并且不会影响到更新和原有的配置。
sudo systemctl edit [email protected]
在编辑器中输入如下内容:
### Editing /etc/systemd/system/[email protected]/override.conf
### Anything between here and the comment below will become the contents of the drop-in file
[Service]
ExecStart=
ExecStart=-/sbin/agetty -o '-p -- \\u' 115200 - $TERM
[Install]
WantedBy=dev-%i.device
### Edits below this comment will be discarded
# ...
其中,ExecStart
覆盖原有的命令行,强制使用 115200 的波特率,可以参考 getty 的文档来了解更多的参数。连接的波特率也要和这里的一致,否则会出现乱码。
WantedBy
用于指定这个服务的启动依赖,这里使用 dev-%i.device
来指定依赖于 /dev/ttyUSB0
这个设备,这样的话在插入设备的时候就会自动启动这个服务。
至此我们就完成了一个可以自动启动的 USB tty 服务了,可以在没有网络的情况下使用 USB tty 来进行一些基本的配置。
碎碎念
感觉现在写技术文档越来越离谱了,好多东西写个需求就被 Copilot / GPT 抢答了……
哦,还有个建议,在有网络的情况下给 Linux 主机跑个 tailscale 什么的,SSH 起来可以说是非常方便了。