分类
省时省力—在 Linux 上进行自动备份‖
数据的备份。虽然原因可能
由于机器擅长于完成普通而
人们与生俱来的拖延倾向的
各不相同,但是,最常见的一个
重复的任务,因此,自动化备份
关键所在。
解释是,执行例行备份确实烦琐。
的过程是降低工作内在的枯燥性和
| 如果您使用 Linux,那 。本文中的方案,可以让您 简单的到更高级而且安全的 | 么您就已经可以使用那些创建定 使用几乎每个 Linux 发行版本 网络备份。 | 制备份解决方案的极其强大的工具 都附带的开放源代牍ぞ呃粗葱写?br> |
| 简单备份 |
| 本文按照一步一步的方 的。 | 法来进行讲述,只要您遵循那些 | 基本的步骤,此方法会是非常直观 |
| 在研究更高级的分布式备份解决方案 让我们来分析一个名为 arc 的方便的脚 份快照。 | 之前,让我们首先来看一个简单而强大的存档机制。 本,它可以让我们在 Linux shell 提示符中创建备 |
| 清单 1. arc shell 脚本 |
| #!/bin/sh |
| tar czvf $1.$(date +%Y%m%d%-H | %M%S).tgz $1 |
| exit $? |
| arc 脚本接收一个单独 日期嵌入到生成的存档文件 以调用 arc 脚本,将 beos beoserver.20040321-01484 | 的文件或目录名作为参数,创建 的名字之中。例如,如果您有一 erver 目录名传递给它以创建一 4.tgz | 一个压缩的存档文件,同时将当前 个名为 beoserver 的目录,您可 个压缩的存档文件,如: |
| 使用 date 命令是为了嵌入一个日期 月、日、小时、分、秒 —— 虽然秒域的 date)来了解其他选项。另外,在清单 1 使得 tar 显示出它正在存档的文件。如 | 和时间戳以帮助您组织存档文件。日期的格式是年、 使用有一些多余。查看 data 命令的手册( man 中,我们向 tar 传递了 -v(verbose)选项。这就 果您喜欢静默地进行备份,那么删除这个 -v 选项。 |
| 清单 2. 存档 beoserver 目录 |
| $ ls |
| arc beoserver |
| $ ./arc beoserver |
| beoserver/ |
| beoserver/bookl.dat |
| beoserver/beoserver_ab_off |
| beoserver/beoserver_ab_on |
| $ ls |
| arc beoserver b | eoserver.20040321-014844.tgz |
| 高级备份 |
| 这个简单备份是实用的 将数据备份到多个媒体上, 独的存储媒体或单独的位置 | ;不过,它仍然包含一个人工备 并备份到分开的不同地理位置。 。 | 份的过程。行业最佳经验通常建议 中心思想是避免依赖于任何一个单 |
| 在下一个例子中我们将 ,它展示了对两台远程服务 | 应对这一挑战,我们将分析一个 器和一台离线存储服务器的系统 | 如图 1 所示的假想的分布式网络 管理。 |
| |
![]() |
| 服务器 #1 和 #2 上的备份文件将安 过程将在没有人工干涉的情况下定期进行 具套件(OpenSSH)的一部分),以及磁 部计划是,使用 cron 进行调度,使用 s OpenSSH 安全 shell(ssh)加密进行远 文件传输。要获得另外的资料请务必查看 | 全地传输到离线存储服务器上,而且整个分布式备份 。我们将使用一组标准的工具(开放安全 shell 工 带存档器(tar)和 cron 任务调度服务。我们的全 hell 程序和 tar 应用程序完成备份过程,使用 程访问、认证、安全 shell 拷贝(scp)以自动完成 每个工具的手册。 |
| 使用公钥/私钥进行安全的远程访问 |
| 在数字安全的上下文中,密钥(key 断。公钥私钥模式的有趣之处在于,使用 可以自由地发布一个公钥,这样别人就可 改变了数字安全的原因之一是,发送者和 贡献,公钥/私钥加密使用电子商务和其 公钥和私钥来创建一个非常安全的分布式 | )指的是用来加密或解密其他数据片断的一个数据片 公钥加密的数据,只有用相应的私钥才可以解密。您 以对发送给您的消息进行加密。公钥/私钥模式彻底 接收者不必再共享一个通用的密码。除了其他方面的 他安全传输成为可能。在本文中,我们将创建并使用 备份解决方案。 |
| 要进行备份过程的每台 端口可以通过任何内部防火 全 shell。 | 机器都必须运行 OpenSSH 安全 墙被访问。如果您访问远程的服 | shell 服务(sshd),同时让 22 务器,那么很有可能您正在使用安 |
| 我们的目标将是,不需 是设置无密码的访问:不要 会占用您大约一个小时的时 它是公认非常安全的。 | 要人工提供密码就可以安全地访 这样做。这样做不安全。不用那 间,建立起一个与使用“无密码 | 问机器。一些人认为最简单的办法 样,本文中我们将使用的方法可能 ”帐号同样方便的系统 —— 不过 |
| 让我们首先确保 OpenSSH 已经安装 的 OpenSSH 是 2004 年 2 月 24 日发布 发布版本,至少所用的版本应该要比版本 特定旧版本的缺陷的细节(请参阅本文后 是非常稳定的,而且已经证明不存在其他 | ,接下来查看它的版本号。完成本文时,最新的发行 的版本 3.8。您应该考虑使用一个较新的而且稳定的 2.x 新7梦?OpenSSH Security 网页以获得关于 面的 参考资料 中的链接)。到目前为止,OpenSSH SSH 工具所报告的很多缺陷。 |
| 在 shell 提示符中,输入 ssh 并给出重要的 V 选项来检查版本号: |
| $ ssh -V |
| OpenSSH_3.5p1, SSH p | rotocols 1.5/2.0, OpenSSL 0x | 0090701f |
| 如果 ssh 返回的版本 的软件都使用最新的稳定版 | 号大于 2.x,则机器处于相对良 本,这对于安全相关的软件来说 | 好的状态。无论如何,建议您所有 尤其重要。 |
| 我们的第一个步骤是,使用将会有特 机器(见图 1)。 | 权访问服务器 1 和 2 的帐号登录到离线存储服务器 |
| $ ssh accountname@somedomain.com |
| 登录到离线存储服务器 /密钥对。 -t 选项是必须 Digital Signature Algori ssh-keygen 手册以获得更 | 以后,使用 ssh-keygen 程序并 的,用来指定我们要生成的密钥 thm,DSA),它让我们可以使用 多细节。 | 给出 -t dsa 选项来创建一个公钥 类型。我们将使用数字签名算法( 更新的 SSH2 协议。参阅 |
| 在 ssh-keygen 执行的过程中,在询 密钥存储的位置。当询问在何处存储密钥 一个名为 .ssh 的隐藏目录(如果原来不 件。 | 问您口令(passphrase)之前,将提示您输入 ssh 时只需要按下回车键,然后 ssh-keygen 程序将创建 存在),以及两个文件,一个公钥文件和一个私钥文 |
| ssh-keygen 的一个有 车键。如果您没有给出口令 好主意。当要求输入口令时 一个简单的密码字符串。 | 趣特性是,当提示输入一个口令 ,那么 ssh-keygen 擅挥?br>,确保输入一个足够长的字符消 | 时,它让您可以只是简单地按下回 加密的密钥!如您所想,这不是个 息,最好包含混合字符而不仅仅是 |
| 清单 3. 永远选择好的口令 |
| [offsite]:$ ssh-keygen -t dsa |
| Generating public | /private dsa key pair. |
| Enter file in which to save t | he key (/home/accountname/.ssh/id_dsa): |
| Enter passphrase | (empty for no passphrase): ( | enter passphrase) |
| Enter same passphrase again: | (enter passphrase) |
| Your identification has been | saved in /home/accountname/.ssh/id_dsa. |
| Your public key h | as been saved in /home/accou | ntname/.ssh/id_dsa.pub. |
| The key fingerprint is: |
| 7e:5e:b2:f2:d4:54 | :58:6a:fa:6b:52:9c:da:a8:53: | 1b accountname@offsite |
| 由于 ssh-keygen 生成的 .ssh 目录 一个 -a 选项来查看新创建的目录: | 是一个隐藏的“dot”目录,所以要给 ls 命令传入 |
| [offsite]$ ls -a |
| . .. .bash_logout .bash_profile | .bashrc .emacs .gtkrc .ssh |
| 进入隐藏的 .ssh 目录并列出其内容: |
| [offsite]$ cd .ssh |
| [offsite]$ ls -lrt |
| id_dsa id_dsa.pub |
| 现在,在隐藏的 .ssh id_dsa.pub)。您可以使用 令来分析每个密钥文件的内 | 目录中,我们已经拥有了一个私 vi 或 emacs 等文本编辑工具 容。您将看到由混合字符构成的 | 钥(id_dsa)和一个公钥( 或者简单地使用 less 或 cat 命 内容已经经过了 base64 编码。 |
| 然后,我们需要将公钥 用安全拷贝程序来将公钥传 | 拷贝并安装到服务器 1 和 2 上 送到每一台远程机器上。 | 。不要使用 ftp。更合理的是,使 |
| 清单 4. 将公钥安装到远程服务器上 |
| [offsite]$ scp .s | sh/id_dsa.pub accountname@se | rver1.com:offsite.pub |
| accountname@serve | r1.com's password: (enter pa | ssword, not new |
| passphrase!) |
| id_dsa.pub 100% | | **************************** | *| 614 00:00 |
| [offsite]$ scp .ssh/id_dsa.pu | b accountname@server2.com:offsite.pub |
| accountname@serve | r2.com's password: (enter pa | ssword, not new |
| passphrase!) |
| id_dsa.pub 100% | | **************************** | *| 614 00:00 |
| 在安装完新的公钥后,我们就可以使 。现在,登录到每台机器,并将 offsite 的文件中,这个文件存储在每台远程机器 简单地使用 cat 命令来将 offsite.pub | 用创建私钥和公钥时指定的口令来登录到每一台机器 .pub 文件的内容附加到一个名为 authorized_keys 的 .ssh 目录下。我们可以使用一个文本编辑器或者 文件的内容附加到 authorized_keys 文件: |
| 清单 5. 将 offsite.pub 添加到已授权密钥列表 |
| [offsite]$ ssh ac | countname@server1.com |
| accountname@server1.com's pas | sword: (enter password, not new |
| passphrase!) |
| [server1]$ cat offsite.pub >> ./ssh/authorized_keys |
| 接下来的步骤是考虑一 所有者有读、写和执行的权 。最后,将先前上传的 off 访问权限很重要,因为 Ope | 些额外的安全性。首先,我们修 限。然后,我们确保 authorize site.pub 密钥文件删除,因为 nSSH 服务器可能会拒绝使用具 | 改 .ssh 的访问权限,以使得只有 d_keys 文件只能由所有者来访问 再也不需要它了。确保设置适当的 有不安全访问权限的密钥。 |
| 清单 6. 使用 chmod 修改权限 |
| [server1]$ chmod 700 .ssh |
| [server1]$ chmod | 600 ./ssh/authorized_keys |
| [server1]$ rm offsite.pub |
| [server1]$ exit |
| 在服务器 2 上完成同样的步骤后, 型的访问。在离线服务器上您可以输入下 | 我们就可以返回到离线存储机器上来测试新的口令类 面的内容: |
| [offsite]$ ssh -v ac | countname@server1.com |
| 在检验您的帐号现在可以使用新的口 -v 或 verbose 标记选项来显示调试信息 过程是如何工作的之外,还可以显示出您 中您可能并不需要指定 -v 标记;但是在 | 令而不是原来的密码来访问远程的服务器时,使用 。调试输出除了能让您在一个高的层面上观察到认证 可以以其他方式无法得到的重要信息。在以后的连接 测试连接时它相当有用。 |
| 使用 ssh-agent 自动化机器访问 |
| ssh-agent 程序如同一个看门人,它 启动后,它就会在后台运行,并且可以由 。这就使得 ssh 程序可以请求一个已经 安全口令。 | 根据需要安全地提供对安全密钥的访问。ssh-agent ssh 和 scp 程序等其他 OpenSSH 应用程序所使用 解密了的密钥,而不是在每次需要时向您询问私钥的 |
| 让我们来仔细研究一下 | ssh -agent。ssh-agent 运行 | 时它会输出 shell 命令: |
| 清单 7. ssh-agent 应用 |
| [offsite]$ ssh-agent |
| SSH_AUTH_SOCK=/tmp/ssh-XX1O24 | LS/agent.14179; export SSH_AUTH_SOCK; |
| SSH_AGENT_PID=14180; export S | SH_AGENT_PID; |
| echo Agent pid 14180; |
| 我们可以使用 shell 的 eval 命令 | 来让 shell 执行 ssh-agent 显示的输出命令: |
| [offsite]$ eval `ssh-agent` |
| Agent pid 14198 |
| eval 命令告诉 shell 去评价(执行 号(`)而不是单引号!执行后,eval `s SSH_AUTH_SOCK 和 SSH_AGENT_PID shell shell 控制台中来查看它们的值: | )ssh-agent 程序生成的命令。确保您指定的是反引 sh-agent` 语句将返回代理的进程标识符。在幕后, 变量已经被导出而可以使用。您可以将它们显示在 |
| [offsite]$ echo $SSH_AUTH_SOCK |
| /tmp/ssh-XX7bhIwq/agent.14197 |
| $SSH_AUTH_SOCK (SSH Authenticat 用程序可以通过它来与 ssh-agent 通信 ~/.bash_profile 文件以确保 SSH_AUTH_ | ion Socket 的缩写)是一个本地套接字的位置,应 。将 eval `ssh-agent` 语句加入到您的 SOCK 和 SSH_AGENT_PID 始终被注册。 |
| ssh-agent 现在就已经 | 成为一个后台进程,可以用 top | 和 ps 命令查看得到。 |
| 现在我们就已经可以使 ssh-add 的程序,这个程序 | 用 ssh-agent 共享我们的口令 将我们的口令添加(发送)到运 | 。为此,我们必须使用一个名为 行着的 ssh-agent 程序。 |
| 清单 8. 用于免口令登录的 ssh-add |
| [offsite]$ ssh-add |
| Enter passphrase for /home/ac | countname/.ssh/id_dsa: (enter passphrase) |
| Identity added: /home/account | name/.ssh/id_dsa |
| (/home/accountname/.ssh/id_dsa) |
| 现在,当我们访问 server1 时,不会再被提示输入口令: |
| [offsite]$ ssh accountname@server1.com |
| [server1]$ exit |
| 如果您还不相信,那么尝试去掉(ki 这一次,您将注意到,server1 将会询问 | ll -9)ssh-agent 进程,然后重新连接 server1。 存储在 .ssh 目录下 id_dsa 中的私钥的口令: |
| [offsite]$ kill -9 $SSH_AGENT_PID |
| [offsite]$ ssh accountname@server1.com |
| Enter passphrase for key '/home/ | accountname/.ssh/id_dsa': |
| 使用 keychain 简化密钥访问 |
| 到现在为止,我们已经 ,而且我们已经创建并安装 识到,大部分设置工作只需 执行 ssh-agent 的过程在 | 了解了几个 OpenSSH 程序(ssh 了私钥和公钥来启用一个安全而 要进行一次。例如,创建密钥、 每台机器只需要进行一次。那真 | 、scp、ssh-agent 和 ssh-add) 且自动的登录过程。您可能已经意 安装密钥、通过 .bash_profile 是好消息。 |
| 不太理想的消息是,我们每次登录到 ssh-agent 与我们将要用来自动化备份工 与 ssh-agent 通信的原因是,cron 作业 $SSH_AUTH_SOCK shell 变量。 | 离线的机器上时,都必须调用 ssh-add,而且, 作的 cron 调度进程并不直接兼容。cron 进程不能 是作为 cron 的子进程来执行,这样它们就不会继承 |
| 幸运的是,有一个解决方案不但可以 们使用 cron 来自动进行各种需要对其他 表的三篇 developerWorks 系列文章中, 得链接),Daniel Robbins 介绍了一个 ssh-agent 的一个前端,简化了整个无密 历了很多改进,现在由 Aron Griffis 维 月 17 日。 | 消除 ssh-agent 和 ssh-add 的局限,而且可以让我 机器进行安全地无密码访问的过程。在他 2001 年发 即 OpenSSH key management(参阅 参考资料 以获 名为 keychain 的 shell 脚本,它是 ssh-add 和 码的过程。随着时间的过去,keychain 脚本已经经 护,其最新的 2.3.2-1 发布版本公布于 2004 年 6 |
| keychain shell 脚本 错误检测、丰富的文档以及 方便地下载得到(参阅 参 | 太长以致于无法在本文中列出, 非常多的跨平台代码。不过,ke 考资料 以获得链接)。 | 因为精心编写的脚本中包括了很多 ychain 可以自项目的 Web 站点上 |
| 下载并安装了 keychain 后,使用它 加到每个 .bash_profile 文件: | 就很简单了。只需要登录到每台机器并将下面两行添 |
| keychain id_dsa |
| . ~/.keychain/$HOSTNAME-sh |
| 在您第一次重新登录到 启动,否则,以后再登录时 务现在可以使用 OpenSSH 安全和更容易的使用,现在 | 每台机器时,keychain 将向您 ,keychain 将不会再要求您重 命令来安全地访问远程的机器, 我们已经兼得。 | 询问口令。不过,除非机器被重新 新输入口令。最好的是,cron 任 而不需要交互地使用口令。更好的 |
| 清单 9. 在每台机器上初始化 |
| KeyChain 2.3.2; http://www.ge | ntoo.org/projects/keychain |
| Copyright 2002-2004 Gentoo Te | chnologies, Inc.; Distributed under the |
| GPL |
| * Initializing /h | ome/accountname/.keychain/lo | calhost.localdomain-sh |
| file... |
| * Initializing /home/accountn | ame/.keychain/localhost.localdomain-csh |
| file... |
| * Starting ssh-agent |
| * Adding 1 key(s)... |
| Enter passphrase for /home/ac | countname/.ssh/id_dsa: (enter passphrase) |
| 脚本化备份过程 |
| 我们的下一个任务是创 2 的完全数据库备份。在我 用 mysqldump 命令行工具 | 建执行必要的备份过程的 shell 们的例子中,每个服务器都运行 来将一些数据库表导出到一个 S | 脚本。目标是执行服务器 1 和 着 MySQL 数据库服务器,我们使 QL 输入文件中。 |
| 清单 10. 服务器 1 的 dbbackup.sh shell 脚本 |
| #!/bin/sh |
| # change into the backup_agen | t directory where data files are stored. |
| cd /home/backup_agent |
| # use mysqldump u | tility to export the sites d | atabase tables |
| mysqldump -u sitedb -pG0oDP@s | swrd --add-drop-table sitedb --tables |
| tbl_ccode tbl_machine tbl_session tbl_stats > userdb.sql |
| # compress and archive |
| tar czf userdb.tgz userdb.sql |
| 在服务器 2 上,我们将设置一个类 脚本都通过下面的步骤标记为可执行的: | 似的脚本来备份站点数据库中给出的独有表单。每个 |
| [server1]:$ chmod +x dbbackup.sh |
| 在服务器 1 和 2 上设 们将创建一个 shell 脚本 据文件。 | 置了 dbbackup.sh 后,我们返 来调用各个远程 dbbackup.sh | 回到离线的数据服务器,在那里我 脚本并随后传输压缩的(.tgz)数 |
| 清单 11. 用在离线的 | 数据服务器上的 backup_remote | _servers.sh shell 脚本 |
| #!/bin/sh |
| # use ssh to remo | tely execute the dbbackup.sh | script on server 1 |
| /usr/bin/ssh backup_agent@ser | ver1.com "/home/backup_agent/dbbackup.sh" |
| # use scp to securely copy th | e newly archived userdb.tgz file |
| # from server 1. | Note the use of the date c | ommand to timestamp |
| # the file on the | offsite data server. |
| /usr/bin/scp back | up_agent@server1.com:/home/b | ackup_agent/userdb.tgz |
| /home/backups/use | rdb-$(date +%Y%m%d-%H%M%S).t | gz |
| # execute dbbackup.sh on server 2 |
| /usr/bin/ssh backup_agent@ser | ver2.com "/home/backup_agent/dbbackup.sh" |
| # use scp to tran | sfer transdb.tgz to offsite | server. |
| /usr/bin/scp back | up_agent@server2.com:/home/b | ackup_agent/transdb.tgz |
| /home/backups/transdb-$(date | +%Y%m%d-%H%M%S).tgz |
| backup_remote_server 我们已经设置的无密码的访 行命令。感谢 keychain, | s.sh shell 脚本使用 ssh 命令 问,ssh 命令可以通过离线的服 整个认证过程现在可以自动完成 | 来执行远程服务器上的脚本。由于 务器在服务器 1 和 2 上远程地执 。 |
| 调度 |
| 我们的下一个步骤,也 在离线的数据存储服务器上 执行备份脚本两次,3:34 )选项调用 crontab 程序 | 是最后一个步骤,是调度 backu 的执行。我们将向 cron 调度服 执行一次,8:34 再执行一次。 。 | p_remote_servers.sh shell 脚本 务器中添加两个条目,以要求每天 在离线的服务器上使用 edit(-e |
| [offsite]:$ crontab -e |
| crontab 调用 VISUAL 个条目并保存和关闭文件。 | 或 EDITOR shell 环境变量所指 | 定的默认的编辑器。然后,输入两 |
| 清单 12. 离线的服务器上的 Crontab 条目 |
| 34 3 * * * /home/backups/remo | te_db_backup.sh |
| 34 20 * * * /home/backups/rem | ote_db_backup.sh |
| 一个 crontab 行包括两个主要部分 ,用来指定一个命令应该何时执行: | ,时间表部分和后面的命令部分。时间表分为多个域 |
| 清单 13. Crontab 格式 |
| +---- minute |
| | +----- hour |
| | | +------ day of the month |
| | | | +------ month |
| | | | | +---- day of the week |
| | | | | | +-- command to execute |
| | | | | | | |
| 34 3 * * * /home/backup | s/remote_db_backup.sh |
| 检验您的备份 |
| 您应该对备份进行例行地检查匀?br>免,但是永远不能因此而懒惰。如果您的 | 保程序正确进行。自动程序可以使烦琐的工作得到避 数据值得备份,那么它也值得您时常进行抽样检查。 |
| 考虑添加一个 cron 作业来提醒您自 安全密钥也是一个好主意,同样您也可以 | 己至少每个月对备份进行一次检查。另外,经常修改 调度一个 cron 作业来提醒您做这件事。 |
| 另外的安全防范 |
| 要获得更高的安全性, Detection System,IDS) IDS 将会通知您。IDS 到位 名和加密。 | 可以考虑在每台机器上安装并配 ,比如 Snort。可以预见,当入 后,您将可以添加其他层次上的 | 置一个入侵检庀低常╪trusion 侵正在发生或者近期发生过时, 安全,比如对您的备份进行数字签 |
| GNU Privacy Guard(GnuPG)、Open 过 shell 脚本对存档文件进行加密,不 这样做(参阅 参考资料 以获得关于 Sno | SSL 和 ncrypt 等流行的开放源代码工具可以支持通 过不建议在没有 IDS 提供的额外层次保护的情况下 rt 的更多信息)。 |
| 结束语 |
| 本文向您展示了如何让您的脚本在远 希望您能由此得到灵感而开始考虑保护您 源代码工具来构建新的解决方案。 | 程服务器执行以及如何执行安全自动的文件传输。我 自己的重要数据,并使用 OpenSSH 和 Snort 等开放 |
