##概要
こんにちは。今回はcapistrano × unicornを用いた自動デプロイを行う時にGit Hubへのssh接続ができず、長時間エラーにはまってしまったので解決方法を書きました。
環境
Rails 5.0.7
AWS EC2
unicorn
capistrano
エラー内容
#bundle exec cap production deployコマンドを実行
Permission denied (publickey).
こちらはcapistranoで自動デプロイコマンドを実行した時に、EC2へのアクセスは上手くいくが、EC2にアプリをクローンする時に、EC2→Git Hubへのssh接続ができずに起きたエラーです。
このエラーはCapistranoを使用していない場合でも,手動でサーバーやGit Hubにssh接続を試みた時にも起こりうるエラーです。
解決策
解決策はズバリssh-agentでした。
このエラー内容で検索するとssh-agentを使用するという方法はかなりたくさん出てくるのですが、初心者の私には結局何をしたらいいのか理解するまでにかなり時間がかかってしまいました。
その時の私の設定としては
ローカルにEC2へ接続する鍵を置き、EC2サーバーにGitに接続する鍵を置くというものでした。
EC2への鍵→ローカル
Git Hubへの鍵→サーバー
このようにデプロイ時に必要なssh接続する為のkeyparは2セットです。
ssh接続とは手元に秘密鍵、接続先に公開鍵をセットしておくことでコマンドを実行するとアクセス可能になるという方法です。(私はこの時点でssh接続さえあまり理解できてませんでした。)
しかし検索したところサーバー上に秘密鍵を置いておくという環境はセキュリティ的によろしくないそうです。
スクールのカリキュラムや初学者用のデプロイ記事ではサーバー上に鍵を置く方法が書いてあることが多いように思えました。
では、どうするかというと
ローカル上に鍵を二つとも置いておきます。
EC2への鍵→ローカル
Git Hubへの鍵→ローカル
これではサーバーからGit Hubへ接続できないのでは、と思いますが
それを可能にするのがssh-agentです。
具体的には以下コマンドで実行します。(※ローカルにEC2,Git Hubそれぞれへの鍵を設置している前提です。)
#まずはローカル上で秘密鍵のディレクトリまで移動します。
$ cd .ssh
#続いてEC2,Git Hubそれぞれへの鍵があるかを確認
.ssh $ ls
github_rsa #GitHubの鍵
aws_rsa #EC2の鍵
#確認した鍵をssh-agentに登録します。
.ssh $ ssh-add github_rsa
.ssh $ ssh-add aws_rsa
#↑での登録が上手くできているか確認します。
.ssh $ shh-add -l
#文字列が二つでるはずです。(※他の記事では鍵名が末尾に表示されるとありましたが私のターミナルではありませんでした。)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx(RSA)
yyyyyyyyyyyyyyyyyyyyyyyyyyyyy(RSA)
#ダウンロードした鍵であれば.pemの可能性もあります。
以上が、
ローカルにあるEC2、Git Hubへの二つの鍵をssh-agentに登録する。
という作業になります。
それではこの鍵を用いて、
1.ローカルからEC2へ接続
2.EC2からGit Hubへ接続
を行ってみます。
#末尾の -A に注目!
$ ssh -i ~/.ssh/aws_rsa username@IP -A
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
末尾の-Aというのがssh-agentを使用するというオプションになります。
これがないとssh-agentに登録しているGit Hubの鍵をEC2に持っていくことができません。
次にEC2からGit Hubにアクセスしてみます。
[username@ip ~] $ssh -T github
Hi "Git Hubのユーザー名"! You've successfully authenticated, but GitHub does not provide shell access.
このようにサーバーでコマンド一つでGit Hubと接続できれば成功です。
※もしこのコマンドでパスワードを聞かれた場合はssh-agentの使用に失敗しています。
以上がssh-agentを使用して ローカル→サーバー→Git Hubへと接続する方法となります。
それでも自動デプロイできないという方は↓
##補足
その他の理由で接続エラーが起きる事があります。
capistranoを用いて自動デプロイを行う際はサーバーへの接続鍵を指定しているコードにforward_agent: trueのオプションを追記する必要があります。
set :ssh_options, auth_methods: ['publickey'],
keys: ['~/.ssh/first_aws_rsa'],
forward_agent: true
ssh-agentは一度ターミナルを閉じるとリセットされます。
一度は上手く接続されたのに、急に接続されなくなったという方はssh-add -lで正常に登録されているかどうかを確認してください。
さらに毎回デプロイコマンドを実行する前に一度手動で接続をしなければなりません。
#一度は成功したのにしばらくするとエラーになるという場合はこのフローを行う。
#ローカル
$ ssh-add 鍵名
$ ssh -i ~/.ssh/aws_rsa username@IP -A
#サーバー
$ ssh -T github
ターミナルを落としてもssh-agentを持続させるオプションもあるようなのですが、私は今の所それを実行することはできませんでした。
以上です!