買ったらまず実施！RaspberryPiのセキュリティ対策

# はじめに
本記事は主にこちらを参考にさせて頂きました。
https://qiita.com/mochifuture/items/00ca8cdf74c170e3e6c6
https://qiita.com/nokonoko_1203/items/94a888444d5019f23a11

買ってすぐのRaspberryPi本体へ適用する前提での方法となります。

私はセキュリティの専門家ではないので、下記だけでは不十分だ！という意見があれば、
積極コメント頂けるとありがたいです！

# 必要なもの
・RaspberryPi (本例ではRaspberryPi3 ModelB)
・PC (SSH接続の確認に使用。本例ではWindows10)
・上記RaspberryPiとPCのLAN接続環境（ルータにつなげばOK）

# RaspberryPiとセキュリティ
安価で必要十分な性能を備えるRaspberrypPiですが、
デフォルト状態でのセキュリティに関しては、例えばWindows10のPCと比べて、
素人目にもヤバい！と思える部分が多くあり、
なんとあの[NASAでもRaspberryPiが原因となった情報流出](https://monoist.atmarkit.co.jp/mn/articles/1909/30/news042.html)が起こっています。
![space_uchu_bouenkyou_bg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/e14201c8-ecb9-f70d-c3d0-d7e7c7f5c235.png)

## 何がヤバい？
端的に言うと、「鍵」にあたる情報が随所でオープンになっています。

例えば自転車のダイヤルキーに例えると、初期値として「1111」や「1234」があり、
それを自分だけが知るキー番号に変えることで、初めて鍵として機能します。

RaspberryPiにおいてはユーザ名やパスワード、ポート番号等が鍵に相当しますが、
デフォルト設定では初期値（ユーザ名の場合「pi」）から変更されていないため、
上記ダイヤルキーの例でいうキー番号が「1111」の状態に相当します。
![dorobou_picking.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/294bc9ba-ce96-2605-0423-20f8a6a558a1.png)
これではRaspberryPiのデフォルト値を知っている攻撃者から筒抜けですね‥



## 具体的な危険ポイント
### ポイント1：ユーザ名とパスワードがデフォルトのまま
デフォルト設定ではユーザ名が「pi」、パスワードが「raspberry」となっています。
どの機種でも共通なので、知っていれば簡単にログインできてしまいます。
~~（最近のRaspbianでは初期設定に従えばパスワード変更されますが、ユーザ名はそのままです）~~
→**最近のRaspberryPi OSは初期設定に従うとパスワードとユーザ名を自分で設定できるため、この危険ポイントは解消されています**

### ポイント2：電源を入れると自動的にログインされる
デフォルト設定では電源を付けるとユーザ名やパスワードなしで自動ログインされます。
スマホにロックが掛かっていない状態と同じですね！
例えばWindowsパソコンではログイン時にユーザ名とパスワードを求められるので、こんなことは発生しません。

→**最近のRaspberryPi OSはデフォルト設定でログイン時にパスワードとユーザ名の入力が求められるため、この危険ポイントは解消されています**

### ポイント3：SSHのポート番号が22
SSHとは、CUIによる遠隔操作の主流である通信手段です。
RaspberryPiを遠隔操作できて便利ですが、同時に攻撃者に遠隔操作される原因ともなります。
これはWindowsでも同様に発生する問題ですが、
デフォルトではSSHのポート番号が22となっており、ネットワークのIPが分かれば遠隔操作可能となってしまいます。
※変更後の番号を忘れるリスクもありポート番号変更の必要性は意見が割れているので、実際に変更するかどうかは各自ご判断いただければと思います

### ポイント4：SSHがパスワード認証
デフォルトではSSH接続はパスワード認証で実施されますが、
よりセキュリティレベルの高い公開鍵認証が推奨されます。
https://l-w-i.net/t/openssh/auth_001.txt

パスワードは「知識認証」、公開鍵は「所持認証」にあたり、
それらを組み合わせた公開鍵認証は、多要素認証の観点からセキュリティレベルが高いそうです。
上の例でいうと、ダイヤルキーと南京錠を組み合わせるイメージですかね！
http://njs-net.hatenablog.com/entry/2015/07/10/091655

## どうやって危険を防ぐ？
下記リンクで恐ろしさが触れられていますが、攻撃はしらみ潰しに行われる事が多いです。
https://www.braveryk7.com/change-22-port/

しらみ潰しに対抗するためには、攻撃に必要な組み合わせを増やすことが有効です。
上のダイヤルキーの例でいうと、ダイヤルの桁数を増やす（例えば4ケタ→8ケタ）事に相当します。
そのために上記ポイントで触れた**ユーザ名、パスワード、ポート番号、SSH認証法を複雑なものに変えます**

ネットワークには上で挙げたポイント以外にも、IPやファイアウォールなど、攻撃を防ぐ鍵に相当する仕組みがあります。

ダイヤルキーに例えるならば、これらの防御手段が4ケタとすると、

ユーザ名を設定すれば5ケタ
パスワードを設定すれば6ケタ
SSHのポート番号を変えれば7ケタ
SSHを公開鍵認証にすれば8ケタ
というように、
組み合わせの数を増やすことでセキュリティレベルが上がる事が、実感できると思います。

# 手順

## ⓪Rootユーザにパスワードを設定

下記のコマンドを実行し、メッセージに従いパスワードを設定する

```
sudo passwd root
```

※誤解されがちですが、rootユーザーにパスワードを設定することは、
セキュリティ的にはむしろリスクを増やす操作なので、④で対策します。
（パスワード未設定のrootユーザには、そもそもログインできない）
これ以降の操作でユーザ設定がおかしくなった時など、いざという時の回復用に設定します。

## ①ユーザ名とパスワードを変更

**※最近のRaspberryPi OSは初期設定に従うとパスワードとユーザ名を自分で設定できるため、この操作は不要です**

デフォルトの「pi」ユーザを削除し、任意のユーザ名とパスワードを設定します

### ユーザの追加

```
sudo adduser [新ユーザ名]
```
→パスワードの入力を求められるので、特定されにくいパスワードを入力すると以下の画面が出てくる

```
　フルネーム []:
　部屋番号 []:
　職場電話番号 []:
　自宅電話番号 []:
　その他 []
　以上で正しいですか？ [Y/n]
```
律儀に記入すると個人情報の流出リスクが増えるので、特別な理由がなければ空欄のままYを入力するのが良いかと思います。

### 「pi」ユーザから新ユーザに権限コピー

```
groups pi
```
上記で「pi」ユーザの権限を確認し、下記操作で出てきた権限を全て新ユーザにも追加します。（pi,adm‥以降が追加する権限です）

```
sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,netdev,input,spi,gpio 新ユーザ名
```

```
groups [新ユーザ名]
```
で権限を追加したグループ一覧が表示されれば成功です。

### 「pi」ユーザから新ユーザにフォルダコピー
下記コマンドを実行します

```
sudo cp -r /home/pi/* /home/[新ユーザ名]
```
以上でポイント1対策は完了です。

## ②自動ログインの解除とpiユーザの削除

**※最近のRaspberryPi OSはデフォルト設定でパスワードとユーザ名を入力したログインが必要なため、この操作は不要です**

上記の状態ですと、電源を入れると自動で「pi」ユーザにログインされてしまいます。
上記自動ログインを解除した上で、「pi」ユーザを削除します。
### 自動ログインを解除

```
sudo raspi-config
```

上記コマンドを実行すると、以下のような画面が出てきます
![48efc727.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/2ef8b80b-527c-e7ab-25d7-c993563f756a.png)

Boot options → B1 Desktop/CLI → B1 Consoleと選択してください

※2021/10追記：最新版のRaspberryPi OSでは1 System Options → S5 Boot / Auto Login → B1 Consoleと進む必要があるようです

![dbac3c9c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/1479c1b6-c578-14f1-6303-affcc4f01f3d.png)
![1f6bbe87.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/05f160f9-bbaf-5311-1403-8b190d8740b2.png)
※最後の画面が電源ON時のログイン方法を表しており、それぞれ以下の意味となります。
B1 Console：コンソールでログイン。ユーザとパスワード入力必要
B2 Console Autologin：コンソールでログイン。ユーザ名とパスワード入力不要
B3 Desktop：GUIでログイン。ユーザ名とパスワード入力必要
B4 Desktop：GUIでログイン。ユーザ名とパスワード入力不要

この状態でrebootすれば、コンソール画面が表示されるので、
新ユーザ名とパスワードを入力してログインします。
**※コンソールログインに変更するのは、
GUIだと下記「pi」ユーザ削除時にpiプロセス実行中のエラーが出るからです。**

### 「pi」ユーザの削除
下記コマンドを実行して、piユーザを削除します

```
sudo userdel -r pi
```
下のちょっと怖いメッセージが出てくるかもしれませんが、
気にせず続けてください
（重大な操作時に出てくるようです。今回はユーザで初めてsudoした事に由来）

```
あなたはシステム管理者から通常の講習を受けたはずです。
これは通常、以下の3点に要約されます:
　#1)他人のプライバシーを尊重すること。
　#2)タイプする前に考えること。
　#3)大いなる力には大いなる責任が伴うこと。
```


パスワードが求められるので入力すると、piユーザが削除されます。
このあと

```
id -a pi
```
を実行して、

```
id: 'pi': no such user
```
と出てくれば削除成功です。
このあと

```
sudo raspi-config
```

を実行し、前と同じ流れで
Boot options → B1 Desktop/CLI → B3 Desktopと選択してrebootすれば、
新ユーザでGUI画面にログインできます。

※この状態ではsudoした際に毎回パスワードが求められますが、
煩わしいと感じる方は[こちら](https://blog.pinkumohikan.com/entry/use-sudo-command-without-password)を参照して自己責任でパスワード確認をOFFにしてください

### 起動時認証ユーザを「pi」→新ユーザに変更
[参考リンク](https://qiita.com/k_eita/items/ff64e4687e38ffa1f7d7)

```
sudo nano /etc/systemd/system/autologin@.service
```
を実行（nanoの部分はviやvimでもOK）し、
ExecStart=-/sbin/agetty --autologin pi --noclear %I $TERM
と記載されている部分を
ExecStart=-/sbin/agetty --autologin 新ユーザ名 --noclear %I $TERM
に変更して保存

※この変更を実行しても起動時はパスワード入力が求められるので安心してください。

## ③SSHのポート番号を22から他番号に変更
※変更後の番号を忘れるリスクから、ポート番号変更の必要性は意見が割れており、
変更するかどうかは皆さんで判断いただければと思います。
### SSHの有効化
デスクトップ左上にあるアイコンをクリックし、
![78df4076.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3ee2e974-5788-7092-0a5e-b7fdf37725ee.png)
[設定] → [Raspberry Piの設定]にある[インターフェイス] → [SSH] → [有効]をチェック

下記コマンドを実行し、/bootフォルダ内にsshフォルダを作成

```
cd /boot
sudo mkdir ssh 
```
これでrebootすればSSHが有効となります

### ポート番号の変更
下記のコマンドを実行し、

```
sudo nano /etc/ssh/sshd_config
```
開かれたファイルの上の方にある
 #Port 22
の部分を
Port 新ポート番号
に変更し、（コメントアウトを外すのを忘れずに）

```
sudo /etc/init.d/ssh restart
```
でSSHを実行し、

```
ssh [新ユーザ名]@[RaspberryPiのIPアドレス] -p [新ポート番号]
```
でSSH接続できれば成功です。

## ④SSHを公開鍵認証に変更
上記の方法ではSSH接続はパスワード認証で実施されますが、
公開鍵認証とした方がよりセキュリティレベルが高いそうです。
https://l-w-i.net/t/openssh/auth_001.txt

### 秘密鍵と公開鍵の作成
※これはSSH接続元となる**PC側（本例ではWindows10）での作業**です。
間違えてRaspberryPi側で作成した場合、id_rsaとid_rsa.pubを削除して下さい
※WindowsPCとRaspberryPiが、同ネットワークにある前提で話を進めます。

コマンドプロンプトで下のコマンドを実行します（メールアドレスは任意です）

```
ssh-keygen -t rsa -b 4096 -C "email@example.com"
```
鍵の生成場所を聞かれますが、こだわりがなければEnterでデフォルトの場所へ

```
Enter file in which to save the key (C:\Users\[ユーザ名]\.ssh\id_rsa):
```
パスワードが求められるので、
好きなパスワード（2段階認証の観点ではRaspberryPiユーザパスワードとは別のもの推奨）を入力すると、
上で指定したフォルダにid_rsa（公開鍵）とid_rsa.pub（秘密鍵）が生成されます。

### 公開鍵のRaspberryPiへの送信
色々とやり方（SDカード、Samba等）がありますが、ここではSSHで送信します。

**RaspberryPi側の**ホームディレクトリ直下に.sshフォルダを作成します
（権限関係でハマるので、**絶対に「sudo mkdir」としないでください**）

```
mkdir ~/.ssh
```

**PC側で**下記コマンドを実施し、
SSH通信（厳密には[scp](https://ja.wikipedia.org/wiki/Secure_copy)）で公開鍵を送信（この時点ではパスワード認証を使用）

```
cd [公開鍵の場所 (デフォルトではC:\Users\[ユーザ名]/.ssh/id_rsa)]
scp -P [新ポート番号] id_rsa.pub [新ユーザ名]@[RaspberryPiのIPアドレス]:/home/[新ユーザ名]/.ssh
```

### ※RaspberryPiのIPアドレスの調べ方

```
ifconfig
```
これにより表示される

```
wlan0: flags=   <UP,BROADCAST,RUNNING,MULTICAST>  mtu
        inet 192.168.***.***以下続く
```
このinetの右に記載されている数字がRaspberryPiのIPアドレスとなります。


### 公開鍵のパーミッション変更
**RaspberryPi側で**下記コマンドを実行します。

**・id_rsa.pubの内容をauthorized_keysに追加**

```
cd ~/.ssh/
cat id_rsa.pub >> authorized_keys
```
**・authorized_keysのパーミッションを600に**

```
chmod 600 authorized_keys
```
**・.sshフォルダのパーミッションを700に（うまくいかなければsudoを加える）**

```
chmod 700 ~/.ssh
```

**・公開鍵ファイルを削除**

```
rm ~/.ssh/id_rsa.pub
```

※なお、過去に他のPCから本RaspberryPiに接続したことがある場合は、下記のパーミッション変更操作は不要です（公開鍵のauthorized_keysへの書込のみ必要）

```
chmod 600 authorized_keys
chmod 700 ~/.ssh
```

**公開鍵認証での接続を確認**
**PC側で**下記コマンドを実行し、公開鍵認証でSSH接続

```
ssh [新ユーザ名]@[RaspberryPiのIP] -i [秘密鍵のパス] -p [ポート番号]
```
※秘密鍵のパスは、ファイル名まで記載します
（デフォルトでは「C:\Users\\[ユーザ名]\\.ssh\id_rsa」）

公開鍵認証のパスワードが要求されるので入力します。
Rasberrypiのユーザ名が表示されれば成功です

### 各種SSH設定の変更
SSHのセキュリティを向上させるため、下記の設定変更を実施します。
・rootユーザでのログイン禁止
・パスワード認証を無効化して公開鍵認証のみ許可
・空パスワードを無効に


③のときと同様に、**RaspberryPi側**でsshd_configを編集します。
※OSのバージョンによりデフォルト設定が変わりますが、
変更後さえ合っていれば問題ありません

```
sudo nano /etc/ssh/sshd_config
```
開かれたファイルに対し、下記部分を変更します
**・rootユーザでのログインを禁止**
上の方に記載されている
「#PermitRootLogin prohibit-password」を「PermitRootLogin no」に変更

**・パスワード認証を無効化して公開鍵認証のみ許可**
真ん中付近に記載されている
「#PasswordAuthentication yes」を「PasswordAuthentication no」に変更

**・空パスワードを無効に**
PasswordAuthenticationのすぐ下に記載されている
「#PermitEmptyPasswords no」を「PermitEmptyPasswords no」に変更

### 設定の反映と公開鍵認証接続の再確認
下記コマンドでSSHサービスを再起動し、設定を反映させます

```
sudo /etc/init.d/ssh restart
```

再度**PC側で**下記コマンド実行し、公開鍵認証接続できれば成功です！

```
ssh [新ユーザ名]@[RaspberryPiのIP] -i [秘密鍵のパス] -p [ポート番号]
```

<br>

**以上で、本記事でのセキュリティ対策は全て完了です！**

![home_security.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0557944b-9310-680c-2339-40c492d761dd.png)
**お疲れさまでした！**