初心者がSSHについて学ぶ(´･ω･`)

#この記事について
 

■ 対象：<font color="DeepSkyBlue">**IT初心者しょぼん君：**</font color>(´･ω･`)
・初心者向け、イメージを掴むキッカケになることが目的の記事
・砕いた理解で、一部正確ではない場合があります。

■ しょぼん君のぼやき
<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『使ってるけど、よく知らぬ』




#SSHとは

SSH(Secure Shell)とは、安全に通信を行って、ネットワークに接続された機器を遠隔操作するための通信手段（プロトコル）の１つです。「通信する側とされる側で、SSHでやり取りをしよう！」と取り決めることで安全に通信を行います。

SSHには、SSH1 と SSH2 の2種類の通信手段（プロトコル）があります。
現在はSSH2を利用するのが主流となっているため、これより以下は、主にSSH2について話をしています。

SSHを利用するためには、前提としてSSHプロトコルを使用する為のソフト(例えば、OpenSSHなど)が導入されており、サーバー側で「SSHデーモン」、クライアント側で「SSHクライアント」が起動されている必要があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/147613/c11338dc-c451-3c42-7082-a42cd04e45aa.png)

Linuxではほぼデフォルトで導入され、起動されています。sshコマンドが使えるか確認してみましょう。

```sshコマンドが使えるか確認.
$ ssh -V
```

<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『sshコマンドって、sshの通信を可能にするツールのコマンドだったんだね』

#sshの認証方法
sshの通信では、通信してやりとりする相手が本当に正しいか。を確認するために認証を行います。
sshの主要なユーザー認証方式では、「パスワード認証方式」と「公開鍵認証方式」の2通りがあります。


###①パスワード認証方式
パスワード認証方式は、ユーザー名とパスワードでログインする方式です。ユーザー名とパスワードは接続先OSのユーザーアカウントで作成をした情報を使用します。
強固なパスワードを設定し、管理をしっかり行えばパスワード認証方式でも問題はありませんが、それらの管理や設定は各ユーザーに依存するため、一定水準で安全に利用するためにはパスワード認証方式は使用せず、SSHの設定ファイルを変更して無効にするのが標準です。


<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『ユーザー名とパスワードを知っているから、正真正銘しょぼんだよ』

###②公開鍵認証方式
事前にローカル側で作成した公開鍵を、ログイン先のサーバに登録することで、登録された公開鍵に対応した秘密鍵を持っているクライアントのみが接続できる認証方式です。「パスワード認証」と比べ事前の準備が必要ですが、個々のユーザーの設定に依存しづらいという側面もあり、より安全な認証です。

<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『この秘密鍵の証明が目に入らぬか〜！ということだね』

しょぼん君が、「目に入らぬか〜！」と言うには、サーバーがしょぼん君のことを知っていなければいけません。そして、サーバーはその秘密鍵が本物かを見極める必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147613/f0a342a6-a0fa-5f63-3b94-150943779697.png)




また、しょぼん君は通信要求をしている相手が、本物の対象サーバーなのかを確かめる必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147613/706ee410-0ecd-42ea-82c5-2b3438603d0d.png)


公開鍵認証方式では「秘密鍵と公開鍵」を利用して上のような「ユーザー認証」「ホスト認証」を実施ししています。


##公開鍵認証方式

公開鍵認証方式では、クライアントとサーバー、それぞれの「公開鍵」「秘密鍵」を利用して、安全な通信を実現します。

クライアントの公開鍵は通信先のサーバーに事前になんらかの方法で配置しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147613/405c117c-db04-61de-938e-4ea3f9a480bf.png)


ここでは、いくつかある利用方法のうち「鍵交換」と「署名」に絞ってお話しします。

###鍵交換
１つ目の利用方法として、鍵交換があります。
鍵交換では、通信を開始する際にお互いの公開鍵を交換します。（ディフィー・ヘルマン鍵共有など）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147613/9f313f75-1d03-cfae-fbcd-b820dc0ee3a0.png)

各々の秘密鍵と、交換した公開鍵を組み合わせて計算をすることで、鍵交換した間でしか知り得ない共通情報（下図では計算結果A）を得ることが出来ます。ここで得られた計算結果は共通鍵暗号方式の鍵（暗号鍵）として利用されます。またそこから、セッションIDも生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147613/a857ad3b-e0b8-0e76-2b86-318006a287c8.png)

以下のお互いにしか知り得ない情報が生成された。
・共通鍵
・セッションID


`共通鍵暗号方式`
暗号化と復号に同一の（共通の）鍵を用いる暗号方式

<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『お互いの計算結果が同じになる性質を利用して、それを合鍵（共通鍵）にしちゃうんだね。それとは別にセッションIDというのもあるとな。』


###署名(電子署名)
鍵交換では、共通鍵で暗号化された経路が作成されましたが、さらにお互いが正しい通信相手であることを証明する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147613/6d7a177e-6071-596d-05a1-438629c77288.png)


そこで「署名」を利用します。
「公開鍵」「秘密鍵」には、それぞれ以下の性質があり、秘密鍵で作成した「署名」を公開鍵で「検証」することで公開鍵に対応した秘密鍵を持った相手であることを確認します。



`公開鍵`
人に知られても問題ない（メールなどで送っても良い）
秘密鍵で作成した電子署名の妥当性を検証出来る

`秘密鍵`
人に知られてはいけない
公開鍵を生成出来る
電子証明を生成出来る

<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『事前にサーバーに配置しておいたしょぼんの公開鍵で、秘密鍵の署名を検証して確認するんだね。』


また、鍵交換時に作成された「セッションID」を利用することで、署名の流用を防止することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147613/4ad49a79-90ca-4a9e-15dd-1209c712a077.png)


<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『しょぼん印を盗まれてもセッションIDが違ければ別人ってわかるね』




##SSH通信をやってみる
実際に鍵を作成して、通信をしてみましょう。通信先のサーバーが準備されていることを前提に以下の作業を実施します。それぞれクライアント側の作業とサーバー側の作業があります。


### 秘密鍵と公開鍵を生成（クライアント）



ホームディレクトリ配下に、権限を指定して.sshフォルダを作成します。


```鍵を作成するディレクトリを作成.
$ install -m 0700 -d ~/.ssh
```

鍵を作成します

```鍵を作成.
$ cd ~/.ssh
$ ssh-keygen -t rsa -b 4096 -C "Qiita@hoge.com" -f ~/.ssh/id_rsa
```

ssh-keygenのオプション
`-t`「鍵の種類を指定」
`-b`「生成する鍵のビット数を指定」
　　　RSA 鍵の場合、最小のサイズは 1024 ビットであり、デフォルトは 2048 ビット
`-C`「コメントを追加」
`-f`「鍵を格納するファイル名を指定」




>Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):パスフレーズを入力（入力しないとなしになる)
Enter same passphrase again:  パスフレーズを再入力
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.

```鍵が作成されたか確認.
$ ls ~/.ssh
config		id_rsa		id_rsa.pub	known_hosts	known_hosts-e	known_hosts.old
```

`id_rsa.pub` ->公開鍵
`id_rsa` ->秘密鍵


<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『鍵が出来た。~/.sshに鍵を置くのがデフォルトなのだね』

作成した公開鍵を、サーバーに配置することでSSHでの通信が実現します。




###サーバー側
sshでログインしたいユーザーのホームディレクトリ配下に、.sshディレクトリがない場合には権限を指定して作成。

    $ install -m 0700 -d ~/.ssh

authorized_ファイルを作成し、権限を変更する。
内容は、クライアント側で作成した「id_rsa.pub」の内容を記載する。

    $ vi ~/.ssh/authorized_keys
    $ chmod 600 ~/.ssh/authorized_keys

ルートになり、sshd_configを編集する

    $ sudo su -
    # vi /etc/ssh/sshd_config

以下の#を外す
>
 #RSAAuthentication yes
 #PubkeyAuthentication yes
 #AuthorizedKeysFile     .ssh/authorized_keys

追加で以下を設定しても良い
PasswordAuthentication:no
　--> パスワードログインを禁止
PermitRootLogin:no
　--> rootでのログインを禁止

sshdを再起動（以下コマンドはCentOSの場合）

    # service sshd restart



###ログイン

以下のどちらかのオプション指定でログイン

    ssh -l <ログイン先ユーザー名> -p <ポート番号> <host>

    ssh -p <ポート番号> <ログイン先ユーザー名>@<host>


<details>
<summary>sshのオプション</summary>
-l「ユーザーを指定」
　　　<ログイン先ユーザー名>@ と同じ
-p「ポート番号を指定」
　　　sshのデフォルトは22番ポートだが、変更している場合は指定が必要
</details>


<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『繋がった。ログイン情報指定するのって面倒だね』

#Tips

ログイン情報を事前に書き込んで、覚えさせておくことが可能です。

    vi ~/.ssh/config
例えば以下のような内容を書き込みます。
>HOST RA_KU_SI_TA_I  <--（ログインの際に入力する文字です）
    HostName 192.168.111.1 <--（ホスト名やIPアドレス）
    User hoge <--（ユーザー名）
    Port 1234  <--（ポート番号
）

以下コマンドでログイン可能になります。

    ssh RA_KU_SI_TA_I

<font color="DeepSkyBlue">**しょぼん君：**</font color>(´･ω･`)『別資料を参照しながらは面倒だったから、これは便利だな』


---
参考：[SSHの公開鍵認証における良くある誤解の話](https://qiita.com/angel_p_57/items/2e3f3f8661de32a0d432)