Githubにアクセスするときに、一般的なhttpsというURLではなく、git@github.com:~というパスでレポジトリを指定し、アクセスすることができます。
これはよりセキュリティの高いSSH接続を使った方法です。
ここでは、ローカル環境(自分のPC)で秘密鍵と公開鍵を作成し、Githubに公開鍵を登録して、SSH接続する方法を解説しています。
SSHとは何か?
SSHとは、サーバーを遠隔操作する方法の1つで、通信内容を暗号化しているものです。
通信を暗号化していないものにtelnetという通信方法があり、そのパワーアップバージョンです。
簡単にいうと、AWSやGithubなどのサーバー(レンタルサーバー)などに自分のパソコンのコマンドライン(黒画面)からアクセスできる仕組みです。
SSHの接続方法には、パスワードを使う方法と、公開鍵と秘密鍵を使う方法の2種類があります。
ここでは、よりセキュリティの高い公開鍵と秘密鍵を使う方法について解説しています。
公開鍵と秘密鍵の作成
.sshディレクトリに移動
SSHに関する接続先(ホスト)や公開鍵、秘密鍵などの情報はユーザーのルートディレクトリ配下の「.ssh」ディレクトリに保存します。
このため、公開鍵と秘密鍵を作成するコマンドを実行する前に、対象のディレクトリに移動します。
なお、「.ssh」の「.(ドット)」は隠しディレクトリであることを示しています。
$cd ~/.ssh
公開鍵と暗号鍵の生成
「.ssh」ディレクトリを移動したら「ssh-keygen」コマンドを使って公開鍵と暗号鍵を生成します。
「-C」オプションの後ろに、Githubで使用しているメールアドレスをつけます。
$ ssh-keygen -t ed25519 -C "your_email@example.com"
実行すると以下の3回で入力を求められます。
- どこにカギを作成するか(ファイルパスの確認)
- パスワードの設定
- パスワードの確認
指定された場所(.ssh/id_暗号化形式)にそのまま保存し、パスワードは空にすることが一般的です。
このため、単に3回Enterキーをクリックするといった記述もみかけます。
もちろんセキュリティレベルを上げるために、保存先を変更したりパスワードをかけることも非常に有効です。
-tオプションとは何か?
「ssh-keygen」の「-t」オプションは、作成する暗号化方法を指定するためのオプションです。
暗号化はデフォルトは「RSA」になっています。ここでは「ed25519」を指定しています。
ed25519とは何か?
「-t」オプションで指定している「ed25519」とは、暗号化方法の一つです。
より詳しく言うと「EdDSA(エドワーズ曲線デジタル署名アルゴリズム)」の中の一つです。
EdDSAは比較的新しい暗号で、RSAと比較し鍵の長さが短くセキュリティが高いといったメリットを持っています。
ただし、ed25519を使うには、OpenSSH 6.5以降であるといった条件があります。これらを満たせない場合はRSAを使用する必要があります。
-Cオプションとは何か?
「ssh-keygen」の「-C」オプションは、コメントを指定することができるオプションです。
デフォルトは「ユーザー名@ホスト名」となっています。
-Cをオプションを使用せずに、「ssh-keygen -t ed25519」として公開鍵と暗号鍵を作成することはできます。
実例
「ssh-keygen」を実行すると、以下のように、鍵が生成され、保存場所とパスワードを聞かれます。
基本的には全てEnterで問題ありません。
$ ssh-keygen -t ed25519 -C "example@gmail.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/c/Users/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/user/.ssh/id_ed25519
Your public key has been saved in /c/Users/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:LUzTvf1111111111w75V0lYHH1ZT1l1z1K111X1 example@gmail.com
The key's randomart image is:
+--[ED25519 256]--+
| .o.+o+++o.++o |
| o oooEoo=.o |
| . o .+s..o+ |
| ....o.00= . |
| =. .S o . |
| . . oo . o . |
|o . aa . oo |
| + . a dod . |
| . ..ase o..|
+----[SHA256]-----+
以上で公開鍵と暗号鍵の生成は完了です。
「ls」コマンドでファイルを確認すると「id_ed25519」と「id_ed25519.pub」が生成されていることがわかります。
$ ls
config id_ed25519 id_ed25519.pub known_hosts
「id_ed25519」が秘密鍵(超重要!)、「id_ed25519.pub」が公開鍵となります。拡張子「pub」はpublic(公開用)という意味です。
秘密鍵をssh-agentに登録する
ssh-agentとは何か?
「ssh-keygen」コマンドで生成した秘密鍵は非常に長くてランダムな文字列になっています。
▼秘密鍵の例(Xの部分がランダムなアルファベットや記号になっています)
$ cat id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END OPENSSH PRIVATE KEY-----
これを毎回入力するのは非常に面倒です。
このため、公開鍵と秘密鍵の照合を代理で行ってくれる便利な機能として「ssh-agent」が用意されています。
ssh-agentの起動
「ssh-agent」以下のコマンドで起動します。
$ eval "$(ssh-agent -s)"
実例
$ eval "$(ssh-agent -s)"
> Agent pid 496
プロセスID(pid)が表示されればOKです。
秘密鍵をssh-agentに登録する
秘密鍵をssh-agentに登録します。「ssh-add」コマンドの引数で、生成した秘密鍵のパスを渡します。
$ ssh-add ~/.ssh/id_ed25519
実例
$ ssh-add ~/.ssh/id_ed25519
Identity added: /c/Users/user/.ssh/id_ed25519 (example@gmail.com)
「Identity added(ID追加)」が表示されれば完了です。先ほど「-C」オプションで指定した、コメント内容も表示されています。
公開鍵をGithubに登録する
公開鍵をコピーする
GithubでSSHを使った通信を行えるようにするために、生成した公開鍵をGithubに登録します。
$ clip < ~/.ssh/id_ed25519.pub
clipコマンドとは?
「clip」コマンドはクリップボードに指定した内容をコピーできるコマンドです。「<」の後ろにファイルパスを指定することで、ファイルの中身をクリップボードにコピーします。
$ clip < ファイルパス
Githubに登録する
Githubの自分のアカウントページを開き、メニューの中の「Settings」をクリックします。
左メニューの「SSH and GPG keys」をクリックします。
右上の「New SSH key」というアイコンをクリックします。
「Key」の欄に「ctrl + v」で先ほどクリップボードにコピーした、公開鍵の内容を貼り付けます。
「Title」はGithubでどんなSSHキーを登録してあるかわかりやすくするためのものです。入力しない場合は、「-C」で指定した内容が入ります。
「Add SSH key」をクリックすれば、SSH公開鍵の登録は完了です。
以下のように表示されれば登録完了です。
GithubへのSSH接続をテストする
Githubに公開鍵の登録が完了したら、自分のPC(ローカル)からリモートサーバーにSSH接続できるかテストを行います。
以下のコマンドを実行します。
$ ssh -T git@github.com
「Are you sure you want to continue connecting?」と表示されるので、「yes」と入力します。
これで、GithubにSSH接続できる状態になったので、再度上記のコマンドを実行します。
$ ssh -T git@github.com
これで、「Hi <Githubのアカウント名>! You’ve successfully authenticated, but GitHub does not provide shell access.」と表示されればSSHで接続成功です。
なお、「-T」オプションはPTY(疑似端末)の接続をしないオプションです。
sshでGithubに接続しますが、Githubはptyを許可していないので、わざわざGithubのターミナルを起動せずにそのまま終了するために付けます。なお「-T」がなくても接続確認は可能です。
実例
「ssh -T git@github.com」コマンドを実行します。
$ ssh -T git@github.com
The authenticity of host 'github.com (52.192.72.89)' can't be established.
ED25519 key fingerprint is SHA256:+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
まだ、GithubにSSH接続をしたことが無い場合は、接続してもいいか?という確認が出るので「yes」と入力します。
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
Connection reset by 52.192.72.89 port 22
これで、ローカルのSSHのconfigファイルにGithubがホストの一つとして登録されました。
再度、「ssh -T git@github.com」コマンドを実行します。
$ ssh -T git@github.com
Hi account-name! You've successfully authenticated, but GitHub does not provide shell access.
SSHで正しく接続できることが確認できました。
-Tオプションがない場合
なお、「-T」オプションがない場合は「PTY allocation request failed on channel 0」や「Connection to github.com closed.」というメッセージが表示されます。
「PTYのリクエストは失敗しました、Githubとの接続を終了します」という内容です。
$ ssh git@github.com
PTY allocation request failed on channel 0
Hi account-name! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
SSHのエージェント転送機能を設定する(Agent Forwarding)
エージェント転送機能とは何か?(Agent Forwarding)
SSHには「エージェント転送(Agent Forwarding)」という機能があります。
エージェント転送(Agent Forwarding)機能は、あるリモートサーバーにSSH接続したときに、そのリモートサーバーから更に他のリモートサーバーに簡単にSSH接続できるようにするための機能です。
通常、リモートサーバーから他のリモートサーバーにSSH接続しようとすると、接続元のリモートサーバーの中にも秘密鍵を置いてssh-agentの設定をする必要があります。
ですが、エージェント転送(Agent Forwarding)を使うと、接続元のリモートサーバーに秘密鍵を置くことなく、そこから他のリモートサーバーにSSH接続することが可能になります。
ローカル環境(自分のPC)
↓ SSH接続
リモートサーバー1
↓ SSH接続 ※秘密鍵を共有
リモートサーバー2
Githubにエージェント転送機能でSSH接続する
リモートサーバーとGithubに対して、エージェント転送(Agent Forwarding)機能を使う流れは以下のようになります。
ローカル環境(自分のPC)
↓ SSH接続
リモートサーバー
↓ SSH接続 ※秘密鍵を共有
Github
このためには、リモートサーバーに接続したときに、秘密鍵の共有(エージェント転送機能)を許可するようにします。
SSHのエージェント転送機能の使い方
エージェント転送(Agent Forwarding)機能を使う方法は大きく2つあります。
オプションで許可する
エージェント転送(Agent Forwarding)機能を使用する、すなわち、秘密鍵を共有する方法の一つ目は「-A」オプション使用する方法です。
SSHでリモートサーバーに接続するときに、以下のように「-A」オプションをつけます。
$ ssh -A <SSHアカウント名>@<サーバー名>
これだけでエージェント転送(Agent Forwarding)機能がオンになります。
SSHのconfigファイルで許可する
エージェント転送(Agent Forwarding)機能を使用する際に、毎回「-A」オプションをつけるのは面倒です。
これを「-A」をつけずに、通常通りにリモートサーバーにアクセスエージェント転送(Agent Forwarding)機能をONにすることができます。
以下のように、SSHのconfigファイル(~/.ssh/config)に「ForwardAgent yes」を追記します。
VSCodeを使っている場合は以下のコマンドを入力します。
$ code ~/.ssh/config
Vimを使っている場合は以下のコマンドを入力します。
$ vi ~/.ssh/config
「config」ファイルを開いたら以下のようにします。「ForwardAgent yes」を記載していることがポイントです。
Host <好きな名前>
HostName <ホスト名>
User <ユーザー名>
Port <ポート番号>
ForwardAgent yes
保存して閉じれば設定は完了です。
こうすることで、「ssh <好きな名前>」でリモートサーバーにアクセスでき、かつ、エージェント転送(Agent Forwarding)機能がオンになります。
$ ssh <好きな名前>
エージェント転送機能がないとどうなるか?
リモートサーバーにSSH接続したときにエージェント転送機能をONにしておかないと、Githubなどの他のサーバーにSSH接続しようとしたときに次のようなエラーが発生します。
Authentication failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
アクセス権がありませんと表示され、接続できません。
リモートサーバーにGithubのメールアドレスとアカウント名を登録する
リモートサーバーからGithubにSSH接続するためには、リモートサーバーのGitにメールアドレスと名前を登録する必要があります。
Git関連の登録がまだの場合は以下のコマンドを実行してください。
まずは「git init」でGitを使えるようにします。
$ git init
「git add」と「git commit」で最初のコミットをしておきます。
$ git add .
$ git commit -m "First Commit"
続いて、リモートサーバーのGitにメールアドレスと名前を登録します。ダブルクオーテーションの中を自分のメールアドレスと名前にしてください。
$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"
GithubのレポジトリにSSH接続でプッシュする
SSH接続を使って、Githubのレポジトリにリモートサーバーのコミットをプッシュします。
まずは、Githubにレポジトリを作成し、レポジトリで「SSH」のタブをクリックして、表示された「git@github.com:~」をコピーします。
リモートサーバーに上記のレポジトリのSSHのパスを登録します。
$ git remote add <リモートレポジトリ名> git@github.com:<アカウント名>/<レポジトリ名>.git
GithubのリモートレポジトリをSSHで登録できたら、「git push」でリモートサーバーのコミット履歴をGithubにプッシュします。
$ git push <リモートレポジトリ名> <ブランチ名>
実例
リモートレポジトリ名を「origin」とする場合は以下のようになります。
$ git remote add origin git@github.com:user/repogitory.git
続いて、「git push」を実行します。
$ git push -u origin master
The authenticity of host 'github.com (13.114.40.48)' can't be established.
ECDSA key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
ECDSA key fingerprint is 111:11:11:11:11:41:11:15:1d:1a:1e:1e:11:11:31:21:11.
Are you sure you want to continue connecting (yes/no)?
過去にSSH接続したことがないサーバーにアクセスしようとしてるが、接続してもいいか?と聞かれるので「yes」と入力します。
「-u」は上流ブランチに設定するというオプションです。
以下のように表示されたら、git pushは完成です。
Counting objects: 12015, done.
Compressing objects: 100% (11633/11633), done.
Writing objects: 100% (12015/12015), 219.57 MiB | 4.30 MiB/s, done.
Total 12015 (delta 2629), reused 0 (delta 0)
remote: Resolving deltas: 100% (2629/2629), done.
To git@github.com/user/repogitory.git
* [new branch] main -> main
Branch main set up to track remote branch main from origin.
参考リンク
- Github公式 新しい SSHキーを生成してssh-agentに追加する
- Github公式 アカウントへの新しい SSH キーの追加
- Github公式 SSH接続をテストする
- Github公式 SSHエージェント転送の利用