眾所周知,使用互聯網絡的人越來越多,而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