分类: LINUX
2011-01-27 23:43:50
在日常工作中,我们越来越多的使用 SSH(Secure Shell) 客户端软件通过网络登录到开启 SSH 服务的远程系统上,并且在远程系统上执行操作。不同于传统的网络访问服务(例如 telnet, rlogin, ftp)用明文传送数据包括密码,SSH 通过把传输的数据加密在网络中进行安全的通信。
SSH 提供多种安全验证方式,包括基于口令的和基于密钥的安全验证 RSA/DSA。
通常我们使用基于口令的安全认证,通过输入远程系统的账户和口令同远程系统建立连接。例如使用 SSH 命令,用“账户 @ 主机 命令”作为参数,登录远程系统,执行命令,并返回结果。执行过程中,SSH 要求输入用户在远程系统上的密码。像下面所演示的这样,
[linuxStar@remoteLinuxHost ~]# ssh winStar@remoteWinHost "pwd winStar@remoteWinHost's password: < 在这里输入 winStar@remoteWinHost 的密码 > /home/winStar <"pwd"命令在 winStar@remoteWinHost 上的执行结果 > |
但是当在一些脚本中需要调用 SSH 命令与远程系统上建立连接时,密码输入变成了脚本自动化的一个障碍。这时候,脚本停下来等待密码输入,而无法继续执行。用户不得不守在电脑前为连接远程系统输入密码。那么怎样才能做到需要从一台主机连接到另一台远程系统时,无需输入密码而登录呢?
SSH 提供了基于密钥的安全验证。我们可以使用 SSH 的这种安全认证方式来实现无密码的同远程系统建立连接。通过生成密钥对,把公钥加入到另一台开启 SSH 服务的系统的特定用户的信任列表中(RSA 是 ~/.ssh/authorized_keys 文件,DSA 是 ~/.ssh/authorized_keys2 文件),就能实现无需输入远程系统的账户密码而同远程系统建立连接。具体的配置方法,会在下面的章节涉及。
在这个例子中,我们使用 OpenSSH 软件来实现 SSH。OpenSSH (Open Secure Shell) 是开源软件。实际上,我们已经在各种不同版本的 Windows/Linux/AIX/Solaris/HPUX 的操作系统下安装过 OpenSSH,配置了 SSH 基于密钥的安全验证,并且实现了需要连接所有这些主机的任务的自动化脚本,这些脚本现在还在使用,并且每天都运行多次。
在下面的章节中,以一台 Linux 主机和一台 Windows 主机为例子来说明怎样实现 SSH 基于密钥的安全验证和不同系统之间的脚本自动化。本文中的方法也适用于其他安装了 SSH 的系统之间的通信,如 Windows 与 Unix,Linux 与 Linux,Linux 与 Unix 等。
Linux 操作系统环境 | Red Hat Enterprise Linux Server release 5.3 (Tikanga) |
---|---|
OpenSSH 的版本 | openssh(4.3p2-29.el5) |
主机名 / 用户 | remoteLinuxHost/linuxStar |
Windows 操作系统环境 | Windows 2000 Service Pack 4 |
---|---|
OpenSSH 的版本 | openssh(5.1p1-10) |
主机名 / 用户 | remoteWinHost/winStar |
要在 Windows 上安装 OpenSSH,需要先安装 Cygwin 软件。Cygwin 是在 Windows 操作系统上模拟 Linux 环境的软件。访问 Cygwin 的国内镜像 Cygwin.cn()可以查询详细的 Cygwin 安装指南和下载 Cygwin 软件。
在安装 Cygwin 软件的过程中,需要注意两个选项。
关于“默认文本文件格式”的安装选项
在安装过程中,有个选择项“Default text file type”。Cygwin 提供两个选项 : Unix / binary(Cygwin 推荐 ) 和 DOS / Text。如果你要开发执行的脚本是一些 DOS 格式的 CMD 或者 BAT 脚本,建议选择“DOS / Text”选项。
安装 Cygwin 后,可以使用 mount 命令来查询默认的文本文件格式。
Administrator@remoteWinHost ~ $ mount C:\cygwin\bin on /usr/bin type system (textmode) |
如果需要改变这个选项的话,需要重新安装 Cygwin,并在安装过程中正确选择"Default text file type"。
关于“选择安装包”的安装选项
在选择安装包面板,选择 ALL -> Net category -> 选择 openssh(5.1p1-10),相关的安装包 openssl(0.9.81-1), libopenldap, libwrap 被自动选中。
安装 Cygwin 软件完成后,通过下面的步骤来配置 SSH 服务。
增加环境变量 CYGWIN=ntsec tty。
以 Administrator 账户在 Cygwin 中执行 ssh-host-config,将 CYGWIN sshd 设置为操作系统服务:
Administrator@remoteWinHost ~ $ ssh-host-config -y < 省略 > *** Warning: The following functions require administrator privileges! *** Query: Do you want to install sshd as a service? *** Query: (Say "no" if it is already installed as a service) (yes/no) yes *** Info: Note that the CYGWIN variable must contain at least "ntsec" *** Info: for sshd to be able to change user context without password. *** Query: Enter the value of CYGWIN for the daemon: [ntsec] ntsec tty *** Info: The sshd service has been installed under the LocalSystem *** Info: account (also known as SYSTEM). To start the service now, call *** Info: `net start sshd' or `cygrunsrv -S sshd'. Otherwise, it *** Info: will start automatically after the next reboot. *** Info: Host configuration finished. Have fun! |
命令执行成功后,打开开始菜单,运行命令 services.msc,可以在本地服务中看到 CYGWIN sshd 已经被添加进去。
CYGWIN sshd 服务配置完成之后,使用 net start 命令启动 sshd 服务:
Administrator@remoteWinHost ~ $ net start sshd --------The CYGWIN sshd service is starting. --------The CYGWIN sshd service was started successfully. |
CYGWIN sshd 服务在 Windows 系统上就被安装成功了。因为 CYGWIN sshd 被添加到本地服务中,每次重启机器,CYGWIN sshd 服务会被自动启动。
出于安全考虑,我们一般会创建一个特定的账户用来执行一类特定的任务。在本例中,我们希望创建一个账户 winStar,如果想创建其他的账户,步骤是一样的。
首先创建 windows 系统账户 winStar。
然后在 Cygwin 中使用 mkpasswd 命令把 winStar 账户导入到 Cygwin 的账户密码文件 /etc/passwd 中:
Administrator@remoteWinHost ~/.ssh $ mkpasswd -l -u winStar >> /etc/passwd |
使用 passwd winStar 命令为这个 Cygwin 账户设置密码。
在 Cygwin 中,使用 su - winStar 切换到 winStar 账户可能无法完成。我查阅了 Cygwin 网站,Cygwin 建议使用 ssh winStar@remoteWinHost 来代替 su 命令。
OpenSSH 在 Linux 操作系统上的安装比 Windows 上简单的多。较新版本的 Linux 系统会在安装系统时自动安装 OpenSSH,并把 sshd 服务设置为开机自动启动。
使用 ps 命令检查 sshd 是否开启:
# ps -ef | grep sshd root 2666 1 0 Feb20 ? 00:00:00 /usr/sbin/sshd |
使用 ssh -ver 命令检查 SSH 的版本:
# ssh -ver OpenSSH_4.3p2, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008 |
如果发现系统中没有安装 OpenSSH,需要自己安装 OpenSSH。建议从 OpenSSH 的主页下载最新的源码包,OpenSSH 的主页是 。按照说明使用"make""make install"命令编译和安装 OpenSSH。然后启动 sshd 服务。
# service sshd start |
为了实现从 Linux 到远程 Windows 系统的无密码登录,按照下面的步骤配置 RSA 密钥认证。
首先登录 Linux 系统,切换到需要配置的账户,执行 ssh-keygen 命令生成一对 RSA 密钥。
在要求输入专用密钥文件时,直接回车,接受缺省设置 ~/.ssh/id_rsa。
在提示输入密码短语 passphrase 时,直接回车,使用空密码短语。这样做可以实现不用输入密码短语直接登录的目的,但是专用密码文件失去了密码的保护。专用密码文件好像 linuxStar@remoteLinuxHost 的身份证一样,要小心保护好。如果被盗用,则可能以 linuxStar@remoteLinuxHost 的身份直接登录远程系统。
[linuxStar@remoteLinuxHost ~]$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/linuxStar/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/linuxStar/.ssh/id_rsa. Your public key has been saved in /home/linuxStar/.ssh/id_rsa.pub. The key fingerprint is: c3:12:75:21:2b:32:78:8b:ec:1f:30:71:20:20:e2:6f linuxStar@remoteLinuxHost.cn.ibm.com |
命令执行成功后,生成专用密钥文件~ /.ssh/id_rsa 和公钥文件~ /.ssh/id_rsa.pub。
将生成的公钥内容拷贝到远程系统特定用户的 SSH 配置目录 authorized_keys 文件中。在这里我们把它拷贝到 winStar@remoteWinHost:~/.ssh/authorized_keys 文件中。由于 RSA 认证还没有完全设置好,SSH 提示我们输入 winStar 在 remoteWinHost 上的密码。
使用 ssh-copy-id 命令
[linuxStar@remoteLinuxHost .ssh]$ ssh-copy-id -i id_rsa.pub winStar@remoteWinHost winStar@remoteWinHost's password: Now try logging into the machine, with "ssh 'winStar@remoteWinHost'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting. |
如果找不到 ssh-copy-id 命令,在远程系统没有 authorized_keys 的情况下,还可以直接使用 scp 命令。
[linuxStar@remoteLinuxHost .ssh]$ scp id_rsa.pub winStar@remoteWinHost:~/.ssh/authorized_keys --------winStar@remoteWinHost's password: --------id_rsa.pub -------- 100% 408 0.4KB/s 00:00 |
拷贝完成后,确保远程系统上 authorized_keys 文件的可读可执行。
[winStar@remoteWinHost .ssh] chmod 644 ~/.ssh/authorized_keys |
RSA 认证配置完成了。这时在 Linux 上执行 ssh winStar@remoteWinHost,无需再输入 winStar 在 remoteWinHost 上的密码。
[linuxStar@remoteLinuxHost ~]$ ssh winStar@remoteWinHost Last login: Mon Nov 16 10:15:22 2009 from remoteLinuxHost winStar@remoteWinHost ~ $ |
反之,如果使用 Cygwin 在 Windows 用户下生成 RSA 认证密钥对,把公钥文件内容拷贝到远程 Linux 系统 ~/.ssh/authorized_keys 文件,就能够实现从 Windows 到 Linux 的无密码登录。
SSH 的基于密钥的安全验证使我们可以不用输入密码而与远程系统建立连接。基于这种功能,我们可以开发脚本,去执行一些需要连接多个远程系统的自动任务。例如自动在不同平台编译 C/C++ 的代码,执行在各种系统上的自动测试任务等等。
下面的例子是个简单的 shell 脚本,实现了连接远程系统执行 pwd 命令。
#!/bin/sh
#/home/linuxStar/index.sh
sayHello() {
ssh $1 < |
执行这个脚本,可以看到下面的结果:
[linuxStar@remoteLinuxHost ~]$ ./index.sh Hello! I'm from winStar@remoteWinHost, I'm at /home/winStar |
在实际的工作中,pwd 可以被实际的命令组合或者 script 调用代替。也可以在脚本中连接更多的远程系统,成为一台中心控制系统连接多个远程系统执行任务的架构。
关于 & 和 wait 的小提示。sayHello ITMUser@remoteWinHost 末尾的 & 符号的作用是把该条命令放到后台去执行。通过使用这个符号,可以实现同时在多个系统上执行并行任务,不必等到一个命令执行之后再执行下一个。wait 指令等待所有的后台任务执行完成。通常我们会在 wait 后开发一些分析执行结果的代码。
除了 SSH 的密钥验证配置,我们也使用 Samba 和 NFS 服务在不同的系统间共享数据,从而完成能连接多个不同系统执行任务的自动化脚本,可以大幅提高工作效率和质量。