[Raspberry Piメモ] SSHでログインするまで

今頃になってRaspberry Piを使おうと思ったので、先人たちの知恵をお借りして設定していく。先人たちがたくさん資料を残してくれているおかげで、ここでは特に新しい話題はないが、それでもつまづいたところ・調べたことをまとめる。

なお、最後に書いたようにDockerを入れてみようとしたところエラーが出てインストールできなかった。RaspbianとDockerはつい先日安定版が更新されたばかりらしく、Issueがオープンになっている。

* [Docker-CE need updating for raspbian buster #709](https://github.com/docker/for-linux/issues/709)

#インストール
[NOOBというOSをインストールするためのソフト](https://www.raspberrypi.org/downloads/noobs/)を書きこんだSDカードを挿してからRaspberry Piを起動すると、インストールするOSを選ぶ画面が表示される。特にGUIが要らなければ「Raspbian Lite」を選んでインストールすれば良い。なお、NOOBが無くてもディスクイメージを書くことでインストールできるが、ライタソフトが必要になるらしいので、NOOBの方が手っ取り早いかと思う。

> 言語設定の注意: NOOBでインストールしていると、画面下に言語設定が表示される。ここで日本語を選択すると、再起動後にメッセージが日本語化されるらしいのだが、フォントが無いために■■■■■と表示される「豆腐現象」に陥る。これが嫌なら、まずは英語のままとし、キーボード配置をJapaneseにすると良い。

* NOOB入手元: https://www.raspberrypi.org/downloads/noobs/

何度かやり直すと思うので、フォーマッタを用意した方が良い。SDカードはOSインストール時にパーティションが切られるのだが、Windowsだとこれがフォーマットできないことがあるためだ。フォーマットにはSDカードの仕様を策定している団体SD Associationの[SDメモリカードフォーマッター](https://www.sdcard.org/jp/downloads/formatter/)があるので用意しておくと良い。(というかセッティング開始から1時間でお世話になった)

* SD AssociationのSDメモリカードフォーマッター入手元: https://www.sdcard.org/jp/downloads/formatter/

# パッケージ更新
パッケージを更新する前にミラーサイトの設定をする。デフォルトでは海外のミラーサイトを使う設定になっているので、ダウンロードに時間がかかることがある。日本のサーバを選んでおくとダウンロード時間が改善する。

* ミラーサイト一覧: http://www.raspbian.org/RaspbianMirrors

ミラーサイトの設定ファイル`/etc/apt/sources.list`はパーミッションが622(rw-r--r--)なので、`sudo nano /etc/apt/sources.list`で開く。以下は2019年7月時点の安定板であるコードネーム`buster`で使うときの設定となる。

```sh
# deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
deb http://ftp.jaist.ac.jp/raspbian buster main contrib non-free rpi
deb http://ftp.tsukuba.wide.ad.jp/Linux/raspbian/raspbian/ buster main contrib non-free rpi
deb http://ftp.yz.yamagata-u.ac.jp/pub/linux/raspbian/raspbian/ buster main contrib non-free rpi
```
設定ができたら、更新のコマンドを実行する。コマンド自体はあまり理解できていないが、以下を実行すると各パッケージが最新になるらしい。なお、ファームやカーネルの更新ができるとされる`rpi-update`は実験用らしいので、一般人は実行しない方が良いらしい。(安定して世に出回ってからの方が安心ということ)

* [If rpi-update is not recommended, what is?](https://www.raspberrypi.org/forums/viewtopic.php?t=137546)
* [やらないで！！　rpi-update](https://www.yukkuriikouze.com/2019/02/05/1608/)
* [Raspberry Pi(Raspbian)のリポジトリ設定とパッケージ更新 ](https://www.コンフレッジ.com/raspberry-piraspbian%E3%81%AE%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E8%A8%AD%E5%AE%9A/)

```sh
# パッケージのリストを更新
sudo apt update
# パッケージを更新
sudo apt dist-upgrade
# いらないソースを消す
sudo apt autoclean
```

# ユーザ設定
デフォルトではユーザ名`pi`、パスワード`raspberry`になっているので、そのままSSHを有効にするのは怖い。SSHを有効にする前に、ユーザの設定をしておく。やり方は色々あるらしいが、以下を参考に`pi`の名前を変える方式にした。参考にしたページに書いてある通り、`pi`ユーザは削除はしない方が良いと思うためだ。

* [[Raspbian]ユーザ名変更の個人的に「正しい」と思うやり方](https://jyn.jp/raspberrypi-username-change/)

1. 一時的にユーザ`tmp`を作成し、sudoグループに加える
1. いったんログアウトし、`tmp`で作業する
1. `pi`ユーザおよびグループを改名する
1. `pi`ユーザのパスワードを変える
1. `新名称のpi`でログインしなおし、`tmp`を削除する

# 言語設定
ここまでは英語版で作業してきたが、日本語が使えるように設定する。ただし、日本語フォントはインストールしない。というのも、SSH経由で利用する場合はSSHのターミナルはPCなので、Raspberry Pi側に日本語フォントが無くても文字化けが起きないからだ。

設定は`raspi-config`から`Localization Options`を選び、`Change Locale`を開いて、ロケールのち一覧から`ja_JP.UTF-8.UTF-8`を選択する。デフォルトロケールも`ja_JP.UTF-8.UTF-8`に設定したら、処理が完了するのを待つ。設定は再起動すると反映される。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/0e62dfb9-9a8b-6a4b-7c53-864f3055e6db.png" width=30%> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/4064026d-961c-6d49-2097-311cb1f18c23.png" width=30%> 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/0eb98a76-b6b5-7f6e-558a-b569c878e6db.png" width="30%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/1f6f6a2d-78df-2d7a-0860-5fc2a0ea494f.png" width="30%">
> 図は既にロケールを変更後にPC側のSSHのターミナルで表示しているので、豆腐表示になっていない。


# SSHをつなぐ
キーボードを行ったり来たりするのが面倒なので、まずはSSHを有効化してしまい、PCからSSHを介して設定を行う(事前にユーザとパスワードをデフォルトから変えているならリスクは小さいはず)。SSHの有効化には`raspi-config`コマンドで設定画面を開く。

* [RaspbianのSSH有効化、ユーザ作成](https://qiita.com/deco1183/items/9546dd5ff7a97322c27b)
 * ユーザ作成や`pi`の削除はしない。

設定画面を開いたら、`Interfacing Options` > `SSH`を開き、有効化する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/e57bbfa8-48be-a2da-ce74-e46ef7d39b6d.png" width=30%> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/6840e173-d543-57b3-4e90-045f7855c9d2.png" width=30%> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/237b79d0-b5c1-3847-3367-e0a946fd83a3.png" width=30%> 

設定ができたら`putty`などでログインする。IPは`ip a`コマンドで調べられる。

##公開鍵を登録する
puttygenなどで接続元(PC側)で秘密鍵と、対になる公開鍵(ssh-rsaから始まる)を作成する。`Key Comment`はログイン時にどの鍵を使ったかの表示に使われるので、設定しておくと良い。秘密鍵にはパスワードがつけられるので、念のため設定しておくと安全だが、普通は付けない模様。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/57e3d8cf-d157-4d87-2c76-983ac4809a13.png" width=30%> 

Raspberry Pi側に公開鍵の保存場所が予め存在しなければ自分で用意し、公開鍵を保存するファイル`authorized_key2`を作る。ファイル名は、`sshd_config`の`AuthorizedKeysFile`で指定しているものであればよい。作成したら、先ほど用意した公開鍵を追加する。

最後にパーミッションを設定する。(他の人が見えてしまうような鍵は信用できないためか、パーミッションエラーになるらしい?)

* [SSHが鍵認証されないとき、パーミッションを疑え。 ](https://takuya-1st.hatenablog.jp/entry/20090216/1234742055)
* [SSHD_CONFIG (5)](https://euske.github.io/openssh-jman/sshd_config.html)

```sh
cd ~
mkdir .ssh
nano .ssh/authorized_key2
(鍵を編集…1行に1つの公開鍵を書く)

chmod 700 .ssh/
chmod 600 .ssh/authorized_keys2
```

登録したら、一旦SSHの接続を切り繋ぎなおして確認する。puttyの場合、IPとポートに加えて、Connection > SSH > Authで秘密鍵を設定することで、ログインできるようになる。Connection > Data から`Auto-login username`を設定しておけば、ユーザ名を入力する手間が省けるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/cd7f3179-f510-f5bd-f111-928ff5d9f7b2.png) ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/0daaed79-d3d7-6b0e-4bae-acc8987a9143.png)

ログイン時に公開鍵で入ったことが表示されたらOKとなる。下図ではパスワードを設定した鍵でログインしているので、パスワード入力もしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/6794ea21-17f3-e4a0-5986-ff6245a83c37.png)

##sshd_configを変える
`/etc/ssh/sshd_config`に設定ファイルが置かれているので、適宜書き換える。基本的にはデフォルト値で特に問題ないらしいが、ログインに関する設定値は変えておく必要がある。設定後、SSHサーバかRaspberry Pi本体を再起動して、SSHでログインできることが確認できたら設定完了。

* [SSHD_CONFIG (5)](https://euske.github.io/openssh-jman/sshd_config.html)
* [sshd_configの設定項目の理解を目指す](https://unskilled.site/sshd_config%E3%81%AE%E8%A8%AD%E5%AE%9A%E9%A0%85%E7%9B%AE%E3%81%AE%E7%90%86%E8%A7%A3%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99/)

| 項目| 設定値 | 備考 |
|:------------------------|:-------------------------|:-----------------------|
| Port | 適当 | well-known port 以外の適当な値でよい |
| PermitRootLogin| no | rootでログインさせない。 |
| PubkeyAuthentication | yes |  公開鍵でログインできるようにする。 |
| PasswordAuthentication | no | パスワード認証はしない。(PermitEmptyPasswords) |

> PermitEmptyPasswordsをnoにするというのを見かけるが、[SSHD_CONFIG (5)](https://euske.github.io/openssh-jman/sshd_config.html)によると、このオプションはパスワード認証が有効な時にしか影響しないらしい。公開鍵であればパスワードの有無は問われないので、デフォルト(コメントアウト)のままで支障はない。

# 次やること
node.jsでサーバを動かしたい。Dockerを使って環境を作る事例があるみたいなので、倣ってやってみる。本当に、Raspberry Pi事例が豊富で助かる。ただ、RaspbianもDockerもバージョンが上がりたてだったため、エラーが出てしまった。とりあえずすぐ必要ではないから困らないものの、タイミングが悪い。

```
Loading new aufs-4.19+20190211 DKMS files...
It is likely that 4.19.58-v7+ belongs to a chroot's host
Building for 4.19.58+, 4.19.58-v7+ and 4.19.58-v7l+
Building initial module for 4.19.58+
Error! Bad return status for module build on kernel: 4.19.58+ (armv7l)
Consult /var/lib/dkms/aufs/4.19+20190211/build/make.log for more information.
dpkg: パッケージ aufs-dkms の処理中にエラーが発生しました (--configure):
 installed aufs-dkms package post-installation script subprocess returned error exit status 10
処理中にエラーが発生しました:
 aufs-dkms
E: Sub-process /usr/bin/dpkg returned an error code (1)
```

ビルドログ`/var/lib/dkms/aufs/4.19+20190211/build/make.log`を見てみると、以下のようにコンパイルでこけているようだった。https://download.docker.com/linux/raspbian/dists/buster/stable/ を見る限り、つい1日前にアップロードされたようだから、もう少し待たないといけない。

```sh
/var/lib/dkms/aufs/4.19+20190211/build/fs/aufs/super.h:134:2: error: unknown type name ‘vfs_readf_t’
  vfs_readf_t  si_xread;
  ^~~~~~~~~~~
/var/lib/dkms/aufs/4.19+20190211/build/fs/aufs/super.h:135:2: error: unknown type name ‘vfs_writef_t’
  vfs_writef_t  si_xwrite;
  ^~~~~~~~~~~~
In file included from /var/lib/dkms/aufs/4.19+20190211/build/fs/aufs/branch.h:33,
                 from /var/lib/dkms/aufs/4.19+20190211/build/fs/aufs/aufs.h:38,
                 from /var/lib/dkms/aufs/4.19+20190211/build/fs/aufs/module.c:25:
/var/lib/dkms/aufs/4.19+20190211/build/fs/aufs/super.h:134:2: error: unknown type name ‘vfs_readf_t’
  vfs_readf_t  si_xread;
  ^~~~~~~~~~~
```