GitHub Actions + rsyncでXserverへの自動デプロイを組んでいてerror in libcryptoやConnection closedが出たら、まず(1)SSH秘密鍵をGitHub Secretsに「手動コピペ」ではなくgh secret setで登録し直す、(2)それでも繋がらなければXserverの「国外IPアクセス制限」をオフにする、の2点を順番に確認してください。今回はこの2つの壁に連続でぶつかって、原因の切り分けにかなり時間を使いました。
背景
前回(WordPressデプロイをGitHub Actions+rsyncに変えた話)の設計を実際に構築していたときの話です。デプロイ専用のSSH鍵を発行してXserverに登録し、GitHub Secretsに鍵を設定して.github/workflows/deploy.ymlを作ったところまでは順調でした。ところがドライラン実行で、立て続けに2つの障害にぶつかりました。
1つ目の壁: error in libcrypto
最初に出たのはこのエラーでした。
Load key "/home/runner/.ssh/deploy_key_***_<timestamp>": error in libcrypto
***@***: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(232) [sender=3.2.7]
最初は「コピペミスだろう」と思って鍵を再度コピペし直しましたが、2回試しても同じ症状。ここで「手動コピペが何か壊してるな」という仮説に切り替えました。
鍵の種類もed25519からRSA(PEM形式)に変えてみましたが、それでも同じエラーが再現したので、鍵の形式自体は原因ではないと判断しました。
# 最初: ed25519で発行 → libcryptoエラーになった
ssh-keygen -t ed25519 -f ~/.ssh/<鍵名> -C "<コメント>" -N ""
# 鍵の種類を変えても再現したため、最終的にこちらに変更
ssh-keygen -m PEM -t rsa -b 4096 -f ~/.ssh/<鍵名> -C "<コメント>" -N ""
最終的に効いたのは、手動コピペそのものをやめることでした。GitHub CLI(gh)を使って、ローカルの鍵ファイルを直接Secretsに送るようにしたところ、鍵の読み込みエラーは完全に解消しました。
brew install gh
gh auth login --hostname github.com --git-protocol ssh --web
gh secret set DEPLOY_SSH_PRIVATE_KEY --repo <owner>/<repo> < ~/.ssh/<鍵名>
改行コードや末尾の空白とか、エディタやブラウザのコピペを経由すると鍵の内容が微妙に変わってしまうことがあるみたいです。鍵に限らず、長い文字列のSecretsを登録するときはコピペよりCLI経由の方が安全だなと感じました。
2つ目の壁: Connection closed
鍵の問題が解消した後、今度は別のエラーに変わりました。
Connection closed by <IP> port ***
ここがこの記事で一番伝えたいポイントです。エラーメッセージが「Permission denied」から「Connection closed」に変わったということは、鍵自体は通っていて、サーバー側が接続そのものを切っているということ。つまり原因が「鍵の問題」から「サーバー側の制限」に切り替わったと判断できました。
調べたところ、Xserverには「国外IPアクセス制限」という機能があり、これがGitHub Actionsの実行サーバー(海外のIPアドレス)からの接続をブロックしていました。
サーバーパネル →「SSH設定」→「アクセス制限」→「国外IPアクセス制限」をオフにすると解消しました。僕の環境ではこの設定でしたが、Xserverの管理画面の項目名や場所は変更されている可能性があるので、最新の画面で確認してください。
なお、Xserverの共用サーバーはSSHが公開鍵認証のみでパスワード認証に対応していないため、この制限をオフにしても、パスワードの総当たり攻撃のリスクが増えるわけではありません。
オフにした後、ドライランが無事成功しました。
ARGS: -avzrn --delete
...
total size is 78,393 speedup is 93.66 (DRY RUN)
✅ [DONE]
まとめ
GitHub Actions経由のSSHデプロイで詰まったら、エラーメッセージの「変化」に注目するのがコツかなと思います。
error in libcrypto/Permission denied→ 鍵そのものの読み込み問題。手動コピペをやめてgh secret setで登録し直すConnection closed→ 鍵は通っている。サーバー側のアクセス制限を確認する(Xserverなら「国外IPアクセス制限」)
今回は「コピペミスかな」で何度も同じ対処を繰り返してしまったのが時間を食った原因でした(笑)。同じ症状が再現するなら、仮説そのものを疑った方が早く解決できると思います。
よくある質問
error in libcryptoは鍵の種類(ed25519/RSA)が原因ですか?
僕の環境では鍵の種類を変えても再現したので、原因ではありませんでした。手動コピペでSecretsに登録していたことが原因でした。
国外IPアクセス制限をオフにするとセキュリティは下がりますか?
公開鍵認証のみのSSH環境であれば、パスワード総当たり攻撃のリスクは元々低いため、影響は小さいと考えています。ただし環境やセキュリティ要件によって判断は変わるので、ご自身の運用方針に合わせて検討してください。
GitHub CLIのgh secret setは何がコピペと違うのですか?
ローカルの鍵ファイルの内容をそのままコマンドで送るため、エディタやブラウザの貼り付け処理で改行や空白が変化するリスクがありません。


コメント