Tailscale経由でGitHub ActionsのVMにsshする

GitHub AcionsのVM上でTailscaleをセットアップすると、Tailscale経由でGitHub ActionsのVMsshできます。

Tailscale知らない人へ

Tailscaleが何かご存じない方は、過去に記事を書いているのでそちらを参考にしてください。

mstshiwasaki.hatenablog.com

事前準備

  • Tailscaleのアカウントを取っておくこと
  • 作業用のPC/MacでTailscaleをセットアップしておくこと
  • GitHub ActionsのSecretsで SSH_APIKEY という名前でログインに使うsshの公開鍵を登録しておくこと

サンプルworkflow

事前準備が出来たら、まずは試してみましょう。GitHub Actionsで以下のようなworkflowを .github/workflows/tailscale.yml みたいな名前で保存してpushします。

gist.github.com

うまくいけば sudo tailscale up が走ったところで以下の様な感じで認証用URLが表示されるはずです。ブラウザでそのURLにアクセスしてホストを認証すればOKです。

Run echo "Setting up tailscale ..."
Setting up tailscale ...

To authenticate, visit:

    https://login.tailscale.com/a/XXXXXXXXXXXXXXXXX

※たまにこのメッセージが何もログに出ないでずっとこのステップで止まるときがあったので、意味も無くechoを入れてあります。これを入れてからは再発してませんが、たまたまの可能性もあります。

URLを認証すると自動的に先ほどのステップは終了し、次のステップに移行します。以下のようなメッセージがログに出るはずです。

ssh -i /path/to/your_key runner@100.80.196.90

こはちょっとアドホックにやっていて、 tailscale status コマンドで一番上の行に表示されるIPアドレスを取ってきています。このコマンドは利用しているアカウントに紐付くノードの情報を表示してくれるのですが、最上段にコマンドを実行したホストのアドレスが表示されているように見えるので、head -n1 で取れるという前提で実装してあります。もしかすると1行目にコマンドを実行しているホストのIPが出ないかもしれないので、その場合はTailscaleのadmin画面から追加されたホストのIPを調査しましょう。自分が試した範囲だと fv-azNNN-NNN というホストで登録されてるようです(Nは数値)。

最後は sleep を使って一定時間待ってます。sleepが終了するとjobの実行が終了し、ホストとの接続は切断されます。sshで接続中でも切られるのでご注意を。

接続が完了したら念のためTailscaleのadmin画面で登録を解除したら作業完了です。

何が嬉しいか

GitHub Actionsに限りませんが、新しいことをやろうとするとCIサーバー上にsshしたいときが出てきます。CircleCIはこの機能が標準で用意されていますが、GitHub Actionsにはありません。

コツ

今回試してみて初めて知ったのですが、意外にもGitHub ActionsのLinux VMでは最初からsshdが動いていました。おそらくUbuntuをそのままインストールしたからこうなっているんだとは思うのですが、もしかするとGitHubはこの展開を予想していた...?

なので、基本的にやってることは慣れてる人からすれば「ですよねー」という設定ですが、一カ所ハマりどころが。workflowを実行しているユーザーは runner らしいんですが、どうも /home/runnerパーミッションがデフォルトでは755らしく、他の設定が正しくてもsshでログインできません。上記YAMLファイルでコメントアウトしてる部分にありますが、 tail -f /var/log/auth.log してsshd側のメッセージを見てやっと気付きました。

今回はサンプルということで最後はsleep使ってますが、 tail -f などしておくとGitHub Actions側の最長起動時間制限とかに引っかからなければ長く動いてくれるんじゃないでしょうか。

tailscale.com

なお、今回のサンプルではURLをクリックするという手動操作が発生していますが、Pre-authentication keys という機能で事前にキーを生成しておけばこの作業は不要になるようです。頻度高く使う場合はこれを生成しておいてSecretsに入れとくと捗るかもしれません。

tailscale.com

他の選択肢

今回Tailscaleを試そうとしたきっかけは ruby-jpのSlackにある #cimxschmitt/action-tmate というactionが紹介されていたからでした。Tailscale使えばtmateのようなサービスを間に挟むより速いでしょうし、そのまま ssh で繋げるというのもメリットです。

VM上でsshdが動いているので ngrok 使っても同様にsshでログインできるんじゃないかという気がしますが、こちらも間にサービスが挟まれるので直接VMと通信できるTailscaleのほうが操作は快適かもしれません。試してないのでわかりませんけど。