在线调试Github Actions

0x00 背景

Github Action提供了便捷的流水线能力,但是对于较为复杂的场景,只能依靠不断试错来定位和解决Action报错,效率非常低下。网上也有人提供了基于tmate的远程调试方案,但该方案也存在着一些不足。本文尝试提供一些其它的解决方案。

0x01 tmate方案简述

tmate是一款实时终端共享工具,主要支持Linux系统。其基本原理是:tmate运行后会创建一个shell会话,并连接到服务端,然后展示一个ssh地址;访问端使用ssh工具访问这个地址,获取tmate创建的shell。

基本使用方法如下:

  • 共享端

先保证~/.ssh目录下存在rsa_id文件,如果不存在可以使用ssh-keygen -t rsa命令生成。

$ tmate

此时,底部会提示访问端使用的ssh地址,如:`qsMzYcuPFTFYzKvXa6cgggDyc@lon1.tmate.io`。

  • 访问端
$ ssh qsMzYcuPFTFYzKvXa6cgggDyc@lon1.tmate.io

连上后,共享端和访问端访问的是同一个shell,任何一方的操作都会同步到对方终端中;而且任何一方退出也会导致对方shell退出。

因此,tmate方案的优缺点总结如下:

  • 优点
    • 无需第三方服务支持
    • 访问端无需安装额外的工具
  • 缺点
    • 不支持Windows
    • 连接断开后无法重新连接

已经有人将tmate封装到了Github Action中,具体使用方法可以参考:https://github.com/marketplace/actions/debugging-with-tmate

0x02 使用pytmate代替tmate

pytmate是用纯python实现的tmate,不仅提供了终端分享的能力,还增加了对Windows系统的支持以及断开ssh后不会自动退出分享端shell的逻辑。

因此,pytmate可以解决tmate存在的上述两个问题。

使用方法如下:

$ python3 -m pip install tmate
$ tmate
[TMateClient] Connect SSH server ssh.tmate.io:22...
[Notify] web session read only: https://tmate.io/t/ro-mfZVpKgGUKAtmLuFsyyhK92af
[Notify] ssh session read only: ssh ro-mfZVpKgGUKAtmLuFsyyhK92af@sgp1.tmate.io
[Notify] web session: https://tmate.io/t/bJT5pQpYEcBHjXnxZR6Uxw25G
[Notify] ssh session: ssh bJT5pQpYEcBHjXnxZR6Uxw25G@sgp1.tmate.io

目前对Win10 1809以上系统版本支持较好,因为系统支持了pty;对于低版本Win10以及Win7系统,可以执行不需要交互式执行的命令,交互式命令由于无法实时输出,看起来像是卡住了一样。

在Github Action中使用pytmate可以参考:https://github.com/drunkdream/pytmate/blob/master/README.md#%E5%9C%A8%E7%BA%BF%E8%B0%83%E8%AF%95github-actions

0x03 使用wsterm + frp

wsterm是用纯Python实现的一款基于WebSocket的终端Shell工具,其本身目标是为了提供一个易于跨网络访问的远程调试终端工具,支持自动将本地的工作区文件/目录同步到远程机器上。

虽然wsterm不支持反向连接,无法在外部直接访问Github Action中的wsterm服务端,但可以通过借助于frp之类的工具,将内部端口暴露到外网中,然后wsterm客户端直接去连接这个外网地址即可。wsterm本身提供了基于token的权限校验机制,可以在一定程度上保证服务端的安全性。

使用wsterm最大的优势是工作区自动同步能力,可以方便地进行本地修改,远程执行,极大降低了远程调试代码的成本;也不会因为终端意外退出导致修改没有同步到本地的问题。

目前网上有提供一些免费或收费的frp服务端,可以通过这些服务进行wsterm端口的映射;也可以使用自己的服务器搭建frp服务。

具体使用方法可以参考:https://github.com/wsterm/wsterm/blob/master/.github/workflows/debug-linux.yml

这里启动Action是通过在Github issue中发送特定字符串(如:Debug Linux)的方式,Action启动后会将访问地址回复到issue中;frp使用的则是freefrp.net提供的免费服务。

wsterm也提供了一个issue页面,可以用于进行在线调试。

0x04 总结

在线调试Github Action主要是两种思路:

  • 利用第三方终端分享服务(如:tmate等)将内网机器上的Shell暴露出来
  • 结合远程Shell工具(如:ssh、wsterm等)和内网端口映射工具(如:frp等)将Shell暴露出来

第一种思路实现相对会简单一些,但功能会受到第三方服务的限制,扩展性不好;第二种思路虽然实现会复杂一些,但扩展性较好,可以根据实际需求使用不同的组合。

分享