事前準備
- NAS に、admin 権限のアカウントを作っておく(例えば adminx). admin アカウントを使ってもいいが、この目的専用の password にしておきたかった、というだけの理由。
- NAS の ssh サービスを有効にしておく
- 同じネットワーク上に常時動作してある linux を使う (Raspberry PI など)
下記 5 つのファイルを作成し、Linux host で crontab 設定する。
NASをリモート起動する場合は、WOL を使用(NAS の WOL 設定をお忘れなく)。
1) auto_poweroff.sh - NAS 上で動かすスクリプト
#!/bin/sh
PASSWD="adminx アカウントのパスワード平文"
SMBLOG="./smbstatus.log"
NSLOG="./netstat.log"
LOCKFILE="./auto_poweroff.lock"
## RAID scrubbing check
ps -ef | grep "\[md1_resync\]"
if [ $? -eq 0 ]; then exit 0; fi
## RAID scrubbing check -- end
## established session check (UPNP, ftp, sftp, ssh)
netstat -ut > $NSLOG
M=`cat $NSLOG | wc -l`
while [ $M -gt 0 ]; do
LINESTR=`sed -n $M\P $NSLOG`
echo $LINESTR | grep -E "^(tcp|udp)" > /dev/null
if [ $? -eq 0 ]; then
SESSION=`echo $LINESTR | awk -F' ' '{print $6}'`
if [ $SESSION = "ESTABLISHED" ]; then
IPPORT=`echo $LINESTR | awk -F' ' '{print $4}'`
echo $IPPORT | grep -E ":(5001|2222|ftp)$" > /dev/null
if [ $? -eq 0 ]; then break; fi
echo $IPPORT | grep -E ":ssh$" > /dev/null
if [ $? -eq 0 ]; then
CLIENT=`echo $LINESTR | awk -F' ' '{print $5}'`
CLIENTNAME=`echo $CLIENT | sed -e "s/^\(.\+\):[0-9]\+$/\1/g"`
IPADDR=`nslookup $CLIENTNAME | grep "Address" | tail -n 1 | sed -e "s/^Address.*:[ \t]\+\([0-9a-fA-F.:]\+\).*/\1/g"`
IPPORT="$IPADDR:`echo $CLIENT | sed -e "s/^.\+:\([0-9]\+\)$/\1/g"`"
SSHCLIENT="`echo $SSH_CLIENT | awk -F ' ' '{print $1}'`:`echo $SSH_CLIENT | awk -F ' ' '{print $2}'`"
if [ $IPPORT != $SSHCLIENT ]; then break; fi
fi
fi
fi
M=`expr "$M" - 1`
done
if [ $M -gt 0 ]; then
echo "$LINESTR"
rm -f $LOCKFILE
exit 0
fi
## UPNP session check -- end
## samba session check
echo $PASSWD | sudo -S /usr/builtin/bin/smbstatus -A > $SMBLOG
N=`cat $SMBLOG | wc -l`
while [ $N -gt 0 ]; do
IPADDR=`sed -n $N\P $SMBLOG | awk -F' ' '{print $5}'`
echo $PASSWD | sudo -S ping -c 1 -W 3 $IPADDR > /dev/null
if [ $? -eq 0 ]; then break; fi
N=`expr "$N" - 1`
done
if [ $N -gt 0 ]; then
echo "IP $IPADDR is alive."
rm -f $LOCKFILE
exit 0
fi
if [ -e $LOCKFILE ]; then
echo 'Execute poweroff'
rm -f $LOCKFILE
echo $PASSWD | sudo -S poweroff
exit 2
else
echo 'Check one more time later'
echo -n > $LOCKFILE
fi
exit 1
2) sendscript.sh - 上記実行ファイルの転送と実行を host 上で行う script
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage: $0 [nas_server_address]"
exit 2
fi
THIS_FILE_PATH=`dirname $0`
PASSWD="adminx アカウントのパスワード平文\n"
echo "["`date "+%Y%m%d_%H%M"`"]"
ping -c 1 -W 3 $1 > /dev/null
if [ $? -ne 0 ]; then
echo "Target $1 in power-off. Quitting..."
exit 1
fi
expect -c "
set timeout 30
spawn $THIS_FILE_PATH/chkfile.sh $1
expect \"Password:\"
send $PASSWD
expect eof
catch wait result; exit [lindex \$result 3]
"
if [ $? -ne 0 ]; then
expect -c "
set timeout 30
spawn $THIS_FILE_PATH/scp.sh $1
expect \"Password:\"
send $PASSWD
expect eof
catch wait result; exit [lindex \$result 3]
"
fi
expect -c "
set timeout 30
spawn $THIS_FILE_PATH/ssh.sh $1
expect \"Password:\"
send $PASSWD
expect eof
catch wait result; exit [lindex \$result 3]
"
3) scp.sh - 実行ファイル転送サブ・スクリプト
#!/bin/bash
THIS_FILE_PATH=`dirname $0`
scp -p $THIS_FILE_PATH/auto_poweroff.sh adminx@$1:./
4) ssh.sh - 転送スクリプトを実行させるサブ・スクリプト
#!/bin/bash
ssh adminx@$1 "./auto_poweroff.sh"
5) chkfile.sh - 実行ファイルが NAS に存在するかを調べるサブ・スクリプト
#!/bin/bash
ssh adminx@$1 "ls ./auto_poweroff.sh"
exit $?
6) 上記 5 つのファイルをホスト Linux 上の同じディレクトリに置き(例では、~/nasctrl/)、chmod 750 としておく. Root である必要はなく、単なる 1 ユーザアカウントで OK.
セコメントをする