ようこそNICのホームページへ(なが〜い試運転中)   
HP パソコン 健康 落語 海外 思うまま 電子工作

UPSからNASとサーバーをシャットダウンする方法(その2)
UPS (OMRON BY50S) NAS(QNAP TS-231P) サーバー(shuttle xs36v4)

Last update:2018/04/24    Build:2017/9/27


(その1)へ  (その2)へ  (その3)へ 

 
UPSを入れたのでNASは自動でシャットダウンできるようにした(ここ)。 しかし24時間運転のサーバーもUPSに繋いで電源が 落ちたときは自動でシャットダウンしたい。UPSのUSBが1カ所しかないため、両方をシャットダウンできる方法を考える


 うまくいったのでその結果を書きます。ここに至るまでのトラブルや悩んだことは(その3)に書きます(予定)

機器
 サーバー :shuttle XS36V4  (OS:Ubuntu 14.04LTS) のこと
 NAS  :QNAP TS-231P (OS:Linux)      のこと
 UPS  :OMRON  BY-50S            のこと
ネットワーク構成
 インターネット----ルーター--|-------ルーター ----|------ NAS
         (終端装置) |          |
               | |------ メインPC

|-------サーバー(HTTP,HTTPS,SSH)


0.前提 

1)UPSとNASをUSBケーブルで接続し、UPSの商用電源が落ちた時は自動でNASがシャットダウンする ようにセットする。
2)サーバーとNASはLANで繋がっている(私の場合、間にルーターが入っています。これが問題を複雑化)
3)NAS(masterとして)から信号をサーバーに送り、サーバーがシャットダウンするようにセットする
4)関連するルーターやHUBもUPS電源でバックアップしておく

流れとしてとしては
 UPSの商用電源が落ちたことを知る =>サーバーに知らせてシャットダウンする
です。

これらを行うための主な課題は
1)どうやってUPSの商用電源が落ちたことを知るか
2)どのようにサーバーに知らせるか


1.結論として

1)NASはNUT(Network UPS Tools)を使っている。
2)NUTのupsmonがデーモンで動き、UPSの電源を見張っている?
3)コマンド /sbin/upsc qnapups@localhost ups.status  で商用電源が落ちたかどうかが解る
 OL:on line 商用電源有り
 OB:on battery 商用電源が落ちバッテリーから電力を供給中
 その他:略  (参考: UPSMON(8) または   pdf版)
 ups.status はDebian系か??
4)NAS上のcronで1分毎に上記3)をチェックする
5)「OB」になったら1分間待ち、次でも商用電源が回復していない場合はサーバーをシャットダウンする信号を送る
6)サーバーにログインしてルートでシャットダウンするため、パスワード入力処理とルートになるための処理を事前にセットしておく


2.NASとサーバーに専用のユーザーを作成する 

項目  NAS  サーバー
ユーザー名USER2(サーバーと同じとした)  USER2
ssh認証 パスワードのみ

3.サーバー上でパスワードなしでsudoを実行する

サーバー上のUSER2をadminグループに編入してルートになれるようにする。
シェルからシャットダウンするため「sudo 」でパスワードを求められないようにする
root権限でシャットダウンさせるためパスワードを求められないよう
 /etd/sudoers を変更する必要あり
  → これは危険かも? rootでなくてシャットダウンできないか?

サーバー上で
 sudo visudo で /etc/sudoers に以下の行を追加
 (直接編集しないこと、失敗すれば全くログインできなくなることも。rootでも/etc/sudoers は編集できない)

 user2 ALL=NOPASSWD:/sbin/shutdown, /sbin/poweroff
 ↑ユーザー名        ↑シャットダウン関係のコマンドのみ許可する


==============================   visudo  ====================

  GNU nano 2.2.6                      ファイル: /etc/sudoers.tmp                                                    
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

user2 ALL=NOPASSWD:/sbin/shutdown, /sbin/poweroff  <=パスワードなしでsudo

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

==============================   visudo  ここまで ====================


4.スクリプトとcrontabの作成

サーバーにログインする時にパスワードを求められる。
「Keep the Light Alive」さんのページを見つけた。ssh_askpassを使えばよいとのこと。
スクリプトや命令もある。ありがたく使わせていただく(感謝!!)
以下のスクリプトとコマンドを追加する。

「Keep the Light Alive」さんのページのスクリプト
#!/bin/bash
if [ -n "$PASSWORD" ]; then
  cat <<< "$PASSWORD"
  exit 0
fi
read PASSWORD
export SSH_ASKPASS=$0
export PASSWORD
export DISPLAY=dummy:0
exec setsid "$@"

「Keep the Light Alive」さんのページのスクリプトを使うコマンド例
このスクリプトをssh_pass.shとかにしておいて、こんな感じで使います。
$echo password | ./ssh_pass.sh ssh user@example.com "ls -a"

後はシェルスクリプトを作成しcronで1分ごとに廻す。


cronは以下の通り
[user2@NAS sd]$ cat crontab-sdfns-170925
# /home/user2/sd/crontab-sdfns-170925   - crontab for ubuntu
#  2017/09/25  
#  
#
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/share/homes/user2/sd
HOME=/share/homes/user2/sd
#
#minute hour    mday    month   wday    who     command
#
#   2017/09/12  check  omron ups power off  fron nas QNAP
#   
*    *       *       *       *       /share/homes/user2/check_power.sh

シェルスクリプトは以下の通り
[user2@NAS sd]$ cat check_power.sh
#!/bin/sh
# check_power.sh  2017/09/25 last update
# script check for omron power
# variable ups-status ( ol:on line  ob:on battery )
# variable ol-watch   ( 0:normal   1: more than 1 minute after on battery ) 
#

/sbin/upsc qnapups@localhost ups.status > /share/homes/user2/sd/ups-status

check=`cat /share/homes/user2/sd/ups-status` 
if [ $check = "OL"  ] ; then
   echo "0" > /share/homes/user2/sd/ol-watch
   date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' ' >>/share/homes/user2/sd/ups_watch_log.txt
             echo " OMRON UPS OK on line" >>/share/homes/user2/sd/ups_watch_log.txt

elif [  $check = "OB"  ] ; then
   check2=`cat /share/homes/user2/sd/ol-watch`
   if [  $check2 = "0"  ] ; then
     echo "1" > /share/homes/user2/sd/ol-watch
     date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' ' >>/share/homes/user2/sd/ups_watch_log.txt
       echo " UPS On Battery:wait 1 minute" >>/share/homes/user2/sd/ups_watch_log.txt

   elif  [ $check2 =  "1"  ] ; then
     date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' '  >>/share/homes/user2/sd/ups_watch_log.txt
       echo " OMRON UPS Power Off shutdown xs36v4 " >>/share/homes/user2/sd/ups_watch_log.txt  
     echo password | /share/homes/user2/sd/ssh-askpass-2.sh              (次の行に継続) 
       ssh  user2@192.168.1.◎◎ -p 1234  "sudo shutdown -P now"
  fi
else
   date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' ' >>/share/homes/user2/sd/ups_watch_log.txt
              echo " others what ??? " >>/share/homes/user2/sd/ups_watch_log.txt

fi
(2018/04/24 追記ここから)
2018年4月24日にスクリプトを修正しました。
変更点1:ファイルパス+ファイル名を変数で与えるようにしたこと
変更点2:サーバーをシャットダウンする時間を簡単に変えられるようにした(upper time)
サーバーをシャットダウンするタイミングは下図のとおり(upper=3の場合)
#!/bin/bash
# 
# check_power.sh  2018/04/24 last update  (introduce upper time)
# check_power.sh  2017/09/25 build
# script check for omron power
# file1='/share/homes/user2/sd/ups-status' ( OL:on line  OB:on battery )
# file2='/share/homes/user2/sd/ups_watch_log.txt' ( log file )
# file3='/share/homes/user2/sd/ol-watch'   ( 0:normal   1: more than 1 minute after on battery ) 

upper=3   # upper time(minutes) of waiting for shutdown
normal=0  # initila value , state of power on line
file1="/share/homes/user2/sd/ups-status"
file2="/share/homes/user2/sd/ups_watch_log.txt"
file3="/share/homes/user2/sd/ol-watch"
password="mypass"

/sbin/upsc qnapups@localhost ups.status > $file1

check=`cat $file1` 

if [ $check = "OL"  ] ; then
   echo $normal > $file3
   date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' ' >>$file2
   echo " OMRON UPS OK on line" >>$file2

elif [  $check = "OB"  ] ; then
   check2=`cat $file3`
   if [  $check2 -lt $upper  ] ; then
     check2=$(( check2+1 ))
     echo $check2 > $file3
     date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' ' >>$file2
     echo " UPS On Battery power :wait 1 more minute" >>$file2

   else 
     date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' '  >>$file2
     echo " OMRON UPS Power Off shutdown xs36v4 " >>$file2  
     echo $password | /share/homes/user2/sd/ssh-askpass-2.sh   (次の行に継続) 
       ssh  user2@192.168.1.999 -p port_num  "sudo shutdown -P now"
   fi
else
   date "+%Y/%m/%d %H:%M:%S"| tr '\n' ' ' >>$file2
   echo ' others what ???  $check= ' $check>>$file2

fi
(2018/04/24 追記ここまで)

パスワードなしでログインするためのssh-askpassスクリプトは以下のとおり「Keep the Light Alive」さんのスクリプトそのままです
[user2@NAS sd]$ cat  ssh-askpass-2.sh
#!/bin/bash
if [ -n "$PASSWORD" ]; then
  cat <<< "$PASSWORD"
  exit 0
fi
read PASSWORD
export SSH_ASKPASS=$0
export PASSWORD
export DISPLAY=dummy:0
exec setsid "$@"


5.crontabのセット


QNAPはUSER2ではcrontabをセットできないので
adminでログインしてcrontabをセットする、このとき「−u user2」を忘れると
adminのcrontabが書き換えられてしますので要注意。

crontab ファイル名(フルパス) −u user2
逆ではエラーがでる。
crontab −u user2 ファイル名(フルパス) <==これはエラー

これでUPSの商用電源が落ちた時に(クローンが動いたときから)1分待って回復しなければサーバーが自動でシャットダウンされる。

 待つ時間を1分としたのは、商用電源が落ちた時刻とcronが動くタイミングで最大2分近くになることもあるため、安全側をとって1分とした。
(UPSの情報を見ると、今のバッテリー状態(新しい)と負荷の状況(少ない)だと53分とでており、 安全側を考えても30分以上は十分もつと考えられるが・・)



 


電子工作へ     HomePage     このページのトップ