分类: LINUX
2008-07-22 13:57:14
轻松进行自主、安全、分布式网络备份 |
级别: 中级 Carlos Justiniano (Carlos.Justiniano@ecuityinc.com), 软件设计师, Ecuity Inc. 2004 年 7 月 08 日 重要数据的丢失可能意味着致命的破坏。尽管如此,还是有无数专业人员忽视了对他们的数据的备份。虽然原因可能各不相同,但是,最常见的一个解释是,执行例行备份确实烦琐。由于机器擅长于完成普通而重复的任务,因此,自动化备份的过程是降低工作内在的枯燥性和人们与生俱来的拖延倾向的关键所在。 如果您使用 Linux,那么您就可以使用创建定制备份解决方案的极其强大的工具。本文中的解决方案可以让您使用开源工具执行从简单的到更高级而且安全的网络备份,几乎所有 Linux 发行版本都包含这些工具。 本文采取循序渐进的方法。只要遵循这些基本步骤,该方法就会非常直观。 在学习更加先进的分布式备份解决方案之前,我们先看一个简单但功能强大的归档机制。我们查看一个名为 arc 的简单脚本,该脚本支持从 Linux 的 shell 提示符创建备份快照。
arc 脚本接受单个文件或目录名作为参数,创建压缩的归档文件,并将当前日期嵌入到生成的归档文件名中。例如,如果存在一个名为 beoserver 的目录,那么可以调用 arc 脚本并将 beoserver 目录名传递给该脚本来创建压缩的归档文件,比如 beoserver.20040321-014844.tgz。 使用命令
上面的简单备份示例很有用;但是它仍然包含一个手动备份过程。行业最佳实践建议经常进行备份,并备份到位于多个地理位置的多种介质上。其中心思想是避免完全依赖单一存储介质和单一存储地点。 我们将在下一示例中解决这个挑战,分析一个虚构的分布式网络(如图 1 所示),它将展示一位系统管理员能够访问两台远程服务器和一台离线数据存储服务器。 服务器 #1 和 #2 的备份文件可以安全地传输给离线存储服务器,且整个分布式备份过程将会在无人干预的情况下定期进行。我们将使用一组标准工具,包括部分 Open Secure Shell(OpenSSH)工具,还有磁带归档工具(tar)和 cron 任务调度服务。我们的整个计划是将 cron 用于调度,将 shell 编程和 tar 应用程序用于备份过程,将 OpenSSH 安全 shell 加密用于远程访问、身份验证和安全 shell 复制(scp)以自动化文件传输。有关这些工具的更多信息,请务必阅读它们的手册。
在数字安全语境中,密钥是一段数据,用于对其他数据进行加密或解密。公钥与私钥方案非常有趣,因为使用公钥加密的数据只能由相关私钥进行解密。您可以随便发布公钥,这样其他人就可以对要发送给您的数据进行加密。公钥与私钥方案给数字安全带来变革的原因之一是数据的发送方和接收方不必使用公共的密码。此外,公钥与私钥加密推动了电子商务和其他安全事务的发展。在本文中,我们将创建和使用公钥与私钥,以创建一种高度安全的分布式备份解决方案。 备份过程使用的每台机器都必须运行 OpenSSH 安全 shell 服务(sshd),同时让 22 端口可以通过任何内部防火墙被访问。如果您访问远程的服务器,那么很有可能您正在使用安全 shell。 我们的目标将是,不需要人工提供密码就可以安全地访问机器。一些人认为最简单的办法是设置无密码的访问:不要这样做。这样做不安全。不用那样,本文中我们将使用的方法可能会占用您大约一个小时的时间,建立起一个与使用 “无密码” 帐号同样方便的系统 —— 不过它是公认非常安全的。 我们首先确保 OpenSSH 已经安装,接下来检查它的版本号。完成本文时,最新的发行的 OpenSSH 是 2004 年 2 月 24 日发布的版本 3.8。您应该考虑使用一个较新的而且稳定的发布版本,至少所用的版本应该要比版本 2.x 新。访问 OpenSSH Security 网页以获得关于特定旧版本的缺陷的细节(请参阅本文后面的 参考资料 中的链接)。到目前为止,OpenSSH 是非常稳定的,而且已经证明不存在其他 SSH 工具所报告的很多缺陷。 在 shell 命令提示符中,键入
如果 ssh 返回的版本号高于 2.x,那么该机器的软件配置相对较好。但是,本文推荐全部软件使用最新稳定版,这对于与安全相关的软件尤其重要。 首先,我们使用能够访问服务器 #1 和 #2 的帐号登录到离线存储服务器(参见图 1)。
登录到离线存储服务器之后,使用 ssh-keygen 程序和 -t dsa 选项创建一个公/私钥对。-t 选项必不可少,它用于指定想要生成的加密密钥的类型。我们将使用数字签名算法(DSA),该算法支持使用较新的 SSH2 协议。有关详细内容,请参见 ssh-keygen 手册。 在 ssh-keygen 的执行过程中,将会提示您指定存储 ssh 密钥的位置,然后要求您输入密码短语(passphrase)。当 ssh-keygen 程序询问 ssh 密钥的存储位置时只需按回车键,该程序将创建一个名为 .ssh 的隐藏目录(如果该目录尚未创建)并附带两个文件,分别是公钥文件和私钥文件。 ssh-keygen 的一个有趣特性是,您可以在提示输入密码短语时直接按回车键。如果您不提供密码短语,那么 ssh-keygen 会生成一个未加密的密钥。可以想象这不是一个好想法。要求输入密码短语时,应当确保输入的密码短语具有合理的长度,包含字符和数字,不要使用简单字串。
因为 ssh-keygen 创建的 .ssh 目录是一个隐藏的 “点” 目录,所以为了查看这个新创建的目录,需要将 -a 选项传递给 ls 命令:
输入隐藏的 .ssh 目录并列出其内容:
现在,我们在隐藏的 .ssh 目录内有一个私钥(id_dsa)和一个公钥(id_dsa.pub)。要检查密钥文件的内容,可以使用诸如 vi、emacs 等文本编辑器,也可以使用 less 或 cat 命令。您将会发现密钥文件的内容由使用 base64 编码的字母和数字组成。 下面,需要复制公钥并将其安装到服务器 #1 和 #2 上。不要使用 ftp,而应使用安全的复制程序将公钥传输到每个远程机器上:
新公钥安装之后,我们可以使用在创建私钥和公钥时指定的密码短语登录到每个机器上。现在,登录到每个机器并将 offsite.pub 文件的内容附加到名为 authorized_keys 文件中,该文件存储在每个远程机器的 .ssh 目录中。我们可以使用文本编辑器或 cat 命令将非现场 offsite.pub 文件的内容附加到 authorized_keys 文件:
下面添加一些额外的安全性。首先我们更改 .ssh 目录的访问权,只允许所有者拥有读取、写入和执行的权限。其次,确保 authorized_keys 文件只能被其所有者访问。最后,删除以前上传的 offsite.pub 密钥文件,因为现在已不需要它了。确保正确设置访问权限非常重要,因为 OpenSSH 服务器可能拒绝使用具有不安全的访问权的密钥。
在服务器 #2 上完成相同的过程之后,我们就可以返回到离线存储服务器来测试新的密码短语类型的访问。在离线服务器上,您可以键入如下内容:
在检验您的帐户现在能够使用新的密码短语而不是旧密码来访问远程服务器时,使用
ssh-agent 程序如同一个看门人,它根据需要安全地提供对安全密钥的访问。ssh-agent 启动之后在后台运行,并且可以由 ssh、scp 程序等其他 OpenSSH 应用程序访问。它允许 ssh 程序请求已解密密钥,而不是每次需要时都要求您提供私钥的密码短语。 让我们进一步研究一下 ssh-agent。当 ssh-agent 运行时,它会输出 shell 命令:
使用 eval 命令可以指示 shell 执行 ssh-agent 显示的输出命令:
现在,ssh-agent 已经成为后台进程,可以使用命令 现在,我们可以将密码短语与 ssh-agent 共享了。为此,必须使用程序 ssh-add 将密码短语添加(发送)至运行中的 ssh-agent 程序。
现在,当我们访问服务器 #1 时,不会被要求输入密码:
如果还不确信,那么可以尝试删除(
迄今为止,我们已经学习了几个 OpenSSH 程序(ssh、scp、ssh-agent 和 ssh-add),而且我们已经创建并安装了私钥与公钥来支持安全、自动化登录过程。您可能已经注意到,本文的大多数设置工作只需做一次。例如,创建密钥、安装密钥、通过 .bash_profile 执行 ssh-agent 的过程在每台机器只需要进行一次。这真是好消息。 不太理想的消息是,每次登录离线服务器的时候都必须调用 ssh-add,而且,ssh-agent 与我们将要用来自动化备份工作的 cron 调度进程并不直接兼容。cron 进程不能与 ssh-agent 通信的原因是,cron 作业是作为 cron 的子进程来执行,这样它们就不会继承 幸运的是,有一个解决方案不仅消除了有关 ssh-agent 和 ssh-add 的限制,而且可以让我们使用 cron 来自动进行各种需要对其他机器进行安全地无密码访问的过程。Daniel Robbins 于 2001 年在 developerWorks 发表了一个包含三部分的系列 OpenSSH key management(参阅 参考资料 中的链接),其中提供了一个称为 keychain 的 shell 脚本。它是 ssh-add 和 ssh-agent 的前端,可以简化整个无密码过程。从那时起,这个 keychain 脚本经过了多次改进,现在由 Aron Griffis 维护,目前最新版本是 2004 年 6 月 17 日发布的 2.3.2-1 版本。 keychain shell 脚本太大了,本文不方便列出来,因为这个精心编写的脚本中包括了很多错误检测、丰富的文档以及非常多的跨平台代码。不过,keychain 可以从项目的 Web 站点上方便地下载得到(参见 参考资料 中的相关链接)。 在下载并安装之后,keychain 脚本使用起来非常简便。只需登录每台机器并向 .bash_profile 文件添加下面两行代码:
在您第一次重新登录到每台机器时,keychain 将要求您输入密码短语。不过,除非机器被重新启动,否则,以后再登录时,keychain 将不再要求您重新输入密码短语。最好的是,cron 任务现在可以使用 OpenSSH 命令来安全地访问远程计算机,而不需要交互地使用密码短语。现在我们能够同时获得更好的安全性和易用性。
本文的下一个任务是创建 shell 脚本来执行必要的备份过程。它的目标是对服务器 #1 和 #2 进行完全的数据库备份。在本文的示例中,各服务器都运行 MySQL 数据库服务器,我们将使用 mysqldump 命令行实用工具将一些数据库表导出到一个 SQL 导入文件中。
在服务器 #2 上,我们将设置一个类似的脚本来备份站点数据库中给出的独有表单。每个脚本都通过下面的步骤标记为可执行:
在服务器 #1 和 #2 上都有了 dbbackup.sh 文件之后,我们返回到离线数据服务器。在那里,我们将创建一个 shell 脚本来调用各个远程 dbbackup.sh 脚本,然后传输压缩的(.tgz)数据文件。
shell 脚本 backup_remote_servers.sh 使用 ssh 命令执行远程服务器上的脚本。因为我们已经设置了无密码访问,所以 ssh 命令能够从离线服务器执行服务器 #1 和 #2 上的命令。现在,整个身份验证过程都是自动的,这归功于 keychain。
本文的下一个也是最后一个任务是,调度离线数据存储服务器上的 shell 脚本 backup_remote_servers.sh 的执行。我们将给 cron 调度服务器添加两个条目,以要求每天对脚本备份两次,一次在凌晨 3:34,另一次在晚上 8:34。在离线服务器上使用编辑选项(
crontab 调用默认编辑器。默认编辑器使用 shell 环境变量
一个 crontab 行包括两个主要部分,即时间调度部分及其后接的命令部分。时间调度被划分为字段,用于说明命令应该在何时执行:
应该对备份进行例行检查,以保证备份过程工作正常。自动备份过程能够去除不必要的枯燥工作,但是不应因此而变得懒惰。如果数据值得备份,那么它也值得您时常进行抽样检查。 考虑添加 cron 作业来提醒自己每月至少检查一次备份。此外,每隔一段时间修改一次安全密钥也是个好主意,也可以调度一个 cron 作业来提醒自己及时更改安全密钥。
为了加强安全,可以考虑在所有机器上安装和配置入侵检测系统(IDS),例如 Snort。当入侵正在发生或者最近曾发生过,IDS 将会通知用户。使用 IDS,还能够添加其他级别的安全性,例如对备份进行数字签名和加密。 流行的开源工具(比如 GNU Privacy Guard (GnuPG)、OpenSSL 和 ncrypt)都支持通过 shell 脚本保护归档文件,但是本文不建议在没有 IDS 提供的额外防护级别的情况下这样做(有关 Snort 的更多信息,请参阅 参考资料)。
本文展示了如何在远程服务器上执行脚本,以及如何进行安全和自动化的文件传输。我希望您能由此得到灵感而开始考虑保护您自己的重要数据,并使用 OpenSSH 和 Snort 等开放源代码工具来构建新的解决方案。
|