分类

  • 软件天地

  • 省时省力—在 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. 分布式网络

      

      服务器 #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 等开放


    上一页 下一页




    map