ラズパイでやらなければいけない４つのセキュリティ対策！

この記事は[Raspberry_Pi - ラズパイでやらなければいけない４つのセキュリティ対策！](https://nokonoko1203.qrunch.io/entries/DIek2g0AhGRDkGDZ)の再投稿です。

# はじめに

ラズパイは低価格で高スペックで出来ることも多いのですが、セキュリティ面を何も気にせずデフォルトで利用するのはかなり危ないです！

というのも、ラズパイを使う以上はおそらくインターネットに接続することになると思うのですが、ラズパイはrootユーザーの名前とパスワードが公開されているので、インターネットに接続した段階で、猛烈なアタックを受けます。

なので

- 新規ユーザーの作成

- SSHで公開鍵認証

- ポート番号等の設定変更

- piユーザーの削除

を行っていきます

参考：[5ステップで完了！ラズベリーパイ(B+)のセキュリティ設定まとめ！](http://masatolan.com/raspberry-pi/raspberry-pi-security/)

# 前提条件！

参考：[Raspberry PiにSSHで公開鍵認証を使いたい！](http://g2-girichan.hatenablog.com/entry/2017/02/07/173543)

まずはルートユーザーでログインします。

ラズパイの設定が終わっていない方は[こちら](http://doboku-it-engineer.com/programming/raspberrypi3-b)を参考にして

①piユーザーのパスワードの変更

②ラズパイをSSHで接続

③ホスト名を変更してアクセス

などが出来るようにしてみてください！

現在の状況
- ユーザー名：pi
- パスワード：任意で設定したもの
（SSHの公開鍵認証でログインする際に利用するパスフレーズとこのユーザーのパスワードは別物ですので混同しないように気を付けてください！）

＊＊＊＊＊
この記事はCGIモード（コマンドライン操作限定のモード）での構築手順記事になります！
GUI操作のモードで始めると後記の`piユーザーの削除`の項目でハマりますので`追記`項目をご覧になってCUIモードに変更してセキュリティ対策を行うようにした方が良いと思われます！
＊＊＊＊＊

# ユーザー追加

参考：[RaspberryPiをRaspbianで使う場合の初期設定メモ（ユーザ追加）](https://qiita.com/R-STYLE/items/b481ba2d695ddf8bcee4)

前述の通り、デフォルトのpiユーザーはユーザー名は当然のこと、パスワードも公開されており、今後色々といじっていくには危険な状態なので、ユーザーの追加と権限の付与を行なっていきます。

## ①rootのパスワードを設定

まずrootのパスワードを設定します。

```
$ sudo passwd root
Enter new UNIX password: #rootのパスワードを設定
Retype new UNIX password: #パスワードを再入力
passwd: password updated successfully
```

## ②ユーザーの追加

次にユーザーの追加を行います。

`sudo adduser 〇〇`を実行すると以下のような出力がされますので、それに従い入力してください。

```
# 〇〇というユーザーを追加
$ sudo adduser 〇〇
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LANG = "ja_JP.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
Adding user `〇〇' ...
Adding new group `〇〇' (1003) ...
Adding new user `〇〇' (1003) with group `〇〇' ...
Creating home directory `/home/〇〇' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: #新しく作成するユーザーのパスワードを設定
Retype new UNIX password: #パスワードの再入力
passwd: password updated successfully
Changing the user information for 〇〇
Enter the new value, or press ENTER for the default
	Full Name []: #入力の必要なければそのままEnter
	Room Number []: #同上
	Work Phone []: #同上
	Home Phone []: #同上
	Other []: #同上
Is the information correct? [Y/n] Y #「Y」と入力してEnter
```

## ③管理者権限の付与

```
# piユーザーのグループを確認
$ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev spi i2c gpio

# 同じグループに新規ユーザーを登録
$ sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,netdev,input,spi,gpio 〇〇
〇〇 : 〇〇 adm dialout cdrom sudo audio video plugdev games users input netdev pi spi gpio
```

追加が出来たら、`exit`コマンドで一度ラズパイからログアウトして、追加してユーザーでログインできるか確認します。

```
# ラズパイからログアウト
$ exit

# ラズパイに新規ユーザーでログイン
$ ssh 〇〇＠192.168.XXX.XXX
```

## ④新規ユーザーがパスワードなしでsudoを実行できるようにする

```
# sudo 設定
$ sudo visudo
```

上記コマンドで`/etc/sudoers`ファイルをエディタで開いて、下の方にある`#includedir /etc/sudoers.d`の項目を編集して`pi ALL=(ALL) NOPASSWD: ALL`を削除してpiユーザーをパスワードなしでのsudoを実行できなくし、`〇〇 ALL=(ALL) NOPASSWD: ALL`を追記しましょう！

```
#includedir /etc/sudoers.d
〇〇  ALL=(ALL) NOPASSWD: ALL
```

その後、デフォルトのpiユーザーをsudoers（管理者のグループ）から除外しましょう。

```
# piユーザをsudoグループから外す
$ sudo gpasswd -d pi sudo
Removing user pi from group sudo
```

piユーザーのグループを確認し、それと同様の権限を与えるために、新規ユーザーを同様のグループに追加しましょう！

# 公開鍵と秘密鍵を作成

参考:[SSHサーバの設定(ポート番号変更、rootのログイン禁止、パスワード認証禁止)
](https://www.adminweb.jp/web-service/ssh/index8.html)

公開鍵認証では、サーバーに保存した公開鍵と自分で所有しておく秘密鍵を作成し、これらの組み合わせがマッチした時だけ接続が許可される方式です。

このため、**秘密鍵が流出してしまうと自由にサーバーにアタックをかけることが出来てしまうので、絶対に流出しないように注意しましょう！**

## ①鍵の作成

```
# 鍵を作成
$ ssh-keygen -t rsa
```
入力すると以下が表示されます。

```
# 保存場所の確認
$ Enter file in which to save the key (C:\Users\[username]/.ssh/id_rsa):

# 公開鍵認証で接続する際のパスフレーズの入力
$ Enter passphrase (empty for no passphrase):

# 確認のための再入力
$ Enter same passphrase again:
```

ファイルの保存先はデフォルトで問題ないと思いますが、パスフレーズはセキュリティ面を気にして任意の物を入力しましょう！

全て入力すると`.ssh`という隠しフォルダの下にid_rsaとid_rsa.pubという２つのファイルが作られていると思います。

id_rsaが秘密鍵でid_rsa.pubが公開鍵になります。

## ②ラズパイに公開鍵を送信

[こちら](http://doboku-it-engineer.com/programming/raspi-ssh)を参考にして公開鍵をSSHでラズパイに送信します。

```
# ラズパイのホームディレクトリに.sshディレクトリを作成
$ mkdir ~/.ssh
```

```
# PCでLAN内からRaspberry Piに公開鍵を送信
$ scp -P 22 .ssh/id_rsa.pub 〇〇@192.168.XXX.XXX:/home/〇〇/.ssh
```

## ③公開鍵のパーミッションを変更
ラズパイでは公開鍵認証でアクセスされた際に、authorized_keysというファイルの中から対応する公開鍵を探しに行くようです。

なので

- **初めて公開鍵を設定した**

か

- **既に公開鍵を作成しており、別の公開鍵がラズパイに入っている**

かのどちらかによってやることが異なります

### 初めて公開鍵を設定した
 
- **公開鍵（authorized_keys）のパーミッションは600にして**

- **.sshフォルダのパーミッションは700にして**

- **id_rsa.pubをauthorized_keysに結合したら、id_rsa.pubは消さなければならないようです。**

 
 ```
 # ラズパイに接続
 $ ssh 〇〇@192.168.XXX.XXX

# パーミッションを700に変更
$ chmod 700 ~/.ssh

# id_rsa.pubの内容をauthorized_keysに書き込み
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

# パーミッションを600に変更
$ chmod 600 ~/.ssh/authorized_keys

# authorized_keysに書き込みしたの、不要となったid_rsa.pubを削除
$ rm ~/.ssh/id_rsa.pub
 ```

参考：[【秘密鍵/公開鍵】コピペで出来る！鍵認証の設定方法](https://qiita.com/nnahito/items/dbe6fbfe347cd66ae7e6)

### 既に公開鍵を作成しており、別の公開鍵がラズパイに入っている

すでに別のマシンなどでラズパイと公開鍵認証で接続したことがある方はこちらです！

既存のauthorized_keysに書き込むだけで完了です。

```
 # ラズパイに接続
 $ ssh pi@192.168.XXX.XXX
 
 # 転送したid_rsa.pubの内容をauthorized_keysに書き込み
 $ cat ~/id_rsa.pub >> .ssh/authorized_keys
```

# ラズパイとSSHの設定変更

参考：[SSHサーバの設定(ポート番号変更、rootのログイン禁止、パスワード認証禁止)](https://www.adminweb.jp/web-service/ssh/index8.html)

[セキュアなSSHサーバの設定](https://qiita.com/comefigo/items/092137ac40f319cb14fa)

ラズパイ側の`/etc/ssh/sshd_config`にSSH設定の変更内容を記述していきます。

`vi`コマンドで編集していきます。

**※必ずしもviで修正する必要はありません！ぼくはviが使えないので`nano`で修正しています…**

おそらく概ね以下のような内容になっていると思います。

```
# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# Expect .ssh/authorized_keys2 to be disregarded by default in future.
#AuthorizedKeysFile	.ssh/authorized_keys .ssh/authorized_keys2

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation sandbox
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

# override default of no subsystems
Subsystem	sftp	/usr/lib/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#	X11Forwarding no
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server
```

この中の一部を修正していきます。

### ①パスワード認証を無効して公開鍵認証のみ許可する

`PasswordAuthentication yes`を`PasswordAuthentication no`に

※これを設定すると、上記の公開鍵認証の設定がしっかり行われていない場合、ログインできなくなります！自分はなんどもやらかして、その度にOSの再インストールを行なっているので注意してください！

```
# 公開鍵認証での接続を確認してからnoにする
$  〇〇＠192.168.XXX.XXX -i ${秘密鍵のパス} -p ${ポート番号}
```

### ②空パスワードを無効

`# PermitEmptyPasswords yes`を`PermitEmptyPasswords no`に

### ③rootユーザでのログインを禁止

`#PermitRootLogin prohibit-password`を`PermitRootLogin no`に

ちなみに、頭に`#`がついている行は設定に反映されない（コメントアウトされている）部分ですので、修正するさいは削除しましょう。

### ④port番号の変更
SSHの接続はデフォルトでは22番が使われておりますが、どのマシンでも大抵22番が使われているため、外部からの攻撃はまず22番のポートが狙われます。

なので、`#Port 22`の箇所の数字を49152 ～ 65535番の中から任意の数字に変えてポート番号を変更しましょう。

### ⑤SSHの再起動
`sudo /etc/init.d/ssh restart`と入力して実行。

これで設定が反映されます。

# piユーザーの削除

新規ユーザーでログインできることを確認したら、piユーザーを消しましょう！

```
$ 〇〇＠192.168.XXX.XXX -i ${秘密鍵のパス} -p ${ポート番号}
```

```
# ユーザーを確認
$ id -a pi
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),29(audio),44(video),46(plugdev),60(games),100(users),101(input),108(netdev),999(spi),998(i2c),997(gpio)

# 削除
$ sudo userdel -r pi
userdel: group pi not removed because it has other members.
userdel: pi mail spool (/var/mail/pi) not found

# 削除されていることを確認
$ id -a pi
id: ‘pi’: no such user 
```

以上でラズパイの最低限のセキュリティ設定が完了です！

お疲れ様でした！

## 追記

@matthew6186 さんからご指摘ありましたが、CUIモード（コマンドライン操作のみのモード）での操作が前提となっております。すみません…

以下、抜粋させていただき追記いたします。

GUIありのRaspbianを使っていると、OS起動時に自動的にpiユーザでログインしてしまうため、そのままpiユーザを削除しようとすると以下のようなエラーになるようです。

```
$ sudo userdel -r pi
[sudo] password for user:
userdel: user pi is currently used by process 570
```

プロセスを確認すると、確かにpiユーザがプロセスを起動していることが分かります。

```
$ ps aux | grep 570
pi         570  1.5  0.1  14692  7292 ?        Ss   21:16   0:00 /lib/systemd/systemd --user
user  2619  0.0  0.0   7348   472 pts/0    S+   21:17   0:00 grep --color=auto 570
```

これを回避するためには、あらかじめRaspbianの起動モードをCUIモードに設定しておいたほうが良いです。
下記の内容を設定・再起動後に改めてuserdelをすれば、記事に記載の通りpiユーザを削除することができます。

```
$ sudo raspi-config

> 3.Boot Options
>> B1 Desktop/CLI
>>> B1 Console

-> reboot
```

# ~/.ssh/configを設定して簡単にSSH接続する
参考：[~/.ssh/configについて](https://qiita.com/passol78/items/2ad123e39efeb1a5286b)

Mac（クライアント）側でSSHの設定ファイルである`~/.ssh/config`を編集することで、毎回`$ 〇〇＠192.168.XXX.XXX -i ${秘密鍵のパス} -p ${ポート番号}`のような長いコマンドを入力せずとも`ssh raspi`という短いコマンドだけでラズパイに接続できるようになります！

```
$ sudo nano ~/.ssh/config
```

```
Host raspi
    HostName 192.168.XXX.XXX
    User ${ラズパイのユーザー名}
    port ${SSHのポート}
    IdentityFile ${秘密鍵のパス}
```

以上の設定を保存すると`ssh raspi`で接続できるようになります！

## ~/.ssh/configを設定して簡単にSSH接続できない！！！
参考：[「ssh config」および「ssh-agent」の活用](https://www.qoosky.io/techs/eaf8fcc1b5)

`ssh_config`の設定をいじってみましょう！

```
$ sudo nano /etc/ssh/ssh_config
```

ファイルの文末に以下を追加してみましょう！

```
Host raspi
    HostName 192.168.XXX.XXX
    User ${ラズパイのユーザー名}
    port ${SSHのポート}
    IdentityFile ${秘密鍵のパス}
```

つながりました！！

```
$ ssh raspi
Enter passphrase for key '~/.ssh/id_rsa': 
Linux raspberrypi 4.14.50-v7+ #1122 SMP Tue Jun 19 12:26:26 BST 2018 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Nov 15 22:51:44 2018 from 192.168.2.4
〇〇@raspberrypi:~ $
```