sshd中tcp-wrappers的調用

今天配置sshd的時候,發現openssh-server不同過xinetd依然可以得到tcp-wrappers的知識,好奇之下就察看了 sshd和tcp-wrapper的代碼,做成筆記寫在下面。這些筆記對想使用tcp-wrappers的程序員來說有一定的參考價值。

一些基礎知識

什麼是ssh

ssh secure shell,是用戶在進行傳輸的時候使用的一種保密協議。本來這是爲telnet登錄開發的一種保密性更好的協議,它有RSA(公鑰),DSA(密鑰)兩 種加密方式,通信的雙方倒入同樣的公鑰和密鑰來進行通信,就算是使用公鑰,因爲解碼的複雜性很大,所以保密性依然很好。

什麼是openssh

這是openbsd開發組開發的一個ssh實現,廣泛的用於linux等操作系統上,其中包括了sshd(ssh遠程登錄守護進程),sftp(加ssh的ftp守護子系統),ssh(遠程登錄程序等組件)。

什麼是tcp-wrappers

tcp-wrappers是一個驗證ip合法性的函數庫,其還包括了一個驗證ip合法性的守護進程程序。

openssh-server如何使用Tcp-wrapperts

平 時,tcp-wrappers都是和xinetd或者inetd一起工作,xinetd調用tcp-wrappers來進行IP合法性的檢查。而sshd 則不同,雖然其也可以工作在xinetd後面,但是在獨立運行的時候,sshd依然可以使用tcp-wrappers來進行ip合法性的驗證。看下面的代 碼(截取至sshd.c第942-957)


#ifdef LIBWRAP
 
/* XXX LIBWRAP noes not know about IPv6 */ 
{
    struct request_info req;   
    request_init(&req, RQ_DAEMON, av0, RQ_FILE, sock_in, NULL);   
    fromhost(&req);   
    if (!hosts_access(&req)) {     
        close(sock_in);     
    close(sock_out);     
    refuse(&req);   
}
/*
XXX IPv6 verbose("Connection from %.500s port %d", eval_client(&req), remote_port); */ 
}#endif
/* LIBWRAP */

其中的host_access就是Tcp-wrapperts的api,其功能就是判斷進來的ip是否可以訪問sshd。如果返回false,則close掉socket_in,換句話說,要使用tcp-Wrappert,只需要這麼一個函數就足夠了。

而host_access API則查找用戶定義好的hosts.allow和hosts.deny。這兩個文件的位置可以在編譯Tcp-Wrappert的時候指定,一般的發行版都把這兩個文件給放到了/etc下面。

Tcp-wrapperts自己如何工作

這 些代碼在host_access.c裏面,其中host_access這個函數要查找兩個表,一個是hosts.allow,一個是 hosts.deny。如果在hosts.allow裏面,待驗證ip是合法的,則返回YES這個結果;如果hosts.allow匹配不通過,則在 hosts.deny裏面匹配,如果匹配通過,則返回NO;默認返回YES。參考下面的代碼。

int     hosts_access(request)
struct request_info *request;
{
        int     verdict;
        if (resident <= 0)
            resident++;
        verdict = setjmp(tcpd_buf);
        if (verdict != 0)
            return (verdict == AC_PERMIT);
        if (table_match(hosts_allow_table, request))
            return (YES);
        if (table_match(hosts_deny_table, request))
            return (NO);
            return (YES);
}

在這個文件裏面,還有兩個重要的變量。就是

               
char   *hosts_allow_table = HOSTS_ALLOW;
char   *hosts_deny_table = HOSTS_DENY;

這兩個變量指定了這個函數庫所需要的hosts.allow和hosts.deny的位置,它們通過HOST_ALLOW 和 HOSTS_DENY這兩個宏得到路徑,而這些都會在編譯的時候指定,運行時無法修改。這也算是小小的不便吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章