DHCPサーバーの構築

今更、何でこんな事を…と思う作業

ホームゲートウェイと呼ばれている各家庭の入口に置かれたルーターの性能が悪すぎて、悲しいことに内蔵しているDHCPサーバーをそのまま利用できない状況です。

仕方なく、別にサーバーを立てて、そこに個別のDHCPサーバーを作らなければならない状況です。天下のNECさん、まともな製品を作ってくださいよね。仕様通りの機能が無くてもレンタル料金を搾取するって詐欺ですね。

我が家のネット環境の変革

最初のネット常時接続

プライベートな写真やこのブログの公開は、以前から長い期間を継続して行っています。それは家に置かれた電化代の少ない小さなサーバーで、Webサーバーを構築して実行しています。

そのための家庭内のネットワーク環境は、契約した常時接続のネットワーク環境で行われていますが、当初は FTTH(光回線)とADSLが混在している時代の環境でした。

(0) その頃にADSLを申し込みましたが、NTTの庁舎からの距離が長く途中で中継されているためメタル線で接続されていないことが判明してアウトでした。(1) そして暫くして普及し始めたフレッツ光で常時接続される環境が提供されたのが最初でした。その頃のレンタルは沖電気工業製のルーターでした。

その後の変革

暫くフレッツ光で 初期のWebサーバーを公開していましたが、世界的に見てもグローバルIPアドレスが不足していて、グローバルアドレスの割り振りに問題があるため世界的に IPv6の試行が始まりました。

我が家のサーバーも技術が無いのに対応に迫られました。しかしNTTのフレッツ光は何故かIPv6の利用を、その頃のオプションとして有料での提供でした。世界的に移行しなければならないIPv6環境への試行が有料オプションだなんてありえないと感じました。

経緯は忘れましたが、KDDIに移行

契約料が安かったからかも知れませんが、(2) 少ししてKDDIの光回線に移行しました。IPv6は無料のまま利用でき、ネットワーク環境も良好でした。今ではこのまま継続していれば良かったのかと後悔しています。

家族のスマホ購入で光回線も切替

時代の流れで妻や子供達のスマホを購入する事になりました。当時の電話としての安さからWillcomのPHSを使用していた流れで、Yモバイルのスマホになり、(3) その親会社のソフトバンクに光回線を切替えると料金が割り引かれて安くなると説明されて切替えました。実際には、色々な条件で割引の規制が行われていて、安くなっていませんでした。

はっきり言ってソフトバンクはNTTに任せっきりなのか技術力がないと感じました。設置されたホームゲートウェイは最悪で、ローカルアドレスを割振るDHCPサーバー機能にネームサーバーを指定できなくて、更に内部にあると思われるネームサーバーが機能をいつの間にか停止してしまうようで、名前の解決ができなくてネットの検索ができない事が多発しました。

Wifiの接続を使用させないようにして、従量制の回線の稼働率を上げながら知らない間に金儲けするような悪意を感じて、不信感が募りました。当時社長の孫さんの意向でしょうか。

そのためWifi接続では、インターネットに接続できない…とほとんどの期間に表示していて、外部回線を使用すれば利用できるのですが、分かっていても使わないためスマホからは何の通信もできない日々が続きました。半日経ったり数時間経つと繋がることもあり、スマホ利用を急ぐ時はホームゲートウェイの電源を再投入し初期化して利用していました。

高価な常時接続の光回線なのに、大昔のパソコン通信のような利用に際してのお膳立てが必要な環境になってしまい苦労しました。その頃、実はWebで公開していた昔のサーバー内にDHCP機能があったのですが、老朽化で物理的に故障して使えなくなり、新しく立ち上げたPogoPlugのWebサーバーにDHCP機能が組み込めなかったりとストレスの溜まる期間でした。

そしてブラスト光の電話セールスで切替

ソフトバンクの前に調子良く利用できていたKDDIに戻したい気持ちがありましたが、ブラスト光の売り込みがあり、特に安くなく使い物にならないソフトバンク以外なら何でも良かったのが本音です。(4) ブラスト光はオプションをカスタマイズすると契約料金も安く快適で、ホームゲートウェイは中国製ファーウェイのHG8045Qで、色々な細かな設定もでき実に使いやすく安定していました。

問題は、ならず者国家の北朝鮮と大差のない習近平ひきいる中国共産党の傘下にある企業が制作しているルーターなので、バックドアや何が仕掛けられているのか分からない恐怖を感じながら利用していることです。

特に安くなるわけでもないけど光回線契約をKDDIに戻すことに

電話のセールスで、北海道や九州の複数の au光の代理店が売り込んできたので、安くなるわけではないものの気になるファーウェイのルーターを外す意味で、(5) au光に乗り換えを承諾しました。

ただ後々確認して分かったことは、レンタルになるホームゲートウェイがNEC製だと知りました。ソフトバンクで痛い目にあっている出来の悪かったNEC製なので、あれから年月は経っているのでまさかとは思いますが不吉な予感を感じました。

レンタルルーター説明書を確認、やはり使えねえ〜

機種名からネットで説明書を探し、機能を真っ先に確認しましたが、やはりDHCPサーバーにDNSを設定する箇所が見当たらなくて、不吉な予感はあたっていました。

説明書によると、DHCPで割振る開始アドレスの位置を設定できるらしく、固定で割り当てされているサーバーのアドレスの変更までは必要がないと胸をなでおろしました。

ところが送られてきたルーターを設定し始めて分かったことは、設定項目を入れる箇所があっても何を入れても受付けずに全てエラーを返して機能しないことが分かりました。天下のNECさん作りが悪すぎだよ、これって製品としてテストして出荷している市販品ですか。

DHCPで振られるアドレスが、サーバーの固定アドレスと競合

①工事費は、詐欺に有ったと思い諦めて切替の契約を破棄して戻すか、②旧型でも中古品でもまともに使えるルーターに交換させるか、あるいは③自分でDHCPサーバーを立ち上げて処理させるか、3択の選択に悩む大きな問題に直面しました。

最新のRaspberry pi に期待して画策

③の実現性を1週間位で見極めることにしました。以前、Raspberry pi にDHCPサーバーを組み込もうと考えて挫折したことがありました。それはインストールしてもエラーが起こり、対策方法をネットの検索では見付けられずに諦めた経緯があります。でもそれから Debian のバージョンも上がり、Raspberry pi の利用者も大きく増えていることを考えると、今ならできそうな気がします。

腹を決めDHCPサーバーを立ち上げることに

まずはワーキングとして動作させていた最新の Raspberry pi に組み込み動作検証から始めました。ネットの情報を確認するとシステムの立ち上げで自動的に起動しないことが頻繁に起こるようで、サーバーが起動してから10秒位待たせてスクリプトで起動したり、皆さん苦労して動作させているのが現状のようでした。

systemd の振舞に則った対策をしているサイト

DHCPサーバーが停止しても自動的に再起動させるための systemd に則った手順を定義して対策しているサイトを見つけることができました。ほぼ丸写しで立ち上げできる目処が立ち、レンタルルーター内の IPv4 のDHCPサーバー機能を停止して、自前のDHCPサーバーを利用する目処が立ちました。

今後のためにDHCPサーバーの記録を残す

もしもの事も考えて、検証したワーキングサーバーの組み込みは自動で立ち上げしないようにしておき dhcp_disable、公開しているWebサーバーの Raspberry pi 内にDHCPサーバー機能を組込むことにしました。

ISC-dhcp-server インストール

DHCPサーバーをインストールします。isc-dhcp-server は、純粋の systemd としての構成になっていないようなので、前述の親切なネット情報を参考にして組込み、起動しなかったり何かの状況で停止しても再起動させる手順の追加が必要になります。

$ sudo apt install isc-dhcp-server
以前に未選択のパッケージ libisccfg-export163 を選択しています。 (データベースを読み込んでいます ... 現在 174552 個のファイルとディレクトリがインストールされています。) .../libisccfg-export163_1%3a9.11.5.P4+dfsg-5.1+deb10u3_armhf.deb を展開する準備をしています ... libisccfg-export163 (1:9.11.5.P4+dfsg-5.1+deb10u3) を展開しています... 以前に未選択のパッケージ libirs-export161 を選択しています。 .../libirs-export161_1%3a9.11.5.P4+dfsg-5.1+deb10u3_armhf.deb を展開する準備をしています ... libirs-export161 (1:9.11.5.P4+dfsg-5.1+deb10u3) を展開しています... 以前に未選択のパッケージ isc-dhcp-server を選択しています。 .../isc-dhcp-server_4.4.1-2_armhf.deb を展開する準備をしています ... isc-dhcp-server (4.4.1-2) を展開しています... 以前に未選択のパッケージ selinux-utils を選択しています。 .../selinux-utils_2.8-1+b1_armhf.deb を展開する準備をしています ... selinux-utils (2.8-1+b1) を展開しています... 以前に未選択のパッケージ policycoreutils を選択しています。 .../policycoreutils_2.8-1_armhf.deb を展開する準備をしています ... policycoreutils (2.8-1) を展開しています... selinux-utils (2.8-1+b1) を設定しています ... policycoreutils (2.8-1) を設定しています ... selinux-autorelabel-mark.service is a disabled or a static unit, not starting it. libisccfg-export163 (1:9.11.5.P4+dfsg-5.1+deb10u3) を設定しています ... libirs-export161 (1:9.11.5.P4+dfsg-5.1+deb10u3) を設定しています ... isc-dhcp-server (4.4.1-2) を設定しています ... Generating /etc/default/isc-dhcp-server... Job for isc-dhcp-server.service failed because the control process exited with error code. See "systemctl status isc-dhcp-server.service" and "journalctl -xe" for details. invoke-rc.d: initscript isc-dhcp-server, action "start" failed. isc-dhcp-server.service - LSB: DHCP server Loaded: loaded (/etc/init.d/isc-dhcp-server; generated) Active: failed (Result: exit-code) since Mon 2021-03-01 10:58:51 JST; 52ms ago Docs: man:systemd-sysv-generator(8) Process: 623 ExecStart=/etc/init.d/isc-dhcp-server start (code=exited, status=1/FAILURE) 3月 01 10:58:49 web-server dhcpd[644]: bugs on either our web page at www.isc.org or in the README file 3月 01 10:58:49 web-server dhcpd[644]: before submitting a bug. These pages explain the proper 3月 01 10:58:49 web-server dhcpd[644]: process and the information we find helpful for debugging. 3月 01 10:58:49 web-server dhcpd[644]: 3月 01 10:58:49 web-server dhcpd[644]: exiting. 3月 01 10:58:51 web-server isc-dhcp-server[623]: Starting ISC DHCPv4 server: dhcpdcheck syslog for diagnostics. ... failed! 3月 01 10:58:51 web-server isc-dhcp-server[623]: failed! 3月 01 10:58:51 web-server systemd[1]: isc-dhcp-server.service: Control process exited, code=exited, status=1/FAILURE 3月 01 10:58:51 web-server systemd[1]: isc-dhcp-server.service: Failed with result 'exit-code'. 3月 01 10:58:51 web-server systemd[1]: Failed to start LSB: DHCP server. man-db (2.8.5-2) のトリガを処理しています ... libc-bin (2.28-10+rpi1) のトリガを処理しています ... systemd (241-7~deb10u6+rpi1) のトリガを処理しています ...

インストールしてもそのままでは稼働しません。いくつかの呪文のような修正を施して動作させる必要があります。割振るアドレス範囲等の情報をIPv4 / IPv6に対応して定義しますが、今回はIPv4のみ作成します。アドレスの要求を受付けるインターフェイス eth0 の定義、それとインストール時に出されていた上記メッセージに書かれている debug に関する修正で、no を yes に書き換える必要があります。

起動のタイミングや何らかの問題で停止しても再起動させるように、新規に次のような定義ファイルを作成します。内容は参考にしたサイトの丸写しで問題無く動作するようです。systemd では、ユニットファイルと呼ぶ定義ファイルを /etc/systemd/system/ の下に配置するようで、丸コピーした次の例では isc-dhcp-server.service.d としてディレクトリを配置して、更にその下に定義ファイル 10-additional.conf を作成していました。

試していませんが、例えば 直接 /etc/systemd/system/ ディレクトリの下に isc-dhcp-server.service と名付けて以下内容のユニットファイルを配置しても良さそうです。

$ cat /etc/systemd/system/isc-dhcp-server.service.d/10-additional.conf

[Unit] SourcePath=/etc/init.d/isc-dhcp-server [Service] Type=forking PIDFile=/var/run/dhcpd.pid RemainAfterExit=no Restart=on-failure RestartSec=15s

要求にアドレスを割振る範囲やDNSの設定

稼働させるための定義ファイルを作成します。割振るアドレスは、192.168.11.31 〜 192.168.11.200 の範囲としています。

定義した内容の注目箇所のみに省略した内容で、次に示します。

$ sudo vi /etc/dhcp/dhcpd.conf

# dhcpd.conf
#
# Sample configuration file for ISC dhcpd
#

# option definitions common to all supported networks...
option domain-name "sunao-mita.pgw.jp";
#option domain-name-servers ns1.example.org, ns2.example.org;

default-lease-time 600;
max-lease-time 7200;

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# network, the authoritative directive should be uncommented.
authoritative;

subnet 192.168.11.0 netmask 255.255.255.0 {
 range 192.168.11.31 192.168.11.200;
 option routers 192.168.11.1;
 option domain-name-servers 192.168.11.2, 192.168.11.20;
 option broadcast-address 192.168.11.255;
 ignore declines;
}

アドレス要求に答えるインターフェイスの設定

DHCPサーバーへのアドレス要求を受け付けるインターフェイスを定義します。なお、IPv6に関しては、レンタルのホームゲートウェイに任せます。そのためIPv4の機能のみ自前で稼働させます。定義内容は、最後にある空欄に eth0 を追加しているだけです。

$ cat /etc/default/isc-dhcp-server

〜〜省略
# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACESv4="eth0"
INTERFACESv6=""

ついでにDHCP関連の簡易コマンドを作成

稼働状況を確認したり、定義を変更して再起動したり、停止したり、サーバーを再起動で自動的に起動したり、サーバーの再起動で自動起動させないようにしたりすることも多く発生すると思われますが、/usr/local/bin 内にコマンドを作成しておきます。

  • dhcp_status …稼働状況の確認や簡易ログ
  • dhcp_start …手動で開始
  • dhcp_stop …手動で停止
  • dhcp_restart …定義変更等で再起動
  • dhcp_enable …サーバーの電源投入で自動起動させる
  • dhcp_disable …サーバーの電源投入で起動させない
  • dhcpリース …割振り状況のリストを表示
  • dhcpジャーナル …蓄積されたジャーナル、statusの簡易ログが蓄積?

定義を次のようにしています。rootになって、cd /usr/local/bin に移動して、dhcp_status を最初に作成して、それにリンクを定義しています。

$ sudo su -
# cd /usr/local/bin
# vi dhcp_status

#!/bin/sh
# status start stop enable disable restart 
rc=`echo $0 | sed -e "s/^.*_\(.*\)$/\1/"`

sudo systemctl $rc isc-dhcp-server.service

各コマンドに対するリンクを張ります。

# chmod +x dhcp_status
# ln -s ./dhcp_status dhcp_start # ln -s ./dhcp_status dhcp_stop # ln -s ./dhcp_status dhcp_restart # ln -s ./dhcp_status dhcp_enable # ln -s ./dhcp_status dhcp_disable

ついでにアドレスを割振ったリース状況の確認コマンドも作成しておきます。理由は、直ぐに忘れる少し長いステートメントのコマンドをリースとかdhcpとかの簡単な文字列から見付けて利用するためです。それとジャーナルの確認コマンドも追加です。

# vi dhcpリース
#!/bin/sh
less /var/lib/dhcp/dhcpd.lease 
# chmod +x dhcpリース

# vi dhcpジャーナル
#!/bin/sh
journalctl -u isc-dhcp-server.service
# chmod +x dhcpジャーナル

安全のためか稼働には修正の必要がある

dhcpサーバーを導入して、debug を修正する必要があるらしいので、no ⇒ yes に書き換えます。

$ cat /etc/dhcp/debug
#
# The purpose of this script is just to show the variables that are
# available to all the scripts in this directory. All these scripts are
# called from dhclient-script, which exports all the variables shown
# before. If you want to debug a problem with your DHCP setup you can
# enable this script and take a look at /tmp/dhclient-script.debug.

# To enable this script set the following variable to "yes"
RUN="yes"

if [ "$RUN" = "yes" ]; then 〜〜以下省略

準備ができたので起動して確認

$ sudo systemctl daemon-reload
$ dhcp_restart

稼働しているのかエラーで停止しているのか確認

作成した簡易コマンド dhcp_status を起動すると状況が表示されますが、画面から溢れている部分は矢印キーで移動して、最後に q で終了します。

$ dhcp_status
Warning: The unit file, source configuration file or drop-ins of isc-dhcp-server.service changed on disk. Run '
 isc-dhcp-server.service - LSB: DHCP server
   Loaded: loaded (/etc/init.d/isc-dhcp-server; generated)
  Drop-In: /etc/systemd/system/isc-dhcp-server.service.d
           └─10-additional.conf
   Active: active (running) since Wed 2021-03-03 09:58:22 JST; 13h ago
     Docs: man:systemd-sysv-generator(8)
  Process: 28579 ExecStart=/etc/init.d/isc-dhcp-server start (code=exited, status=0/SUCCESS)
 Main PID: 28592 (dhcpd)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/isc-dhcp-server.service
           └─28592 /usr/sbin/dhcpd -4 -q -cf /etc/dhcp/dhcpd.conf eth0

 3月 03 23:06:51 web-server dhcpd[28592]: DHCPACK on 192.168.11.31 to b0:4e:26:84:7b:34 (Archer_C1200) via eth0
 3月 03 23:07:12 web-server dhcpd[28592]: reuse_lease: lease age 61 (secs) under 25% threshold, reply with unal
 3月 03 23:07:12 web-server dhcpd[28592]: DHCPREQUEST for 192.168.11.31 from b0:4e:26:84:7b:34 (Archer_C1200) v
 3月 03 23:07:12 web-server dhcpd[28592]: DHCPACK on 192.168.11.31 to b0:4e:26:84:7b:34 (Archer_C1200) via eth0
lines 1-17

割当てられたIPアドレスのリース状況

割振られたIPアドレスやリースの確認は、作成した簡易コマンド dhcpリース を利用して、矢印キーで移動して確認します。操作は、コマンド less の操作になります。最後に q で終了します。

$ dhcpリース
  set vendor-class-identifier = "MSFT 5.0";
  client-hostname "Archer_C1200";
}
lease 192.168.11.32 {
  starts 3 2021/03/03 14:06:22;
  ends 3 2021/03/03 14:16:22;
  cltt 3 2021/03/03 14:06:22;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet dc:a6:32:8d:18:2c;
  uid "\001\334\2462\215\030,";
  set vendor-class-identifier = "dhcpcd-8.1.2:Linux-5.10.11-v7l+:armv7l:BCM2711";
  client-hostname "working";
}
lease 192.168.11.54 {
  starts 3 2021/03/03 14:06:37;
:

DHCPの稼働で蓄積されたジャーナルの確認

ジャーナルの確認には、作成した簡易コマンドで dhcpジャーナル を使用します。操作は less の操作と同じです。最後は q で終了します。

$ dhcpジャーナル
-- Logs begin at Mon 2021-03-01 20:50:19 JST, end at Thu 2021-03-04 00:52:41 JST. --
 3月 01 20:50:34 web-server dhcpd[1270]: reuse_lease: lease age 81 (secs) under 25% threshold, reply with unalt
 3月 01 20:50:34 web-server dhcpd[1270]: DHCPREQUEST for 192.168.11.31 from b0:4e:26:84:7b:34 (Archer_C1200) vi
 3月 01 20:50:34 web-server dhcpd[1270]: DHCPACK on 192.168.11.31 to b0:4e:26:84:7b:34 (Archer_C1200) via eth0
 3月 01 20:50:37 web-server dhcpd[1270]: DHCPREQUEST for 192.168.11.32 from dc:a6:32:8d:18:2c (working) via eth
 3月 01 20:50:37 web-server dhcpd[1270]: DHCPACK on 192.168.11.32 to dc:a6:32:8d:18:2c (working) via eth0
 3月 01 20:50:54 web-server dhcpd[1270]: reuse_lease: lease age 101 (secs) under 25% threshold, reply with unal
 3月 01 20:50:54 web-server dhcpd[1270]: DHCPREQUEST for 192.168.11.31 from b0:4e:26:84:7b:34 (Archer_C1200) vi
 3月 01 20:50:54 web-server dhcpd[1270]: DHCPACK on 192.168.11.31 to b0:4e:26:84:7b:34 (Archer_C1200) via eth0
 3月 01 20:51:01 web-server dhcpd[1270]: DHCPREQUEST for 192.168.11.52 from dc:a6:32:4a:d7:39 (web-server) via 
 3月 01 20:51:01 web-server dhcpd[1270]: DHCPACK on 192.168.11.52 to dc:a6:32:4a:d7:39 (web-server) via eth0
 3月 01 20:51:04 web-server dhcpd[1270]: reuse_lease: lease age 3 (secs) under 25% threshold, reply with unalte
 3月 01 20:51:04 web-server dhcpd[1270]: DHCPREQUEST for 192.168.11.52 from dc:a6:32:4a:d7:39 (web-server) via 
 3月 01 20:51:04 web-server dhcpd[1270]: DHCPACK on 192.168.11.52 to dc:a6:32:4a:d7:39 (web-server) via eth0
 3月 01 20:51:12 web-server dhcpd[1270]: reuse_lease: lease age 11 (secs) under 25% threshold, reply with unalt
 3月 01 20:51:12 web-server dhcpd[1270]: DHCPREQUEST for 192.168.11.52 from dc:a6:32:4a:d7:39 (web-server) via 
 3月 01 20:51:12 web-server dhcpd[1270]: DHCPACK on 192.168.11.52 to dc:a6:32:4a:d7:39 (web-server) via eth0
lines 1-17

ネット環境を日常の状況により操作

DHCPサーバーを一時的に停止する場合 dhcp_stop や、
停止から起動する場合 dhcp_start
定義情報を書き換えて再起動するには dhcp_restart
更にはサーバーの停止再起動でDHCPサーバーを自動起動させたくない時 dhcp_disable、サーバーの再立ち上げで自動起動させたい場合 dhcp_enable
等を簡易コマンドで操作します。

常時稼働の検証サーバー構築

非力なノートパソコンで色々な検証は無理

ちょっとした検証や学習用として、ミスって止めても問題の起こらないサーバーとして、最新のラズベリーパイ Raspberry pi 4 B+ 4GB を購入して構築を始めました。

なおここから記述している作業は基本的に、Linux の Ubuntu が稼働しているパソコン上での作業が中心です。一部でターゲットとして構築している Raspberry pi 本体での作業の場合もあります。

構築を始めたサーバーの利用目的

最大の目的は、プライベート写真を公開している現在のウェブシステムでは、単純に写真を撮影日を元にしてディレクトリに入れて、単純なインデックスを付けているだけなので、特定な条件により選び出すような使い方ができません。

公開システムの構築を思い立った頃に、データベースの知識不足とセキュリティを考慮したシステムを作る自信が無かったこともあって、そのまま大幅な改修もできないまま現在に至っています。

当時気にしていたのはSQLインジェクション

当時はSQLインジェクションなんて呼ばれている攻撃で、データベースシステムが改ざんされる話があちこちで騒がれていたし、データベース未使用でも色々な攻撃でダウンさせられる事件も頻繁に起きていたので、可能な限り最低限の運用に重点を置いていました。

最低限なシステムが功を奏したのか、ヤドカリのように何世代にも渡って殻 (サーバー) を乗換えながらネットに公開していましたが、まだ改ざんされた経験はありません。ちょっと心配になるくらい切れ目なく攻撃の記録がログに残されています。

真の目的は、何の事はないSQL言語の学習用

今のプライベート公開写真のシステムは、データベースを利用しないで、サーバー側で動作する Ruby言語のスクリプトと、端末側で動作する JavaScript の記述を組合せて構築していますが、サーバー側での Ruby スクリプトからデータベースを利用して効率的な検索ができるようになれば、見たい写真の選択が容易になって理想だろうと考えてます。

今回のシステム構築の備忘録

項目リスト

  1. Raspberry pi 4 B+ 、電源アダプタ、ケース類を 購入
  2. Raspbian 最新版のダウンロード と microSD 32GB Class10 への書込み
  3. USBキーボード、マウス、 micro HDMI へモニタを接続してシステム起動
  4. 表示に従って、キーボード種別や言語を指定、その他の問いに答えて初期設定
  5. リブート、初期設定システムの確認と最新アップデートの適用
  6. 初期起動は、microSD で、実システムには、2.5インチ USB ハードディスクへ
  7. vi コマンドで編集するため、vimの設定
  8. 初期設定済み pi ユーザーを sunao ユーザーに置き換え
  9. 基本はリモート作業で利用するため、RSA秘密鍵の生成と SSHの設定
  10. リモート操作で基本の仮想端末 byobu / screen の設定
  11. サーバー内からメールを転送することができる設定
  12. Logwatch と Cron の動作確認

検討内容や作業内容

1.Raspberry pi の機材購入

後の事を考えて最新版で最大メモリ搭載を選択

今回は、サーバーとして利用する予定なので、Wi-Fiや4GBのメモリも全く必要がないのですが、後々不要となって再利用を考えた場合、パソコンとしてセットアップしてみたり、別のOSを入れてみたりと考えると、現時点の最新最上で導入していても良いかなと思い、それに沿った Raspberry pi と ケース、micro HDMIケーブル、電源を一緒に購入しました。

手持ちのものは有るもので間に合わせ

行く行くは入出力を直接持たない単体のサーバーとして稼働の予定なので、初期のセットアップでの間に合せで使用する microSD や キーボード、マウスは使い古しの余っているもので代用させます。

実行時にシステムディスクとして常設する予定の USBハードディスクは、過去に公開ウェブサーバーで使用していたものをパーティションを再定義しての流用を考え購入しません。

2.OSのダウンロードとmicroSDへのセットアップ

OSは最新版のRaspbian

システムは、一般的な Raspbian の最新版のデスクトップを含むフルサイズのものを公式サイトから普通にダウンロードしました。 sha256sum コマンドでエラーのないことを確認してから解凍し、–.img ファイルを作成しました。

$ cd download-dir
$ ls
2020-02-13-raspbian-buster-full.zip

$ sha256sum 2020-02-13-raspbian-buster-full.zip
  〜〜しばらく時間がかかりハッシュチェック完了〜〜
c9c382b659bd96b859ccb9e2ac0c2292a91a37c286ab464f2f380d451077663d  2020-02-13-raspbian-buster-full.zip
$ unzip *.zip
$ ls
2020-02-13-raspbian-buster-full.img  2020-02-13-raspbian-buster-full.zip

手持ちの 32GB microSD Class10 のものに、単純に dd コマンドで書込みました。

$ sudo dd if=2020-02-13-raspbian-buster-full.img of=/dev/mmcblk0 bs=4096
   〜〜しばらく時間がかかり書込み完了〜〜

3.初期設定に必要な機材の接続と電源投入

前述でシステムを書き込んだ microSD を Raspberry pi 本体に挿入し、USBマウス、USBキーボードを接続します。

モニター表示のためにテレビを用意して、HDMIケーブルを接続します。ケーブルの反対側の micro HDMI コネクタを、2つ有る micro HDMI ポートの Raspberry pi 本体電源供給用 Type-C 寄りの HDMIポートに接続します。

必要なものを接続したら電源ON

最後に電源供給用の USB Type-C のポートに 5V電源アダプタを接続して電源ONします。しばらくするとテレビのモニタには、並んだラズベリーマークを表示して動作を始めます。

作成したシステム用の microSD は、固定サイズの 2パーティション構成で作成されて残りのエリアが空きのままなので、システムパーティション(第2パーティション ext4)に残り全てのエリアを取り込むために少し経つと勝手にリブートします。

その度に進化していて初期化手順が異なります

初期のラズベリーパイから何度も初期設定していますが、毎回改良され進化しているので、都度操作手順も設定項目も変わっていて、操作手順を詳細に記録してもあまり意味がないようです。

4.言語やタイムゾーンの初期設定を行います

操作している Raspberry pi 4 B+ 本体を今後はラズパイと省略して呼ぶことにします。ラズパイも初期化する度に初期化の手順や動きが異なりますので、モニターに表示された問に対して返答しながら必要な項目を設定していきます。

日本語の言語選択や Japan / Tokyo 等のタイムゾーン、キーボードの種類の設定も、ただ選択するだけで設定できてしまいます。以前は苦労しながらフォントやキーボード等をカスタマイズしたのが嘘のように簡単です。

インターネットに接続するために、Wi-Fiに接続しますが、これも聞かれるままに接続ポイントとパスワードを指定するだけです。複数の接続ポイントが存在していて、複数を設定するならモニター右上の無線の扇マークのクリックから設定できます。

5.初期設定システムの確認と最新アップデート

リブートして立上がると指定した日本語のデスクトップ画面になっていて、システム時間も日本の時間になっています。画面からターミナルを起動して date コマンドを入力すると一般的な日本の時間が表示されます。

$ date
2020年  3月 29日 日曜日 17:43:47 JST

最新へアップデートを行っておきます。

$ sudo apt update
  〜〜リストされ時間が掛かります〜〜
$ sudo apt -y upgrade
  〜〜少しずつリストされ時間が掛かります〜〜

6.システムパーティションを USBハードディスクへ

現時点のシステムディスクは microSD

現時点で、システムパーティションが microSD 32GB Class10 の第2パーティションになっています。

ラズパイ 3 ならば、USBディスクにシステムを入れて直接起動もできるとネットに情報が上げられています。しかし、ラズパイ 4 ではまだ対応できていないとの情報があって、色々調べましたが現時点ではそれが真実のようです。

microSDで初期起動して、USB-HDDで稼働させます

今までの家屋内で稼働しているラズパイと同様に、起動には microSD の第1パーティションを使い、実際に稼働するOSをUSBハードディスクのパーティションに作成する方法を利用することにします。

再利用なのでパーティションを見直します

まずシステムパーティションやデータの格納パーティションになる USBハードディスクの設定です。前に他で利用していたものの再利用ですので、パーティションの削除から行います。

$ sudo fdisk /dev/sdb

結果として次のような構成に設定しました。今回利用するのは 1TB 2.5インチ USB3.0 のハードディスクです。

作業を後からまとめるつもりで作業していたわけではなかったので、作業中の情報を残していませんでした。そのため次のリストは、後からラズパイの実機立上げ後にリストしたものなので /dev/sda となっています。パソコンで作業している時は、外付けなので /dev/sdb として作業しました。

Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: Rikiki USB 3.0  
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0xa51bb4e8

Device     Boot      Start        End    Sectors   Size Id Type
/dev/sda1  *          2048    4196351    4194304     2G  b W95 FAT32
/dev/sda2          4196352   46139391   41943040    20G 83 Linux
/dev/sda3         46139392   67110911   20971520    10G 82 Linux swap / Solaris
/dev/sda4         67110912 1953525167 1886414256 899.5G  5 Extended
/dev/sda5         67112960  234885119  167772160    80G 83 Linux
/dev/sda6        234887168 1178605567  943718400   450G 83 Linux
/dev/sda7       1178607616 1953525167  774917552 369.5G 83 Linux

次にパーティションにラベルを付けて、以下のように初期化しました。

$ sudo mkfs.ext4 -L rootfs /dev/sdb2    …これがシステムパーティションになる
$ sudo mkswap -L swap /dev/sdb3
$ sudo mkfs.ext4 -L home /dev/sdb5
$ sudo mkfs.ext4 -L share-data /dev/sdb6
$ sudo mkfs.ext4 -L data /dev/sdb7

UUID 等を確認するため blkid コマンドでリストして確認しておきます。以下のリストは控えるのを忘れたため、後から実機上で確認したものなので形式が少し異なっているかもしれません。

$ sudo blkid
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="9969-E3D2" TYPE="vfat" PARTUUID="97709164-01"
/dev/sdb2: LABEL="rootfs" UUID="b1be8a91-ebb8-48f9-a617-9ec4d400fe55" TYPE="ext4" PARTUUID="a51bb4e8-02"
/dev/sdb3: LABEL="swap" UUID="223a9d6f-29bf-4e03-8c89-2d2d96334d5b" TYPE="swap" PARTUUID="a51bb4e8-03"
/dev/sdb5: LABEL="home" UUID="b92fd514-5428-4707-a74b-003754b08bca" TYPE="ext4" PARTUUID="a51bb4e8-05"
/dev/sdb6: LABEL="share-data" UUID="220b06fa-d717-4243-8427-879b0621357f" TYPE="ext4" PARTUUID="a51bb4e8-06"
/dev/sdb7: LABEL="data" UUID="7e720f4d-acb1-4cc1-b85a-1da166507375" TYPE="ext4" PARTUUID="a51bb4e8-07"
/dev/mmcblk0: PTUUID="97709164" PTTYPE="dos"
/dev/sdb1: PARTUUID="a51bb4e8-01"

システムパーティションをハードディスクに移動し確認

次にシステムパーティション(P2)をUSBハードでテスクにコピーして、一部設定を変更してシステムが起動することを確認します。

  〜〜microSDの挿入で自動マウントしたのをアンマウント
$ sudo umount /dev/mmcblk0p1
$ sudo umount /dev/mmcblk0p2

  〜〜作業用マウントポイントの確認
$ ls /mnt
  〜〜システムパーティションの転送元と転送先のマウント
$ sudo mount /dev/mmcblk0p2 /mnt/work
$ sudo mount /dev/sdb2 /mnt/sdb2
  〜〜そのままコピー
$ sudo rsync -a /mnt/work/ /mnt/sdb2/

  〜〜次にシステムマウント用の /etc/fstab を編集
$ sudo vi /mnt/sdb2/etc/fstab
  ---------次が編集後の最終結果-----
proc            /proc           proc    defaults          0       0
PARTUUID=97709164-01  /boot           vfat    defaults          0       2
PARTUUID=a51bb4e8-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

  〜〜システム用パーティションをアンマウントし
       起動用パーティションをマウント
$ sudo umount /mnt/work
$ sudo mount /dev/mmcblk0p1 /mnt/work
  〜〜起動用のコマンドライン定義を変更
$ sudo ls /mnt/work
$ sudo vi /mnt/work/cmdline.txt
  ---------次に USBハードディスクのパーティションをシステムに変更
console=serial0,115200 console=tty1 root=PARTUUID=a51bb4e8-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

  〜〜作業したマウントを開放する
$ sudo umount /mnt/work
$ sudo umount /mnt/sdb2

この状態で修正した、microSD と USBハードディスクをラズパイに挿入して、起動できるか確認します。

利用価値のない microSD を起動に活用

この構成で起動できることが確認できましたので、起動に利用する microSD を入替えたいと思います。

入替える理由は、自分の手持ちの中に容量も少なく速度も遅く、ほとんど利用価値のない microSD 4GB Class4 があり、このシステムでは 1度起動されれば稼働中はほとんどが USBハードディスクでの動作になるため、大きな問題が無いと考えてこちらに置き換えます。

まず正常に起動した 32GB の microSD を作業用パソコンに挿入します。そしてdd コマンドで、microSD 全域を1ファイルとして作業用パソコン内に一時ファイルとしてコピーします。そして取り出してから置換える 4GB の microSD を作業用パソコンに挿入してコピーします。

  〜〜元になる 32GB の microSD を作業用パソコンに挿入
  〜〜microSD 全域をファイル名 mmcblk0 としコピー
$ sudo dd if=/dev/mmcblk0 of=mmcblk0 bs=4096
  〜〜置換える 4GB の microSD に交換して
  〜〜ファイル名 mmcblk0 を microSD にフルコピーする
$ sudo dd if=mmcblk0 of=/dev/mmcblk0 bs=4096

実際には、パラメータの bs= の数値を大きくしてコピーするブロックサイズを大きくした方が作業が早くなると思われます。そして、物理的なサイズが違うため、エリアが足らないとエラーになりますが、起動に必要な第1パーティション部分は全く問題なくコピーされています。

7.普段使いのエディタ vim の整備

リモートで操作してコマンドで整備したり利用したりするために、普段常用しているエディタ vim のフルセットを導入して設定を変更しておくことにします。

マウスのクリックで勝手にビジュアルモードになってしまう

マウスを使用して操作することが多いのですが、マウスのクリックで使用することのないビジュアルモードに勝手に移行してしまう問題があります。これを回避する設定が有るようなのでその設定を行います。

vim の定義ファイルが、各ユーザーのホームディレクトリに置かれているので、そのファイル .vimrc に、呪文のような1行を追加しておきます。

$ cat .vimrc
set mouse-=a

コマンドの履歴を確認できる環境へ

ついでに標準のシェル bash の設定にもカスタマイズを加えておきます。通常のシェルとして起動される bash は、ユーザーのホームディレクトリに .bashrc として設定ファイルを持っています。

色々な設定の雛形がコメントとして記述されているので有効にして、再起動するだけで利用できるものもあります。

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignorespace

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=100000
HISTFILESIZE=100000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

   〜〜所々省略してます
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'

# some more ls aliases
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'
   〜〜所々省略してます
export HISTTIMEFORMAT='%F %T '
export PROMPT_COMMAND='history -a; history -c; history -r' # 履歴のリアルタイム反映

色々な設定値を試してみながら、都度カットアンドトライしてみて馴染むものを残せば良いのだと思います。

8.規定値の pi ユーザーを sunao に置き換え

今まで利用しているユーザー名 sunao を複数の既存システムと統一して作業するのに、デフォルトの pi ユーザーのままでは色々と支障が出てきます。そのため uid:1000 を pi から sunao に入替えて、pi は 1001 として残しておきます。

関係するファイルは、rootユーザーで変更してしまいます。実行するコマンドは次のコマンドです。

  • vipw / vipw -s
  • vigr / vigr -s
  • visudo
# vipw
    〜〜前後省略 該当部分のみ〜〜
sunao:x:1000:1000:,,,:/home/sunao:/bin/bash
pi:x:1001:1001:,,,:/home/pi:/bin/bash
    〜〜

:pi から :sunao に置換する場合は、viエディタ内でのコマンド操作で、 :%s/:pi/:sunao/g のように行うと一括で置換されます。

9.リモート認証の鍵生成

ssh を利用してリモート作業を行うのに、パスワード入力の認証は煩わしいのと、外部からパスワードを繰り返しチャレンジされるセキュリティの問題を回避するために、秘密鍵と公開鍵を生成してお互いに接続する環境を整えます。

接続する側をクライアント、接続される側をサーバーと呼び、考え方としてはクライアント側のユーザーが、ssh-keygen コマンドを実行するとデフォルトでは、ユーザーのホームディレクトリに .ssh サブディレクトリが作成されて、その中に秘密鍵と公開鍵のペアが生成されて置かれます。

鍵の生成例

ユーザー名: test で rsa 鍵を生成して、生成された .ssh ディレクトリのリストを表示しています。 id_rsa が秘密鍵で、id_rsa.pub が公開鍵になります。公開鍵の内容イメージも例示しておきます。

test@working:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/test/.ssh/id_rsa): 
Created directory '/home/test/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/test/.ssh/id_rsa.
Your public key has been saved in /home/test/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:WgJ+bZ4WB2zKR8DqhtCeinpQlLgyTtfdCac/OnGnQFw test@working
The key's randomart image is:
+---[RSA 2048]----+
| . . ..          |
|. o   .+ E       |
| +  o.o @ .      |
|=.oo.+ X +       |
|+=.+. * S .      |
|..+ o. X B .     |
|.o .  . O +      |
|o .    + .       |
|o.      .        |
+----[SHA256]-----+


test@working:~$ ls -al .ssh
合計 16
drwx------ 2 test test 4096  4月 13 15:47 .
drwxr-xr-x 3 test test 4096  4月 13 15:47 ..
-rw------- 1 test test 1823  4月 13 15:47 id_rsa
-rw-r--r-- 1 test test  394  4月 13 15:47 id_rsa.pub


test@working:~$ cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8TsyIMEyb6OSY3V6uqX+kzlcuHowJImBIseyoJcRgSIcJvGtECVxVg9UjN41elMsF213ycDSjOpwnvDbFERfRqdxdyZaqehPO1+sRamgzTl6lzjSwFJIThwkcOM4ybNYHzqiNqKAxnOPgA5/HzJTBQINvmESkW8J4NbIrkjG6QsL2HOffC2ssnunFdvgeFPLSlxUi4mmdeuavX/F0dIa4IfTojirS6l8K9bKNQQ7j8HgaXBfZmIHpG/6iOnl+NvK/dQ53RGG0TVdrfEwxNzhdMVZ5mSPOpwuIs5gnYb3Of4sW6fc2boGr5lMSNx/7NrXzE6YDj1kpKvD1H7dPEfBP test@working

鍵認証でリモートログインするには

鍵を生成したクライアントのユーザーが、リモートで接続するサーバー側ユーザーのホームディレクトリの .ssh に置かれた authorized_keys ファイルに生成した公開鍵の情報を追加で丸コピーします。もしファイルがなければ新規に作成します。

authorized_keys ファイル内にコピーされている公開鍵とペアになる秘密鍵を持つユーザーが鍵認証でリモートログインできるようになります。セキュリティ上の課題はありますが、秘密鍵を流用コピーして接続することが可能です。

生成する鍵には、パスワードやパスフレーズを含めてセキュリティを向上させることは可能ですが、常時稼働する特定のサーバー同士で特定のファイルやディレクトリ等を rsync コマンド等を利用して自動でバックアップコピーさせるような使い方では、お互いの root ユーザーがパスフレーズ無しで認証できれば人手介入の必要がありません。

鍵認証できればパスワード認証禁止へ

鍵認証でのリモートログインの確認ができれば、セキュリティの脅威になるパスワード認証をできないように変更します。パスワードやパスフレーズを省略して生成した鍵認証でのログインはパスワードを求められることもなくストレス無く作業が進められます。

$ sudo vi /etc/ssh/sshd_config
    〜〜該当する部分の近くのみ表示
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
#PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Kerberos options
    〜〜

10.リモートで操作するために byobu 設定

リモート接続の環境では意図しない色々な状況で接続が切れます。でも byobu を導入して作業していれば、仮に接続が切れてもサーバー側では処理が継続したままで、再び接続すれば以前の状態に復帰したり、切断した後も実行していた結果を後から確認することも可能になります。

趣味や趣向的な好みの問題でしょうか、byobu と screen の組合せが好きで、仮想端末の byobu をコントロールするキー割り当て (エスケープ文字と呼びます) を Ctrl (コントロール) +B キーにするのが好みでそれに置き換えます。

簡単な操作でリモート接続

byobu は、使い慣れると手放せない機能で、リモートの仮想端末から ssh 接続すると、以前に切断した時の画面に戻って操作の継続が可能になります。再び ssh 接続を終了して切断するのも、単に [F6]キーを押下するだけです。

設定の手順

まず ssh でリモート側から、サーバーの ipアドレス (と必要ならユーザー名) を指定してリモートからログインします。ログインは自動的に行われるため、そのままログインしたサーバー側ユーザーの打鍵待ちとなるプロンプトが表示されます。

最初に byobu [Enter] と打鍵して byobu を起動します。標準では tmux と連携しているので、 byobu+tmux の画面が表示されます。次のように選択して byobu+screen に変更します。

$ byobu-select-backend 

Select the byobu backend:
  1. tmux
  2. screen

Choose 1-2 [1]: 2

エスケープ文字と呼ぶ仮想端末 byobu を制御するためのコマンド文字を変更します。画面は崩れますが、[F9]キーの押下で次のメニューが表示され、そこで Change escape sequence を選択するとエスケープ文字の変更ができます。ここでは A から B に変更しました。 ⇒ Escape key: ctrl-B_

┌────────────────────┤  Byobu Configuration Menu │                                                                      │                                                        
│                                                                      │                      
│     Help -- Quick Start Guide                                        │                      
│     Toggle status notifications                                      │                      
│     Change escape sequence                                           │                      
│     Byobu currently launches at login (toggle off)                   │                      
│                                                                      │                      
└──────────────────────                                                                       

最終的に変更された定義ファイルは、次の内容です。

$ cat .byobu/keybindings
source $BYOBU_PREFIX/share/byobu/keybindings/common
bindkey "^B"
escape "^Bb"
register x "^B"

このままでは、ssh でリモートログインしても自動的に byobu は起動しないので、自動起動と自動終了を有効にする変更を行います。

$ byobu-enable

The Byobu window manager will be launched automatically at each text login.

To disable this behavior later, just run:
  byobu-disable

これで byobu の設定が完了しました。

11.メール転送できる環境を整備

設定用の雛形からコピーして、設定ファイル main.cf を作成します。以前の情報でアナウンスされていた雛形の置き場所以外に、最新のパッケージには .proto の文字列を付加した雛形が同包されているようです。

雛形をコピーして項目の設定

$ sudo cp /etc/postfix/main.cf.proto /etc/postfix/main.cf   # … 雛形をコピー
$ sudo vi /etc/postfix/main.cf
    〜〜コメントも挿入されていて長いので有効行のみ

compatibility_level = 2 command_directory = /usr/sbin daemon_directory = /usr/lib/postfix/sbin data_directory = /var/lib/postfix mail_owner = postfix
myhostname = working.sunao-mita.pgw.jp
mydomain = sunao-mita.pgw.jp
myorigin = $myhostname
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain local_recipient_maps = unix:passwd.byname $alias_maps
unknown_local_recipient_reject_code = 550
mynetworks = 127.0.0.0/8, [::ffff:127.0.0.0]/104, [::1]/128, 192.168.11.0/24, [240d:1a:34d:7f00::0]/64
relayhost = [smtp.nifty.com]:587
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
home_mailbox = Maildir/
smtpd_banner = $myhostname ESMTP $mail_name (Raspbian)

debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/postfix
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
#html_directory =

#manpage_directory =
#sample_directory =
#readme_directory =
inet_protocols = ipv4, ipv6

# 最終行へ追記:送受信メールサイズを10Mに制限
message_size_limit
= 10485760

# メールボックスサイズを1Gに制限
mailbox_size_limit
= 1073741824

# SMTP-Auth 設定

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/nifty.auth
smtp_sasl_security_options = noanonymous

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_mynetworks,permit_auth_destination, permit_sasl_authenticated,reject

コピーした時点で最初から有効となっている行と、更新や挿入した行を抽出しています。追加や更新した行は、該当行の文字列を太くして表現しています。

@Nifty でリレーするための認証組込み

@Nifty に作成したメールをリレーしますが、送信する時点で、ユーザー名とパスワードによる認証を必要とします。次のような nifty.auth ファイルを作成して変換すると nifty.auth.db ファイルが生成されます。

$ sudo vi /etc/postfix/nifty.auth
[smtp.nifty.com]:587 --userid--:--password--

sudo postmap /etc/postfix/nifty.auth


$ ls -al /etc/postfix/
合計 176
drwxr-xr-x   5 root root  4096  4月 15 17:06 .
drwxr-xr-x 121 root root 12288  4月 13 16:12 ..
-rw-r--r--   1 root root    60  3月 22 09:42 dynamicmaps.cf
drwxr-xr-x   2 root root  4096  1月 15 23:05 dynamicmaps.cf.d
-rw-r--r--   1 root root 28057  4月 15 16:06 main.cf
-rw-r--r--   1 root root 27122  3月 22 09:42 main.cf.proto
lrwxrwxrwx   1 root root    31  3月 22 09:42 makedefs.out -> /usr/share/postfix/makedefs.out
-rw-r--r--   1 root root  6208  3月 22 09:42 master.cf
-rw-r--r--   1 root root  6208  3月 22 09:42 master.cf.proto
-rw-r--r--   1 root root    41  4月 15 17:06 nifty.auth
-rw-r--r--   1 root root 12288  4月 15 17:06 nifty.auth.db
-rwxr-xr-x   1 root root 29872  1月 15 23:05 post-install
-rw-r--r--   1 root root 10268  1月 15 23:05 postfix-files
drwxr-xr-x   2 root root  4096  1月 15 23:05 postfix-files.d
-rwxr-xr-x   1 root root 11532  1月 15 23:05 postfix-script
drwxr-xr-x   2 root root  4096  1月 15 23:05 sasl

同じ内容のファイルを変換しても、実行結果は同じ内容になるので、すでに動作している認証ファイルを今回はそのままコピーしてきます。ただし、 –userid– の部分と –password– の部分を @Nifty に接続してメールを読み込むための適正なユーザー名とパスワードに置き換えて、手順のコマンドの実行で認証用 db の nifty.auth.db が生成できます。

色々なユーザー宛に作成されたメールも root に集約

続いて各所で発生した通知等が発生した場合に、転送されてきて @Nifty へ集約されて確認ができるように、 aliases ファイルを定義して有効に設定します。

$ sudo vi /etc/aliases

# See man 5 aliases for format
postmaster:    root

# /etc/aliases
mailer-daemon: postmaster
munin: root
nobody: root
hostmaster: root
usenet: root
news: root
webmaster: root
www: root
ftp: root
abuse: root
noc: root
security: root
csgboxuser: root
webadm: root

pi: sunao
root: sunao
sunao: sunao.mita@nifty.com


$ sudo newaliases
$ sudo systemctl start postfix.service

メール送信テストでエラーとなってしまった

メール送信のテストをしてもログを確認するとエラーが出ているようで、@Nifty には送られていないようです。構築しようとしているラズパイと同じバージョンの公開サーバーでは問題なく送信できているので、/etc/postfix ディレクトリ内のファイルを見比べたり、main.cf と master.cf を同様に修正してみましたが同様のエラーが継続しています。

実績の有るシステムと構成を比較してみる

エラーの内容には、SASL と表示されているため @Nifty の認証時点のエラーのようです。ネットの検索情報から sasl2-bin をインストールしていますが、それ以外にも必要なモジュールが不足しているような気がします。

   〜〜構築中の sasl のインストールリスト〜〜
$ sudo apt list --installed | grep sasl

libgsasl7/stable,now 1.8.0-8+b1 armhf [インストール済み、自動]
libsasl2-2/stable,now 2.1.27+dfsg-1+deb10u1 armhf [インストール済み]
libsasl2-modules-db/stable,now 2.1.27+dfsg-1+deb10u1 armhf [インストール済み]
sasl2-bin/stable,now 2.1.27+dfsg-1+deb10u1 armhf [インストール済み]

   〜〜公開しているサーバーのインストールリスト〜〜
$ sudo apt list --installed | grep sasl

libauthen-sasl-perl/stable,now 2.1600-1 all [インストール済み]
libgsasl7/stable,now 1.8.0-8+b1 armhf [インストール済み、自動]
libsasl2-2/stable,now 2.1.27+dfsg-1+deb10u1 armhf [インストール済み]
libsasl2-modules-db/stable,now 2.1.27+dfsg-1+deb10u1 armhf [インストール済み]
libsasl2-modules/stable,now 2.1.27+dfsg-1+deb10u1 armhf [インストール済み]
sasl2-bin/stable,now 2.1.27+dfsg-1+deb10u1 armhf [インストール済み]

比べると相違が有るのは明らかですが、これがエラーの原因だったようです。違いのどちらが原因か、両方必要だったのかは検証していません。

バージョンにより多少パッケージに相違あり

数年前からラズパイのサーバーを家で何台稼働させていますが、Raspbian のバージョンに相違があってパッケージ構成も少し変更されているようです。最新のラズパイに置き換えた公開サーバーと今回設定中のラズパイでは、バージョン 10 ですが、以前のサーバーではバージョン 9 のようです。

なお、master.cf に関しては、雛形の master.cf.proto の内容に戻しても影響なく @Nifty では認証できていました。今回はメールの転送を組込むだけでハマってしまいました。3日以上悩んでやっとの解決でした。

12.システムログを監視する Logwatch の組込み

メール転送機能を動作させられたので、ログを監視してメールでレポートを送信できる機能の組込みを行います。この機能は毎日明方頃に実行されて、前日の色々な処理の履歴から抽出した情報をレポートとして通知してきます。

いつも見ているわけではありませんが、異常に気が付いた時に過去のレポートを見直したりできるので有効な機能だと思っています。

$ sudo apt install logwatch
他のサーバー類と同様に監視メールが届き完了

Logwatch によるメールが、@Nifty の私宛に届いていたので、やっと基本的な機能の組込みが完了しました。これでやっと出発点に辿り着きました。これからが検証用のサーバーとしての設定の始まりです。思っていたより長く時間が掛かりました。

家屋内のネームサーバー

ローカルのネームサーバー

細かいことは知りませんが、現在 IPv4で機能するネームサーバーを家の中に立てています。家屋内のプライベートアドレスを割り振る DHCPサーバーに、ローカルのネームサーバーのアドレスを渡して、IPv4 / IPv6 アドレス共に名前解決をしています。

日本国内では、IPv4/IPv6が混在しているらしい

ゆくゆくはネット環境が、IPv6の世界に完全移行して不要になるのだろうと思っています。趣味で北海道とか出歩くこともあって、旅先からリモートで家に置かれた公開サーバーを操作することも時々あるのですが、場所によっては IPv4 だったり IPv6だったりしています。

IPv4 なら家に置かれたホームゲートウェイで、入口のグローバルアドレスから家屋内に置かれたプライベートアドレスの公開サーバーにアドレス変換して接続しますが、IPv6 のアドレスは家屋内の機器にも一律に割り振られていて、外部に置かれた DDNS で名前から直接アドレスが引かれると、そのままダイレクトに機器に接続されるイメージなので家屋内にローカルのネームサーバーは不要のようです。

たぶん当面はローカルのネームサーバーが必要かと

いずれにしてもローカルで、IPv4 を併用している機器が家屋内に現存している限り、ローカルのネームサーバーが必要なのだろうと思っています。

公開Webサーバーをローカルネームサーバー仕立てます

そこで、ハード的には余裕のあるオーバースペックのラズパイで、このブログが利用している公開サーバーをローカルのネームサーバーの1つとして機能追加しようと考えたのですが、過去の立上げから長い年月が過ぎているので作業内容も曖昧です。次があるのかは分かりませんが、トラブった時の参考資料としても有効かと思いまとめることにしました。

ネームサーバーのBIND9 をインストール

次のファイルリストが、ネームサーバーの BIND9 をインストールした時の初期状態のファイル群です。以前にカスタマイズした時は、 db.root のファイルがあったようですが、同様のファイルが別の場所に移されたようです。 → /usr/share/dns/root.hints

root@web-server:~# ls -l /etc/bind
合計 48
-rw-r--r-- 1 root root 2761  6月 21  2019 bind.keys
-rw-r--r-- 1 root root  237  6月 21  2019 db.0
-rw-r--r-- 1 root root  271  6月 21  2019 db.127
-rw-r--r-- 1 root root  237  6月 21  2019 db.255
-rw-r--r-- 1 root root  353  6月 21  2019 db.empty
-rw-r--r-- 1 root root  270  6月 21  2019 db.local
-rw-r--r-- 1 root bind  463  6月 21  2019 named.conf
-rw-r--r-- 1 root bind  498  6月 21  2019 named.conf.default-zones
-rw-r--r-- 1 root bind  165  6月 21  2019 named.conf.local
-rw-r--r-- 1 root bind  846  6月 21  2019 named.conf.options
-rw-r----- 1 bind bind   77  1月  1 12:10 rndc.key
-rw-r--r-- 1 root root 1317  6月 21  2019 zones.rfc1918

db.root の移行は、named.conf.default-zones の中の頭の部分に記載されています。

複数サーバーを立て、マスターとスレーブに仕立てます

このラズパイサーバーをマスターにして、他に稼働するネームサーバーをスレーブとしてデータを受取りながら稼働するサーバーに仕立てる予定です。

bind.keys  …そのまま
db.0     …そのまま
db.127   …そのまま
db.255   …そのまま
db.empty …そのまま
db.local …そのまま
named.conf …そのまま
named.conf.default-zones …そのまま
named.conf.local   …変更する (自分で定義したいゾーンをここで指定する)
named.conf.options …変更する (全体的な動作を定義するらしい)
rndc.key      …そのまま
zones.rfc1918 …そのまま
ゾーンの定義はファイルを追加、ファィルとの対応を記述

自分で定義するゾーンファイルを作成して、このディレクトリに追加すると共に、このファイルが配布の元になるマスターか、配布されたコピーのスレーブなのか、更にはどこから配布を受取るのかや、どこに配布するのかも含めて、 named.conf.local ファイルに記述します。

サーバーの全体的な振舞を定義

また、ローカルのネットワークの流れや解決できない情報を上位のサーバーに渡す先についてのサーバー全体の動作に関する情報などは、 named.conf.options ファイルに記述するようです。

named.conf.options には、次のブルーの部分の追加と修正を行いました。どこからの情報かは不明ですが、いままで同様の設定で稼働しているので、深く考えずにそのまま移行します。

// LAN内のIPアドレスグループをLOCALと定義
acl "LOCAL" {
  192.168.11.0/24;
  240d:1a:34d:7f00::/64;
  localhost;
  localnets;
};

// ネームサーバー共通設定
options {
	directory "/var/cache/bind";

	// If there is a firewall between you and nameservers you want
	// to talk to, you may need to fix the firewall to allow multiple
	// ports to talk.  See http://www.kb.cert.org/vuls/id/800113

	// If your ISP provided one or more IP addresses for stable 
	// nameservers, you probably want to use them as forwarders.  
	// Uncomment the following block, and insert the addresses replacing 
	// the all-0's placeholder.

	forwarders { 8.8.8.8; 8.8.4.4;};

        allow-query { LOCAL; };
        allow-query-cache { LOCAL; };

	allow-transfer  { none; };

	masterfile-format text;

	//========================================================================
	// If BIND logs error messages about the root key being expired,
	// you will need to update your keys.  See https://www.isc.org/bind-keys
	//========================================================================
	dnssec-validation auto;

	auth-nxdomain no;    # conform to RFC1035
	listen-on-v6 { any; };
};

192.168.11.0/24 が、IPv4 のローカルネットアドレスで、 240d:1a:〜::/64 が IPv6 のローカルネットアドレスです。

管理するゾーンの名前とアドレスの対応表を作ります

そして、自分で定義したゾーンファイルは、後で識別しやすいように 〜.zone をファイルの最後に付加しておくことにします。

sunao-mita.pgw.jp.zone      …名前からアドレスに変換する定義
11.168.192.rev.zone         …IPv4のアドレスから名前に変換する逆引きファイル
240d:1a:34d:7f00::.rev.zone …IPv6のアドレスから名前に変換する逆引きファイル
MyMemories.localdomain.zone …試験的に変換させるオマケのファイル

管理するゾーン定義の関連付け

初期の named.conf.local ファイルは、次のようになっているので対応するゾーンの定義と対応するファイル、マスターとして転送する場合は送り先のアドレス、スレーブとして受取るならマスターになるサーバーのアドレス等を記述します。

//
// Do any local configuration here
//
  // この部分にゾーン情報を追加します
// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";  // コメントから有効に変更
定義の関連付け例

単純に単独で機能させるだけのサーバーなら、正引き逆引きの各ゾーン毎に定義して、次のような内容を追加します。この場合は、/etc/bind ディレクトリ下に sunao-mita.pgw.jp.zone と命名したファイルが置かれています。

シンプルな記述例、単独でファイル管理
zone "sunao-mita.pgw.jp" {
        type master;
        file "/etc/bind/sunao-mita.pgw.jp.zone";
};
マスターファイルを管理し、スレーブに転送

なお、複数のネームサーバーを稼働させていて、マスターのサーバーのデータを更新したら、スレーブ側のサーバーに自動転送させるには、各ゾーン毎に次のような記述を追加します。

zone "sunao-mita.pgw.jp" {
        type master;   // 転送先のスレーブサーバーを列記
        allow-transfer { 192.168.11.23; 192.168.11.20; 192.168.11.21; };
        notify yes;
        also-notify { 192.168.11.23; 192.168.11.20; 192.168.11.21; };
        file "/etc/bind/sunao-mita.pgw.jp.zone";
};

示したゾーンの定義は、マスターとして管理しスレーブ3台に配送する定義です。スレーブ側では、受取ったデータを自分で管理するマスターのデータと混乱しないように、slaves のディレクトリを作成してその中に受取るようにします。

スレーブで、マスターから受取るディレクトリを分ける
zone "sunao-mita.pgw.jp" {
        type slave;
        masters {
                192.168.11.2;  // マスターのデータを管理するサーバー
        };
        file "/etc/bind/slaves/sunao-mita.pgw.jp.zone";
};

マスターデータは、各ゾーン毎に定義するため、複数サーバーで、各ゾーン毎にマスターデータを管理するサーバーを決めて稼働することができます。

少し実行させてみて、スレーブ側のサーバーにマスターで更新した最新のシリアルナンバーのデータが配布されたようで、置かれているのを確認できたので、これで完了でしょう。

編集したマスターデータと配布されたコピー

スレーブにコピーされたデータは、マスター側の更新したデータを直接コピーしたものではなく、適度に編集されて配布されるようです。

参考までにマスター側の原本とスレーブ側のコピーの中身を表示しておきます。素人の記述内容に問題が多くて違いが大きいのかは分かりませんが…

;;  sunao-mita.pgw.jp

$TTL    86400
@      IN      SOA    sunao-mita.pgw.jp.  root.sunao-mita.pgw.jp. (
        2020010202      ;Serial
        3600            ;Refresh
        900             ;Retry
        604800          ;Expire
        86400           ;Minimum TTL
)
                IN      NS      dns.sunao-mita.pgw.jp.
                IN      NS      dns2.sunao-mita.pgw.jp.
                IN      NS      gate.sunao-mita.pgw.jp.
                IN      MX      10 mail.sunao-mita.pgw.jp.

                IN      A       192.168.11.2
                IN      AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
dns2            IN      A       192.168.11.20
dns             IN      A       192.168.11.2
ubuntu-sv       IN      A       192.168.11.199
rpi1-disk       IN      A       192.168.11.23
rpi1-disk       IN      AAAA    240d:1a:34d:7f00:11cf:af0d:3b62:8501
ubuntu-dtp      IN      A       192.168.11.100
gate            IN      A       192.168.11.1
virt            IN      A       192.168.11.105
Radio           IN      A       192.168.11.20
DebianPogo      IN      A       192.168.11.22
DebianPogo      IN      AAAA    240d:1a:34d:7f00:225:31ff:fe00:9df0
mail            IN      A       192.168.11.2
mail            IN      AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
PogoV6          IN      AAAA    240d:1a:34d:7f00:225:31ff:fe00:9df0
dns2            IN      AAAA    240d:1a:34d:7f00:ba27:ebff:feac:28a8
dns             IN      AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
www             IN      A       192.168.11.2
www             IN      AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
RadioV6         IN      AAAA    240d:1a:34d:7f00:ba27:ebff:feac:28a8
rpi1-com2       IN      A       192.168.11.21
rpi1-com2       IN      AAAA    240d:1a:34d:7f00:ba27:ebff:fe0c:5ef3
note            IN      A       192.168.11.51
note            IN      AAAA    240d:1a:34d:7f00:3906:1714:acef:3e46
web-server      IN      A       192.168.11.2
web-server      IN      AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae



collection      IN      CNAME   virt
share           IN      CNAME   rpi1-disk

なお、動きが把握できていませんが、記述ミスに気が付き修正してマスター側で bind9 を restart すると、内容が直ぐに反映しましたが、その後も配布されているにも関わらずスレーブ側のデータ内容は古いシリアルの物を受取っているままでした。

$ORIGIN .
$TTL 86400      ; 1 day
sunao-mita.pgw.jp       IN SOA  sunao-mita.pgw.jp. root.sunao-mita.pgw.jp. (
                                2020010202 ; serial
                                3600       ; refresh (1 hour)
                                900        ; retry (15 minutes)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
                        NS      dns.sunao-mita.pgw.jp.
                        NS      dns2.sunao-mita.pgw.jp.
                        NS      gate.sunao-mita.pgw.jp.
                        A       192.168.11.2
                        MX      10 mail.sunao-mita.pgw.jp.
                        AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
$ORIGIN sunao-mita.pgw.jp.
collection              CNAME   virt
DebianPogo              A       192.168.11.22
                        AAAA    240d:1a:34d:7f00:225:31ff:fe00:9df0
dns                     A       192.168.11.2
                        AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
dns2                    A       192.168.11.20
                        AAAA    240d:1a:34d:7f00:ba27:ebff:feac:28a8
gate                    A       192.168.11.1
mail                    A       192.168.11.2
                        AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
note                    A       192.168.11.51
                        AAAA    240d:1a:34d:7f00:3906:1714:acef:3e46
PogoV6                  AAAA    240d:1a:34d:7f00:225:31ff:fe00:9df0
Radio                   A       192.168.11.20
RadioV6                 AAAA    240d:1a:34d:7f00:ba27:ebff:feac:28a8
rpi1-com2               A       192.168.11.21
                        AAAA    240d:1a:34d:7f00:ba27:ebff:fe0c:5ef3
rpi1-disk               A       192.168.11.23
                        AAAA    240d:1a:34d:7f00:11cf:af0d:3b62:8501
share                   CNAME   rpi1-disk
ubuntu-dtp              A       192.168.11.100
ubuntu-sv               A       192.168.11.199
virt                    A       192.168.11.105
web-server              A       192.168.11.2
                        AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
www                     A       192.168.11.2
                        AAAA    240d:1a:34d:7f00:a284:cc24:64bd:daae
マスターの更新を直ちにスレーブに反映させるには

修正を直ちに反映させるためには、何かのアクションが必要のようです。ネットで調べてみると reload のキーワードが見付かりました。他にも強制的に配布するコマンドもあるようです。

# service bind9 reload

実行してみるとスレーブ側のデータも最新のシリアルに更新されたようです。 定義の中に、$TTL 86400 ; 1day の記述がありますが、更新されても1日は前の情報を保持する指定なのでしょうか。

やっと念願の公開サーバー交換

宿題事項だったサーバーの交換

2020年元旦になって、数年前から懸念していた公開サーバーを入れ換えることができました。交換したサーバーは、現在の状況で最新版のラズパイで、Raspberry pi 4 B+ / 4GBメモリ で一応最強モデルです。

長く放置できそうな OS

利用する OS は、色々悩みましたが使い慣れているラズパイではデフォルトとなる Raspbian の最新版に落ち着きました。このハードなら色々な OS の選択肢もあるようですが、今までの公開サーバー(PogoPlug E02) のように数年で交換を悩まなそうな見通しを考慮し、日常的で簡単な保守だけで長く安定的に公開させられればとの考えもあっての選択です。

多少のオーバースペックは安心材料

処理速度やメモリ量から考えるとハード的には、完全にオーバースペックのように思います。しかし、ラズパイって昔発売の低スペックのモデルも最新の処理能力の高いモデルも入手する金額に大きな差がないようなので、処理が遅すぎて後で悔やむよりも少し奮発しておけば気が楽になります。

悲願だった交換が完了

換える前のサーバーが非力で、OS の Debian も少し古くなったバージョンで、組込みLinuxを代表するようなシステムだったので、日常的な保守では簡単にバージョンアップができないシステムでした。そのため、このブログ WordPress が稼働する PHP もバージョン5 までしか対応できなくて、セキュリティレベルが低いと警告されていました。

いずれにしても、見た目には同じような動作のままで入替えができたようなので安心しています。使ってみた感じでは、反応がかなり早くなっているので、このブログでも写真の公開でもストレス無く反応しているように感じました。

気持ちだけ焦ってしまう

公開サーバーの更新

遅いし、PHPがバージョンアップ不能

ウェブ用のサーバーを更新しようと思い立ったのは、いつだったのだろうと考えてしまうくらい長い月日が流れてしまいました。

問題は色々あって進まない

自分の能力不足だったり、最適と思える価格と能力を持つ機材が思い当たらなかったり、時間が無かったりと、タラタラと言い訳が出てしまいそうで情けないです。

ラズパイの最新版登場

一応ラズパイも、メモリー搭載が大きくなって処理能力が格段に改善された最新モデルも発売になったので、これを利用して置き換えようと思い立ちました。

簡単な試行では機敏な反応、期待できそう

まずはサーバーとしての基本を設定しなければなりません。素の状態で動作させ始めると確かに速そうな感触です。置き換えられれば反応の悪さが改善しそうな予感です。

Apache稼働でレスポンス良さそう

今動いているこのブログの機能の移行が最大の問題点なのですが、Apacheを稼働させ、写真の公開データをコピーして稼働出来る事を確認しました。単純な作りなので移行も簡単です。

さて、大問題のこのブログですが、WordPressで構成され、PHP上のアプリとして機能して、Mysqlと呼ばれるデータベースを使用しています。

Mysqlが無くなってしまいました

最新のラズパイのOSからはMysqlが削除されて、代替としてMariadbに変わったようです。Mysqlが、Oracleに吸収されたような話を聞いた記憶がありますが、中立性のオープンソースデータベースでしょうか。

操作上の違いがあるのか、ないのかも不明で、ブログの素人の移行作業には更にハードルが上がったとしか思えません。参ったものです。

まずはメールやシステムログのレポート

その前に色々な機能を追加して、サーバーとして稼働させられる様な状況を作る必要があります。

稼働したシステムログを監視して、メールで毎日通知する機能だとか、メールを発信できる機能が必須です。

他のラズパイサーバーが、Postfixでニフティにメールをリレーしているので、それをコピーして稼働させることにしましたが、バージョンも上がっているようで、予想外の四苦八苦です。

システムログのサマリーがメールで届くのか?

明日の朝以降に、Logwatchのメールが届けば、次のステップとしてブログの移行について試行錯誤のテストに移行しようかと考えてます。

Volumio を2台稼働させることに

Volumio2 を私がいる2階の部屋でのバックグラウンド・ミュージックのサーバーとして稼働させています。特に問題もなく安定しているので、1階の居間でも同様に稼働させようと思い立ちました。

もともと1年以上の間、追加で置こうとしている1階には、安定稼働の様子見のため古いバージョンでしたが、電源を入れたままで動作させていました。そのため里帰り的な事なので何の問題もないと思っていて、時間を無駄にする痛い目にも合いました。

複数台の Volumio

2台を識別するために、システム名を標準の Volumio の名称をそのまま残しておき、後に ‘-1F’ と ‘-2F’ を付加した名称にしました。1台の稼働のときは想像できなかったことですが、ブラウザからコントロールする時に、1つの接続からどちらをコントロールするのか選択して操作できることです。

上に表示され細い枠で囲まれているのが操作対象

Volumio の一般的操作

一般的な操作や設定だけなら、ブラウザで接続した状態からIPアドレスの設定や無線LANの設定、ボリュームアップダウンの刻み幅、DACの設定、電源オフ、再起動等ほとんどの操作ができます。

ブラウザでの操作だけなら、マウスやキーボード、モニタとなるテレビも不要です。とは言っても、自動で振られたIPアドレスが何になっているのかとか、確認したい場合もありますし、既に設定してあるデータを新しく立ち上げた側にコピーしたいこともあるでしょう。

リモートからコマンド操作するに

リモートでログインしてコマンドで操作する ssh ですが、有効にすると利用できるようになります。方法は、ブラウザで操作する接続先のアドレスの後に /DEV/ を指定すると設定する項目が表示されます。ここで ssh を有効にするための項目の [ENABLE] ボタンをクリックします。

コマンドで操作したいこともあると思います。最悪はローカルで直接ログインする方法ですが、機材を持込むか逆に機材のある場所に本体を持ってこないといけないので、ぜひとも ssh を有効にしておくことを勧めます。

パスワードに関する注意点

本体にモニタ、マウスとキーボードを取付けて、ユーザー名: volumio と パスワード: volumio が初期値ですが、それでログインすれば操作できます。重要な注意点としては、パスワードを変更する時に記号を含めると、キーボードの配置が想定と異なっていてログインできなくなる事があることです。これにはマジでハマります。

大きな画面と小さな画面の配置

Volumio の操作画面ですが、スマートフォンで操作する縦型で小さな画面と、パソコンで一般的な横に広い大きな画面で、配置される項目に大きな違いがあるようです。

スマートフォンの小さな画面

パソコンでもブラウザの横を縮めて小さくするとスマートフォンの表示と同じような配置になります。帯状のボタンが横一列に並び、左が一覧表示、真ん中がプレイバック、右がキューとなっているようです。そのボタンは、スマートフォンのように小さな画面では最上部に、大きな画面では最下段に表示されています。

大きな表示の画面

一般的な操作の選択

プレイバック (中)

3つの選択ボタンの真ん中のプレイバックが、イニシャルのデフォルト画面のようです。この状態の時にアーティストや曲名を表示していて、ウェブラジオならその下に放送局名が表示されているようです。また、mp3のような楽曲のデジタルデータでも登録されていれば同様に情報が表示されます。

小さな画面の場合

プレイバックが選択されている時に、複数台の Volumio が稼働している場合に、どの Volumio を操作するのかの選択ができるようです。

スクロールすると下にMultiroom Devices の項目内にリストされています。

小さな画面は縦に、大きな画面は横に並んでいるようです。

大きな画面の場合

一覧表示 (左)

左の一覧表示には、先端をホームとして色々な選択できる項目を表示し、そこから選ぶことができるようです。項目としては、|お好み|プレイリスト|音楽ライブラリ|アーティスト|アルバム|ジャンル|Media Servers|last 100|ウェブラジオ| とありますが、使い方がよく分かりません。

|ウェブラジオ|

ウェブラジオでは、Volumio の推奨の局やジャンル別、国別等とラジオ局を選べる項目がリストになっています。希望する局をクリックすると、右のキューの項目に転送されて受信が始まり、演奏が流れ出します。クリックする度にキューに蓄積して受信を開始します。ただし、局リストにあっても受信できない局もあるようで、その場合はエラーになります。

|プレイリスト|

プレイリストでは、自分で付けたグループ名で登録した項目が、一覧表示されています。いつも利用したい放送局をジャンル別や、利用頻度の多い局を集めたグループ等でまとめて登録しておくと、毎回ウェブラジオから選び出す必要が無くなります。

なお、プレイリストへの登録方法は、選択された結果の右のキューにリストされた項目をグループ名を付与して一括で登録することができます。

|音楽ライブラリ|

音楽ライブラリは、Volumio に登録した外部の共有ネットサーバー等のエリアを参照して楽曲を選択できるようにする項目のようです。

|last 100|

last 100 は、演奏した楽曲や選択した局がリストされているような気がしますが、どのタイミンクで取り込まれているのかよく分かりません。

|アーティスト|アルバム|ジャンル|お好み|Media Servers|

その他の項目は、今ひとつ利用方法が分かりませんが、音楽ライブラリから楽曲を選択すると、その後にその楽曲内にあった情報として、アーティスト、アルバム、ジャンルが対応するリストになっているようです。どのタイミングで取り込まれているのか不明です。

キュー (右)

キューへの追加

右のキューには、左の一覧表示から選曲した楽曲や、選択したウェブラジオ局が、その都度リストの最後に追加される仕組みのようです。複数回の繰り返しを行うと繰り返した分だけリストに追加されるようです。

キューにリストされたラジオ局の切替

ここにリストされた楽曲の場合は、該当の演奏が終わると次の楽曲に移りますが、ウェブラジオの選局では、別の局に変更されるまで受信が続きます。ここにリストされているウェブラジオ局は、クリックして別の局への受信切替が可能です。

キューからの消去と編集

ここにリストされている楽曲やウェブラジオ局は、各項目の右にある(x)で個々に消去することも、ゴミバケツマークのクリックでまとめて全て消去することも可能です。操作性が難しく上手く整理できないかもしれませんが、上下の入替えのような単純な編集が可能です。

プレイリストの新規作成、更新

キュー上にリストされた楽曲やウェブラジオ局は、フロッピーマークのクリックで、グループ名を付与して一括でプレイリストを新規作成することができます。ただし、注意点は新規名を付与しないで既存の名前を選択すると、以前に何が登録されていたのかに関係なく、現在のキューにリストされていたものと置き換えられます。言い換えれば強制的な更新となります。

プレイリストのバックアップと再利用

作成されたプレイリストのデータについては、労力が費やされているので障害での消去も考えてバックアップするなり、別の Volumio にコピーして再利用するなりしたいと思います。

その方法としては、 ssh 等によるリモートログインでコマンド操作を行い、/data/playlist/ の下に置かれたデータを扱います。コマンドとしては、rcp 等でコピーすれば良いと思います。

次に、普段使いのLinux PC で、自分のホームに取り込んだ1つの例を示します。

:~$ mkdir ~/volumio-playlist
:~$ rcp volumio@192.168.11.18:/data/playlist/* ~/volumio-playlist/
volumio@192.168.11.18's password:
-普段のバック曲                                      100% 3242   420.1KB/s   00:00
Guitar & piano                                              100% 1257   594.4KB/s   00:00
Jazz                                                        100% 2166   695.2KB/s   00:00
Relax & Easy listening                                      100% 1124   555.5KB/s   00:00
Retro 50s-80s & Beatles                                     100% 3978   929.0KB/s   00:00
Solo                                                        100%  713   387.4KB/s   00:00
シンフォニー&クラッシック                       100% 3196   585.1KB/s   00:00
ダンス系・スイング&タンゴ                       100% 3490   843.0KB/s   00:00
ボサノバ & シャンソン                              100% 1887   376.8KB/s   00:00
日本歌謡・アイドル他                              100% 2451   431.7KB/s   00:00
映画                                                      100% 2234   766.9KB/s   00:00
:~$ ls ~/volumio-playlist/
 -普段のバック曲          'Retro 50s-80s & Beatles'    'ボサノバ & シャンソン'
'Guitar & piano'           Solo                         映画
 Jazz                     'シンフォニー&クラッシック'   日本歌謡・アイドル他
'Relax & Easy listening'  'ダンス系・スイング&タンゴ'

プレイリストのデータは、キューから作成されたグループ毎に 1ファイルとして作られています。それと、キューにリストされた項目が1行ずつではなくて、グループ全体が 1行になっているようです。

1ファイル1行ですが、一応テキストエディタで編集は可能だろうと思います。ただ、実用的とは思えません。例として Jazz の内容を次に示します。

:~$ cat ~/volumio-playlist/Jazz
[{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1723864","title":"Smooth Jazz Florida","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1625448","title":"SmoothJazz.com Global","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1292701","title":"Jazz Lounge","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=959067","title":"The UK 1940s Radio Station  1920s 1930s 1940s","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1469526","title":"The Great American Songbook","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1151057","title":"Smooth Jazz - Tampa Bay","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1423641","title":"Deep Pockets Jazz","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1441882","title":"Swing Street Radio","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1638696","title":"1000 HITS Jazz","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=559409","title":"Jazz International","albumart":"/albumart"},{"service":"webradio","uri":"http://yp.shoutcast.com/sbin/tunein-station.m3u?id=1733465","title":"Smooth Sounds Radio","albumart":"/albumart"},{"service":"webradio","uri":"http://89.16.185.174:8000/stream","title":"Linn Jazz","albumart":"https://radio-directory.firebaseapp.com/volumio/src/images/radio-thumbnails/Linn Jazz.jpg"},{"service":"webradio","uri":"http://icy1.abacast.com:80/kplu-jazz24aac-64","title":"Jazz24","albumart":"https://radio-directory.firebaseapp.com/volumio/src/images/radio-thumbnails/Jazz24.jpg"},{"service":"webradio","uri":"http://8.38.78.173:8210","title":"Audiophile Jazz","albumart":"https://radio-directory.firebaseapp.com/volumio/src/images/radio-thumbnails/Audiophile Jazz.jpg"}]

最後に反省、アホなことしてました

Volumio の複製なんて簡単に設置できると思っていたら、意外に時間を取られて無駄な時間を使っていました。原因は、昨年の暮れになって家の中をリフォームしていたのと、光回線のキャリアの変更とか色々重なり、以前設置していた場所が家のネットワークやインターネットから切り離されていたのでした。

でもなかなかわからなかったのは、運悪く切り離された場所にもルータが置かれていて、イーサネットの接続ランプはリンクアップしているように時々点滅していたことです。思い込みは直さないと失敗の元です。

情けない!! アホなことをしてしまいました。

Volumio の情報メモ

ネットチューナー なのか ウェブラジオ なのか一般的な呼び名が分かりませんが、最近では私の居る部屋で常に バックグラウンド ミュージック を流しっぱなしのサーバーが置かれています。これについてのメモを残しておきます。

パソコンなどの広い画面からの操作

かなり完成度の高いシステムで、 Volumio 2 と言うシステムが公開されていて、それを単純にダウンロードして micro SD にコピーして利用しています。他の書き込みでメモしている部分もあるようなので、重複しているものもあるかと思われますが、適当にメモとして記述しておきます。

スマホやパソコンなどを利用した狭い画面

夜に重宝するのが、極端な強弱を伴わない静かなサウンドトラック等を常時流してくれる局で、ゆっくり聞きながら眠りにつけるのでとても重宝しています。


volumio@volumio1:~$ gpio -v
gpio version: 2.44
Copyright (c) 2012-2017 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty
Raspberry Pi Details:
  Type: Pi 3, Revision: 02, Memory: 1024MB, Maker: Unknown
  * Device tree is enabled.
  *--> Raspberry Pi 3 Model B Rev 1.2
  * This Raspberry Pi supports user-level GPIO access.
volumio@volumio1:~$ gpio readall
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 1 | ALT0 | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 | ALT0 | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 1 | 37 || 38 | 0 | ALT0 | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | ALT0 | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+

この Volumio と呼ばれるシステムは、バージョンが 2 となって公開されているシステムで、raspbian OS が基になっているようですが、基本的にセキュリティアップデートを対象としていないようで、過去に古いレビジョンの Volumio で利用していてシステム内から最新版に更新したことがありました。結果は今一つな感じで仕切り直して新しくクリーンインストールした経験を持ちます。

単純に最新版をクリーンインストールすると、過去に選択した局の情報が引き継げないので、吟味して選択しながらまとめた情報はもったいないのでバックアップしておき、インストール後に戻すのが良いと思われます。

$ ssh volumio@volumio1.local
volumio@volumio1.local's password:
                       ___
                      /\_ \                        __
         __  __    ___\//\ \    __  __    ___ ___ /\_\    ___
        /\ \/\ \  / __`\\ \ \  /\ \/\ \ /' __` __`\/\ \  / __`\
        \ \ \_/ |/\ \L\ \\_\ \_\ \ \_\ \/\ \/\ \/\ \ \ \/\ \L\ \
         \ \___/ \ \____//\____\\ \____/\ \_\ \_\ \_\ \_\ \____/
          \/__/   \/___/ \/____/ \/___/  \/_/\/_/\/_/\/_/\/___/
             Free Audiophile Linux Music Player - Version 2.0
          C 2015 Michelangelo Guarise - Volumio Team - Volumio.org
Volumio Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
volumio@volumio1:~$

ssh でリモート接続して参照した一部の情報を次に示します。

volumio@volumio1:~$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0         7:0    0 282.6M  0 loop /static
mmcblk0     179:0    0  14.4G  0 disk
|-mmcblk0p2 179:2    0   2.3G  0 part /imgpart
|-mmcblk0p3 179:3    0  12.1G  0 part
`-mmcblk0p1 179:1    0    61M  0 part /boot
volumio@volumio1:~$ df
Filesystem                  Size  Used Avail Use% Mounted on
/dev/mmcblk0p2              2.4G  673M  1.6G  31% /imgpart
/dev/loop0                  297M  297M     0 100% /static
overlay                     274M  220M   34M  87% /
devtmpfs                    497M     0  497M   0% /dev
tmpfs                       509M     0  509M   0% /dev/shm
tmpfs                       509M   35M  475M   7% /run
tmpfs                       5.3M  4.1k  5.3M   1% /run/lock
tmpfs                       509M     0  509M   0% /sys/fs/cgroup
tmpfs                       509M   25k  509M   1% /tmp
tmpfs                       509M     0  509M   0% /var/spool/cups
tmpfs                        21M  9.7M   12M  47% /var/log
tmpfs                       509M     0  509M   0% /var/spool/cups/tmp
/dev/mmcblk0p1               63M   39M   25M  61% /boot
//RPI1-DISK/共有/volumio  317G  175G  143G  56% /mnt/NAS/共有
tmpfs                       102M     0  102M   0% /run/user/1000
volumio@volumio1:~$ sudo cat /etc/fstab
[sudo] password for volumio:
proc            /proc           proc    defaults        0       0
/dev/mmcblk0p1  /boot           vfat    defaults,utf8,user,rw,umask=111,dmask=000        0       1
tmpfs   /var/log                tmpfs   size=20M,nodev,uid=1000,mode=0777,gid=4, 0 0
tmpfs   /var/spool/cups         tmpfs   defaults,noatime,mode=0755 0 0
tmpfs   /var/spool/cups/tmp     tmpfs   defaults,noatime,mode=0755 0 0
tmpfs   /tmp                    tmpfs   defaults,noatime,mode=0755 0 0
tmpfs   /dev/shm                tmpfs   defaults,nosuid,noexec,nodev        0 0
volumio@volumio1:~$ mount
/dev/mmcblk0p2 on /imgpart type ext4 (rw,relatime,stripe=1024,data=ordered)
/dev/loop0 on /static type squashfs (ro,relatime)
overlay on / type overlay (rw,relatime,lowerdir=/mnt/static,upperdir=/mnt/ext/dyn,workdir=/mnt/ext/work)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,size=485032k,nr_inodes=121258,mode=755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,noexec)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct)
mqueue on /dev/mqueue type mqueue (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,noatime,mode=755)
tmpfs on /var/spool/cups type tmpfs (rw,noatime,mode=755)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
tmpfs on /var/log type tmpfs (rw,nodev,relatime,size=20480k,mode=777,uid=1000,gid=4)
configfs on /sys/kernel/config type configfs (rw,relatime)
tmpfs on /var/spool/cups/tmp type tmpfs (rw,noatime,mode=755)
/dev/mmcblk0p1 on /boot type vfat (rw,nosuid,nodev,noexec,relatime,fmask=0111,dmask=0000,allow_utime=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro)
rpc_pipefs on /run/rpc_pipefs type rpc_pipefs (rw,relatime)
//RPI1-DISK/共有/volumio on /mnt/NAS/共有 type cifs (ro,relatime,vers=default,cache=strict,username=sunao,domain=,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.11.23,file_mode=0666,dir_mode=0777,soft,nounix,serverino,mapposix,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=99412k,mode=700,uid=1000,gid=1000)

各種データの格納先ディレクト

どこに何が格納されているのかは、はっきり言ってよく分かりません。また、どのようなフォーマットを必要としているのかも不明です。

ただ、選択したラジオ局のプレイリスト、演奏中や演奏待ちのキューは、 /data 下のディレクトリに集められているらしいので、コマンド tree をインストールしてディレクトリ部分だけをリストにしたものを次に示します。

volumio@volumio1:~$ tree -d /data
/data
|-- INTERNAL
|-- albumart
|   |-- folder
|   |-- metadata
|   `-- web
|       |-- 1.FM%20-%20Bossa%20Nova%20Hits%20Radio
|       |-- 1.FM%20-%20Movie%20Soundtracks%20Hits%20Radio
|       |-- 1000%20HITS%2070s
|       |-- 1000%20HITS%20Oldies
|       |-- 181.FM%20Christmas%20Swing
|       |-- FeLove%20Cl%C3%A1sica
|       |-- J-Pop%20Powerplay%20-%20Kawaii
|       |-- J-Pop%20Sakura
|       |-- J1%20Gold%20-%20Japan%27s%20Oldies
|       |-- JamendoLounge
|       |-- Japan%20Hits%20-%20Asia%20DREAM%20Radio
|       |-- Johann%20Sebastian%20Bach
|       |   `-- Goldberg%20Variations%20(feat.%20piano%3A%20Chen%20Pi-Hsien)
|       |-- Radio%20Caprice%20-%20Bossa%20Nova
|       |-- Radio%20Caprice%20-%20Swing
|       |-- Radio%20Caprice%20-%20Symphony
|       |-- Retro%20Oldies%20Radio
|       `-- Swinging%20Radio%20England
|-- backgrounds
|-- configuration
|   |-- audio_interface
|   |   `-- alsa_controller
|   |-- miscellanea
|   |   |-- alarm-clock
|   |   |-- albumart
|   |   |-- appearance
|   |   |-- my_music
|   |   `-- wizard
|   |-- music_service
|   |   |-- lms
|   |   |-- mpd
|   |   |-- squeezelite
|   |   |-- streaming_services
|   |   |   |-- services_configs
|   |   |   `-- services_tokens
|   |   |-- upnp_browser
|   |   `-- webradio
|   `-- system_controller
|       |-- i2s_dacs
|       |-- my_volumio
|       |-- network
|       |-- networkfs
|       |-- system
|       |-- volumio_command_line_client
|       `-- volumiodiscovery
|-- favourites
|-- playerstate
|-- playlist
`-- plugins
    |-- music_service
    |   |-- lms
    |   |   |-- i18n
    |   |   `-- node_modules
    |   |       |-- balanced-match
    |   |       |-- brace-expansion
    |   |       |   `-- node_modules
    |   |       |       `-- balanced-match
    |   |       |-- concat-map
    |   |       |   |-- example
    |   |       |   `-- test
    |   |       |-- fs-extra
    |   |       |   `-- lib
    |   |       |       |-- copy
    |   |       |       |-- copy-sync
    |   |       |       |-- empty
    |   |       |       |-- ensure
    |   |       |       |-- json
    |   |       |       |-- mkdirs
    |   |       |       |-- move
    |   |       |       |-- output
    |   |       |       |-- remove
    |   |       |       |-- util
    |   |       |       `-- walk
    |   |       |-- fs.realpath
    |   |       |-- glob
    |   |       |-- graceful-fs
    |   |       |-- inflight
    |   |       |-- inherits
    |   |       |-- ip
    |   |       |   |-- lib
    |   |       |   `-- test
    |   |       |-- jsonfile
    |   |       |-- kew
    |   |       |   `-- test
    |   |       |-- klaw
    |   |       |   `-- src
    |   |       |-- minimatch
    |   |       |-- multimap
    |   |       |   `-- test
    |   |       |-- once
    |   |       |-- path-is-absolute
    |   |       |-- rimraf
    |   |       |-- v-conf
    |   |       |   `-- node_modules
    |   |       |       |-- fs-extra
    |   |       |       |   `-- lib
    |   |       |       |       |-- copy
    |   |       |       |       |-- copy-sync
    |   |       |       |       |-- empty
    |   |       |       |       |-- ensure
    |   |       |       |       |-- json
    |   |       |       |       |-- mkdirs
    |   |       |       |       |-- move
    |   |       |       |       |-- output
    |   |       |       |       |-- remove
    |   |       |       |       |-- streams
    |   |       |       |       |-- util
    |   |       |       |       `-- walk
    |   |       |       `-- multimap
    |   |       |           `-- test
    |   |       |-- wireless-tools
    |   |       |   `-- test
    |   |       `-- wrappy
    |   `-- squeezelite
    |       |-- i18n
    |       |-- node_modules
    |       |   |-- balanced-match
    |       |   |-- brace-expansion
    |       |   |   `-- node_modules
    |       |   |       `-- balanced-match
    |       |   |-- concat-map
    |       |   |   |-- example
    |       |   |   `-- test
    |       |   |-- fs-extra
    |       |   |   `-- lib
    |       |   |       |-- copy
    |       |   |       |-- copy-sync
    |       |   |       |-- empty
    |       |   |       |-- ensure
    |       |   |       |-- json
    |       |   |       |-- mkdirs
    |       |   |       |-- move
    |       |   |       |-- output
    |       |   |       |-- remove
    |       |   |       |-- util
    |       |   |       `-- walk
    |       |   |-- fs.realpath
    |       |   |-- glob
    |       |   |-- graceful-fs
    |       |   |-- inflight
    |       |   |-- inherits
    |       |   |-- ip
    |       |   |   |-- lib
    |       |   |   `-- test
    |       |   |-- jsonfile
    |       |   |-- kew
    |       |   |   `-- test
    |       |   |-- klaw
    |       |   |   `-- src
    |       |   |-- minimatch
    |       |   |-- multimap
    |       |   |   `-- test
    |       |   |-- once
    |       |   |-- path-is-absolute
    |       |   |-- rimraf
    |       |   |-- v-conf
    |       |   |   `-- node_modules
    |       |   |       |-- fs-extra
    |       |   |       |   `-- lib
    |       |   |       |       |-- copy
    |       |   |       |       |-- copy-sync
    |       |   |       |       |-- empty
    |       |   |       |       |-- ensure
    |       |   |       |       |-- json
    |       |   |       |       |-- mkdirs
    |       |   |       |       |-- move
    |       |   |       |       |-- output
    |       |   |       |       |-- remove
    |       |   |       |       |-- streams
    |       |   |       |       |-- util
    |       |   |       |       `-- walk
    |       |   |       `-- multimap
    |       |   |           `-- test
    |       |   |-- wireless-tools
    |       |   |   `-- test
    |       |   `-- wrappy
    |       `-- unit
    `-- system_controller
        `-- backup_restore
            |-- i18n
            `-- node_modules
                |-- balanced-match
                |-- brace-expansion
                |-- concat-map
                |   |-- example
                |   `-- test
                |-- fs-extra
                |   `-- lib
                |       |-- copy
                |       |-- copy-sync
                |       |-- empty
                |       |-- ensure
                |       |-- json
                |       |-- mkdirs
                |       |-- move
                |       |-- output
                |       |-- remove
                |       |-- util
                |       `-- walk
                |-- fs.realpath
                |-- glob
                |-- graceful-fs
                |-- imurmurhash
                |-- inflight
                |-- inherits
                |-- jsonfile
                |-- kew
                |   `-- test
                |-- klaw
                |   `-- src
                |-- minimatch
                |-- multimap
                |   `-- test
                |-- once
                |-- path-is-absolute
                |-- rimraf
                |-- slide
                |   `-- lib
                |-- v-conf
                |   |-- node_modules
                |   |   `-- fs-extra
                |   |       |-- docs
                |   |       `-- lib
                |   |           |-- copy
                |   |           |-- copy-sync
                |   |           |-- empty
                |   |           |-- ensure
                |   |           |-- json
                |   |           |-- mkdirs
                |   |           |-- move
                |   |           |-- move-sync
                |   |           |-- output
                |   |           |-- remove
                |   |           `-- util
                |   `-- test
                |-- wrappy
                `-- write-file-atomic
242 directories

作成したプレイリストの格納先

自分でカスタマイズしたり好みのリストを作れるプレイリストについて次に示します。

最初の画面の右側中の [プレイリスト] をクリックするとリストが出てきます。2番目の画面でリストの下に隠れている [日本歌謡・アイドル他] をクリックすると3番目の画面になります。

3番目の画面は、各放送局を選択する画面です。ここでクリックした局が選択され、キューにコピーされて放送の受信が始まります。クリックされる度にキューにコピーされるようです。

実際のデータ格納先は、 /data/playlist 以下のディレクトリに保存されるようです。ただ単純に ls コマンドで表示すると、 ls が持つ気配り(?)で日本語文字が、??? の並びで表示されてしまうようです。

volumio@volumio1:~$ ls /data/playlist/
Guitar & piano           ??????????????????&??????????????????
Jazz                     ???????????????????????????&?????????
Relax & Easy listening   ???????????? & ???????????????
Retro 50s-80s & Beatles  ??????????????????????????????
Solo                     ??????

回避策はコントロールキャラクタも表示させるオプションを指定するか、 cat でパイプして表示すれば漢字で表示できるようです。

volumio@volumio1:~$ ls --show-control-chars /data/playlist/
Guitar & piano  Relax & Easy listening   Solo  ダンス系・スイング&タンゴ    日本歌謡・アイドル他
Jazz            Retro 50s-80s & Beatles  シンフォニー&クラッシック     ボサノバ & シャンソン  映画

volumio@volumio1:~$ ls /data/playlist/ | cat Guitar & piano Jazz Relax & Easy listening Retro 50s-80s & Beatles Solo シンフォニー&クラッシック ダンス系・スイング&タンゴ ボサノバ & シャンソン 日本歌謡・アイドル他 映画
右上のボタンでキューに移動

放送を受信しているラジオ局は、画面右の選択ボタンで表示しているキューにリストされています。

普段聞いている放送局ならここのキューにリストされているので、そこをクリックして選択するだけで簡単に放送局の切り替えができます。

左のアイコン上に薄緑の三角が表示されているのが、受信中の放送局ですが、一部をキューから削除したり、リストの順番を上下に移動したりすると表示位置の追従ができないようです。

プレイリストの生成

プレイリストを作成するには、前節で説明しているキューにリストされている放送局全体に新しいグループ名を付与して生成します。

注意点は、すでに作成されている下に並ぶ名称をクリックすると、一瞬で置換されます。

ウェブラジオからプレイリストの Jazz を作成

Volumio から、標準で提供されているウェブラジオの放送局があります。ここでは、お薦めや国別、ジャンル別等の色々な切り口からリストになっていて、選んでもエラーになって受信できないものや好みの合わないものも多数あります。

実際に聞いてみて自分の好みで選択して、必要なものをキューに残して、後で分かりやすいグループ名(今回は Jazz)を付与してプレイリストを作成します。

まずは、左のボタンで一覧表示にして、家のマークのホームボタンをクリックし、中からウェブラジオをクリックします。

ウェブラジオ内の項目を辿って、好みに合う放送局を探しながらキューに移します。

受信できない放送局も多数残るので、キューに移された放送局を個々に選びながら吟味して不要な放送局は、右の(☓)マークで削除しながら整理します。

好みの Jazz 放送局が集められたので、プレイリストにグループ名 Jazz で登録します。不要なプレイリストは右の点をクリックして削除可能です。

ラズパイにUPS機能を組込む

目指すものは

ラズパイ1B+ネットワーク共有サーバーとして、バッテリーバックアップを行いながら常時起動しておくことを考えています。

利用する部材は

アマゾンで購入の手作りUPSは、2,499円で購入しました。最近出荷されているモデルのラズパイのボード本体を固定する穴位置と重なる同じ穴位置形状の制御ボードです。ラズパイとの接続は、IOの 40ピンコネクタにそのまま重なる HAT と呼ばれる一連の製品群で、板状のバッテリーが付属していて信じられないくらい安いと感じます。

しかし、一般的な国内メーカーが販売するような完成されたパッケージ品とは大きく異なり、付属資料は全く無くて適当なキーワード(例えば UPS HAT) を元にネットで検索すると、それらしい情報が見つかり色々と提供されているサンプル類は、自分の責任で確認してバグ取りや性格に合わせたカスタマイズ作業が必要です。

完成したサーバーのイメージは

今回のネットワーク共有サーバーシステムは、2TBの2.5インチHDDと組合せて、100均のケースに組んで動作させています。ケースからは、AC100VからDC5V-2.4Aに変換した Micro USB のケーブル、イーサネットの RJ-45 のケーブルの2本だけが出ています。

バッテリー監視用のサービスソフト

以前、普段使いのノートPCのLinux(Ubuntu)立上げ後に、ネットワーク共有サーバー上に自動的に、Windowsファイルの一部をバックアップするsystemdのサービスを追加したことがあり、同様に常時起動のラズパイ1B+バッテリー監視のサービスを起動しようと考えました。

今回の作業背景

何となくネットで見付け、半信半疑の思いつきで購入した安価な製品で、ラズパイに装着できる制御ボードバッテリーのセットです。付属の説明書類は一切無いもので、使うにはどのようにするのかも含めて、頭をフル回転して情報収集から始めました。

Raspi UPS HAT Board と呼ばれているようで、資料が公開されています。

この公開資料では色々と説明されていて、サンプルコードも多数提示されているのですが、何か詰が甘くて動作を検証しても期待したような結果が出ません。公開されているサンプルのままで期待した結果だったモジュールは、C言語で記述された File:Ups-hat-c.zip だけでした。これはモジュールとして解説の手順でコンパイルすると、ups-read が作成されます。

この ups-read の利用方法としては、引数を [付ける/付けない] により少し異なりますが、バッテリー電圧とバッテリー容量が取得できます。ただ信用できない値が渡されることが多いのですが、そこを考慮すれば簡単に bash とか一般的なシェルからバッテリーの情報を取得できるため、色々な処理を自分で記述するのが簡単にできます。

解説の中には、root権限で実行するためにパスワード無しの sudo を冠して実行するための /etc/sudoers の追加記述がありますが、最新の raspbian では単純にユーザー権限のままでも実行できるようでした。

バッテリーの充放電の検証

引数無しでは、バッテリー容量がパーセンテージで表した整数値のみで返されます。これはバッテリー制御ボードから直接受け取った情報を特定の関数で変換していると思われますが、ちょっとした落とし穴があって、パーセンテージから判断して 0 〜 100 と思い込みますが、0〜100 ではない場合があり、 割合を表す数値としてはありえない 120 とか 112 とかになっていることがあります。

さらに雑音のような、前後の読み取りからはかけ離れた突発的な数値、197 とか 213 とかありえない値が渡されることがあり、その辺りの対策も必要です。

なお、サンプルの中でのステートメントのロジックでは、100%ならのような表現を色々な箇所で使っていますが、実際に渡される情報と一致しないため期待した結果にならないようです。

引数には、vc が指定でき、両方指定すれば電圧と容量が、当てにならない小数点以下6桁で、3.498750V 9.480469% のように表示されます。10秒毎に読み取ってリストにして確認してみましたが、電圧の変化と容量の変化にはある程度の相関関係があるようです。

実際の制御ボードには、バッテリーの充電や放電の状況を直接見える LED が付けられているのですが、私が持つ個体では完全充電されていてもそれを表す表示になることがないようで、かなりいい加減です。その程度に思って利用した方が良いようです。

ちなみに、バッテリー容量が 0.000000% でも動作していますが、電圧値が、3.000000V を下回った頃に、一気に電力不足でシステムが異常停止しているようでした。バッテリー容量が 5.000000% 以下になったのを見て正常な停止処理に移行させた方が良さそうです。

作ろうとしている私のネットワーク共有サーバーとしての動作環境は、ラズパイ1B+ 2TB 2.5インチ HDD で構成されています。フル充電から 5.0% まで容量が減衰する動作継続時間は、優に1時間を越えています。ある程度バッテリーが劣化しても余裕がありそうです。

先程の公開資料ですが、その中で提供されているサンプルは、ほぼ python で記述されていて、I2Cインタフェースからバッテリーの電圧と容量を取得するルーチンが紹介されています。


正常な停止処理に移行させるには

その中に UPS のバッテリーを監視して shutdown を起動するサンプルが次の項目に紹介されています。

Driver and Sample code

  • File:Rpi-ups-hat.zip
  • File:UserManual.pdf

zip を解凍すると、rpi-ups-hat ディレクトリ下に example.py と raspiupshat.so があります。raspiupshat.so が、UPSのバッテリー電圧と容量を取得できるライブラリです。

example.py では、そのライブラリを利用して、無限ループで容量をチェックして、5% を切ると shutdown コマンドが起動される例として記述されています。

残念なことにサンプルでは、os.system(“sudo shutdown”) の行で、ライブラリ os が import されていないため、エラーメッセージを表示して正常終了には移行せず、アブノーマルエンドしてしまいます。

UserManual.pdf は、英語と中国語?で書かれた利用条件の説明です。その中で wiringPi のインストールが必須として書かれていますが、最新の raspbian では事前にセットアップされているようです。

これを流用させて頂き、UPS制御として組込みます。


バッテリー監視の常駐サービス

systemd のサービスとして起動する方法については、次のサイトを参考に制作しますが、一度私のノートPCで作成した経験があるので、自分の備忘録も見返しながらの作業になります。

参考にしたサイトは、作り方を事細かく説明してくれています。


ここからが作業の本題

Raspbian 起動時に、一度だけ起動して常時バッテリーを監視して、容量が 5% を下回った時に shutdown プロセスを起動させます。

systemd に登録するサービスの指示書が、ユニットファイルと呼ばれます。

  • パッケージ名: UPS-Watch-shut
  • ユニットファイル名: ups-watching.service

サービス(ユニットファイル)の登録は、 /etc/systemd/system/ups-watching.service で、この中には登録するサービスの情報を決められた書式で記述します。

そして実際に動作させるプログラムは、パッケージ名で管理するディレクトリに集めるようで、 /opt/UPS-Watch-shut/bin に置きます。バッテリーの情報を取得するライブラリ raspiupshat.so もここに置きます。

systemd のサービスとして組込み

カレントで作成して、それを該当するディレクトリにコピーして、所有者を root に変更したり、アクセス権の変更をします。

まずは、ユニットファイルの作成です。

$ vi ups-watching.service
[Unit]
Description = UPS Watching AutoRun
After=network-online.target remote-fs.target nss-lookup.target
ConditionPathExists=/opt/UPS-Watch-shut/bin
[Service]
ExecStart=/opt/UPS-Watch-shut/bin/startup-1st.sh
Restart=no
Type=simple
[Install]
WantedBy=multi-user.target

追加するサービスの準備を行います。

$ sudo cp ups-watching.service /etc/systemd/system
$ sudo chown root:root /etc/systemd/system/ups-watching.service
$ sudo chmod 644 /etc/systemd/system/ups-watching.service

サービスから最初に起動するモジュールを作成します。

$ vi startup-1st.sh
#!/bin/sh
exec /usr/bin/env python /opt/UPS-Watch-shut/bin/ups-shutdown.py

パッケージをまとめるディレクトリを作成します。

$ sudo mkdir -p /opt/UPS-Watch-shut/bin
$ sudo chmod 755 /opt/UPS-Watch-shut/bin
$ sudo cp startup-1st.sh /opt/UPS-Watch-shut/bin
$ sudo chown root:root /opt/UPS-Watch-shut/bin/startup-1st.sh
$ sudo chmod 755 /opt/UPS-Watch-shut/bin/startup-1st.sh

シャットダウンプログラム

提供されていた python のサンプルプログラムは、サンプルの指示手順で解凍すると pythonの原形とバッテリー情報取得ライブラリ raspiupshat.so が提供されています。少し手を加えて、動作するように直し、単体ではシャットダウンが行われることを確認できました。

$ vi ups-shutdown.py
#!/usr/bin/env python
# Raspi UPS Hat
# We only provide 2 interface to get battery information;
#
#Interface 1:
#Function: get current battery voltage
#Return value: battery voltage;
#float getv();
#Interface 2:
#Function:    get battery capacity
#Return value: 0~100+
#float getsoc();
#
import sys
# import Raspi UPS Hat library
import raspiupshat
import os
import time
import datetime
# init Raspi UPS Hat
raspiupshat.init();
# Get info
now = datetime.datetime.now()
print("{0:%Y-%m-%d %H:%M:%S} ; ".format(now) + "Voltage:%5.2fV ; Battery:%5i%%" % (raspiupshat.getv(), raspiupshat.getsoc()))
if raspiupshat.getsoc() >= 100:
        print "Battery FULL"
if raspiupshat.getsoc() < 20:
        print "Battery LOW"
while 1:
        if raspiupshat.getsoc() < 5:
                print "System will shutdown now,bye!"
                os.system("sudo shutdown -h 0")
        # now = datetime.datetime.now()
        # print("{0:%H:%M:%S} ; ".format(now) + "Voltage:%5.2fV ; Battery:%5i%%" % (raspiupshat.getv(), raspiupshat.getsoc()))
        # time.sleep(10)

無限ループ内の最後の3行は、確認時に10秒毎に時間とバッテリー電圧値、バッテリー容量を表示するためのものです。必要なら先頭のコメント ‘#‘ を消すことでデバッグ行の表示ができます。
それとバッテリー情報収集用のライブラリ raspiupshat.so を同じ場所に配置します。

$ sudo cp ups-shutdown.py /opt/UPS-Watch-shut/bin
$ sudo chown root:root /opt/UPS-Watch-shut/bin/ups-shutdown.py
$ sudo chmod 755 /opt/UPS-Watch-shut/bin/ups-shutdown.py
$ sudo cp raspiupshat.so /opt/UPS-Watch-shut/bin
$ sudo chown root:root /opt/UPS-Watch-shut/bin/raspiupshat.so
$ sudo chmod 755 /opt/UPS-Watch-shut/bin/raspiupshat.so

サービスとして定義している ups-watching.service により startup-1st.sh が起動されます。その中で単純にシャットダウンプログラムの ups-shutdown.py を起動しています。


ユニットファイルを systemd に登録

ここからは、systemd へのサービス(ユニットファイル)の登録と検証作業です。ユニットファイル等を追加や変更した後には、必ず次のコマンド sudo systemctl daemon-reload を実行します。

そして一緒にステータスも確認しておきます。

$ sudo systemctl daemon-reload
$ sudo systemctl status ups-watching.service
● ps-watching.service - UPS Watching AutoRun
   Loaded: loaded (/etc/systemd/system/note-startup-1st.service; disabled; vendor preset: enabled)
   Active: inactive (dead)

ステータスで表示される Loaded: 行のカッコ内の1つ目と2つ目のセミコロンの間の disabled となっているのは、自動起動が無効になっているということのようで、自動起動できるように設定します。

自動起動が行われるように設定

$ sudo systemctl enable ups-watching.service
Created symlink /etc/systemd/system/multi-user.target.wants/ups-watching.service → /etc/systemd/system/ups-watching.service.
$ sudo systemctl status ups-watching.service
● ups-watching.service - UPS Watching AutoRun
Loaded: loaded (/etc/systemd/system/ups-watching.service; enabled; vendor preset: enabled)
Active: inactive (dead)

ユニットファイルの定義内に、[ Install ] の WantedBy= で定義しているユニットにリンクが張られ、先ほどの /etc/systemd/system/ups-watching.service; の後の disabledenabled に変わっています。

これで再立ち上げで自動実行されるようになっているはずですが、その前にコマンドで起動して確認したり、停止させる操作をして動作を確認します。


$ ls -l /opt/UPS-Watch-shut/bin/
-rw-r--r-- 1 root root 7416 1月 25 11:07 raspiupshat.so
-rwxr-xr-x 1 root root   76 1月 24 22:49 startup-1st.sh
-rwxr-xr-x 1 root root  987 1月 25 11:06 ups-shutdown.py

$ sudo systemctl daemon-reload
$ sudo systemctl start ups-watching.service
$ sudo systemctl status ups-watching.service
 ups-watching.service - UPS Watching AutoRun
Loaded: loaded (/etc/systemd/system/ups-watching.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2019-01-26 08:57:28 JST; 5h 36min ago
Main PID: 367 (python)
CGroup: /system.slice/ups-watching.service
└─367 python /opt/UPS-Watch-shut/bin/ups-shutdown.py
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:31:08 ; Voltage: 4.34V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:31:18 ; Voltage: 4.35V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:31:28 ; Voltage: 4.35V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:31:38 ; Voltage: 4.35V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:31:48 ; Voltage: 4.35V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:31:58 ; Voltage: 4.35V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:32:08 ; Voltage: 4.35V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:32:18 ; Voltage: 4.35V ; Battery: 100%
1月 26 14:32:48 rpi1-disk startup-1st.sh[367]: 14:32:28 ; Voltage: 4.35V ; Battery: 100%

上記の結果では、実際に shutdown 動作を行う python のプログラムの ‘#’ のコメントを取り除き、メッセージ書き出しのステートメントを有効にし組込みました。

systemd の動作に不慣れで、正しく理解できていないのですが、systemctl status コマンドでは、処理中で書き出されたメッセージが直接表示されているわけではないようで、別に journalctl -u コマンドで表示できるようです。

書き出されたメッセージが、キューかバッファのような所に蓄積されていて、 systemctl status の実行時に移されて、journalctl -u で見られる場所に蓄積していくような感じです。そのため、最新の情報を確認するためには、systemctl status を先に実行してから journalctl -u を実行して確認する必要があるようです。

メッセージの各行先頭には、systemctl status で移された日時が記述されているようで、前回の確認から今回新しく加えられた行を判別することが可能なようです。なお、操作方法は less コマンドの操作と同じなので、‘/’ で文字列を検索したり、行をスキップしたり、‘1G’ で先頭行に移動したり、‘G’ で最終行に移動することもでき、上下の矢印キーで前後にメッセージを辿ることができます。

実際の動作検証作業

本番でのシステム終了動作を確認するために、ssh でリモート接続したまま、バッテリーの情報を 10 秒毎に表示して確認しましたが、5% になった後の1分後くらいにセッション切断のメッセージと共に、4% を表示して停止していました。

期待したシステム終了が行われているようで一安心です。メッセージが蓄積されている journalctl -u コマンドの結果例を次に示します。このコマンドは一般ユーザーで確認できるようです。

$ journalctl -u ups-watching.service

 1月 26 08:57:28 rpi1-disk systemd[1]: Started UPS Watching AutoRun.
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 2019-01-26 08:57:32 ; Voltage: 3.77V ; Battery:
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: Battery LOW
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 08:57:32 ; Voltage: 3.77V ; Battery:    5%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 08:57:42 ; Voltage: 3.78V ; Battery:    5%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 08:57:52 ; Voltage: 3.77V ; Battery:    5%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 08:59:54 ; Voltage: 3.77V ; Battery:    5%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:00:04 ; Voltage: 3.77V ; Battery:    5%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:00:14 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:00:24 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:00:34 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:00:44 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:00:54 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:01:05 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:01:15 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:01:25 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:01:35 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:01:45 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:01:55 ; Voltage: 3.78V ; Battery:    6%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:02:05 ; Voltage: 3.78V ; Battery:    7%
 1月 26 09:14:56 rpi1-disk startup-1st.sh[367]: 09:02:15 ; Voltage: 3.78V ; Battery:    7%
lines 1-22

今回のUPSバッテリー監視と shutdown では、特にプログラムやサービスについての依存関係は無いので、これで完了です。

次は、UPSバッテリーの充放電に伴う携帯メールへの通知についての対策を考えています。

ラズパイで ネットチューナー

長く生きていると誰にでもじわじわと押し寄せる老朽化ですが、私の頭もご多分に漏れず処理能力がかなり落ちていると思います。処理は遅いし途中で別の優先事項が割り込むと、元の作業が長期中断したり継続の見込みのない保留になったりしています。

仕掛り中のラズパイ1B+のネット共有サーバーも少し保留で、1年以上前に設定して有効な利用もないまま据え置かれたラズパイがあり、こちらは妻が使用しているステレオに接続して試用をして、その後そのまま据え置かれていました。

ラズパイに専用のDACを重ねて、ミュージックサーバーの専用OS – Volumio2を入れて利用する物です。WiFi経由でネットに接続したら音飛びが酷くて、経過見で置かれてそのままになってしまったようです。忘れましたが、WiFi機能があるのでラズパイ3B でしょうね。

ラズパイもサーバーとして長く稼働していると、原因が相性なのか性能なのか不明ですが、 SD のシステムやデータが壊れるのを度々経験していて、ちょっと心配です。そんなこともあって、相性が良いと評判の東芝製 microSD をわざわざ購入して設定しました。今回は稼働したまま1年以上置かれていましたが、壊れてはいませんでした。

妻が独身時代から利用していたステレオが老朽化して、電解コンデンサや機械的に可動するボリューム類も対応不能な状況になって、当時手軽な価格でネットで購入できるメインアンプとしてマランツの PS3001 を購入しました。これが、接続もされないままひっそりと片隅に置かれたままになっていました。

それをバックグラウンド・ミュージックのシステムとして使おうと考えて、スピーカーも購入していました。邪魔にならないように静かに音が流れるだけの環境での使用なので、大きなスピーカーの必要もなくて安い手頃なものを購入していました。これが今回は日の目を見ることになりました。

自分の部屋にマランツの大きくて重いアンプと小さな Volumio のラズパイを運びスピーカーを接続しました。日の目を見たミュージックサーバーは何の問題もなく音を出し始めました。

1年以上前にセットアップしたシステムなので、当然のように新しいシステムが提供されていました。悩むところですが今後のこともあるので、経験としてアップデートしてどのような結果になるのか興味があるし知りたいところです。そんなわけで、Volumio2 システムのアップデートも試してみました。

見た目は問題なくアップデートできたようです。この時点で止めといても良かったのですが、ネット上には NHK のラジオを組込む記事なども見付けることができ、プラグインを2つ組込んで対応できたようなので試してみようと考えました。
プラグインの組込みを実行すると、どれを選んでも同じエラーになります。古いシステム情報との競合のようです。ssh でログインして、update や upgrade を試してみましたが、システム全体の作りが元は同じ raspbian を使用しているもののモジュールの更新は考慮していないようです。

そこで最初からのクリーンインストールを試して、動作の違いを検証してみようと思い立ちました。そこで問題なのが選択してせっかく作った playlist を保存しておき、最新の Volumio2 のインストール後に戻すことができるかです。

置かれたディレクトリの情報をネットで色々と調べました。でも肝心なディレクトリの情報になかなか辿り着けないで困りました。

全てがそうなのかは分かりませんが、ルート下の data ディレクトリに置かれているようです。例えば、/data/playlist/ の中に、オーナーが volumioユーザーとして、プレイリストのタイトル項目毎にファイルとして分かれて置かれていました。

リモートで作業しているノートPCから、scp コマンドで取り出すことも、戻すことも問題なく出来るようです。例えば、保管用のディレクトリを確保してから、次のようなコマンドで取り出して、新しいシステムをセットアップします。

$ mkdir -p ~/volumio/playlist
$ scp -r volumio@192.168.22.33:/data/playlist/*  ~/volumio/playlist/

作業しているノートPCの volumio/playlist/ に取り出せているので、新しいシステムをクリーンインストール後に、戻すために scp コマンドを利用します。

$ scp -r ~/volumio/playlist/*  volumio@192.168.22.33:/data/playlist/

最新の Volumio2 をセットアップした後で、悩んだことをメモしておきます。それは基本的なことで、ssh したかったのにできなくて困りました。1年前もたしか悩んだような記憶があります。方法はブラウザで、Volumio の /DEV にアクセスして、ssh を有効にする [enable] ボタンをクリックすることです。

なお、初期値のパスワードは、volumioroot も ‘volumio‘ になっているので置き換えを実行しておきます。

最新版の Volumio2 をクリーンインストールしたので、できなかったプラグインは問題なくインストールまでできました。しかし、ネットで紹介された手順の途中で、:9000 番ポートにアクセスして操作するように説明されているのですが、そのポートでは機能が待ち受けていないようで、この作業は保留になりました。

暇ができたら頭の体操としてこの続きを進めたいと思いますが、ただのネットチューナーとしてだけでも十分なバックグラウンド・ミュージックサーバーとして働いています。この先も暇などできないと思うのでこの件は長期保留ですね。

最初からリストされている多くの放送局は動作保証されてませんが、感覚的には半分くらいはまともに機能しているようで、日本の歌謡曲やアイドルの局を流している放送局もあります。時折少し訛った日本語で日本の天気予報や鉄道情報が流れるのもありましたし、曲目や歌手名が漢字で表示されるのもあります。

バックグラウンドで適当に色々な曲が流れるのは私の性に合っているのかもしれません。特に信仰する歌手や曲があってこだわるわけでもないので、わざわざ選んだり入替えたりする手間も必要なくとても合理的です。今はこんな曲が欲しいと大雑把に放送局を選ぶだけで事が済みます。

音量のボリューム操作や放送局の選択は、離れたPCからのブラウザ操作でも、スマホからの操作でもできるし、もし必要なら曲名やアーティスト名の確認も簡単な内容ですが一応できます。今現在は、こんな曲もあったよなぁ〜と思うような懐かしい青春時代の曲が次から次へと流れています。

家に置かれたアナログの固定電話でもバックではデジタルのネットワーク経由だし、すでにラジオも時代は電波を使って放送する時代からネットワークを経由する時代に移行しているのですね、有料放送の NHK はこだわりから時代に遅れてますが今後どうなるのでしょうね。
放送局は、聞ききれないほどの選択量があるので、飽きたら変えるとか気分で変えるとか、良い悪いの判断は一度選んでみないと分からないので、埋もれる局が溢れてます。

ラズパイUPSのメール

ラズパイ1B+のネット共有サーバー化で、UPSバッテリーの減少や充電の経過をメール送信させて、スマホで確認したい、との対策の続きです。

メール機能は、今迄のサーバー設定の流れからpostfixでの設定になりますが、以前の実績のあるサーバーの設定と比較しながら今回も設定しました。一応動作したように感じたのですが、送られてくるはずのログが届きませんでした。

postfixのバージョンも上がっていて、項目が少し増えているようです。丹念に見直すと一部がコメントのままになっている項目とか別に誤りとか、数件気になる場所が見つかりました。

そこを直して立ち上げ直すと、期待しているような送信が行なわれているような印象です。届かなかったログも時間を置いて再送信されたようで、数時間後に届きました。

メモとして、コメントを除いた有効行をリストしておきます。

$ cat /etc/postfix/main.cf
compatibility_level = 2
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/sbin
data_directory = /var/lib/postfix
mail_owner = postfix
myhostname = rpi1-disk.sunao-mita.pgw.jp
mydomain = sunao-mita.pgw.jp
myorigin = $myhostname
inet_interfaces = all
mydestination = rpi1-disk, DebianPogo, DebianPogo.$mydomain, $myhostname, localhost, $mydomain
local_recipient_maps = unix:passwd.byname $alias_maps
unknown_local_recipient_reject_code = 550
mynetworks_style = host
mynetworks = 127.0.0.0/8, 192.168.11.0/24, [::ffff:127.0.0.0]/104 [::1]/128, [240d:1a:34d:7f00::0]/64
relayhost = [smtp.nifty.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/nifty.auth
smtp_sasl_security_options = noanonymous
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
home_mailbox = Maildir/
smtpd_banner = $myhostname ESMTP
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/bin/postfix
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
inet_protocols = ipv4, ipv6
message_size_limit = 10485760
mailbox_size_limit = 1073741824
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_mynetworks, permit_auth_destination, permit_sasl_authenticated, reject
mua_client_restrictions = permit_sasl_authenticated,reject
mua_helo_restrictions = permit_sasl_authenticated,reject
mua_sender_restrictions = permit_sasl_authenticated,reject

mailコマンドでメールするのに、以前は問題なく送信できていたのに、最近のバージョンではサーバー名が短縮されて送信されるようで、リレー先の@niftyでエラーになってしまいます。

どこかの定義で変更できるのかと思い調べたのですが、私には見つけられませんでした。対策としては、-r オプションで、リターンアドレスをフルアドレスで明示して指定することで回避できました。

メールで経過を送信できる目処が立ったので、どのように作るかですが、作成したups-readでバッテリーの容量が取得できるので、単純なシェルスクリプトで容量の変化を検知してメールを作成させることにしました。

バッテリーの減少検知では、50%を切ったら10%減少毎にメールをスマホに送信します。充電では、50%を越えたら15%充電毎にメールをスマホに送信します。

起動方法は、cronにより適当なインターバルで、毎回起動し過去と比較判定して該当すればメールを作成して終了します。

起動された前回の容量とメールを作成した時の容量をファイルに記録しておいて比較する方法です。経過をモニタしながらのデバッグで分かったことは、ups-readから渡される容量が、有り得ない数値を頻繁に表示します。

0 〜 100の範囲を超えて、120 程度は想定内と認識しますが、217 とか 193 などといった異常な数値が頻繁に出てきます。観察すると異常な数値に混じって正常な数値も有るようです。

異常な数値を排除した 0 〜 120 の範囲に入る数値は 、安定していて変化の少ない数値で推移しています。期待するバッテリーの容量と判断しても良さそうです。

対策としては、120 を超える異常な数値の時には前回の数値と置換えて無視することにしました。

$ cat bin/ups-check-mail.sh
#!/bin/bash
T='## UPS Battery Capacity ##'
Msg='UPS Battery Capacity '
DW='*Down* : '
UP='*Up* : '
Rt='sunao@rpi1-disk.sunao-mita.pgw.jp'
To='sunao*****@yahoo.**.jp'    # スマホのメールアドレス
FC='UPS-Check/UPSCap.txt'      # 前回の容量メモ
FM='UPS-Check/UPSCap-msg.txt'  # メール生成時の容量メモ
C=`ups-read`
test -f $FC || echo 100 > $FC  # メモファイルが無い場合
test -f $FM || echo 100 > $FM  # メモファイルが無い場合
UPSCap=`cat $FC`
UPSmsg=`cat $FM`
test $C -gt 120 && C=$UPSCap  # 120% を越えていれば異常と判断し、前回値に補正
if [ $C -lt $UPSCap ]; then  ### 放電 ; 前回との減少変化を検知
  if [ $C -lt 50 ] && [ $((C+9)) -lt $UPSmsg ]; then  # < 50% ; 10% 減少毎にメール作成
    echo $C > $FM
    Tl=`echo "$T" | sed -r "s/( ##)$/ *DOWN* ( $C% )\1/"`  # 減少メールのタイトル作成
    # echo "タイトル: $Tl"  # debug 確認用
    echo -e "`date`\n$Msg$DW$C %" | mail -s "$Tl" -r "$Rt" "$To"    # メールの転送
  fi
else
  if [ $C -gt $UPSCap ]; then  ### 充電 ; 前回との増加変化を検知
    if [ $C -gt 50 ] && [ $((C-14)) -gt $UPSmsg ]; then  # 50% < ; 15% 増加毎にメール作成
      echo $C > $FM
      Tl=`echo "$T" | sed -r "s/( ##)$/ *UP* ( $C% )\1/"`  # 増加メールのタイトル作成
      # echo "タイトル: $Tl"  # debug 確認用
      echo -e "`date`\n$Msg$UP$C %" | mail -s "$Tl" -r "$Rt" "$To"    # メールの転送
    fi
  fi
fi
echo $C > $FC  # 今の容量を記録

AC100V電源を止めても、2時間近くはバッテリーで動作していますが、しばらく待っているとスマホにメールが送られてきます。

備忘録として、単体での起動なら例えば /home/sunao/bin/ の下にスクリプトを置いて起動できますが、cron からの起動ではスクリプトが見付けられずにエラーとなります。cron では、最低限のPATH設定となっているからです。

crontab -e で、起動時間や起動スクリプトを編集する定義の中で、さらに先の行に、PATH= 定義を記述して実行モジュールを読み込むディレクトリをリストしておくとパスが省略されていても起動できるようです。

$ crontab -e
# m h  dom mon dow   command
PATH=/home/sunao/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
##### UPS バッテリーの変化でメール作成 ######
*/5 * * * * ups-check-mail.sh > /dev/null

スマホには、8 〜 9 分間隔で 10%減のメールが届きます。逆に充電時は、11 〜 12 分間隔で 15%増のメールが届きます。気休めですがメールが送られると少し安心できます。

まだ手を加えたい箇所はあるもののネット共有サーバーとして利用できそうな状況になってきました。