【ssh】SSH通信でリモートサーバに接続する流れ(公開鍵認証)[Linux]

#**はじめに**
`amazon EC2`、 `Sakura VPS`、`大学内計算機`、といった3つのリモートコンピュータにsshでローカルから接続することがありましたので、ssh通信する際の導入手順を下記にまとめておきます。

#**SSH導入手順**
###**0. 前提**
・　ローカルマシンOS：MacOS

省略可能な手順はかっこ`（）`で囲んでいます。
また下記では、公開鍵はhelloworld、秘密鍵はhelloworld.pub、リモートサーバ(のIPアドレス)は153.122.203.7であると仮定しています。

###**1. `.ssh`ディレクトリに移動**

```
$ cd ~/.ssh
```

もし`.ssh`ディレクトリがローカルの環境にない場合は、`mkdir`コマンドで作成しましょう。

```
$ mkdir ~/.ssh
```

###**2. 公開鍵と秘密鍵を生成**
`ssh-keygen`コマンドで公開鍵と秘密鍵を生成します。

- `tオプション`　鍵タイプを指定します
- `fオプション`　鍵ファイルを指定します（既に存在するファイルを指定した場合は上書きされます）

上記２つのオプションを利用して鍵を作成します。
**passphrase**を設定する必要がありますが、これらはリモートに最初接続する際、必要となるのでメモなどをとっておきましょう。
注）**passphraseを設定する際、画面上には表示されません**が、問題なく入力されていることに注意しましょう。

```
$ ssh-keygen -t rsa -f helloworld
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): #ここでパスフレーズを設定（画面には表示されません）
Enter same passphrase again:
Your identification has been saved in helloworld.
Your public key has been saved in helloworld.pub.
The key fingerprint is:
SHA256:5qOS0dGA2S3Vvh5IGxWofJQU0bIZw7xvzJjlKbWeHZw furukawatakuya@furukawatakuyanoMacBook.local
The key's randomart image is:
+---[RSA 2048]----+
|     + *=B..     |
|    o + @ +      |
|     . * X       |
|      + O +      |
|     . +S& = .   |
|    . .o* @ E    |
|     o  o= + .   |
|    o  . .+ .    |
|     ..          |
+----[SHA256]-----+
```
ここでは、鍵タイプは**RSA**に指定しています。
注） RSAとは公開鍵暗号方式な暗号化のやり方のうちの一つです。
**RSA**は「**R**ivest **S**hamir **A**dleman」の略ですが、これらはこのやり方を考えた人達です。その頭文字をとってRSAと命名されています。

また鍵ファイルは`helloworld`としています。
実際に作成されたか確認してみます。

###**(3. 秘密鍵と公開鍵が作成されたか確認)**

```
$ ls ~/.ssh
helloworld helloworld.pub
```
`id_rsa`（秘密鍵）と`id_rsa.pub`（公開鍵）の２つのファイルが作成されます。
ここでは、helloworld(秘密鍵ファイル)とhelloworld.pub(公開鍵ファイル)が作成されています。

###**(4. 鍵の中身を確認)**
こちらは鍵の中身を確認しているだけですので、実際には実行しなくても問題ありません。

```
$ less ~/.ssh/helloworld
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,FF7DF72997ED21E3215D332347B69B1C

R44uCeywFmR82VunWoGaBi5Z35aMx0rHXzCNcHtK91+DxQjGWGU2wAt6LSibzPmy
Tqpr+6oxLHIFaOuQo8mRc6pJ+afhbWfYS1PipN/A1L0YtAoMdTJWtONcNtPSSM8/
e51KfYfbsokxoIoSku64E9D85Pi3/7EnUl8ZLgYtlDfc4SidfDOCE1AtMU0BAzwt
CcJyPnMazq741GxawDpx6Y6WSUBpWB2AZH7UcaFFJie6/y3aA3D6vrLu623AHI2G
fFYxVtV2dZRZxqP2KUNY/dxUmjA+e4xWDPRaVfTu3hi031cGrRZ5XRV8JSKX201x
ePbApK/LcVgy+L3ZNCLesZMeihjOXU0tdpYkDTgvZR0yLX0oeXvIFrROZoZU2s1S
w5lzPgvOTRv8ZSESg7y8ODM1ADFI4OQoKBAE/43dj4L5zi+awaxZOL5ENe3ibLwy
6aiYnKwiZDJr6i8yGgWuMqjWSFjPyFoJJsnYE1OVX0XRT96zmJ/h1B8biKhKl63T
qQzjtVRO+3XPlYY4FErUzQnxNDkPM2AMzubcZY4Z6LAJtPqaRShTQLfeTczMQP0/
hE2vI0gipZYk8v9mFTARNFIwBlt3pRMlPErhpaUl4fp1eCADb4sQq1cxUdxbB5W6
y8UCuNz8z8zOfU8S5cTdo3aCKjr2n63gsLKgJy/pvauaZHaUufY395ZxJStOiHHR
E4qklnbZqVOlsaXspijngto2mAxCrds5hDzayW8ru0DGo4GRuHM4A3keurAvN91T
0RDGjnVC769vxPdVlSTdDrymwS2rreWR0FLpIRVTONg2IZfVswJwZE3jq3hvzQqs
9mm1QG5C6VFnNbj8CXmbe+XAhslIDoq65XBGaKZCn/Gwgy/ge4ssEzMP8lVlIWx
```

このように複雑な文字列で鍵は生成されています。

###**5. 鍵をリモートサーバに送信**
`scp ~/.ssh/id_rsa.pub [ユーザ名]@[IPアドレス]`で公開鍵をリモートサーバに送信することができます。
また、
`scp ~/.ssh/id_rsa.pub [ユーザ名]@[IPアドレス]:~/.ssh`とすることで、リモートサーバ`[ユーザ名]@[IPアドレス]`のホームディレクトリ`~`の`.ssh`ディレクトリに公開鍵を送信することができます。

ここで蛇足ですが、`scp`コマンドは**send copy**の略であり、送信先(リモート)のディレクトリを指定してファイルを送ることができるコマンドです。

```
$ scp ~/.ssh/helloworld.pub root@153.122.203.7:~/.ssh
root@153.122.203.7's password: #ここにrootユーザのpasswordを入力
100%  426    13.2KB/s   00:00
```

###**6. リモートサーバにログイン**
ここからリモートサーバにログインして作業します。
SSHでリモートログインするコマンドを一般化すると次のようになります。
`ssh [ユーザ名]@[IPアドレス]`

```
$ ssh root@153.122.203.7
root@153.122.203.7's password: # ここにrootユーザのpasswordを入力

[root@153.122.203.7 ~]#
```
このようになればログイン成功です。

###**7. 公開鍵ファイル（リモート）を作成し、公開鍵（ローカル）を追記**
（リモートサーバ内で作業）

####**7.1 `.ssh`ディレクトリに移動**

```
$ cd ~/.ssh
```
####**7.2 公開鍵のファイル(authorized_keys)を作成**

```
$ touch authorized_keys
```

####**7.3 ローカルから送信した公開鍵を公開鍵ファイルに追記**
`cat id_rsa.pub >> authorized_keys`のコマンドで鍵を公開鍵ファイル（authorized_keys）に追記することができます。

```
$ cat helloworld.pub >> authorized_keys
```

####**7.4 ローカルから送信した公開鍵ファイルを削除**
ローカルから持ってきたhelloworld.pubの中身は、公開鍵ファイルauthorized_keysに無事写され、helloworld.pubは不要になったので削除しておきましょう。

```
$ rm helloworld.pub
```

###**8. 権限の変更**
（リモートサーバ内で作業）

最後に`.sshディレクトリ`と`authorized_keysファイル`の権限を設定します。 `.sshディレクトリ`には読み・書き・実行のすべての権限、authorized_keysファイルには読み・書きの権限を設定します。

```
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
```
権限に関しては、[こちら](https://qiita.com/takuyanin/items/18590600d077df707923)の記事にまとめていますので、上記コマンドの意味がわからなければご参考ください。

ですが、一点、注意点があります。
ディレクトリ(`.ssh`)に対しては`700`の権限を与え、ファイル(`authorized_keys`)に対しては、`600`の権限を与えていますが、こちらの理由は、ファイルとディレクトリで**読み・書き・実行**の定義が違うためです。

- ファイルの権限

|記号|意味|
|:--:|:--|
|r|読み取り(read)|
|w|書き込み(write)|
|x|実行(execute)|

- ディレクトリの権限

|記号|意味|
|:--:|:--|
|w|読み取り：ディレクトリに含まれるファイル一覧の取得|
|r|書き込み：ディレクトリの下にあるファイル・ディレクトリの作成・削除|
|x|実行：ディレクトリをカレントディレクトリにする|

###**9. 公開鍵認証**

公開鍵をコピー・サーバ側に設置できたので、公開鍵認証でログインできるか確認します。作成した秘密鍵が`~/.ssh/id_rsa`に保存されていれば、リモートサーバにログインするときに自動的に鍵を使用した接続を行うようになっています。

```
$ ssh root@153.122.203.7
```
こちらのコマンドで、自動的に`~/.ssh/helloworld`の秘密鍵が使用され、接続が行われるはずです。

以上で完了です。


#**補足**
`scp`コマンドの代わりに`ssh-copy-id`コマンドを使うと、
（ローカルPCで公開鍵を生成してそれをリモートサーバに持って行って`.ssh/authorized_keys`に追記しないといけないといった）面倒な作業を一遍に行ってくれます。

```
$ ssh-copy-id -i helloworld.pub root@153.122.203.7 
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "helloworld.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@153.122.203.7's password:

Number of key(s) added:        1

Now try logging into the machine, with:   "ssh 'root@153.122.203.7'"
and check to make sure that only the key(s) you wanted were added.
```
`ssh-copy-id`が何より便利である点は、リモートサーバを指定するだけで、`~/.ssh/authorized_keys`ファイルに公開鍵がコピーされることです。

つまり、公開鍵認証するに当たっては、下記のコマンドで十分になります。

```
$ cd ~/.ssh
$ ssh-keygen -t rsa -f helloworld
$ ssh-copy-id -i helloworld.pub root@153.122.203.7
$ ssh root@153.122.203.7

# ここからリモートサーバで作業
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
```

だいぶ工数が省けました。

#**おわりに**
今回は、コマンドを列挙してSSH通信の流れを記しましたが、鍵認証や暗号化などの仕組みに関しては触れておりません。ですので、次回は、仕組みにフォーカスしてまとめていきたいと思います。

こちらの記事が役に立ったという方は、いいね、よろしくお願いします(^^)
また、[takuyaninのマイページ](https://qiita.com/takuyanin)にlinuxコマンドなどに関していくつか記事をまとめてますので、よければご参考ください。