Raspberry Piの無線LANをmicroSDで設定する

Raspberry Pi 3 Model BやPi Zero Wには無線LAN(WiFi)が内蔵されましたが、何らかの方法でSSIDとパスフレーズを設定しないと無線での通信はできません。
以前に書いた[Raspberry Pi Zero Wの無線LANをディスプレイやキーボードなしで設定する(有線LAN利用)](http://qiita.com/mascii/items/a25af25da8bfd3fd2a71)という記事ではRaspberry Pi Zero Wに**USBで一時的に有線LANポートを設ける**するやり方で、ディスプレイやキーボードを使わずにSSIDとパスフレーズを設定する方法を紹介しましたが、こちらの記事のコメントで**microSDにあらかじめファイルを作成しておくことで、無線LANの設定ができる**というご指摘をいただき、その方法を検証してみましたので紹介したいと思います。

(2017/10/01追記)
ブラウザ上でSSIDとパスフレーズを入力するだけで簡単に`wpa_supplicant.conf`を作成できるツールを作成しました。
[Raspberry Piの無線LANをmicroSDで簡単に設定するためのツールを作った
](https://qiita.com/mascii/items/a43d71572e1919e56398)

# 動作環境
- Raspberry Pi Zero W
    - Raspbian Jessie Lite 2017-07-05
        - イメージをMicroSDに書き込んだ後、MicroSDのルートディレクトリに`ssh`という名前で空のファイルを作成
    - Raspbian Stretch Lite 2017-08-16
        - イメージをMicroSDに書き込んだ後、MicroSDのルートディレクトリに`ssh`という名前で空のファイルを作成

# 設定
SSH接続を利用するにはイメージをmicroSDに書き込んだ後、microSDのルートディレクトリに`ssh`という名前で空のファイルを作成しておく必要があります。
<img width="420" alt="スクリーンショット 2017-07-29 10.42.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/1de72a72-607c-94ad-9bca-fa9e0ef08624.png">
macOSであれば、`touch`コマンドを用いて`touch /Volumes/boot/ssh`といった要領で空のファイル`ssh`を作成できます。

また、Raspberry Piの内蔵WiFiでは2.4GHz帯のみ利用できます。ルーターのデフォルトの設定では、2.4GHz帯のSSIDにはgやGといった文字が含まれていることが多いです。

## 設定ファイルの作成
`wpa_supplicant.conf`というファイルをmicroSDのルートディレクトリに作成していきます。
このファイルをmicroSDのルートディレクトリに作成すると、Raspberry Pi起動時に自動でRaspbian上の`/etc/wpa_supplicant/wpa_supplicant.conf`を上書きするようになっています(microSDのルートディレクトリに作成したファイルは削除されます)。

### 平文のWPAパスフレーズを保存する場合
SSIDが`test`, パスフレーズが`abcd1234`の場合、以下のようなファイルをmicroSDのルートディレクトリに作成します(macOSの場合、`/Volumes/boot/wpa_supplicant.conf`)

```wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
	ssid="test"
	psk="abcd1234"
}
```

パスフレーズが設定されていない場合は、[Life with IT - Raspberry Pi 3でパスフレーズなしのWi-Fiアクセスポイントに接続する設定(Raspbian Jessie Lite)](http://l-w-i.net/t/raspbian/wifi_001.txt)を見て設定してください(自己責任でお願いします)

### 256bitのハッシュ化されたキーを保存する場合
平文のWPAパスフレーズをmicroSD上に保存することに抵抗がある方は、パスフレーズの代わりに、SSIDとパスフレーズの組をハッシュ化した256bitのキーを保存することもできます。
Raspbian上で`wpa_passphrase`コマンドを実行することで、256bitのキーを取得することもできますが、今回はJavaScriptで256bitのキーを取得する方法を2通り紹介します。

#### ブラウザで256bitのキーを取得する場合
[WPA key calculation: From passphrase to hex](http://jorisvr.nl/wpapsk.html)のページにアクセスし、Network SSIDとWPA passphraseを入力し、Calculateボタンをクリックします。

<img width="420" alt="スクリーンショット 2017-07-29 10.42.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/9fc8ae17-a39d-3dec-0f26-f24090e5432f.png">

`899f089ca767f38265424c83ce83193ab145571c0a71e1aca4487d615c411f34`のような256bitのキーが表示されるので、これを元に以下のようなファイルをmicroSDのルートディレクトリに作成します(macOSの場合、`/Volumes/boot/wpa_supplicant.conf`)

```wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
	ssid="test"
	psk=899f089ca767f38265424c83ce83193ab145571c0a71e1aca4487d615c411f34
}
```

#### Node.jsで256bitのキーを取得する場合
Node.js標準モジュールのCryptoを利用して、256bitのキーを取得することもできます。

SSIDが`test`, パスフレーズが`abcd1234`の場合、以下のスクリプトを実行することで256bitのキーを取得できます。

```JavaScript
const crypto = require('crypto');
const key = crypto.pbkdf2Sync('abcd1234', 'test', 4096, 32, 'sha1');
console.log(key.toString('hex'));
```

ターミナル上で実行できる形式はこちら

```
node -e "console.log(require('crypto').pbkdf2Sync('abcd1234','test',4096,32,'sha1').toString('hex'))"
```

<img width="733" alt="スクリーンショット 2017-08-01 3.41.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/0cba61e7-961a-0e52-dece-24d7eb3202f1.png">

ブラウザで256bitのキーを取得する場合と同様に、`wpa_supplicant.conf`をmicroSDのルートディレクトリに作成してください。

#### `wpa_passphrase`コマンドで計算したキーの値と比較
[WPA key calculation: From passphrase to hex](http://jorisvr.nl/wpapsk.html)のページで計算したキーの値、Node.jsで計算したキーの値共に、`wpa_passphrase`コマンドで計算したキーの値と同じものになっていました。
<img width="540" alt="スクリーンショット 2017-07-29 10.42.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/6e4daa52-adc9-6a0f-6042-1e734f8d269f.png">

# SSH接続
Windowsの場合は、[Raspberry PiとMac or Windows PCを有線で直接繋いでさくっとSSH接続する](http://qiita.com/mascii/items/7d955395158d4231aef6)などを参照してください。

macOSでZeroconf(Bonjour)を利用する場合は、以下の方法でSSH接続をすることができます。

Raspberry PiにRaspbianが入っているMicroSDを入れて、電源を入れます。OSが起動するまで1分ほど待ちます。

```text:macOS
$ ssh pi@raspberrypi.local
```

パスワードを聞かれるので、 `raspberry`と入力してreturnキーを押します。

```text:macOS
pi@raspberrypi.local's password: 
```

繋がるはずです。

```text:Raspbian
pi@raspberrypi:~ $
```

うまく繋がらない場合は、以前接続した際の設定が残っている可能性があるので、known_hostsの設定削除を行ってください。

```text:macOS
$ ssh-keygen -R raspberrypi.local
```