本文書は、RaspBerryPi 4BでTinyPilotを設定する場合の、 個人的なカスタム方法について述べる。 間違ってたら教えてね。
PCをリモートから操作するためのRaspberryPi 4Bシステム。具体的には、 リモートKVM(Keyboard/Video/Mouse)を実現する。所謂HPEのiLOMやDellの iDRACのリモートコンソールの真似事ができる。でもリモートでPCを 強制リセットしたり電源On/Offしたりはできないのでご注意。 詳細は以下のURL群を参照。
# curl --silent --show-error https://raw.githubusercontent.com/tiny-pilot/tinypilot/master/quick-install | bash - |
最終的には、RaspberryPi 4BにUSB-HDMIキャプチャデバイスを追加し、以下のように接続することで、TinyPilotシステムとして動作するようになる。
TinyPilotの初期設定が終わり、一通り動作確認をしたら、 実運用に備えて細かい設定変更を施す。我輩は設定変更で以下を実現した。
順番に見ていこう。
※最新Raspberry Pi OSではpiユーザは削除されたそうなのでこの項目は不要。
デフォルトでは、TinyPilotは(というかRaspberryPiは) pi ユーザがパスワード raspberry でログインできるようになっている。まずはこれを変更しよう。
$ passwd Changing password for pi. Current password: New password: Retype new password: passwd: password updated successfully $ |
また、rootのパスワードも変更しよう。sudo su - でrootになってもよい。
$ sudo passwd root (略) |
rootユーザでsshログインできるようにはなっていないので、 そうしたいなら /etc/ssh/sshd_config に "PermitRootLogin yes" を追記 または既存の記述を変更して、systemctl restart sshd で設定を反映する。
デフォルトでは、TinyPilotのWebページ(http://IPアドレス/) はパスワード保護されていない。これだと誰か知らない人にアクセスされて 好き放題されちゃう可能性があって極めて危険なので、とにもかくにも パスワード保護することにする。
TinyPilotのWebサーバは nginx が採用されているため、設定ファイルは /etc/nginx 以下に存在する。どうせその用途にしか使わないんだから、 .htpasswordファイルは /etc/nginx/.htpassword として作ってしまった方が 管理が楽だ。以下の例では、tpuser というユーザを作成している。
$ sudo htpasswd /etc/nginx/.htpasswd tpuser New password: Re-type new password: Adding password for user tpuser $ |
それが終わったら、nginx の設定ファイル /etc/nginx/sites-enabled/tinypilot.conf の server セクション中に、以下を追記する。
location / { proxy_pass http://tinypilot; auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; } |
systemctl restart nginx で nginx を再起動して設定を反映すれば、 パスワード保護は完了だ。http://IPアドレス/ にアクセスしてパスワードを 聞かれることを確認すればよい。
https://でアクセスできるようにするには、まず自己署名でいいので証明書を 作成する必要がある。以下では /etc/nginx/cert/ 以下に cert.key と cert.csr を作成した。
# mkdir /etc/nginx/cert # cd /etc/nginx/cert # openssl genrsa -aes192 -out cert.key 4096 (略) Enter pass phrase for cert.ke: Verifying - Enter pass phrase for cert.key: # # openssl req -new -key cert.key -out cert.csr Enter pass phrase for cert.key: (snip) Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:localhost Email Address []:root@localhost (snip) # |
その後、nginx の設定ファイルを、http(port80)からhttps(port443)を 待ち受けするように変更する。
listen 80 default_server; listen [::]:80 default_server; |
の部分を、以下のように書き換える。
listen 443 ssl default_server; listen [::]:443 ssl default_server; ssl on; ssl_certificate "/etc/nginx/cert/cert.crt"; ssl_certificate_key "/etc/nginx/cert/cert.key"; |
systemctl restart nginx で nginx を再起動して設定を反映すれば、 http:// の代わりに https:// でアクセスできるようになっているはず。
おまけとして、http:// でアクセスされた時に https:// に転送する 設定を /etc/nginx/sites-enabled/tinypilot.conf や /etc/nginx/conf.d/ 以下に追加するといいかもしれない。
server { listen 80; server_name tinypilot; return 301 https://$host$request_uri; } |
TinyPilotでは、(ちょっと工夫しない限り、)USBケーブルで監視対象PCから 電源を得る。USB2.0だと電源的にはかなり頼りないので、なるべく消費電力が 少なくなるよう、使わないデバイスを停止することを考える。 また、ファンレス運用が普通だろうから、温度が高くなった時の対策も必要だ。
今回は以下の対策を施す。
とはいえ、設定は簡単で、/boot/config.txt 末尾に以下を追記するだけ。この設定の /boot/overlays/README に書いてあるので必要に応じて参照。
/boot/config.txt への追記内容 |
---|
# disable bluetooth and wifi dtoverlay=disable-bt dtoverlay=disable-wifi # lower CPU clock when high temp(65C') temp_limit=65 |
あとおまけ。音なんか要らんという人は、audio=on になっている部分を off に変更。これで更に省電力化…かも?
/boot/config.txt の変更内容 |
---|
# Enable audio (loads snd_bcm2835) #dtparam=audio=on ← これがデフォルト # Disable audio dtparam=audio=off ← このように変更 |
TinyPilot上で top コマンドを実行すると、ustream周りのプロセスやビデオキャプチャデバイスのkernel daemonがCPUを利用していることに気づく。下の例では pid 66 とか 552 とか。 これはRaspberryPiの消費電力と温度の上昇に関わってくる。
何もしていないときのTinyPilotのtop出力 |
---|
top - 13:40:59 up 3 min, 1 user, load average: 0.22, 0.32, 0.15 Tasks: 133 total, 1 running, 132 sleeping, 0 stopped, 0 zombie %Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu2 : 1.3 us, 1.6 sy, 0.0 ni, 97.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 3838.7 total, 3623.5 free, 84.3 used, 131.0 buff/cache MiB Swap: 100.0 total, 100.0 free, 0.0 used. 3615.5 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 66 root 0 -20 0 0 0 I 3.0 0.0 0:04.87 kworker/u9:0-uvcvideo 552 ustream+ 20 0 51696 704 588 S 1.7 0.0 0:02.31 main 823 pi 20 0 10324 2908 2476 R 0.7 0.1 0:00.22 top 809 pi 20 0 12204 3624 2836 S 0.3 0.1 0:00.03 sshd 1 root 20 0 15272 7832 6288 S 0.0 0.2 0:04.20 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd 3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp |
リモートKVMとしてTinyPilotを使う場合、ustreamerもnginxも、USB-HDMIキャプチャも常に動いている必要はない。アクセスが必要になった時だけ 手作業で開始させればいい。 だったら、これらを停止・開始するスクリプトを作っておくと便利JAN?
というわけで、以下のようなスクリプトを書いた。TinyPilot-stop.sh が 常時起動不要なサービスを停止するスクリプト、TinyPilot-start.sh が 必要になったときにこれらを起動するスクリプト。USBVIDEODEVは 皆様の環境でUSB-HDMIキャプチャデバイスが刺さっているデバイスを、 lsusb -t か何かで確認して適宜変更すること。
TinyPilot-stop.sh |
---|
#!/bin/sh # Bus 1, Port 1, Port 3 USBVIDEODEV="1-1.3" SERVICES="nginx ustreamer" error_end() { echo $* exit 1 } for i in $SERVICES; do echo -n "stopping service $i ... " systemctl status $i > /dev/null ret=$? [ "$ret" = 3 ] && echo "stopped, skip" && continue [ "$ret" != 0 ] && error_end "status($ret) is not 0 or 3" systemctl stop $i > /dev/null [ "$?" != 0 ] && error_end "failed" echo "OK" done # disconnect USBVIDEO echo "Disconecting USBVIDEO(on $USBVIDEODEV)" echo -n "$USBVIDEODEV" > /sys/bus/usb/drivers/usb/unbind #[ "$?" != 0 ] && error_end "failed(ret=$?)" # echo "OK" echo "done." |
TinyPilot-start.sh |
---|
#!/bin/sh # Bus 1, Port 1, Port 3 USBVIDEODEV="1-1.3" SERVICES="ustreamer nginx" error_end() { echo $* exit 1 } # connect USBVIDEO echo "Conecting USBVIDEO(on $USBVIDEODEV)" echo -n "$USBVIDEODEV" > /sys/bus/usb/drivers/usb/bind #[ "$?" != 0 ] && error_end "failed(ret=$?)" # echo "OK" for i in $SERVICES; do echo -n "starting service $i ... " systemctl status $i > /dev/null ret=$? [ "$ret" = 0 ] && echo "started, skip" && continue [ "$ret" != 3 ] && error_end "status($ret) is not 0 or 3" systemctl start $i > /dev/null [ "$?" != 0 ] && error_end "failed" echo "OK" done echo "done." |
なんとびっくりこれで不要なサービスだのを停止するだけで、RaspberryPiの 温度が5℃くらい下がる。結構効果は大きい。
起動直後からサービス開始する必要がないなら、systemctl で nginx と ustreamer を停止しておくとよい。これで不慮の問題でRaspberry Piが再起動しても、CPU負荷を軽減できる。
nginx と ustreamer を起動時には停止しておく |
---|
# systemctl disable nginx # systemctl disable ustreamer |
温度は、以下のようなスクリプトで5分おきにどうなっているか出力させて みるとよい。csv形式になるようにしてみた。
五分おきにRaspberry Piの温度をcsv形式で出力するスクリプト |
---|
#!/bin/sh INTERVAL=300 echo "Date-Time, Temperature" while : ; do temp=`cat /sys/devices/virtual/thermal/thermal_zone0/temp` echo -n `date +"%Y-%m-%d %H:%M:%S"`, printf " %d.%03d\n" $((temp/1000)) $((temp%1000)) sleep $INTERVAL done |
LinuxやRaspberryPiは結構頻繁にアップデートされている。 最新に追いつきたいなら、 定期的に以下のようなスクリプトを動作させるとよい。ただ、rpi-updateや rpi-eeprom-update は定期的に行うことが推奨されていないそうなので、 マニーな人以外はコメントアウトした方がいいかも。
システムアップデートスクリプト |
---|
#!/bin/sh run() { echo executing "$*" $* echo "exitcode = $?" echo "" } run apt-get update run apt-get upgrade run rpi-update run rpi-eeprom-update |
いつかやろうと思って計画してたんだけど、本体を手放してしまったのでメモだけ。
簡単には、Raspberry PiのGPIO(General Purpose Imput/Output)端子に リレーくっつけて、PCのリセットと電源のジャンパに結線することで、 GPIO経由(=shell scriptで制御可能)でPCのリセット、電源On/Offができるようになる。
リレーは作れるなら自作すればOK。市販品にも 小型リレーボードキット(5V用) LK-RB1なんてのがあるので、これを使えばよい。 ちょいお高いけど、 Amazonでも入手可能。
ケースにフィンがついている場合、フィンを通って空気が上に抜けるような 形で設置すると冷える。手元の環境では置き方だけで4℃くらい違った。
TinyPilot、便利だ。お安く手軽にリモートKVMを実現する手段としては、 十分アリだと思う。そのままでは電源On/Offや強制リセットができないのは残念だが、 デスクトップPCならアリかなと思う。どうしてもアレだったら上のリレー作ればいいしね。