■さくらVPSのバックアップについて スクリプトとデータの2種類を対象とする。 ■システムをバックアップすると仮定すると、 データ量が多いかと言うとそうでも無い。 # df | awk '{sum+=$3};END{print sum/1024/1024"GB"}' 2.69375GB ■システムをバックアップしない理由は以下。 システムはカスタムインストールを使う 定期的なバックアップ先の確保が困難 確実なリストア方法を作るのが面倒 ■githubを使ってスクリプトをバックアップするための準備。 # USER=labunix; \ cd /home/${USER}; \ mkdir myscripts;chown $USER:$USER myscripts ■前回のINPUTパケットの制限スクリプトを移動して、 「/etc/rc.local」も変更する。 # USER=labunix; \ mv /root/myvpsinput.sh /home/${USER}/myscripts/; \ chown -R ${USER}:${USER} /home/${USER}/myscripts/ # grep -v "^#\|^\$" /etc/rc.local MYIPTABLES=/home/labunix/myscripts/myvpsinput.sh;test -x "${MYIPTABLES}" && /bin/bash "${MYIPTABLES}" exit 0 # /etc/rc.local | head -3 [ ok ] Stopping authentication failure monitor: fail2ban. [ ok ] Starting authentication failure monitor: fail2ban. [ ok ] Restarting authentication failure monitor: fail2ban. ■初回のみ、リポジトリを作成して、さくらVPSの仮想マシンでは無い、 自身の所有するサーバにcloneする。 $ git clone git@github.com:labunix/sakuravps.git ■リポジトリにscpでコピーしてgithubにアップロード 実行時には3回のログインが必要 $ VPSIP=XXX.XXX.XXX.XXX; \ VPSPORT=XX022; \ USER=labunix; \ LOCALGIT=/opt/git_work/sakuravps/; \ GITREPO=git@github.com:labunix/sakuravps.git; \ BACKUPSERIAL=`env LANG=C date '+%Y%m%d_%H%M%S'` cd $LOCALGIT; \ git pull $GITREPO; \ rsync -avz --delete -e "ssh -p ${VPSPORT}" ${USER}@${VPSIP}:~/myscripts ${LOCALGIT} git add .; \ git commit -a -m "${BACKUPSERIAL} backup"; \ git push $GITREPO ■sshpassやexpectで自動化出来るが、 スクリプトの更新はログインしている時しかしないので、 上記のスクリプトを手動で実行するものとする。 # apt-cache search sshpass sshpass - Non-interactive ssh password authentication # apt-cache search ^expect\$ expect - 対話型アプリケーションの自動化 ■cryptsetupでデータの暗号化 データを置く気がそもそも無い。 どうしても置くとき用に暗号化パーティションを用意する。 cryptsetup導入時にkernelの変更を伴うので再起動を行う。 # apt-get install -y cryptsetup # modinfo dm_mod filename: /lib/modules/3.2.0-4-amd64/kernel/drivers/md/dm-mod.ko license: GPL author: Joe Thornber <dm-devel@redhat.com> description: device-mapper driver alias: devname:mapper/control alias: char-major-10-236 depends: intree: Y vermagic: 3.2.0-4-amd64 SMP mod_unload modversions parm: major:The major number of the device mapper (uint) # modinfo dm_crypt filename: /lib/modules/3.2.0-4-amd64/kernel/drivers/md/dm-crypt.ko license: GPL description: device-mapper target for transparent encryption / decryption author: Christophe Saout <christophe@saout.de> depends: dm-mod intree: Y vermagic: 3.2.0-4-amd64 SMP mod_unload modversions # shutdown -r now && exit $ exit ■再起動後はモジュールが読み込まれているはず。 $ lsmod | grep dm dm_crypt 22586 0 dm_mod 63645 1 dm_crypt ■「/home」パーティションを分けた構成なので、イメージファイルを1GBで作成する。 「Type uppercase yes」の入力は大文字の「YES」とすること。 # mkdir -p /home/cryptsetup && cd /home/cryptsetup # dd if=/dev/zero of=luks.img bs=1024k count=1000 1000+0 レコード入力 1000+0 レコード出力 1048576000 バイト (1.0 GB) コピーされました、 1.63887 秒、 640 MB/秒 # cryptsetup --verbose -y luksFormat -c aes-cbc-essiv:sha256 --key-size 256 luks.img WARNING! ======== This will overwrite data on luks.img irrevocably. Are you sure? (Type uppercase yes): YES Enter LUKS passphrase: Verify passphrase: Command successful. # cryptsetup luksOpen `pwd`/luks.img luks Enter passphrase for /home/cryptsetup/luks.img: ■暗号化ファイルシステムなので、ジャーナリングは不要。 「ext2」でフォーマット。 # mkfs.ext2 /dev/mapper/luks mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 63872 inodes, 255488 blocks 12774 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=264241152 8 block groups 32768 blocks per group, 32768 fragments per group 7984 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Writing superblocks and filesystem accounting information: done ■ユーザデータ用にマウント # USER=labunix; \ DEST=/home/${USER}/mydata; \ test -b /dev/dm-0 || cryptsetup luksOpen /home/luks.img luks test -d "${DEST}" || mkdir ${DEST} && chown ${USER}:${USER} "${DEST}"; \ mount | grep luks >/dev/null || mount /dev/mapper/luks ${DEST} # mount | grep luks /dev/mapper/luks on /home/labunix/mydata type ext2 (rw,relatime,errors=continue,user_xattr,acl) ■アンマウント方法 # USER=labunix; \ DEST=/home/${USER}/mydata; \ umount $DEST; \ cryptsetup luksClose luks # mount | grep luks ■I/O性能も悪くない。 # hdparm -Tt /dev/vda1 /dev/vda1: Timing cached reads: 12530 MB in 1.97 seconds = 6353.11 MB/sec Timing buffered disk reads: 486 MB in 0.96 seconds = 508.80 MB/sec # hdparm -Tt /dev/dm-0 /dev/dm-0: Timing cached reads: 12882 MB in 1.97 seconds = 6534.49 MB/sec Timing buffered disk reads: 998 MB in 2.39 seconds = 417.17 MB/sec ■ヘッダはバックアップしておく # cryptsetup luksHeaderBackup luks.img --header-backup-file luks.header_`env LANG=C date '+%Y%m%d_%H%M%S'`; \ for list in luks.header_*;do openssl enc -e -aes-256-ofb -in "$list" -out /home/labunix/myscripts/${list}.enc && rm -f "$list" ;done enter aes-256-ofb encryption password: Verifying - enter aes-256-ofb encryption password: ■復号化のテスト # openssl enc -d -aes-256-ofb -in /home/labunix/myscripts/luks.header_20140828_222222.enc -out check.header; \ cryptsetup luksHeaderBackup luks.img --header-backup-file luks.header; \ diff -s check.header luks.header; \ rm check.header luks.header enter aes-256-ofb decryption password: ファイルcheck.headerとluks.headerは同一 ■上記を踏まえ、スクリプト化 sakuravps https://github.com/labunix/sakuravps ■GUI用にXRDP/vino(VNC)、gnome-session gnome-terminal、 テキストブラウザのw3m、tarの解凍用にbzip2を先に導入しておく。 firefoxの「libxul.so」が「xulrunner」経由でサウンド等のGUIアプリを呼ぶ。 キーボードUIはお好みで。 お試し期間は通信量が2Mの制限があって時間がかかる。コーヒータイム。 なお、kernelの変更があるので、再起動も忘れずに。 # apt-get install -y w3m bzip2 xrdp vino gnome-session gnome-terminal xulrunner* # apt-get install -y anthy uim uim-anthy uim-applet-gnome im-switch # shutdown -r now && exit ■暗号化パーティションにFirefoxを導入 # ./myscripts/luks_mount.sh Enter passphrase for /home/luks.img: /dev/mapper/luks on /home/labunix/mydata type ext2 (rw,relatime,errors=continue,user_xattr,acl) # cd mydata/; \ # URL="http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/latest/linux-x86_64/ja/"; \ w3m -dump_source "$URL" | \ sed s/">"/"&\n"/g | grep href=\"firefox | awk -F\" '{print $2}' | \ echo "${URL}`xargs`" | \ xargs wget;unset URL; \ # USER=labunix; \ chown $USER:$USER firefox*; \ exit $ cd mydata/; \ tar jxvf firefox-31.0.tar.bz2 ■依存関係は以下。 $ cat firefox/dependentlibs.list libnspr4.so libplc4.so libplds4.so libnssutil3.so libnss3.so libsmime3.so libssl3.so libmozsqlite3.so libmozalloc.so libxul.so ■ポート転送の設定 RDPポートは開けません。 $ mkdir .ssh $ cat .ssh/config Host XRDP HostName XXX.XXX.XXX.XXX User root GatewayPorts yes LocalForward 3389 127.0.0.1:3389 ■「ssh -X」でログイン時に「/var/log/auth.log」に出るエラーの対処 以下はメッセージの通り、X転送が出来ないことを示している。 「socket」ではなく「inet」を使う。 error: Failed to allocate internet-domain X11 display socket. # grep -B 1 ^Listen /etc/ssh/sshd_config AddressFamily inet ListenAddress 0.0.0.0 # /etc/init.d/ssh restart [ ok ] Restarting OpenBSD Secure Shell server: sshd. ■sshのログイン時に「-X」オプションを付与してX転送を許可する。 「gnome-terminal」が開く事を確認。 $ gnome-terminal & ■firefoxを起動 $ cd mydata/firefox/ && ./firefox & ■XRDPの外部からの接続を許可 ポート転送で許可した時だけ利用可能にするので、 iptablesはずっと開けたままとする。 # iptables -A INPUT -i eth0 -d 153.121.74.197 -p tcp -m tcp --dport 13389 -j ACCEPT ■xrdpが外部から接続出来るようにeth0のIP「XXX.XXX.XXX.XXX」に変更 # cd /etc/xrdp && \ wget -O - http://w.vmeta.jp/temp/km-0411.ini | tee km-0411.ini && \ ln -s km-0411.ini km-e0200411.ini && \ ln -s km-0411.ini km-e0010411.ini # grep -A 7 "^\[xrdp1\]" /etc/xrdp/xrdp.ini [xrdp1] name=sesman-Xvnc lib=libvnc.so username=ask password=ask ip=XXX.XXX.XXX.XXX port=-1 # grep ^ListenAddress /etc/xrdp/sesman.ini ListenAddress=XXX.XXX.XXX.XXX # /etc/init.d/xrdp restart # cat .ssh/config Host XRDP HostName 127.0.0.1 Port 8022 User labunix GatewayPorts yes LocalForward 13389 127.0.0.1:3389 ■「XRDP」にログインしてポート転送している間だけリモートデスクトップが使用出来る。 画面サイズは小さく、若干もっさり。 RDPクライアントはWheezyの「vinagre」を使用した。 「im-switch」で入力メソッドを切り替えて、日本語、英語入力を確認。 $ ssh XRDP labunix@127.0.0.1's password: ■XRDPで接続、firefoxの設定を行う 「履歴を一切記憶しない」など。 ■IPAフォントも入れておく。 # apt-get install -y ^fonts-ipafont* ■「myscripts/myvpsinput.sh」を編集して 自身のサーバからバックアップスクリプトを実行 $ ./myscripts/sakuravps_rsync.sh ■さすがにGUIだと結構リソースを使う。 若干swapを使うようになるのでGUIを常用するなら、 もっと上位の契約にするべき。 # df | awk '{sum+=$3};END{print sum/1024/1024"GB"}' 12.2589GB # ps axo pid,cmd,%cpu,%mem | awk '($NF>1)||($(NF-1)>0.0){print}' 2703 /usr/sbin/spamd --create-pr 0.0 3.0 2800 /usr/sbin/amavisd-new (mast 0.0 4.6 2801 spamd child 0.0 2.8 2802 spamd child 0.0 2.8 2803 /usr/sbin/snort -m 027 -D - 0.6 5.5 2823 /usr/sbin/amavisd-new (virg 0.0 4.6 2824 /usr/sbin/amavisd-new (virg 0.0 4.6 2846 /usr/sbin/clamd -c /etc/cla 0.2 13.7 3012 /usr/bin/freshclam -d --qui 0.1 0.1 5810 ssh XRDP 0.3 0.4 5816 sshd: labunix@pts/1 0.2 0.1 18006 Xvnc :11 -geometry 800x600 0.5 0.7 18139 /usr/lib/scim-1.0/scim-pane 0.1 0.6 18189 gnome-panel 0.1 1.3 19568 Xvnc :12 -geometry 800x600 0.7 0.7 19650 /usr/bin/metacity 0.1 0.8 19660 gnome-panel 0.1 1.4 20280 gnome-control-center --over 0.3 2.2 20852 /usr/sbin/xrdp 0.5 0.5 20911 Xvnc :13 -geometry 800x600 1.9 0.7 20959 /usr/lib/gnome-settings-dae 0.1 1.0 20990 /usr/bin/metacity 0.3 0.8 20999 gnome-panel 0.4 1.4 21391 nautilus /home/labunix 0.5 1.7 ■GUIに頼らなければ、まだリソースに余裕がある。 $ ps axo pid,cmd,%cpu,%mem | awk '($NF>1)||($(NF-1)>0.0){print}' 2709 /usr/sbin/spamd --create-pr 0.3 3.0 2771 /usr/sbin/snort -m 027 -D - 0.1 5.5 2811 /usr/sbin/amavisd-new (mast 0.3 4.7 2812 spamd child 0.0 2.9 2813 spamd child 0.0 2.9 2835 /usr/sbin/amavisd-new (virg 0.0 4.7 2836 /usr/sbin/amavisd-new (virg 0.0 4.7 2838 /usr/sbin/clamd -c /etc/cla 0.0 13.4 3007 /usr/bin/freshclam -d --qui 0.7 0.1 3271 /usr/bin/python /usr/bin/fa 0.1 0.4 3619 -bash 0.1 0.1 $ top -b -n 1 | head -5 top - 02:26:43 up 8 min, 1 user, load average: 0.00, 0.02, 0.03 Tasks: 92 total, 1 running, 91 sleeping, 0 stopped, 0 zombie %Cpu(s): 1.3 us, 0.4 sy, 0.0 ni, 97.4 id, 0.6 wa, 0.0 hi, 0.0 si, 0.4 st KiB Mem: 2061060 total, 857636 used, 1203424 free, 15068 buffers KiB Swap: 13671420 total, 0 used, 13671420 free, 218512 cached ■結局のところ、ログイン中で無いとバックアップはとれないので、 自身のサーバ側には以下の設定だけで良いことになる。 $ grep BACKUPMYDATA myscripts/sakuravps_rsync.sh BACKUPMYDATA=/home/${USER}/sakura_vpsbackup rsync -avz --delete --exclude "firefox/" -e "ssh -p ${VPSPORT}" ${USER}@${VPSIP}:~/mydata ${BACKUPMYDATA} ■暗号化された「luks.header」は自身のサーバのみ保存されるように変更した。 暗号化自体が不要になった気がするが、今回はスルーする。 ■ログイン、ログオフ時に忘れないように。 $ tail -n 1 .bash[r_][cl]* ==> .bash_logout <== echo "su Pass";su root -c '/home/labunix/myscripts/luks_unmount.sh' ==> .bashrc <== echo "su pass";su root -c '/home/labunix/myscripts/luks_mount.sh' ■ログオフ時のメッセージ luksのアンマウントのみ ログアウト su Pass パスワード: ■ログイン時のメッセージ ここまで色々聞かれると、 「自身のサーバからバックアップスクリプトの実行をしなきゃ」と思う。 su pass パスワード: enter aes-256-ofb encryption password: Verifying - enter aes-256-ofb encryption password: Enter passphrase for /home/luks.img: /dev/mapper/luks on /home/labunix/mydata type ext2 (rw,relatime,errors=continue,user_xattr,acl)