Unix/Linux 系统自动化管理 远程登录篇(1)
- UID
- 1066743
|
Unix/Linux 系统自动化管理 远程登录篇(1)
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 的基础知识
Expect 是由 Don Libes 基于 Tcl 语言开发的,并被广泛应用于交互式操作和自动化测试的场景之中,它尤其适用于需要对多台服务器执行相同操作的环境中,可以大幅度得提高系统管理人员的工作效率。目前,大部分 Unix/Linux 系统安装有 expect. 万一系统中没有,可以从 http://expect.nist.gov/ 下载相应的包安装。
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 是如何处理的,其内容如下:
1
2
3
| #!expect – f
expect “hi\n”
send “hello there\n”
|
然后在 shell 下面运行 ”expect response.exp”,它会等待来自标准输入设备的响应,直到用户输入 hi 并回车,它才会发送”hello there”到标准输出设备,并回车。然后结束 expect 脚本的运行。但是,如果用户没有输入 hi 并回车,那么 expect 会继续等待”hi\n”;输入其他的字符并不会影响到 expect 的工作。通常情况下,expect 会一直等会输入,直到最终超时退出。此外, expect 还支持使用正则表达式来预防 expect 匹配到未预想到的输入数据。
spawn 命令会调用另一个程序。它的第一个参数是要启动程序的名字;剩余的参数则会被传递给该程序做为参数。比如
1
| spawn ftp ftp.linux.ibm.com
|
命令会衍生出一个 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 服务器的自动化脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| #!/usr/bin/expect
# 设置超时时间为 60 秒
set timeout 60
# 设置要登录的主机 IP 地址
set host 192.168.0.4
# 设置以什么名字的用户登录
set name root
# 设置用户名的登录密码
set password 123456
#spawn 一个 ssh 登录进程
spawn ssh $host -l $name
# 等待响应,第一次登录往往会提示是否永久保存 RSA 到本机的 know hosts 列表中;等到回答后,在提示输出密码;之后就直接提示输入密码
expect {
"(yes/no)?" {
send "yes\n"
expect "assword:"
send "$pasword\n"
}
"assword:" {
send "$password\n"
}
}
expect "#"
# 下面测试是否登录到 $host
send "uname\n"
expect "Linux"
send_user "Now you can do some operation on this terminal\n"
# 这里使用了 interact 命令,使执行完程序后,用户可以在 $host 终端进行交互操作。
Interact
|
如果要运行该脚本,可以参考如下的操作,假设 expect 脚本的文件名为 t1.expect。另外,在运行该脚本之前,需要将 t1.expect 文件设置成可执行的模式 ;
清单2.运行自动化登录脚本的操作步骤
1
2
3
4
5
6
7
8
9
10
11
| [root@redhat ~]chmod a+x t1.expect
[root@redhat ~]./t1.expect
spawn ssh 192.168.0.4 -l root
root@192.168.0.4's password:
Last login: Fri Jun 12 15:36:01 2009 from 192.168.0.3
Red Hat Enterprise Linux Server release 5.1 (Tikanga)
[root@c96m3h4ms01 ~]# uname
Linux
Now you can do some operation on this terminal
[root@c96m3h4ms01 ~]#
|
|
|
|
|
|
|