承前文:【自動備份 @ Linux -- Part I】

四、執行 ssh-agent 讓機器自動存取

ssh-agent 程式扮演的是守門員的角色,在需要的時侯,以安全的方式提供存取所需的安全金鑰。ssh-agent 啟動後將於背景執行,供其它 OpenSSH 應用程式 - 像是 ssh 與 scp 程式使用。這樣的作法可令 ssh 程式要求一個已經加密後的金鑰,而無須每次皆向使用者要求提供私密金鑰的安全 passphrase。

ssh-agent 執行時將產生以下輸出:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Listing 7. ssh-agent in action

   [offsite]$ ssh-agent
   SSH_AUTH_SOCK=/tmp/ssh-XX1O24LS/agent.14179; export SSH_AUTH_SOCK;
   SSH_AGENT_PID=14180; export SSH_AGENT_PID;
   echo Agent pid 14180;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

我們可以利用 eval 命令,指定 shell 執行 ssh-agent 所顯示的輸出指令:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 [offsite]$ eval `ssh-agent`
Agent pid 14198
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

eval 會要求 shell 執行由 ssh-agent 程式所產生的命令,請務必注意這裡使用的是反引號字元 (`),而不是單引號。執行 eval `ssh-agent`  會回傳代理程式的程序辯識碼。在執行過程的背後,SSH_AUTH_SOCK 與SSH_AGENT_PID 這兩個 shell 變數將 export 出來為可用狀態,你可以執行下面指令查看它們的值:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 [offsite]$ echo $SSH_AUTH_SOCK
/tmp/ssh-XX7bhIwq/agent.14197
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

(註:反引號字元 ` 指的是與鍵盤上的「 ~ 」同屬一個鍵的那個符號。)

$SSH_AUTH_SOCK ( SSH Authentication Socket 的縮寫 ) 指的是本地端 socket 的位置,這是應用程式用來與 ssh-agent 交談所用。為確保 SSH_AUTH_SOCK 與 SSH_AGENT_PID 變數要使用時皆已註冊過,請將 eval `ssh-agent` 這段語法加在你的 ~/.bash_profile 裡。

ssh-agent 於背景執行後,欲查看請使用 top 與 ps 命令。

到此,我們已經準備好透過 ssh-agent 分享 passphrase 了。接下來就是使用 ssh-add 這個程式,將我們的 passphrase 加入 (傳送) 給執行中的 ssh-agent 程式。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Listing 8. ssh-add for hassle-free login

   [offsite]$ ssh-add
   Enter passphrase for /home/accountname/.ssh/id_dsa: (enter passphrase)
   Identity added: /home/accountname/.ssh/id_dsa
   (/home/accountname/.ssh/id_dsa)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

如今當我們存取 server1,不會再被提示要求 passphrase 了:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 [offsite]$ ssh accountname@server1.com
[server1]$ exit
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

若你有所懷疑,可以試試砍掉 ssh-agent 的程序,再連接一次 server1,這麼一來你就會發現 server1 會向你要私密金鑰的 passphrase 了:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 [offsite]$ kill -9 $SSH_AGENT_PID
[offsite]$ ssh accountname@server1.com
Enter passphrase for key '/home/accountname/.ssh/id_dsa':
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

五、keychain 可以簡化金鑰的存取

至此我們已經學到數個 OpenSSH 程式 ( ssh, scp, ssh-agent 以及 ssh-add ),並新建/安裝完私密與公開金鑰,啟動安全、自動的登入程序了。你會發現在這有很多的步驟都只需要作過一次就可以,像是建立金鑰安裝它們、讓 ssh-agent 能透過 .bash_profile 裡的設定執行。

較不完美的就是 ssh-add 必須在我們每次簽入 offsite 的機器就執行一次,且 ssh-agent 無法立即與我們自動化備份所要用到的 cron 排程程序相容。 cron 程序無法與 ssh-agent 溝通的原因在於 cron job 乃以 cron 的子程序執行,但它不繼承 $SSH_AUTH_SOCK 這個 shell 變數。

幸好還有一個解決方案可以解決這裡 ssh-agent 與 ssh-add 的關連性問題,還能讓我們得以透過 cron 將所有必須的安全性備份的程序全部自動化。在 2001 年所推出的 OpenSSH key management,Daniel Robbins 將此 shell script 稱之為 keychain,此乃 ssh-add 與 ssh-agent 的前端程式,能簡化整個無須密碼介入的程序。keychain 經過時間的淬練,現由 Aron Griffis 進行維護,截至 2004 年 6 月 17 日,已釋出至 2.3.2-1 版。

keychain 看起來是一套有點大型的 shell script,不過一個好的 script 本來就應該含括很多的錯誤檢查、豐富的說明文件,以及完整的跨平台程式碼。

(註:你可以到【keychain】這個網站下載它。)

當你下載並安裝完 keychain 後,你會發現它非常容易上手。只要輕鬆登入每台機器,將下列兩行加進它們的 .bash_profile 裡:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 keychain id_dsa
. ~/.keychain/$HOSTNAME-sh
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

第一次登入回每一台機器時,keychain 都會向你要求 passphrase,不過它不會在接下來的每一次登入都跟你要 passphrase - 除非那台機器重新開機。更棒的是:cron 現在已經能夠使用 OpenSSH 的指令,讓你在不需要使用 passphrase 與機器互動的情況下,進行安全的遠端存取了。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Listing 9. Initializing keychain on each machine

   KeyChain 2.3.2; http://www.gentoo.org/projects/keychain
   Copyright 2002-2004 Gentoo Technologies, Inc.; Distributed under the
   GPL

   * Initializing /home/accountname/.keychain/localhost.localdomain-sh
   file...
   * Initializing /home/accountname/.keychain/localhost.localdomain-csh
   file...
   * Starting ssh-agent
   * Adding 1 key(s)...
   Enter passphrase for /home/accountname/.ssh/id_dsa: (enter passphrase)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

六、將備份程序寫成 script

接下來的工作就是建立一些 shell script 了,用 script 來為你完成必要的備份作業。我們的目標是要完成 Server1 與 2 完整的資料庫備份。在本範例中,每台伺服器皆執行 MySQL 資料庫伺服器,而我們也將使用 mysqldump 命令列工具,將一些資料庫表單匯至 SQL 輸入檔。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Listing 10. The dbbackup.sh shell script for server 1

   #!/bin/sh

   # change into the backup_agent directory where data files are stored.
   cd /home/backup_agent

   # use mysqldump utility to export the sites database tables
   mysqldump -u sitedb -pG0oDP@sswrd --add-drop-table sitedb --tables
   tbl_ccode tbl_machine tbl_session tbl_stats > userdb.sql

   # compress and archive
   tar czf userdb.tgz userdb.sql
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

在 server2 我們也置入類似的 script 備份站台資料庫裡的那些表單。每一個 script 皆須設定為可執行:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 [server1]:$ chmod +x dbbackup.sh
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

完成後 server1 與 2 上的 dbbackup.sh 檔後,回到 offsite date server,我們將在那裡建立呼叫遠端 dbbackup.sh script 的 shell script,以便開始進行壓縮檔資料檔 (.tgz) 的傳輸。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Listing 11. backup_remote_servers.sh shell script for use on the offsite data server

   #!/bin/sh

   # use ssh to remotely execute the dbbackup.sh script on server 1
   /usr/bin/ssh backup_agent@server1.com "/home/backup_agent/dbbackup.sh"

   # use scp to securely copy the newly archived userdb.tgz file
   # from server 1.  Note the use of the date command to timestamp
   # the file on the offsite data server.
   /usr/bin/scp backup_agent@server1.com:/home/backup_agent/userdb.tgz
   /home/backups/userdb-$(date +%Y%m%d-%H%M%S).tgz

   # execute dbbackup.sh on server 2
   /usr/bin/ssh backup_agent@server2.com "/home/backup_agent/dbbackup.sh"

   # use scp to transfer transdb.tgz to offsite server.
   /usr/bin/scp backup_agent@server2.com:/home/backup_agent/transdb.tgz
   /home/backups/transdb-$(date +%Y%m%d-%H%M%S).tgz
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

backup_remote_servers.sh 使用 ssh 命令執行遠端伺服器裡的 script。由於我們建立了無須密碼的存取方式,ssh 便能夠從 offsite server 上,要求 server1 與 2 執行命令。整個身份認可的程序現已完全自動化,感謝有 keychain !

七、排程

最後的工作就是呼叫排程工作執行 offsite 資料儲存伺服器上的 backup_remote_servers.sh shell script 了。我們會加兩項到 cron 排程伺服器,要求它在每天 3:34 am 以及 8:34 pm 的時侯執行備份 script。於 offsite 伺服器上呼叫 crontab 程式編輯選項:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 [offsite]:$ crontab -e
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

crontab 會呼叫預設的編輯程式 - 這在 VISUAL 或 EDITOR 的環境變數裡已指定。接下來加入這兩行後即可關閉檔案。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Listing 12. Crontab entries on the offsite server

   34 3 * * * /home/backups/remote_db_backup.sh
   34 20 * * * /home/backups/remote_db_backup.sh
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

crontab 的設定行列可分為兩個段落:時間區段,接著是命令區段。時間區段的各個欄位皆有其意義,用以指定何時執行命令區段裡的指令:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Listing 13. Crontab format

          +---- 分鐘
          | +----- 時
          | | +------ 日
          | | | +------ 月
          | | | | +---- 週
          | | | | | +-- 執行之命令
          | | | | | |
         34 3 * * * /home/backups/remote_db_backup.sh
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


八、確認備份的動作

你應該養成定期檢查備份的習慣,以確保程序確切運作。自動化的程序可省去日常單調沉悶的一些工作,但也別因此偷懶 !

也可以考慮加一條 cron job 提醒你自已至少一個月檢查一次備份的資料。除此之外,也建議你每隔一段時間就變更你的安全性金鑰,同樣地,你也可以設定 cron job 提醒你作這件事。

九、其它的安全性注意事項

為了更安全,建議你在每台機器上安裝入侵偵測系統 Intrusion Detection System (IDS),例如 Snort。它可以提醒你是否機器發生被入侵的情況。


原文參考:【Automate backups on
如有版權問題,請來信 (nicaliu at gmail dot com) 告知,謝謝。

arrow
arrow
    全站熱搜

    nicaliu 發表在 痞客邦 留言(3) 人氣()