Debian GNU/Linux上でのシェルスクリプト実行によるNAS制御
長年、継続利用しているASUSTOR NASの気に入っているところは下記の2点。
- NASを利用しないときはスリープモード機能を設定することで、指定された時間内にデータアクセスがない場合は、システムをサスペンドさせることができる。例えば、30分間、NASへのアクセスがなければサスペンドにするような運用ができる。
- 数種類のバックアップ機能があるが、外部バックアップ機能を利用すると、USB接続HDD(NTFS)にデータをバックアップできる。スケジューリングさせてもよいし都度でもよいし、タイミングは自由に設定できる。
NASといえど、家庭内利用において24時間稼働させる必要はなく、逆に24時間稼働だと電気料金もかかってしまう。ASUSTORのNASでは、PCを利用していてNASを利用したいときに電源オン、NAS利用が終わったら30分後に自動的に電源オフのような使い方ができる。
また、常にリアルタイムバックアップを行っていると、うっかりファイル削除してしまっときにリカバリができないし、すべてのデータがオンライン状態のときランサムウェアに感染してしまうと、データ復旧も絶望的になる。そのためオフラインのバックアップをいくつか持っておくことが非常に重要になっている。
これらの2つの要件をASUSTORのNASは満たしてくれるため、我が家では大変重要な働きをしている。今回、新しく構築したTrueNAS SCALE/NASでも上記2つの機能を持たせたく、TrueNAS SCALEのWebUIで設定メニューを確認してみた。なんとなくバックアップやシャットダウン制御などできそうなのだが、一筋縄ではいかなそう。


TrueNAS SCALEを調査し続ける案もあったのだが、自分のスキルでは時間がかかりそうな雰囲気。そこで、10年以上も前に構築した自作NASでもシェルスクリプト実行によりシャットダウン制御などを行っていたため、TrueNAS SCALEでも同じような方法で制御できないかと考えた。ベースがDebianのためほぼLinux状態で利用することが確認できたのだが、私が試した限りでは、/etc/vconsole.confでのキーボード設定や/etc/fstabでのマウント設定などが反映されない(設定してもリブートの都度、初期化されてしまう)。少々不思議なところがあるし、少し工夫しないといけない部分もあるが、実装したい機能が実現できることが分かった。
※その結果、H342の改造に着手したというのが実際のところ。
必要な事前確認と設定
TrueNAS SCALEのベースはDebianのため、普段linuxを触る時と同じように設定できるものと考えていた。下記の通り、OS自体はDebianそのもののように見える。
root@H342-New[~]# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11" VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
いざ、いろいろと設定変更していこうとしたところ、まず日本語キーボードの問題に直面、コンソールでのキーボード設定がリブートの都度初期化されてしまうのだ。この問題は、ある程度セットアップが完了したためHDMI接続の必要性がなくなり、途中からRLoginを使ってrootによるリモートログインを許容したことで無理やり解決状態にした(rootでのリモートログインは本来NGなのだが、外部からの接続は完全遮断のため)。
root@H342-New[~]# cat /etc/vconsole.conf
# CONSOLE CONFIGURATION FILE
KEYMAP="jp" <== これが有効にならない
なお、参考までにTrueNAS SCALEのSystem Settingsの中に”シェル”というメニューがあるのだが、TrueNAS SCALEとしての”admin”ユーザであり、Linuxのrootユーザではない(プロンプトが “$”)。visudoなどをいじってsudoやsu – ができるように試みたのだが、何をやってもうまくいかなかった。そもそもの考え方ややり方が間違っているのかもしれない。
別の問題はリブートするとWake on LAN機能が無効化されてしまう点だ。ethtoolでwolを有効化設定しても、次回起動時にwolが有効になるだけで、それ以降は再び無効化されてしまう。設定変更後の1回目だけがwolを利用可能な状態なのだ。これは、cronでリブートの都度、ethtoolコマンドを実行させることで解決させた。
root@H342-New[~]# crontab -l
@reboot /usr/sbin/ethtool -s enp1s0 wol g <== リブートの都度、ethtoolを実行
root@H342-New[~]# ethtool enp1s0 | grep -i wake
Supports Wake-on: pumbg
Wake-on: g <== g:wol有効、d:wol無効
また、/etc/fstabの設定を変更してもリブートの都度強制的に初期化されてしまい/etc/fstabへの追加設定が消去されてしまう。かつ、USB接続HDDのデバイス名(/dev/***の部分)が起動ごとに変わってしまうため、永続的なマウントポイントを設定できない。UUIDをfstabに記述したとしても初期化されて設定が削除されてしまうので意味がない。USB接続HDDを利用するたびに、毎回システムにログインしてマウンドコマンドを実行するのも面倒なので、これは後述のリモート制御でカバーする。
root@H342-New[~]# cat /etc/fstab
boot-pool/grub /boot/grub zfs relatime,defaults 0 0
tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=100m 0 0
※ 何を追加しても、再起動の都度、上記の設定に初期化されてしまう
NAS構成
ASUSTORとTrueNAS SCALEの2台構成となったが、USB接続HDDへのバックアップは以下のような設計で運用している。先述の通りASUSTORのNASで実現していたことを、TrueNAS SCALEにも実装した。ただ、ASUSTOR/NASとTrueNAS SCALE/NAS間での連携は取れていないため、手動でメイン、バックアップを使い分けている。

TrueNAS SCALE/NASのリモート制御だが、起動はWake on LANツールで問題なく対応できる。シャットダウンやバックアップなどを毎回リモートログインしてコントロールするのも面倒だし、自分以外の家族がNASを利用するようになったとしても家電製品の電源をオン・オフするような感覚で簡単に利用できないと使い勝手が悪くなってしまう。そこで、ずっと以前にも利用していた「特定ディレクトリでのファイル存在によって、動作を制御する」というやり方を今回も踏襲した。

下記は、毎分で定期的にファイル存在を確認するcron設定。毎分、cronでこれらを走らせてもマシン的には全く問題ない。
root@H342-New[~]# crontab -l
@reboot /usr/sbin/ethtool -s enp1s0 wol g <== これは先ほどのwol有効化の設定
*/1 * * * * /root/poweroff.sh <== NASのシャットダウン
*/1 * * * * /root/mount-usbhdd.sh <== USB接続HDDのマウント
*/1 * * * * /root/usbhdd-backup.sh <== USB接続HDDへのバックアップ
NASのシャットダウン
PCもシャットダウンしてNASも利用しないというときは、NASの電源をオフにしたい。毎回、NASの管理者画面にログインしなくてもシャットダウンできるようにする。

シャットダウンコマンドを実行させるシェルスクリプトは以下の通り。
root@H342-New[~]# cat poweroff.sh
#!/bin/sh
#H342 shutdown script from remote PC
if
test -e /mnt/Pooh-san-20230325/control/shutdown/* <== ディレクトリ内のファイル有無を確認
then
rm -rf /mnt/Pooh-san-20230325/control/shutdown/* <== ファイルがあれば、それを削除して、
/bin/systemctl poweroff <== NASをシャットダウン
else
echo > /dev/null
fi
非常に簡単なシェルスクリプトではあるが、ファイル格納してから最長でも1分後には問題なくNASシステムをシャットダウンできる。わざわざシステムに管理者権限でログイン –> シャットダウンの手順をとならくてもよい。
USB接続HDDのマウント
ブート時にUSB接続のHDDが接続されていれば問題ないのだが、普段はオフラインにしているためNASを利用している途中で「USB接続HDDにバックアップしておきたい」ときがある。こうなると、システムにログインしてマウントコマンドを打たなければUSB接続HDDを利用できない。では、毎回これをやるのかというと面倒なため、Windowsからの共有フォルダ操作一つでマウントができるようにした。

マウントコマンドを実行させるシェルスクリプトは以下の通り。
root@H342-New[~]# cat mount-usbhdd.sh
#!/bin/sh
#H342 USB-HDD mount script from remote PC
if
test -e /mnt/Pooh-san-20230325/control/mount/* <== ディレクトリ内のファイル有無を確認
then
rm -rf /mnt/Pooh-san-20230325/control/mount/* <== ファイルがあれば、それを削除して、
mount --types ntfs UUID=3E8A23848A2337B3 /mnt/usb8 <== USB接続HDDをNTFSでマウント
else
echo > /dev/null
fi
USB接続HDDをマウントするとき、/dev/***形式のデバイス名が利用できない。ブートの都度、/dev/sdg2だったり/def/sdf2だったりで毎回デバイス名が変わってしまう。そのため、UUIDを使ってマウントしている。下記はシステムで利用しているストレージデバイスのUUIDを確認したもの。
root@H342-New[~]# ls -l /dev/disk/by-uuid
total 0
lrwxrwxrwx 1 root root 10 May 5 19:44 10109663148903458986 -> ../../sde2
lrwxrwxrwx 1 root root 10 May 5 19:43 14286568303848588196 -> ../../sda3
lrwxrwxrwx 1 root root 10 May 5 19:44 1c8a83da-205a-4a08-8a4e-1d56e84b2c7d -> ../../dm-1
lrwxrwxrwx 1 root root 10 May 5 19:44 2cb14b69-0552-4f5d-ad5a-4b45071cbb0a -> ../../dm-0
lrwxrwxrwx 1 root root 10 May 5 19:43 3E8A23848A2337B3 -> ../../sdf2 <== USB接続HDD
lrwxrwxrwx 1 root root 10 May 5 19:43 D9E8-55A4 -> ../../sda2
上記のタイミングでは、3E8A・・・のUSB接続HDDは/dev/sdf2のデバイス名になっているようだ。なお、このHDDをフォーマットするとUUIDが変わってしまうため、再度設定をやり直す必要がある。
USB接続HDDへバックアップ
普段はオフラインにしているUSB接続HDDはとても重要な役割を果たしている。NASはraid-zで耐障害性を確保しているが、ファイルを削除すると当たり前だがNASのファイルシステムからは削除されてしまう。raidはバックアップソリューションにはならない。また、万が一、自宅内のPCがランサムウェアに感染しNASに格納されているファイルが影響を受けたとしてもオフラインでバックアップを持っておけば、問題なく復旧ができる。今、我が家には少なくとも2台のオフラインバックアップが存在している。もちろん、家族へのセキュリティに対する啓蒙は頻繁に行っている。
この外部バックアップも共有フォルダへのファイル投げ込み方式で実現している。

バックアップコマンドを実行させるシェルスクリプトは以下の通り。マウント手段を先ほどのとおり個別に作りこんだが、個別にマウント –> バックアップの手順を取らなくても、マウントしてバックアップまでを一気にできるようにしている。特徴はローカルバックアップなのにrsyncを利用している点。本来rsyncはリモートホストとのディレクトリ同期に利用するコマンドだと思うのだが、相手をローカルディスクに設定すればUSB接続HDDのバックアップに使えると考えた(普通のことなのかもしれないが)。バックアップに時間がかかるケースも想定して、「今日はPCをもう利用しないな」というタイミングで実行できるように、バックアップ後にシャットダウンさせている。
root@H342-New[~]# cat usbhdd-backup.sh
#!/bin/sh
#H342 backup --> shutdown script from remote PC
mount --types ntfs UUID=3E8A23848A2337B3 /mnt/usb8 <== NAS起動後に外付けHDDを接続してもOK
if
test -e /mnt/Pooh-san-20230325/control/backup/* <== ディレクトリ内のファイル有無を確認
then
rm -rf /mnt/Pooh-san-20230325/control/backup/* <== ファイルがあれば、それを削除して、
rsync -ah --exclude '/mnt/Pooh-san-20230325/ix-applications' --log-file=/var/log/rsync/`date "+%Y%m%d-%H%M%S"`.log --delete --backup --backup-dir="/mnt/usb8/backup-$(date +%Y%m%d-%H%M%S)" /mnt/Pooh-san-20230325/ /mnt/usb8/backup-latest/ --stats > /home/admin/usbbklog-$(date +%Y%m%d-%H%M%S)
<== USB接続HDDへバックアップ
wait <== バックアップが完了するまで待つ
/bin/systemctl poweroff <== バックアップ完了後、シャットダウン
else
echo > /dev/null
fi
rsyncでのバックアップはオプションを使って以下のように運用している。
- TrueNAS SCALEのストレージプールには、”ix-applications”などシステムが利用するディレクトリが存在していることから、これをバックアップ対象外にする。同様に”control”ディレクトリもバックアップ対象外とする(–exclude)。
- NASの共有フォルダから削除したファイルがいつまでも外付けHDDに残らないように、NASで削除したファイルは外付けHDDのバックアップ領域からも削除する(–delete)。
- かといって、すぐに外付けHDDから完全削除してしまうと「残っていれば復活できたのに」と思うことがあるかもしれないため、外付けHDDのバックアップ領域とは異なるディレクトリに一時的に退避させる(–backup)。ま、後から手動で削除することにはなるのだけれど。

rsyncのログ出力設定はもう少し見直さないといけないのだが、rootでログインした状態ではバックアップされた全てのファイルリストとその結果がわかるように出力し、adminでログインした状態では結果だけがわかるように設定している。ほぼ、同じ出力になるのだが・・・。
以下はrsyncの–log-file設定で出力したもの。
root@H342-New[/var/log/rsync]# cat 20230501-183301.log
・・・ snip ・・・ <== ここに膨大なファイルのリストが表示される
2023/05/01 18:38:13 [15503] Number of files: 324,906 (reg: 298,363, dir: 14,181, link: 12,356, dev: 5, special: 1)
2023/05/01 18:38:13 [15503] Number of created files: 22,509 (reg: 12,527, dir: 3,021, link: 6,957, dev: 4)
2023/05/01 18:38:13 [15503] Number of deleted files: 46,562 (reg: 27,194, dir: 5,522, link: 13,846)
2023/05/01 18:38:13 [15503] Number of regular files transferred: 12,574
2023/05/01 18:38:13 [15503] Total file size: 3.49T bytes
2023/05/01 18:38:13 [15503] Total transferred file size: 725.82M bytes
2023/05/01 18:38:13 [15503] Literal data: 725.83M bytes
2023/05/01 18:38:13 [15503] Matched data: 0 bytes
2023/05/01 18:38:13 [15503] File list size: 1.25M
2023/05/01 18:38:13 [15503] File list generation time: 0.001 seconds
2023/05/01 18:38:13 [15503] File list transfer time: 0.000 seconds
2023/05/01 18:38:13 [15503] Total bytes sent: 734.97M
2023/05/01 18:38:13 [15503] Total bytes received: 7.74M
2023/05/01 18:38:13 [15503] sent 734.97M bytes received 7.74M bytes 2.38M bytes/sec
2023/05/01 18:38:13 [15503] total size is 3.49T speedup is 4,700.16
こちらは、rsyncの–statsオプションで出力したもの。
root@H342-New[/home/admin]# cat usbbklog-20230501-183301
Number of files: 324,906 (reg: 298,363, dir: 14,181, link: 12,356, dev: 5, special: 1)
Number of created files: 22,509 (reg: 12,527, dir: 3,021, link: 6,957, dev: 4)
Number of deleted files: 46,562 (reg: 27,194, dir: 5,522, link: 13,846)
Number of regular files transferred: 12,574
Total file size: 3.49T bytes
Total transferred file size: 725.82M bytes
Literal data: 725.83M bytes
Matched data: 0 bytes
File list size: 1.25M
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 734.97M
Total bytes received: 7.74M
sent 734.97M bytes received 7.74M bytes 2.38M bytes/sec
total size is 3.49T speedup is 4,700.16
異なるのはバックアップ対象のファイルリスト有無だけなので、近いうちにもっとスマートな出力となるように整理したい。
ちょっとの工夫でNASがより便利で快適に
以上がTrueNAS SCALEでの設定以外にOSレベルで行ったセットアップの内容となる。NASといえども一般家庭では24 by 7での運用は必要ないと思うので、利用したいときに起動させて利用が終わったら電源を切るという操作を簡単に実現できるとPC間隔での利用ができて便利だ。内蔵HDDの稼働時間もかなり短縮できて故障リスクも減らせるのかもしれない。起動時のスピンアップのほうが問題だという突っ込みがあるかもしれないけれど。
バックアップ機能も実現できたし当初の目的はある程度達成できたのだが、シャットダウンし忘れるといつまでも稼働を継続してしまうという問題が残っている。この点はASUSTORに負けている。家庭内のPCとのセッションが存在しなくなったらシャットダウンさせるなどの追加設定も盛り込む予定だ。