2020年6月13日土曜日

Raspberry Piのhostnameを起動時に変更したい

半年以上立っていますね。(T . T)
やはり物書きには向いてないようです。^ ^

・・・

最近IoT関連のハンズオンとかやる機会が増えてきています。
参加者はパソコン持参ですが、Raspberry Pi Zero Wを使う場合にちょっと困っています。
ネットワーク用のコネクタが付いていないのでWiFi接続となりますが、ディスプレイやキーボード、マウスを用意するのも大変です。

sshの設定とWiFiのSSID、PSK(Pre-Shared Key)の設定についてはブート時に自動設定する方法がこちらに書いてあります。

/bootフォルダに「ssh」という空ファイルを作成しておくとsshが自動的にONになりますし、「wpa_supplicant.conf」というファイルにWiFiの設定をしておけば自動的にWiFiに接続することができます。

wpa_supplicant.confはこんな感じです。
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP
network={
 ssid="<Name of your wireless LAN>"
 psk="<Password for your wireless LAN>"
}

ここでWiFiの接続先に注意してください。
Raspberry Pi Zero Wがサポートしているのは「802.11 b/g/n」だけなので2.4GHzしかサポートされていません。NECとかBuffaloのルータを使っている場合、SSIDは大体「A」「G」がついたSSIDが2.4GHzのはずです。

2020/09/08 訂正: Aは5HzでGが2.4GHzでした。正確にはご自分のルータの設定を確認してください。

あと私のハマった点は、Raspberry Pi Zero Wが立ち上がったかを確認するのに「ping raspberrypi.local」でまずは確認するのですが、Zeroconfが割と遅いということでしょうか?
あれ、pingが通らないや!と勘違いしないでちょっと時間を置いてみて再度確認して下さい。これで2回程SDカードの初期化からやり直してしまいました。

と、ここまではあちこちのサイトで紹介されています。

Windowsパソコンで作業している場合でも、SDカードへrasbianのイメージを書き込んだあと/bootがマウントできるのでWindowsだけで作業ができます。

ただ、ここで問題なのはセミナーのハンズオンなどで同時に複数台の設定を行う場合です。
WiFi接続がDHCPでも1台だけのセットアップならRaspberry Pi Zero Wのhostnameが「raspberrypi」固定なので
ssh pi@raspberrypi.local
でssh接続が可能です。

ところが複数の参加者が同じWiFiに接続するとhostnameが被ってしまいます。
それぞれのSDカードで別のhostnameにするか、IPアドレスを固定にするかで回避できますが、
残念ながらどちらも初回ブート時に設定する方法は無いようです。

そこでこちらのサイトで回答のあったサービスを利用する方法を応用して初回ブート時にhostnameを変更するイメージを作成することにしました。

こうすることで、SDカードにイメージを書き込んだ後に、Windowdsパソコンでssh、wpa_supplicant.conf、hostnameの3つのファイルを用意することで、参加者各自が任意のhostnameのRaspberry Piを立ち上げることができます。(実際にはsshは設定済みのイメージになるので、会場のWiFiに併せたSSID/pskとhostnameの設定を行います)


STEP1:rasbianのイメージを書き込んだSDカードの用意


こちらのサイトから必要なrasbianのイメージファイルをダウンロードします。本家は遅い場合がありますので、その場合はこちらのサイトも試してみてください。
私はSDカードへの書き込みはSD Memory Card Formatterでフォーマット後に、balenaEtcherを使用しています。


STEP2:/booにsshとwpa_supplicant.confを作成


上で説明したようにrasbianのイメージを書き込んだ後、SDカードを抜き差しすると/bootがWindowsでもマウントされて見えるようになります。ここでsshとwpa_supplicant.confをbootフォルダに作成します。

この時に、ちょっと工夫をしておくことで後でimgファイルを作成する時間が短縮できます。

それは、最近のrasbianではパーティションの拡張作業が初回boot時に自動で行われるようになっているので、そのまま再起動してしまうとパーティションサイズがSDカードいっぱいになってしまいます。後でイメージファイルを作成する時にSDカード全体をイメージファイルにすることになって時間がかかりますし、SDカードにイメージファイルを焼く時間も長くなります。

/boot/cmdline.txtの
init=/usr/lib/raspi-config/init_resize.sh
init=/sbin/init
に書き換えておきます。init_resize.shがパーティションの拡張を行なっているシェルスクリプトです。


STEP3:Raspberry Pi Zero Wを起動


SDカードをRaspberry Pi Zero Wに挿し、電源を入れて下さい。しばらくしてからパソコンからsshで接続できれば、無事にWiFiに接続できています。
この時はまだhostnameは「raspberrypi」のままです。


STEP4:hostname変更サービスの登録


以下の作業で、起動時にhostnameを変更するサービスを追加します。
$ sudo vi /etc/systemd/system/change-hostname.service
[Unit]
Description=Change hostname from sd
ConditionPathExists=/boot/hostname
Before=dhcpcd.service

[Service]
Type=oneshot
ExecStartPre=/bin/bash -c 'CURRENT_HOSTNAME=$(/bin/cat /etc/hostname | /usr/bin/tr -d "\t\n\r");NEW_HOSTNAME=$(/bin/cat /boot/hostname | /usr/bin/tr -d "\t\n\r");/bin/sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\t$NEW_HOSTNAME/g" /etc/hosts'
ExecStart=/bin/mv /boot/hostname /etc/hostname
ExecStartPost=/sbin/reboot

[Install]
WantedBy=multi-user.target

$ sudo systemctl enable change-hostname.service

STEP5:imgファイルの作成


以上で、起動時に/boot/hostnameが存在する場合、hostnameを変更してWiFIで接続してssh可能なrasbianが出来ました。

後は
  1. /boot/cmdline.txtのinitを元に戻す。(パーティション拡張の自動処理)
  2. /etc/wpa_supplicant/wpa_supplicant.confからnetworkを削除(SSID、psk消去)
  3. rm ~/.bash_history(コマンド履歴の削除)
を行なってから電源を切って、SDカードのイメージを作成すれば完了です。

私はSDカードのイメージ作成にはWin32 Disk Imagerを使っているので、「Read Only Allocated Partitions」にチェックを入れて作成されるイメージファイルを小さくしています。

Edisonが故障した一件

 最近またEdisonで遊んでいます。 教育用のデバイスとしてよく出来ているなと思っている Edison ですが、現在3台を所有しています。 最近このうちの1台が調子が悪くなってしましました。具体的にはBeep用のデバイスが壊れたようです。購入時にチェックをしたつもりですが今回久...