思考実験とD.I.Y.

D.I.Y and Gedankenexperiment

【FreeBSD13.5/13.4】各サーバのシステム設定変更を動的にバックアップする

誤ったシステム設定を行ってしまった場合、過去の設定を確認したいことがあります。

そこで、”システム設定”関連のフォルダ他を、変更が行われた際にバックアップし、過去数世代のバックアップを残すように設定しておこうと思います。【注*1

バックアップ用ファイルシステム領域は、メインファイルサーバーの飛ばしたpool復旧作業に際して[*2]、ActiveDirectoryドメインコントローラー(AD-DC)に、RAID1なエンクロージャーを取り付け、そちらに移動してあります[*3]。

FreeBSDな各サーバーの起動時に、””システム設定”関連のフォルダ他に変更が加えられたかを確認して、AD-DCのバックアップ用ファイルシステム領域にバックアップをNFS経由で行う設定をしておこうと思います😀。

"rsync over ssh"で行う方が美しいかもしれませんが、”AD-DCのrsync over ssh設定が必要”なことと、転送すべきデータ総量もそれほどではありませんので、とりあえずNFS経由でバックアップを行うことにしました😅。

1. 準備

(1)ツールのインストール

今回、スクリプトで使うツールをインストールしておきます。

既にインストール済みのパッケージも念のため、アップデートしておくことにしました。

root@FreeBSD:# pkg install gawk gtar rsync

   

2. スクリプト作成(参考)

  • スクリプトは、例外処理の検討はまだ、かなり甘い上、Linuxでも使えるようにするためには、各コマンドの絶対パスを正規化する必要があるため、あくまで参考として紹介させていただきます。
(1)ファイルローテート用サブスクリプト

過去の設定状態を確認したいときのために、何世代分かのTARボールは取っておきたいので、TARボールの末尾に数値を付加して世代管理をすることにしました。

FreeBSDLinuxの/var/log/messages等と同様の考えで世代管理をします。

つまり、TARボール末尾の数値が大きいほど、古い設定情報とすることにしました。

 FreeBSDLinuxの標準ツールでこの処理を行うのも手ですが、

  • FreeBSDLinuxで作りこみ方が違う事。
  • 後々、FreeBSDUbuntuで共通利用することを念頭に置いて。

手前勝手なスクリプトを作ってみました😅。

 

root@FreeBSD:# cd /Share/scripts/common    
root@FreeBSD:# vi rotate-file.sh    

 

 

#!/bin/sh
#
AWK=/usr/bin/awk
#
if [ "$2" = "" ]; then
        echo usage: rotate-dir.sh [target] [max backup number]
fi
#
FNAME=$1
i=$2
#
while [ $i -ge 0 ]; do
        if [ $i -eq $2 ]; then
                if [ -f $FNAME.$i ];then
                        rm -r  $FNAME.$i
                fi
        fi
        if [ $i -lt $2 ]; then
                j=`echo $i | $AWK '{print $1+1 }'`
                if [ -f $FNAME.$i ]; then
                        mv $FNAME.$i $FNAME.$j
                fi
        fi
        i=$*4
done
if [ -f $FNAME ]; then
        mv $FNAME $FNAME.0
fi



 

何世代過去まで、取って置くかはハードコーディングせずに、パラメータで与えることにしてみました。

(2)メインスクリプト

システム設定の変更状況を確認して、rsyncを用いてシステム設定ディレクトリ等のバックアップと、TARボールの世代変更を呼び出すスクリプト(上記)を作成します。

バックアップしておきたいフォルダには”/var/log”もありますが、”/var/log”等は起動のたびに中身が変わるので、変更状況を確認するフォルダから除外します🤔。

変更状況を確認するフォルダは

  • /etc、/boot、/root、/usr/local/etc、/var/yp、/var/cron

にしています。

ただ、/bootディレクトリの中の”entropy”ファイルは、シャットダウンのたびに更新されるので、/bootディレクトリの更新状況を確認する際、このファイルを確認対象から除外する必要があります🤔。

また、コーディング量を減らすためにrsyncの"--mkpath"オプションははrsync Ver 3.2.3以前では使えないオプションなので🤔、3.2.3以前の場合を考えて、とりあえずこのオプションは変数として定義しておくことにしました😅。

root@FreeBSD:# cd /Share/scripts/common    
root@FreeBSD:# vi system.setting-backup.sh    

 

#!/bin/sh
#
#------- Setting Parameter
#
HOSTNAME=`hostname -s`
HOSTVER=`uname -r`
HOSTARC=`uname`
HOSTTYPE=$HOSTARC-$HOSTVER
CHECK_LIST="/etc /boot /root /usr/local/etc /var/yp /var/cron"
TARGET_LIST="$CHECK_LIST"" /var/log /usr/local/samba/lib /usr/local/samba/private /us
r/local/samba3/lib /usr/local/samba3/private"

DIFF_OPTS="--exclude=entropy"
RSYNC_OPTS="--mkpath"
#
#------- Setting Tools
#
GREP=/usr/bin/grep
SORT=/usr/bin/sort
AWK=/usr/bin/awk
TAR=/usr/local/bin/gtar
RSYBC=/usr/local/bin/rsync
DIFF=/usr/bin/diff
#
#------- Setting Backup PATH
#
ARCHPATH1=/share/Backups
ARCHPATH2=System.setting
ARCHPATH=$ARCHPATH1/$ARCHPATH2
#
#------- Checking Backup Directory
#
if [ ! -d $ARCHPATH1 ]; then
        mkdir $ARCHPATH1
fi
cd $ARCHPATH1
#
if [ ! -d $ARCHPATH2 ]; then
        mkdir $ARCHPATH2
fi
cd $ARCHPATH2
#
if [ ! -d $HOSTNAME ]; then
        mkdir $HOSTNAME
fi
cd $HOSTNAME
#
if [ ! -d $HOSTTYPE ]; then
        mkdir $HOSTTYPE
fi
cd $HOSTTYPE
#
#-------- Checking Update Status
#
UPDATE_FLAG=0
STATUS=0
#
for TARGET in $CHECK_LIST
        do
           if [ -d $TARGET ]; then
#
                $DIFF -q $DIFF_OPTS \
                        $TARGET $ARCHPATH/$HOSTNAME/$HOSTTYPE/$TARGET \
                        >> /dev/null
                STATUS=$?
                if [ $STATUS -gt $UPDATE_FLAG ]; then
                        UPDATE_FLAG="$STATUS"
                fi
            fi
        done
#
#--------
#
if [ $UPDATE_FLAG -gt 0 ]; then
        cd /$ARCHPATH/$HOSTNAME/
                if [ -f $HOSTTYPE.gtar.gz ]; then
                        //share/scripts/common/rotate-file.sh \
                                        $HOSTTYPE.gtar.gz 10
                fi
        for TARGET in $TARGET_LIST
            do
                if [ -d $TARGET ]; then
                        $RSYBC -ah $RSYNC_OPTS

--delete \
                                $TARGET/ \
                                /$ARCHPATH/$HOSTNAME/$HOSTTYPE/$TARGET/
                fi
            done
#
        cd /$ARCHPATH/$HOSTNAME/$HOSTTYPE/
        $TAR -czf ../$HOSTTYPE.gtar.gz .
#
fi









;更新状況を確認すべきディレクトリ一覧を$CHECK_LIST変数に設定。

;システム設定のバックアップ対象フォルダを設定。

;$CHECK_LIST変数に設定したフォルダの中で、起動のたびに更新されるファイルを除外リストとして設定。
;"--mkpath"はrsync Ver
3.2.3以前では使えないオプションなので、3.2.3以前の場合を考えて、とりあえず変数として定義
  

;スクリプト中で使うコマンド(プログラム)の絶対パスを設定。








;システム設定バックアップ用ファイルシステムを変数に設定。
;システム設定バックアップ用フォルダ名を変数に設定





























;$CHECK_LISTに設定した更新状況を確認すべきディレクトリを順に確認。


;”diff”でシステム設定とシステム設定バックアップに差があるか確認。

;”diff”の戻り値を変数に代入して保持。
;”diff”の戻り値がUpdate判定フラグよりも多きれば、判定フラグをdiffの戻り値に設定。





;確認ディレクトリストの何れかに差がある場合if/fiの間の処理を実行。
;システム設定バックアップ用フォルダに移動。

;TARボールのファイル名末尾の数字を1づつ増やす。




;システムの各設定ディレクトリをバックアップ先に"rsync"でコピー。






;複製した設定ディレクトリ群に移動。
;複製した設定ディレクトリ群のTARボールを作成。

 

 

2. サーバー設定

訂正
  • 下記、スクリプトでは、サービスの起動順序の関係から、正常に機能しません。
  • 修正スクリプトは下記にて公開しております。

  • 加筆:2025/12/30

確認は、サーバーの起動時に行うことにします。

/usr/local/etc/rc.dにサーバー毎にシステム設定のバックアップを行うスクリプトを配置することで、システムの起動時に、”設定変更確認”&”システム設定のバックアップ”を行います。

root@FreeBSD:# cd /usr/local/etc/rc.d    
root@FreeBSD:# touch 99.system.setting-backup.sh    
root@FreeBSD:# chmod +x  99.system.setting-backup.sh    
root@FreeBSD:# vi 99.system.setting-backup.sh    

 

#!/bin/sh
/
share/scripts/common/system.setting-backup.sh



 

 

 

ブログランキング・にほんブログ村へにほんブログ村 IT技術ブログへ

出典・引用・備考

*1:この投稿の内容は、特定の機種並びに特定の環境での確認結果になります。
同等機種や異なる環境での動作他を保証するものではありませんので、ご留意いただけます様お願いいたします。

*2:

*3:

*4:i - 1