本文書は、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ならアリかなと思う。どうしてもアレだったら上のリレー作ればいいしね。