uzullaがブログ

uzullaがブログです。

ヘッドレスRaspberry Pi Zero w(h)のネットワーク初期設定やコンソールやUSB Gadget/Ethernetなどについてメモ

たまにググるのと、しばしば人に伝える必要があるので書いてしまったほうが早いと思った。

特に目新しいことはありません。

はじめに

Raspberry Pi Zero w(あるいはwh、以後はRaspberry Pi Zero w)は無線つきのラズパイで、実際のところ普通のLinux PCです。ただ、最初から最後までモニタもキーボードも繋がずに使う(head lessで使う)には多少手順が必要です。

基本的には「とにかくRaspberry Pi Zero wがWifiにつながってsshでログインできれば勝ち」という話です。

ここではWifiで入る所までを目指します。(そこまでいけば、もはや何でも一緒だし)

DISCLAIMERなど

  • 当然ながら、本記事を参考にした結果について、一切の責任は取れません。

1, OSをSDに焼く

https://www.raspberrypi.org/downloads/

こちらからraspbianなどをDLします。XなどGUIは不要なのでRAPBIAN STRECH LITEでもよいかと。

zipを手に入れたら解凍し、2018-03-13-raspbian-stretch.imgをとりだします。

最低8GB(後述)のmicroSDを用意し、imgを焼きます。ツールは以下のものが楽ですね。

https://etcher.io/

2, Wifiの接続情報を設定する

(色々かいていたら、nasa9084君から指摘がはいりましたので追記)

焼いたSDをもう一度Macに差し込んでマウントし、ファイルを編集する

(以下は/Volumes/boot に焼いたSDがマウントされていると仮定)

# /boot/ssh ファイルを作成して起動すると、sshdがたちあがる様に設定される。後でsshファイルは消える。
$ touch /Volumes/boot/ssh

# Wifi接続情報を書き込む
$ vi /Volumes/boot/wpa_supplicant.conf

wpa_supplicant.conf の内容

※ 以下はWPA2(+AES)の場合です、WPAやWEPの場合は異なります…が、もう普通WPA2ですよね。WPA2以外の場合はググってみてくれ

country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="使うAPのSSID"
    psk="APのパスフレーズ"
    scan_ssid=1
}

※ scan_ssidSSIDステルス機能をつかったAPに接続する場合だけ必要ですが、まああってもこまらんやろ

※ psk=""をハッシュ(ssidでsalt)する事もできますが、どうせこのテキストをもっていかれたら使えてしまうので…使いまわしているテキストでもなければいらないのでは? 一応 wpa_passphrase は後述もしますが。

3, raspberry pi zero wにsdカードをさして起動

LEDのチカチカがおさまると起動完了、大体1分くらい。

すると/boot/wpa_supplicant.conf/etc/wpa_supplicant/wpa_supplicant.confに上書きコピーされ、wifiにつながるはず。

wifiにつながればそのうちbonjourで自動的に raspberrypi.local のIPが引けるようになるので、以下のようにsshログインする。

$ ssh pi@raspberrypi.local

初期のユーザーはpi、パスワードはraspberryです。さっさと変えましょう。rootになりたければsudoで。

以上です!お疲れ様でした!(?)

トラブルシュート

raspberrypi.localがみつからない場合。

少しまってからarp -aして探してみるなどするとよいでしょう。(ホスト名を変えているなら後述のdns-sdも)

5分駄目ならつながっていない可能性があります、wifi設定間違えているのでは?がんばって。

どうしても駄目なら後述する別の方法をためしてみるとよいかもしれませんね。


======以下蛇足、それ以外の方法========


「物理NICを買ってさすのが確実(tomzohさん談)」

  • (既存の有線LAN環境)
  • OTGケーブルなどと呼ばれるmicroUSB-USB変換ケーブル
  • RaspberryPi 有線LAN usbとかでググってみつかる、対応した有線LAN変換アダプタ

USB Gadget/EthernetWifiを使わずmicroUSBケーブル一本でネットワークをつくる

Raspberry pi zero w のUSBポートを(Macからみて)USB NICにする方法です。既存のWifiが無い時に便利…と思うかもしれませんが、いまどきスマホテザリングMacのインターネット共有モードでAPはすぐつくれますね(説明は省略)。

さておき、以下がやり方です。

1, raspbianを焼く

raspbianを焼く所までは同じ

2, /boot/内のファイルを編集する

config.txt

以下を追記

dtoverlay=dwc2

cmdline.txt

既存のrootwaitの後に以下を挿入(前後にはスペースを入れてください)。

modules-load=dwc2,g_ether

つまり、以下のようになります

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=aaeaec01-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether quiet splash plymouth.ignore-serial-consoles

※ LITEだとnowait 以降はありませんので、末尾に空白をいれてから追加します。

ssh

sshdはデフォルト無効なので、自動で立ち上げるためにtouch /Volumes/boot/ssh で空のファイルを作ります。次回起動時にsshd自動起動が有効になり/boot/sshは削除されます。

以上を行ったらmicroSDをejectしてRaspberry Pi Zero wに差し込みます。

3, Raspberry Pi Zero wを起動し、USB Gadget/EthernetMacに接続

Raspberry Pi Zero wの2つあるmicroUSB端子の内、中央よりのUSBとPCB(基板)に白くシルク印刷された方のコネクタをケーブルでMacとつなぎます。

自動的にRaspberry Pi Zero wは起動開始しLEDが点滅します。1分くらいすると点滅がおわり、起動完了です。

Mac側のシステム環境設定からネットワークをひらき、そこに RNDIS/Ethernet Gadgetバイスができていることを確認します。

※ なお、そのネットワークにはDHCPがないので自己割当IPになるはずですが、それは正常です。

トラブルシュート

ここで、ネットワークインターフェイスとしてRaspberry Pi Zero wを認識しない事があります…。

ホスト側のRNDIS周りがおかしい

OSXではドライバのインストールなどは不要のはずですが、AndroidテザリングなどでHoRNDISをいれていると、挙動がおかしい事があるようです。HoRNDISを消したり、再インストールしてみてください。

あとは別のMacやPCでもためしてみてください。

ケーブルやポートがおかしい

充電専用ケーブル、あるいはUSBポートを間違えている可能性があります。Macのポートがおかしいことすらあります。

Console.appを起動して、フィルタにusbなど入力した上で、USBを抜き差しするなどして、何かしら認識しているか確認してください。

Raspberry Pi Zero wが壊れている(等)

体験談です。手元で二台のRaspberry Pi Zero wを用意し、同一のmicroSDでためしたが片方はどうしてもつながらなかった。

ご愁傷様ですが、あきらめましょう。

4, Raspberry Pi Zero wに接続する

ホスト側にNICとして認識されれば、しばらくすればBonjourraspberrypi.localでIPが引けるようになります。(Windowsだと別途Bonjourをいれましょう)

$ ssh pi@raspberrypi.local

raspberrypi.localがみつからない場合。

例えば以下のエラー

ssh: Could not resolve hostname raspberrypi.local: nodename nor servname provided, or not known

少しまってからarp -aして探してみるなどするとよいでしょう(沢山端末がぶらさがったネットワークではむずかしいが)。

数分まって駄目なら、つながっていない可能性が高い。

もう一つ、初心者向けに書いておくと、以下はsshdがたちあがってませんね、$ touch boot/ssh(等)などしそびれてませんか?

ssh: connect to host raspberrypi.local port 22: Connection refused

5, Raspberry Pi Zero wにWifiを設定する

USB Gadget/Ethernet の Ether でMacにつないでも、Raspiは外にでられません(Macのネットワークを共有するなりすればできますが、省略)。するとaptもできませんのでやはりWifiを設定しましょう。

注意点

  • Raspberry Pi Zero wは2.4GHzしかサポートしていません。
  • デフォルトではWifiは(多分)GBかUSの欧州の周波数モードです(たとえば、日本ではつかえる12ch以上にはつながらない(見えない))。後述の通りcountry=JPを設定しましょう*1

APを探す

(面倒なので、以下rootでやってください)

まず、WifiのモードをJPにします。

vi /etc/wpa_supplicant/wpa_supplicant.conf して以下を追記します。

country=JP

wpa_cli -i wlan0 reconfigure でリロードしたら、以下でRaspberry Pi Zero wから見えるAPが探せます(勿論ステルス設定してないAPならば、ですが)。 (( iwlist wlan0 scan | grep ESSID でもよいが、もう古いので ))

$ wpa_cli scan; wpa_cli scan_result
# 出力例

Selected interface 'p2p-dev-wlan0'
OK
Selected interface 'p2p-dev-wlan0'
bssid / frequency / signal level / flags / ssid
XX:XX:XX:XX:XX:XX   2472    -35 [WPA2-PSK-CCMP][WPS][ESS]   {みつかったAPのSSID}

APは見えたりみえなくなったりするので、一度で見つからなくても何回か叩いてみてください。

あるいは、watchと組み合わせて、以下でも。

$ watch -n 3 'wpa_cli scan; wpa_cli scan_result | cut -f 5'

接続情報を保存する

みつかったら設定を保存します。

$ echo "" >> /etc/wpa_supplicant/wpa_supplicant.conf
$ wpa_passphrase "YOUR_ESSID" "YOUR_PASSWORD" >> /etc/wpa_supplicant/wpa_supplicant.conf

もしくはwpa_cliで設定してもよいですね(後述)

(あるいは分かってる人ならwpa_supplicant.confを修正してくれ。WPA2以外、WPAやWEPの人は別途ググってくれ。)

AP情報を複数保存したい場合は複数回実行することで複数のAPを保存できます。たとえばスマホテザリングAPなどを登録するのもよいかと思います。

また、SSIDステルス機能をつかっているAPにつなぐ場合は、network={〜}の中にscan_ssid=1の追加が必要です。

ところで、この時wpa_supplicant.confにはpass(psk=〜)がssidをsaltとしたハッシュに変換されますが、同時にプレインテキストも保存されてしまうので、気になる人はvi /etc/wpa_supplicant/wpa_supplicant.confして、#psk〜の行は消すなりしてください。(ただ、ハッシュは所詮ハッシュなので暗号化とは違います。もどせないにせよ盗まれたら他で使えます。)

wpa_supplicant.confを作成したら、 wpa_cli -i wlan0 reconfigure でリロードしてすこし待ち、ifconfig wlan0してDHCPからIPがふられていたら完了です。振られていなかったらログをみたり、wpa_cliを手でたたいたりしてためしてみましょう。

(勿論DHCPがないネットワークなら、自分で/etc/network/interfacesを編集してIPをふってくれ)

あとはapt install vimなどしましょう

6, はい、これでOKです。

おつかれさまでした。

余談 wpa_cliのメモ

設定ファイルに書くのもいいですが、wpa_cliのシェルをたたいたほうがわかりやすい事もありますね。なにせどうなっているのかわかる。

$ wpa_cli
wpa_cli v2.3
Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.


Selected interface 'wlan0'

Interactive mode

>

country=JPを設定する

> set country JP
OK

SSIDを探す

> scan
OK
> scan_results
〜さまざまなAP〜

設定して接続する

> add_network
1
> set_network 1 ssid "つなぎたいSSID"
> set_network 1 psk "パスワード"
> enable_network 1
(うまく行けば、接続ができた的なログがずらずらと出る)

※ この設定はsave_configしないと揮発する

現在の状態を見る

> status
bssid=XX:XX:XX:XX:XX
freq=2472
ssid=XXXXXXXXX
id=0
mode=station
pairwise_cipher=CCMP
group_cipher=CCMP
key_mgmt=WPA2-PSK
wpa_state=COMPLETED
ip_address=192.168.X.X
p2p_device_address=XX:XX:XX:XX:XX
address=XX:XX:XX:XX:XX
uuid=XXXXX-XXXXX-XXXXX-XXXXX

設定を保存する

> save_config

Bonjourの一覧からホスト名を探す

OSXでは、dns-sdコマンドを活用することで、Bonjour(avahi)で告知されているホストを探すことができる。

複数のRaspberry piを持っていて衝突しないようにホスト名を変更していて、そのホスト名を忘れた場合にも有効です。(arp -aだと出過ぎてわからん時も)

# _workstation._tcp サービスタイプを一覧する、raspiはこの中にいるはず
$ dns-sd -B _workstation._tcp
Browsing for _workstation._tcp
DATE: ---Sun 29 Apr 2018---
 0:23:25.792  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
 0:23:25.793  Add        2   5 local.               _workstation._tcp.   myraspi [XX:XX:XX:XX:XX:XX]
(おわらないので、Ctrl-cで終了

# 基本的には、上でみつかった"myraspi" に.localを付与してmyraspi.localでつながるはず
# 以下は細かく見ていく場合のdns-sdのメモ

# サービスの一覧(基本的に`_workstation`にraspiはでるはずなので、基本不要)
$ dns-sd  -B  _services._dns-sd._udp  local.
Browsing for _services._dns-sd._udp.local.
DATE: ---Sun 29 Apr 2018---
 0:26:20.519  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
 0:26:20.520  Add        3   5 .                    _tcp.local.          _ssh
 0:26:20.520  Add        3   5 .                    _tcp.local.          _sftp-ssh
 0:26:20.520  Add        3   5 .                    _tcp.local.          _rfb
 0:26:20.520  Add        3   5 .                    _tcp.local.          _workstation
 0:26:20.520  Add        2   5 .                    _tcp.local.          _apple-mobdev2
 0:26:20.774  Add        2   5 .                    _tcp.local.          _afpovertcp
^C

# -BでひいたInstance Nameを指定してホスト名を引く、`myraspi`だけでなく、`[XX〜]`の部分も必要。
$ dns-sd -B _workstation._tcp "myraspi [XX:XX:XX:XX:XX:XX]"  _workstation._tcp local.
Lookup myraspi [XX:XX:XX:XX:XX:XX]._workstation._tcp.local.
DATE: ---Sun 29 Apr 2018---
 0:30:41.692  ...STARTING...
 0:30:41.693  myraspi\032[XX:XX:XX:XX:XX:XX]._workstation._tcp.local. can be reached at myraspi.local.:9 (interface 5)
(おわらないので、Ctrl-cで終了

# myraspi.local. とホスト名がわかる。基本的にここで終わり
# もしIPが必要なら、さらに次を

# ホスト名からIPへ(hostコマンドでは引けない)
$ dns-sd -Gv4v6 myraspi.local
DATE: ---Sun 29 Apr 2018---
 0:29:07.872  ...STARTING...
Timestamp     A/R Flags if Hostname                               Address                                      TTL
 0:29:07.873  Add     3  5 myraspi.local.                          XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX%en0  120
 0:29:07.873  Add     2  5 myraspi.local.                          192.168.123.1                                 120
(おわらないので、Ctrl-cで終了

# これでIPv4とv6両方のアドレスも確認できた

# なお、pingで簡易に調べることはできる
$ ping myraspi.local
PING myraspi.local (192.168.123.1): 56 data bytes

余談

pi@raspberrypi:~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.1G  4.2G  2.6G  62% /
devtmpfs        213M     0  213M   0% /dev
tmpfs           218M     0  218M   0% /dev/shm
tmpfs           218M  3.1M  214M   2% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           218M     0  218M   0% /sys/fs/cgroup
/dev/mmcblk0p1   42M   21M   21M  51% /boot
tmpfs            44M     0   44M   0% /run/user/1000

インストールしてちょっとした所の様子です、最初から4GBほどをつかいます。8GBのmicroSDで16GBはなくても遊べる。

LITEの場合はこちら、なお、LITEでもbuild-essential相当ははいっている。

pi@raspberrypi:~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.1G  1.1G  5.7G  16% /
devtmpfs        213M     0  213M   0% /dev
tmpfs           218M     0  218M   0% /dev/shm
tmpfs           218M  5.8M  212M   3% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           218M     0  218M   0% /sys/fs/cgroup
/dev/mmcblk0p1   42M   21M   21M  51% /boot
tmpfs            44M     0   44M   0% /run/user/1000

余談2

Wifiがおかしい時は、iwconfigもつかってみるとよいでしょう。

# iwconfig wlan0
wlan0     IEEE 802.11  ESSID:"-------------"
          Mode:Managed  Frequency:2.472 GHz  Access Point: --:--:--:--:--:--
          Bit Rate=24 Mb/s   Tx-Power=31 dBm
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Encryption key:XXXX-XXXX-XXXX-XXXX-XXXX-XX
          Power Management:on
          Link Quality=63/70  Signal level=-47 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

余談3 物理的なシリアルでログイン

USB Gadget/Ethernetが動かないなら、どのご家庭にもかならずある(無いならこの節は飛ばしてくれ)であろうシリアルケーブル等でもログインできます*2。 (この方法はログインできなくてもmicroSDが読み書きできれば設定できます。UARTのインターフェイスをもっていれば、ですが。)

※ 以下はRaspberry Pi zero wの話です、Raspberry Pi 3など他のものではハードが異なるので、手法が違います。まあRPi3なら物理Etherあるのでやらないでしょうが…。

config.txtを修正し

enable_uart=1
dtoverlay=pi3-miniuart-bt
# dtoverlay=dwc2 # これは一回コメントアウト

(この写真の変換は、 https://www.amazon.co.jp/dp/B01LVXGT04 です。3.3、5vも変更できて便利)

その上で手持ちのシリアルコンソールをつなぐ。ボーレートは115200。なお、GPIOは3.3vです。

公式のピンレイアウト

https://www.raspberrypi.org/documentation/usage/gpio/README.md

GPIO14(TX) => RX
GPIO15(RX) => TX
GND => GND
# VCCは接続不要

ところで、普段sshで公開鍵認証していると、シリアルとかでログインするときに突然パスワードが必要になり(忘れており)大変ですね(感想)

余談4 USB GadgetのソフトウェアUSBシリアルでログイン

これはセットアップには使えないですが、raspberry piのUSBポートを前述の仮想Etherのように仮想シリアルポートとして使うことができます。

USB Etherはsshでつなげるのでscp等でファイル転送できるのも便利ですが、出先で既にできているプログラムを起動する程度ならネットワークのトラブルもおこりえないこちらのほうが変な問題に遭遇しないであろうと思います。

(ttyGS0有効化だけしておけば、SDカード上の書き換えだけで切り替えもできるし)

/boot/cmdline.txtのnowait以降に以下を追加

modules-load=dwc2,g_serial

/boot/config.txtに以下を追加

dtoverlay=dwc2

ttyGS0を有効に

$ sudo systemctl enable getty@ttyGS0.service
$ sudo systemctl start getty@ttyGS0.service

※ ついでに再起動するなら、上のstartは不要

Macから接続例

$ ls /dev/cu*
…
/dev/cu.usbmodemXXXXX
# このファイル名は多少違うかもしれない、繋ぐ前にlsして、繋いでlsすれば現れたものがそれ

$ screen /dev/cu.usbmodemXXXXX 115200
# つながったら、Enterを一回たたくとログインプロンプトがでるはず

screenの説明が必要かわからないが、終了だけいうと、C-a C-kで終了できる。なお、screenは(元々の用途からいって当然ながら)ウインドウを閉じてもscreenのセッションは残るので、screen -lsでPID(数字)をしらべ、screen kill {PID}として削除する。

よくわからん?GUIでCoolTermや、picocomをつかえばいいのでは?

$ brew install picocom
$ picocom -b 115200 /dev/cu.usbmodemXXXXX
(C-a C-xで終了)

…といったところをツールでやる

イメージを修正できるらしい。

www.pibakery.org

(使ったことはない)

まとめ

色々やりかたはあるが、wifi使えるなら最初のやつが楽。

ただ、wifiがどうしてもうまくいかないことはよくある。ログを見るためにも一応シリアルなどのことを忘れないであげてください…。


しかし…/boot/のどこかに起動後実行されるスクリプトがあれば楽なのにな…。

tomzohさん、nasa9084さんありがとうございました。

こちらからは以上です。

*1:電波法的にも設定しないとオーバーするかもしれないしね…、いいつつ、なんかラズパイのiwconifgにおけるdBmおかしくない??Tx-Power=31 dBmとかないでしょ(海外のフォーラムみてると「表記のバグだ」ってあるので無視してるが…)

*2:シリアルケーブル、amazonで200円くらいからある。ちゃんと動くものかはわからんが