众所周知,使用互联网络的人越来越多,而Internet的安全问题也越来越被人们所关注。在我们日常使用的很多网络连接软件并没有提供必要的安全措施来防范,例如telnet,rlogin,ftp等等均在网络中将用户的密码未加保护地传输,很多不怀好意的入侵者就这样轻而易举地得到您的帐户密码!
在这里我们介绍一下如何安全登录,如何利用OpenSSH方便地建立自己的安全网络通道。
1、OpenSSH简介
1.1 SSH协议
SSH的英文全称为Secure Shell,是IETF(Internet Engineering Task Force)的Network Working Group所制定的一个协议,用于提供安全的远程登录和其他安全网络服务。
SSH协议目前版本号为2,还处于草案阶段。不过由于网络安全市场的强劲需求,已经有许多公司和组织开发了实用的基于SSH协议的软件包。
其中最著名就是SSH Communication Security公司的SSH Secure Shell商用软件包和OpenBSD Project开放源码组织开发的OpenSSH软件包,前者已经在超过八十个国家拥有数百万用户,后者也被难以数计的专业用户和开放源码支持者广泛使用。本文将只介绍基于OpenSSH的应用技术。
1.2 什么是OpenSSH
如前文所述,OpenSSH是一个免费(Free)版本的基于SSH协议的网络连接工具软件包。它将所有通信流量进行加密,可以有效地防范各种监听手段,杜绝网络连接的泄密。OpenSSH具备安全性高、可靠性高、可用性好、功能全面等特点。不仅如此,由于OpenSSH的开放性,用户还可以通过Internet得到广泛及时的技术支持。
OpenSSH目前支持支持SSH协议1.3版本、1.5版本和2.0版本,包括这样一些应用程序:
sshd:服务器端的守护程序,监听来自客户机的连接,负责完成安全验证并提供服务。
Ssh:客户端程序,用于登录到远程机器或执行远程机器上的命令。
Scp:客户端程序,可以安全地将文件拷贝到其他机器。
Ssh-keygen:密钥管理程序,用来产生基于RSA或者DSA加密协议的密钥对,包括一个主机用公开密钥和一个客户用私有密钥。
Ssh-agent:安全验证的代理程序,用来管理本地密钥实现自动连接。
Ssh-add:与上面代理程序配合使用的应用程序,可以将特定的密钥加入到代理程序的管理之中。
Sftp-server:安全文件传输的服务程序。
Sftp:安全文件传输的客户程序,可以与运行sftp-server 的机器建立ftp连接。
Ssh-keyscan:一个用来搜集主机公用密钥的工具程序,效率很高。
1.3 你自己的OpenSSH
想拥有自己的OpenSSH?那好…
首先,我们来了解如何得到OpenSSH软件包。通常情况下,你所安装的Linux系统会自动配置,比如RedHat 7.0,Mandrake 8.0等。如果想自己安装,或者想得到最新的版本,即使你的机器上还没有安装也不要紧,可以到OpenSSH的官方网站www.openssh.org去自行下载,目前的最新版本是2001年5月发布的OpenSSH 2.9。你可以在网页http://www.openssh.com/portable.html上选择离自己最近的站点下载。
接下来自然就是安装,如果你下载了rpm程序包,那么可以使用如下命令来安装,这里假定你拥有最新的2.9版本。
[jack@mypc download]$ rpm -i openssh-2.9p2-1.i386.rpm
如果你下载的是源程序包,那么可以先解压缩该包,然后进入openssh-2.9p2目录来安装。
[jack@mypc download]$ tar -vxzf openssh-2.9p2.tar.gz
[jack@mypc openssh-2.9p2]$ cd openssh-2.9p2
[jack@mypc openssh-2.9p2]$ ./configure
[jack@mypc openssh-2.9p2]$ make
[jack@mypc openssh-2.9p2]$ make install
现在你已经有了自己的OpenSSH包,让我们一起来进入主题,看看如何利用它来快速的建立起自己的安全通道吧。
2、用ssh构建安全通道
2.1 ssh的端口转发功能
前文已经介绍,ssh是OpenSSH包中的一个重要应用程序,它功能非常强大,不仅可以象普通telnet用户一样地登录远程的主机,还可以指令主机去执行特定的命令以完成特定的任务。当然,这些操作是在得到主机的安全验证之后,并且此后的所有网络通讯均被ssh加密传输,安全可靠。
Ssh还有一个很有用的端口转发功能,它能够将TCP 连接通过ssh的安全机制转发到远程机器上,这样我们就可以得到一个可靠的TCP会话,从而实现安全的信息通道。
Ssh端口转发的典型命令格式如下:
ssh -L 4001:localhost:4011 jack@myserver.com
-L选项指示将要被转发的端口对;4001:localhost:4011参数表示本地端口4001将被转发到远端的4011端口(需要注意的是这里localhost指示的是远程主机的名字或者IP地址,它是被远程机器所能解释的名字,在本例中远程主机是myserver.com,而localhost则是指myserver.com本身);jack@myserver.com参数指明ssh通道将连接到myserver.com上,并且使用用户jack所拥有的公用密钥来进行身份验证。
2.2 针对安全通道来配置OpenSSH
要正确地使用OpenSSH的端口转发功能,必须了解其基本的配置方法。
第一步,要产生正确的密钥对,并将公用密钥配置到远程主机的相应位置。以前面提供的典型命令来说,如果我们假定本地用户名也是jack,那么密钥操作如下:
(1)产生密钥对。在本地主机上使用命令ssh-keygen来产生新的密钥对,默认密钥类型是版本1的rsa1密钥,其文件名为identity和identity.pub,保存在当前用户的主目录下的.ssh目录中,即~/.ssh/。(关于ssh-keygen的用法请用man ssh-keygen查看使用手册,而~则代表/home/jack,用户jack的主目录)
(2)拷贝公用密钥到远程主机。将密钥identity.pub拷贝到远程主机上用户jack的主目录下的.ssh目录中,导入到文件authorized_keys中。由于密钥文件是文本格式,可以用命令cat identity.pub >> authtorized_keys来将新的公用密钥添加到该文件尾部。注意:远程主机在对密钥的认证时只读取authorized_keys,而并不检查identity.pub文件,所以导入后可以将之删除。
至于版本2的密钥操作方式与此完全相同,只是新的密钥文件名分别为id_rsa和id_dsa,公用密钥文件分别为id_rsa.pub和id_dsa.pub 。
第二步,本地ssh客户机的配置文件主要是/etc/ssh_config和~/.ssh/config文件,使用端口转发无需对此做特别配置,采用默认值即可。在远程ssh服务器上,其配置文件为/etc/sshd_config,也不用做特别修改。了解配置的具体细节,可以用man ssh和man sshd命令来查看联机使用手册。
3、使用安全通道的程序示例
3.1 示例程序环境
远程主机:myserver.com (192.1.0.99)
本地主机:mypc (192.1.0.3)
远程帐户:jack
本地帐户:jack
操作系统:Mandrake Linux 8.0
编译系统:gcc 2.96
3.2 用ssh命令建立SSH通道
[jack@mypc sshtest]$ ssh -L 4001:localhost:4017 jack@myserver.com
Last login: Tue Aug 7 19:05:10 from 192.1.0.3
3.3 本地程序清单(sshcall.c)
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
int fd;
struct sockaddr_in address;
int address_len;
int rtval;
char server_ip[20]="127.0.0.1";
short int port = 4001;
char sendbuf[100];
char recvbuf[100];
int len;
/* 创建套接字句柄 */
fd = socket(PF_INET, SOCK_STREAM, 0);
/* 配置将要连接的socket到本地端口4001 */
address.sin_family = PF_INET;
address.sin_addr.s_addr = inet_addr(server_ip);
address.sin_port = htons(port);
address_len = sizeof(address);
/* 尝试连接到远程端口,实际上通过了SSH的转发 */
rtval = connect(fd, (struct sockaddr *)&address, address_len);
if(rtval == -1) exit(1);
/* 发送一个字符串 */
strcpy(sendbuf, "Hello! Server.");
send(fd, sendbuf, strlen(sendbuf), 0);
printf("\nData send out!");
/* 等待服务器应答 */
len = recv(fd, recvbuf, 100, 0);
printf("\nData from server: %s", recvbuf);
/* 再等待服务器的另一个字符串 */
len = recv(fd, recvbuf, 100, 0);
printf("\nData from server: %s", recvbuf);
/* 关闭socket */
close(fd);
return 0;
}
3.4 远程服务程序清单(sshlisten.c)
#include
#include
#include
#include
int main(int argc, char* argv[])
{
int fd;
int address_len;
struct sockaddr_in address;
/* 创建套接字句柄 */
fd = socket(PF_INET, SOCK_STREAM, 0);
/* 配置socket到本地4011端口 */
address.sin_family = PF_INET;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = htons(4011);
address_len = sizeof(address);
bind(fd, (struct sockaddr *)&address, address_len);
/* 监听端口并只允许一个连接在监听队列中 */
listen(fd, 5);
while(1)
{
struct sockaddr_in client_address;
int len,datalen;
int client_sockfd;
char *answer = "OK";
char *answer_quit = "QUIT";
char *client_end = "END";
char data[100];
char *client_ip;
printf("waiting...");
fflush(stdout);
/* 等待客户机的连接 */
len = sizeof(client_address);
client_sockfd = accept(fd, (struct sockaddr *)&client_address,
(int *)&len);
/* 打印出实际连接在服务器上所看到的网络地址及端口 */
client_ip = inet_ntoa(client_address.sin_addr);
printf("\nClient IP address is %s, on port %d.",client_ip,
(int)client_address.sin_port);
/* 从客户机读取数据 */
datalen = recv(client_sockfd, data, 100, 0);
if(datalen > 0) data[datalen] = '\0';
printf("\nClient data is: %s", data);
/* 连续发送两个字符串 */
send(client_sockfd, answer, strlen(answer), 0);
send(client_sockfd, answer_quit, strlen(answer_quit), 0);
/* 关闭socket,结束这个连接 */
close(client_sockfd);
printf("\n");
}
return 0;
}
3.5 应用示例说明
将上述两个程序例子分别在客户机和服务器上运行,sshlisten在远程服务器端运行,sshcall在客户端运行,读者可以自行验证结果。注意观察在服务器上sshlisten输出的连接信息,以加深对端口转发的理解。
4、OpenSSH资源
OpenSSH的rpm下载:
ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/rpm/RH71/
openssh-2.9p2-1.i386.rpm
openssh-askpass-2.9p2-1.i386.rpm
openssh-askpass-gnome-2.9p2-1.i386.rpm
openssh-clients-2.9p2-1.i386.rpm
openssh-server-2.9p2-1.i386.rpm
OpenSSH的源程序下载:
ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/
openssh-2.9p2.tar.gz
README
INSTALL
TODO
UPGRADING
OpenSSH的使用手册查阅:http://www.openssh.com/manual.html
SSH基本协议的资源(可以在www.ietf.org网站查询""关键字得到更多):
1. SSH Protocol Architecture
http://search.ietf.org/internet-drafts/draft-ietf-secsh-architecture-09.txt
2. SSH Authentication Protocol
http://search.ietf.org/internet-drafts/draft-ietf-secsh-userauth-11.txt
3. SSH Connection Protocol
http://search.ietf.org/internet-drafts/draft-ietf-secsh-connect-11.txt
4. SSH Transport Layer Protocol
http://search.ietf.org/internet-drafts/draft-ietf-secsh-transport-09.txt