初めてのssh

#初めてsshを使ってGitHubにアクセスしました。

会社でGitLabの方を使っていて、git cloneする時はいつもhttpでアクセスしてました。

プライベートでGitHubも使うようになって、MacBook Air 2台持ちで家に設置用で1台、外に持ち出し用に1台で両方から`git pull` / `git push`してソースコード管理してましたが、毎回 Invalid username or passwordと怒られ、その都度GitHubのdeveloper settingsからPAT (Private Access Token)を再生成して使用してました。

毎回それは面倒なのでググったらsshを使うのが多数派っぽかったので、これを機にsshを使ってみようと思った次第です。

ちなみにPATとsshとどっちがいいの？と思ってググったら以下のstack overflowの記事を見つけました（大体自分が持った疑問て他の人も持ってるんですよね）。
[Which is better for GitHub authentication : SSH Key or tokens?](https://stackoverflow.com/questions/67077837/which-is-better-for-github-authentication-ssh-key-or-tokens)
ざっくり言うと、アクセス制御を細かくできる分（リポジトリ内でのアクセス制御やGitHubアクションのアップデート等）PATの方が推奨だそうです。

なお、httpごしのusername, passwordによるアクセスは2021年8月に廃止されたとのこと。

本題の前に、GitHubにおけるsshについての私のざっくり(& 勝手な)理解ですが、sshで生成した公開鍵をgitに保存して、秘密鍵を自分のローカルに置いて(通常 `~/.ssh` に保管される）、gitから送られる暗号化されたデータ(by公開鍵)を秘密鍵によって復元できたら、そこからはsshが安全な通信を行ってくれる、です。合ってますかね？

<追記>
ssh-agentがクライアント側にいて、一度サインインしたらssh-agentがソケットオープンして通信が行われるらしい。参考↓
[How to set up SSSH and Clone Repository using SSH in Git?](https://www.toolsqa.com/git/clone-repository-using-ssh/)

では、本題のsshを使ったGitHubへのアクセスです。
以下のQiitaページを参考にさせて頂きました。

https://qiita.com/shiro01/items/e886aa1e4beb404f9038


### まずはsshキー生成の一例。

```bash
$ ssh-keygen -t ed25519.     ← -tオプション(typeのtだろね？)は生成するキー種類指定。ed25519はEdwards曲線デジタル署名アルゴリズム。
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/username/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):     ← passphraseはprivate keyを暗号化するもので、入力すると毎回アクセス時に聞かれるらしい (※1)
Enter same passphrase again: 
Your identification has been saved in /Users/username/.ssh/id_ed25519.
Your public key has been saved in /Users/username/.ssh/id_ed25519.pub.
The key fingerprint is:     ← 公開鍵のハッシュ値。sshサーバーからクライアントに送られサーバーの成りすましの確認に使用される。クライアント側のknown_hostsに登録される。
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx unsername@MacBook-Air.local
The key's randomart image is:'     ← randomartはハッシュ値をビジュアル化したもの。違いを視認しやすいために。
+--[ED25519 256]--+
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
|  xxxxxxxxxxx    |
+----[SHA256]-----+
```
生成された公開鍵の確認。

```bash
$ cat .ssh/id_ed25519.pub 
ssh-ed25519 (ランダムな文字列) username@hostname.    ← デフォルトでは末尾にコメントとしてユーザ名@ホストコンピュータ名が付与される    
```

<追記>
サーバーはhost keyを持っていて、clientがサーバーに初めて接続すると `/.ssh/known_hosts` にhost keyが追加される。クライアント側はそれによって同じサーバーにアクセスしているのかどうかわかる仕組み。

### 続きまして生成したssh公開鍵をGitHubに登録。
GitHubの settings > SSH and GPG keys > New SSH key と行って必要情報(TitleとKey)を入力する。
Titleは文字通り鍵のタイトルとなる文字列です。空欄でもOKですが、空欄にすると上記で生成された公開鍵を丸コピしてKeyに入力した場合、username@hostnameがタイトルになります。username@hostnameを削除してKeyに入力した場合は鍵の先頭から一定の文字列がTitleとなりました。


### 最後にssh接続してみる。
まずGitHubの以下のページを参考に。正しく設定できてると以下のようにメッセージが表示されます。
[SSH接続をテストする](https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/testing-your-ssh-connection)

```bash
$ssh -T git@github.com     ← -Tオプション(TerminalのTかな?)は Disable pseudo-terminal allocation.
Hi your-username! You've successfully authenticated, but GitHub does not provide shell access.'

$ git clone git@github.com:your-git-username/Your-repository.git
Cloning into 'Your-repository'...
Warning: Permanently added the ECDSA host key for IP address '13.114.40.48' to the list of known hosts.     ← 13.114.40.48調べたらamazonawsのサーバーだった。ECDSAとは？
remote: Enumerating objects: 105, done.
remote: Total 105 (delta 0), reused 0 (delta 0), pack-reused 105
Receiving objects: 100% (105/105), 2.52 MiB | 247.00 KiB/s, done.
Resolving deltas: 100% (32/32), done.
```
(ご参考) ECDSAはElliptic Curve Digital Signature Algorithm。楕円曲線DSA(デジタル署名アルゴリズム）のこと。

### 以上です。
<br>

<その他予備知識>

**RSAとは?**
Rivest–Shamir–Adlemanのお三方の頭文字で、rsaアルゴリズムを発明した人たち ([RSA (cryptosystem)](https://en.wikipedia.org/wiki/RSA_(cryptosystem))

**ssh シンタックス**
ssh username@server.address
もしusername省略したらログインしているアカウントのusernameが使われる。
<br>

<その他参考にしたサイト>

* passphrase、key fingerprint について<br>
[ssh-keygen: What is the passphrase for?](https://security.stackexchange.com/questions/183636/ssh-keygen-what-is-the-passphrase-for)
* randomartについて<br>
[What is randomart produced by ssh-keygen?](https://superuser.com/questions/22535/what-is-randomart-produced-by-ssh-keygen)