本文是 Unix/Linux 系统管理自动化系列中的一篇,主要讲述如何利用脚本来实现远程服务器系统的自动化登录和在远程系统上执行命令。 Telnet 和 SSH 协议是 Internet 远程登录服务的标准协议和主要方式,它们为用户提供了在本地机器上完成远程机器上工作的能力。用户使用 Telnet 或者 SSH 软件连接远程服务器,在 Telnet 或者 SSH 软件中输入的命令就会在服务器上运行。Telnet 协议本质上是不安全的,因为它使用明文传送数据、用户账号和口令,很容易受到中间人攻击方式的攻击;而 SSH 协议则是比较可靠、专为远程登录会话和其他网络服务提供安全性的协议。通过 SSH 可以对所有传输的数据进行加密,也能够防止 DNS 欺骗和 IP 欺骗。本文主要针对 SSH 协议进行阐述,使用的 SSH 软件是 OpenSSH,它是开放源代码的免费的 SSH 替代软件包。 用户使用 Telnet 或者 SSH 登录不同的操作系统,会得到不同的返回信息。用户可以编写程序根据运程登录的返回信息进行判断和处理,从而实现远程服务器系统的自动化登录。本文将先介绍实现远程自动化登录用到的技术,再详细介绍如何实现 Unix/Linux 系统间远程登录自动化。 所谓自动化远程登录,是指在用户不干预的情况下,不需要手动输入密码,就能登录到远程系统。目前远程登录工具有两种安全认证方式。 基于用户口令的安全认证 当使用登录账户登录时,根据提示输入口令,SSH 就会用安全密码认证协议,将加密传送给 SSHD 服务器。认证成功后,就可以登录到 SSHD 服务器。 针对这种安全认证方式,可以让程序自动输入用户名和密码,实现自动化登录。目前可以用 expect, C 或 Perl 来实现。如果采用 C, 需要很熟悉 TCP/IP 协议,实现起来比较复杂;如果用 expect, 由于 expect 是基于 Tcl 的,需要熟悉 Tcl 语法;如果用 perl 实现,需要采用 perl 的 expect.pm 这个包。但需要用户输入口令,因此这种认证方式存在着安全隐患。 基于 SSH key 交换的安全认证方式 用户需要先在 SSH 客户端为登录账户创建一对密匙:私钥(private key)和公钥 (public key),然后把公钥传送到要登录的 SSHD 服务器上。当用户使用 SSH 客户端登录 SSHD 服务器时,SSH 客户端就会向 SSHD 服务器发出用登录帐户的密钥进行安全验证的请求;SSHD 服务器收到请求,先在登录账号的主目录下寻找对应的公钥,并与客户端发送过来的公钥进行对比;如果两个密钥一致,SSHD 服务器会用公钥加密“质询”(challenge),发送给 SSH 客户端;SSH 客户端收到“质询”之后用客户端的私钥解密,再把它发送给 SSHD 服务器。这样就完成了安全认证的整个过程。 使用基于 SSH key 交换的认证方式,用户只要将在 SSH 客户端生成的公钥复制到远程的 SSHD 服务器。当通过 SSH 客户端登录 SSHD 服务器时,用户不需要输入密码,就可以自动登录到远程 SSHD 服务器。这种方式不仅简便,而且避免了用户名和密码的泄露,比第一种方式要安全。
Expect 的基础知识 Expect 是由 Don Libes 基于 Tcl 语言开发的,并被广泛应用于交互式操作和自动化测试的场景之中,它尤其适用于需要对多台服务器执行相同操作的环境中,可以大幅度得提高系统管理人员的工作效率。目前,大部分 Unix/Linux 系统安装有 expect. 万一系统中没有,可以从 http://expect./ 下载相应的包安装。 Expect 作为基于 Tcl 的高级语言,增加了一些特殊的语法。传统意义上的 Expect 是以 Tcl 扩展包的形式出现的,任何 Tcl 语言编写的应用程序都可以加载 Expect 功能;此外,Expect 已经以模块的方式移植到了 Perl 和 Python 语言中,因此用户同样可以在 Perl 和 Python 脚本中利用 Expect 强大的交互功能。 Send,expect 和 spwan 是 Expect 语言最基本的命令。其中,send 命令会发送字符串给指定进程(process); expect 命令会等待接受该进程返回的结果并且会根据返回的字符串来决定下一步的操作;而 spwan 命令可以发起一个进程的运行。 send 命令接收一个字符串做为参数并发送给指定的进程;从
这行代码中,send 会送出字符串“Hello world”( 不带引号 )。如果 Expect 早已经开始与某一个程序进行交互,那么这个字符串将被发送给该程序;而在通常情况下,这个字符串会被送到标准输出设备。 expect 命令则等待一个响应,通常是来自于 Expect 正在与之交互的进程,或者来自于标准输入设备;它会等待一个指定的字符串或者满足给定的正则表达式的任何字符串。我们可以创建一个名为 response.exp 的文件,来看 Expect 是如何处理的,其内容如下:
然后在 shell 下面运行 spawn 命令会调用另一个程序。它的第一个参数是要启动程序的名字;剩余的参数则会被传递给该程序做为参数。比如
命令会衍生出一个 ftp 进程,并且将 ftp.linux.ibm.com 做为参数传递给这个 ftp 进程。 用户通过 spawn,send 和 expect 这三个基本命令,就可以编写一段 Expect 程序来实现自动化工作。 Expect 脚本实现 本节将利用基于用户口令的安全认证方式,并使用 Expect 来实现 SSHD 服务器的自动化登录过程,并在登录的会话中实现命令在 SSHD 服务器端的执行。本文使用的具体实验环境如下:用户使用的 SSH 客户端机器:操作系统均为 RHELS5.3, IP 地址为 192.168.0.3, Expect 版本为 version 5.43.0;远程的 SSHD 服务器:操作系统均为 RHELS5.3,IP 地址为 192.168.0.4,用户名 / 密码为 root/123456。 清单1.登录 SSHD 服务器的自动化脚本
如果要运行该脚本,可以参考如下的操作,假设 expect 脚本的文件名为 t1.expect。另外,在运行该脚本之前,需要将 t1.expect 文件设置成可执行的模式 ; 清单2.运行自动化登录脚本的操作步骤
SSH 证书简介 SSH 证书使用一对密钥 : 私钥(private key)和公钥 (public key)。公钥(public key)对数据进行加密而且只能用于加密,私钥(private key)只能对所匹配的公钥(public key)加密过的数据进行解密。私钥(private key)只保存你独有的一些秘密信息。SSH 客户端用其向 SSHD 服务器证明自已的身份。公钥是公开的,可以随便将其放入 SSHD 服务器上自已的账号中 , 在认证时,进行私钥和公钥协商,如果匹配,那么身份就得以证明,认证就成功。 目前所有的 OpenSSH 版本都应该既能使用 RSA 密钥又能使用 DSA 密钥。RSA 密钥和 DSA 密钥的生成命令和使用方法相同,本文仅介绍 RSA。 如果采用 SSH 密钥认证的方式实现自动化登录,用户可以参考下面的章节。 生成密钥对 ssh-keygen 程序生成的 RSA 密钥的文件名默认为 id_rsa 和 id_rsa.pub,用户也可以将其更改为别的名称。下面”清单 3. 生成密钥对”的操作过程将采用系统的默认值。 清单3. 生成密钥对
如果 ssh 目录不存在,程序为自动创建本地 SSH 目录 ~/.ssh,并将所生成的密钥分成两个文件存储,私钥为 id_rsa,公钥为 id_rsa.pub。 配置自动化登录 在配置自动化登录的过程中,账户对应的公钥需要被添加到 SSHD 服务器端的配置文件。在 3.0 版本的 OPENSSH 中,用户需要修改的文件为 authorized_keys,早于 3.0 的版本则使用 authorized_keys2 文件。将在客户端生成的 id_rsa.pub 文件内容加入到 authorized_keys 或者 authorized_keys2 文件中即可完成配置工作。 为安全起见,要确保 $HOME/.ssh 目录的安全,只有所有者才有 权写入。如果远程用户的 SSH 配置文件的权限设置不当,服务器可能会拒绝进行认证。 下面是配置自动化登录的具体过程,其场景如下: Openssh 为 OpenSSH_4.3p2SSH,将以 root 用户登录到 SSHD 服务器(192.168.0.4)上,因此公钥的内容将存放在 root/.ssh/authorized_keys。 清单4. 终端操作记录
如果用户在生成 rsa 和 id_rsa.pub 的时候没有输入密码,可以直接使用“ssh root@192.168.0.4”登录,而不用输入密码。 而如果用户在生成 rsa 和 id_rsa.pub 的时候输入了密码,需要进行以下两步操作:
清单5. 终端操作记录
(2) 使用 ssh-add, 装入私钥,并输入生成 rsa 和 id_rsa.pub 时输入的密码 清单6. 终端操作记录
把私钥保存在内存中,为认证提供服务,之后以 root 用户 ssh 登录时,就不用重复输入密码。其生命周期为 ssh-agent 启动的那个 shell,当用户退出该 shell 时,需要重新执行 ssh-agent 和 ssh-add。 只要密钥配置好,以后登录就是自动化了。因此本部分登录过程不需要用脚本来实现,实现了前期拷贝 SSH key 到远程服务器,并添加到相应的位置,并测试自动登录是否成功。
本节的脚本实现基于 SSH key 交换的安全认证方式,并利用 Expect 来实现自动化登录。本节所实现的脚本可以运行在以下的实验环境中:用户使用的 SSH 客户端机器:操作系统均为 RHELS5.3, IP 地址为 192.168.0.3, Expect 版本为 version 5.43.0;远程的 SSHD 服务器:操作系统均为 RHELS5.3,IP 地址为 192.168.0.4,用户名 / 密码为 root/123456。 Expect 脚本的内容如下: 清单7.基于 SSH key 交换的自动化登录脚本
清单 7 基于 SSH key 交换的自动化登录脚本注释掉了主机名,用户名和密码,因此用户在运行脚本时需要手工输入主机名,用户名和密码。一旦 SSH Key 的交换完成,用户就可以直接运行 “ssh host-address – l username”实现自动化登录,而不再需要输入用户名密码。
本文做为 Unix/Linux 系统管理自动化系列中的一篇,主要讲述如何利用 Expect 脚本来实现远程服务器系统的自动化登录和在远程系统上执行命令。 需要读者注意的是,采用基于用户口令的安全认证方式时,将用户名和登录密码尤其是 root 用户的密码以明文的形式存放在 Expect 脚本中是一种非常不安全的行为,可能会引起用户名和密码的泄露;如果远端的服务器需要特别安全的防护措施,那么用户可以采取利用 SSH key 交换的安全认证方式来实现自动化登录。这样既方便了系统管理,同时又能保证系统安全。 |
|