Rasberry Pi 3 B+ にスマートホーム・サーバーを構築する。修正編

Raspbian OS

参考参考

Raspbian Lite版 イメージをダウンロードする。

公式サイト Raspbian Stretch Lite にある赤い Download ZIP ボタン。

イメージをSDカードに書き込む

こから DD for Windows 最新版ををダウンロードして実行、 .bin ファイルを SDカードに書き込む。
※ドライブを認識しない場合はXP互換モードで起動する。

SDカードの bootパーティション に「ssh」ファイルを新規作成する。

bootパーティションに wpa_supplicant.conf を以下の内容で新規作成する。
改行はLF 、WiFi5GHz可能。

country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
  ssid="WiFiのSSID"
  psk="パスワード"
}
SSH でログイン

電源投入後ユーザー名pi、パスワードraspberry、sshでログインする。

# piユーザのパスワードを変更
$ sudo passwd pi
piユーザー名の変更
# piユーザのパスワードを変更 
$ sudo passwd pi
# 仮のユーザ(tmp)を作成する
$ sudo useradd -M tmp
# tmpユーザをsudoグループに追加(そうしないとsudoが使えない)
$ sudo gpasswd -a tmp sudo
# tmpユーザのパスワードを設定
$ sudo passwd tmp
# ログアウトする
$ exit

tmpでログインして下記実行。※エラーならここを参考にプロセス停止する。

# usermod -lでユーザ名をpiからadminに変更
$ sudo usermod -l admin pi
# usermod -dでホームディレクトリを/home/piから/home/adminに変更
$ sudo usermod -d /home/admin -m admin
# groupmod -nでpiグループをadminグループに変更
$ sudo groupmod -n admin pi
# ログアウト
$ exit

adminでログイン

# 仮ユーザを削除(警告的なのが出るかと思いますが、構わず削除して下さい)
$ sudo userdel tmp
ソフトウェアアップデート
$ sudo apt-get update && sudo apt-get -y dist-upgrade && sudo apt-get -y autoremove && sudo apt-get autoclean

ソフトウェアアップデート自動更新設定

$ sudo apt-get install -y unattended-upgrades
$ sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Origins-Pattern {           この行の下に
        "o=${distro_id},n=${distro_codename}";  <-- 挿入
IPを固定する
$ sudo nano /etc/dhcpcd.conf

# IPアドレス固定
# 無線LAN
interface wlan0
    # IPアドレス
    static ip_address=192.168.0.220/24
    # デフォルトゲートウェイ
    static routers=192.168.0.1
    # DNS
    static domain_name_servers=192.168.0.1 8.8.8.8
# 有線LAN
interface eth0
    static domain_name_servers=192.168.0.1 8.8.8.8
    # IPアドレス static ip_address=192.168.0.221/24
    # デフォルトゲートウェイ static routers=192.168.0.1
    # DNS static domain_name_servers=192.168.0.1 8.8.8.8

リブート後に接続確認する。

Raspberry Pi の設定

$ sudo raspi-config を実行

2 Network options –> N1 Hostname : pi

4 Localisation Options –> I1 Change Locale : ja_JP.UTF-8 UTF-8

–>  I2 Change Timezone –> Asia –>  Tokyo

–>  I4 Change Wi-fi Country –> JP Japan

7 Advanced Options –> A3 Memory Split : 16

FQDN追加  ※必要なかった
$ sudo nano /etc/hosts
127.0.1.1       pi
    ↓
127.0.1.1       pi.xxx.com pi
ハードウエア乱数の有効化
$ sudo apt-get install rng-tools

Node-RED インストール

$ bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)
# Node-RED 自動起動設定
$ sudo systemctl enable nodered.service
$ sudo reboot
http://pi.local:1880

一旦バックアップ

  • Raspberry Pi 3 B+ をシャットダウン。
  • Win32 Disk Imagerdownload して解凍 programs へ。
  • SDメモリカードフォーマッターを download して programs へ。
  • 先に tmp.img を作成して WIn32DiskImager でバックアップ。
  • リストアは SDメモリカードフォーマッター で書き戻す。

Mosquitto

参考参考参考TLS参考CAスクリプトCAスクリプト

Mosquitto インストール
$ sudo apt install mosquitto
$ sudo apt install mosquitto-clients
# 自動起動
$ sudo systemctl start mosquitto

平文テスト

# A、トピック(Topic)「test」を購読(Subscribe)開始
$ mosquitto_sub -d -t test

# B、新たにSSHで接続して、トピック(Topic)「test」に発行(Publishe)する
$ mosquitto_pub -d -t test -m "こんにちは 2019/1/8"

# A、購読中のトピック「test」にメッセージが発行されたので内容が表示される
Client mosqsub/4925-pi received PUBLISH (d0, q0, r0, m0, 'test', ... (26 bytes))
こんにちは 2019/1/8
Mosquitto パスワード認証
# 接続ユーザーのパスワードファイルを作成する。
$ sudo mkdir /etc/mosquitto/userpass
$ sudo mosquitto_passwd -c /etc/mosquitto/userpass/admin.pass admin

# 設定サンプルファイルを準備する(内容を理解するため、必須ではない)
$ sudo gzip -d /usr/share/doc/mosquitto/examples/mosquitto.conf.gz
$ sudo mv /usr/share/doc/mosquitto/examples/mosquitto.conf  /usr/share/doc/
mosquitto/examples/mosquitto.conf.example

Mosquitto ローカル設定ファイルを新規作成してファイルにコピペする

$ sudo nano /etc/mosquitto/conf.d/mosquitto.conf
# Mosquitto 起動のローカル設定を書くファイル

# 認証にパスワードファイルが必要になる
allow_anonymous false

# ユーザーのパスワードファイル追加
password_file /etc/mosquitto/userpass/admin.pass
# VSCode SSH FS で編集可能なように権限を書き換えておく
$ sudo chown root:sudo /etc/mosquitto/conf.d/mosquitto.conf
$ sudo chmod g+rwX /etc/mosquitto/conf.d/mosquitto.conf

現在パスワード認証が必要な状態だから前記の平文テストをするとエラーになるのが正常。

パスワード認証テスト

$ sudo systemctl restart mosquitto

# A、パスワード認証でトピック(Topic)「test」に発行(Publishe)する
$ mosquitto_pub -d -h localhost -t "test" -m "パスワード認証で開始します" -u "admin" -P "パスワード"

# B、新たにSSHで接続して、パスワード認証してトピック(Topic)「test」を購読(Subscribe)する
$ mosquitto_sub -d -h localhost -t test -u "admin" -P "パスワード"
※ 過去のメッセージは取得できないので"パスワード認証で開始します"は表示されない。

# A、再度発行
$ mosquitto_pub -d -h localhost -t "test" -m "パスワード認証でこんにちは" -u "admin" -P "パスワード" 
# B、購読中のトピック「test」にメッセージが発行されたので内容が表示される
Client mosqsub/4925-pi received PUBLISH (d0, q0, r0, m0, 'test', ... (39 bytes))
パスワード認証でこんにちは

TLS認証接続

genarete-CA.sh を使用して証明書を作成する。

$ wget https://github.com/owntracks/tools/blob/master/TLS/generate-CA.sh
$ HOSTLIST="pi pi.local"
$ IPLIST="192.168.0.220 172.20.10.220"
$ bash generate-CA.sh
$ bash generate-CA.sh
$ bash generate-CA.sh

※ 肝は、環境変数 HOSTLIST に可能性のあるホスト名とIPアドレスを空白区切りで列挙すること。

上記の操作で作成されたファイルをmosquittoフォルダへコピー

● mqtt_ca.crt  : CA証明書
  mqtt_ca.key  : CAキー (private, public)
  mqtt_ca.srl  : CA serial number file
● mqtt_srv.crt : サーバー証明書
  mqtt_srv.csr : CAリクエスト
● mqtt_srv.key : サーバーキー

# ●ファイルを認証フォルダに移動する
$ sudo cp ca.crt /etc/mosquitto/ca_certificates/mqtt_ca.crt
$ sudo cp pi.crt /etc/mosquitto/certs/mqtt_srv.crt
$ sudo cp pi.key /etc/mosquitto/certs/mqtt_srv.key  
# 残りのファイルはどこかに保管

Mosquitto設定ファイル

ローカル設定ファイルに追加する。

$ cat << EOL >> /etc/mosquitto/conf.d/mosquitto.conf

# 1883 はlocalhost 以外からは受け付けない
listener 1883 localhost
# TSL/SSL ポート
listener 8883

# CA証明書
cafile /etc/mosquitto/ca_certificates/mqtt_ca.crt

# サーバー証明書
certfile /etc/mosquitto/certs/mqtt_srv.crt

# サーバーキー
keyfile /etc/mosquitto/certs/mqtt_srv.key
EOL

クライアント側に必要なファイルはCA証明書ファイル mqtt_ca.crt のみです。

クライアント側から接続する際には、MQTTクライアントアプリでTLS/SSL接続、ポートの指定、mqtt_ca.crtのパス指定が必要になります。

TLS+ユーザー・パスワード・ファイル認証での動作確認
# サーバー再起動して新しい設定を読み込む
$ sudo systemctl restart mosquitto

# TLS+パスワードファイルモードで購読開始
sudo mosquitto_sub -d -t test -h pi.local -p 8883 --cafile /etc/mosquitto/ca_certificates/mqtt_ca.crt -u "admin" -P "パスワード"

# TLS+パスワードファイルモードで発行開始
$ mosquitto_pub -h pi.local -t test -m "TLS Auth for Raspberry Pi 3 B+" -p 8883 --cafile /etc/mosquitto/ca_certificates/mqtt_ca.crt -u "admin" -P "パスワード"

何度も失敗してようやく成功!
肝はCA証明書の作成だった。