tcpwrapper:工作在第四層(傳輸層),能夠對有狀態連接的服務進行安全檢測並實現訪問控制的工具。部分功能上跟iptables重疊。
對於進出本主機訪問某特定服務的連接基於規則進行檢查的一個訪問控制工具,這個訪問控制工具以庫文件形式實現;某進程是否接受libwrap的控制取決於發起此進程的程序在編譯時是否針對libwrap進行編譯的。
tcpwrapper並非對所有的服務都生效,首先主要對於基於tcp的服務生效,其次,主要針對基於tcp並且在編譯(兩種編譯方式:靜態和動態)時鏈接到libwrap庫上的程序才能生效。
所以tcpwrapper的功能並沒有iptables強大。
判斷一個二進制程序是否接受tcpwrapper的控制,只需檢查二進制程序在編譯的時候是否依賴libwrap.so庫
[root@station39 ~]# ldd `which sshd` | grep libwrap
libwrap.so.0 => /lib/libwrap.so.0 (0x00c5a000)
某些二進制文件在編譯時直接以靜態的方式將對libwrap庫的依賴性編譯到文件中去,此時需要使用string來檢查
[root@station39 ~]# strings `which sshd` | grep hosts
[root@station39 ~]# strings `which portmap` | grep hosts //**提供RPC服務的進程
hosts_access_verbose
hosts_allow_table
hosts_deny_table
/etc/hosts.allow
/etc/hosts.deny
鏈接到libwrap.so的獨立進程有:sendmail,slapd,sshd,stunnel,xinetd,gdm,gnome-session,vsftpd,
portmap等等。
兩個重要配置文件/etc/hosts.allow,/etc/hosts.deny
基本語法:
daemon_list: client_list [ :options ]
當來自客戶端的訪問請求訪問某一個接受tcpwrapper控制的進程的時候,tcpwrapper先檢查/etc/hosts.allow 中有沒有匹配到的規則,然後檢查/etc/hosts.deny中有無匹配。如果都沒有,則默認放行。
默認規則:允許
先檢查allow,再檢查deny,如果都沒有,則默認放行。
例:只允許192.168.1.0/24的主機訪問sshd
/etc/hosts.allow /etc/hosts.deny
sshd: 192.168.1. sshd :ALL
PS:所寫的服務名稱一定是可執行的二進制程序的名字。
例:只允許192.168.1.0/24的主機訪問telnet
/etc/hosts.allow /etc/host.deny
in.telnetd: 192.168.1. in.telnetd: ALL
PS:如果有多個服務需用逗號隔開。ALL:通配所有服務。
PS:如果客戶端列表需要定義多個網段,可以這樣寫:
[email protected]: 192.168.0.
[email protected]: 192.168.1.
客戶端的定義:
基於IP地址:192.168.10.1 192.168.1.
基於網絡/掩碼:不接受192.168.1.0/24的格式,只接受192.168.1.0/255.255.255.0長格式。
基於主機名稱:www.a.com .a.com 不很精確,很少使用
基於網絡組(NIS 域):@mynetwork
PS :tcpwrapper不需重啓,立即生效。
下面以telnet來說明tcpwrapper是怎樣使用的:
提供telnet 的二進制程序:in.telnetd(非獨立守護進程,接受超級守護進程的管理)
軟件包:telnet-server
先查看xinetd是否安裝啓用:
[root@station39 ~]# rpm -q xinetd
[root@station39 ~]# yum install xinetd -y
[root@station39 ~]# service xinetd start
[root@station39 ~]# yum install telnet-server -y
[root@station39 ~]# cd /etc/xinetd.d/
[root@station39 xinetd.d]# ls | grep telnet
ekrb5-telnet
krb5-telnet
telnet
[root@station39 xinetd.d]# chkconfig telnet on
[root@station39 xinetd.d]# service xinetd restart
[root@station39 xinetd.d]# netstat -ntlp | grep 23
tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTEN 9612/xinetd
[root@station39 xinetd.d]# setenforce 0
此時telnet 已經可以被訪問了。使用物理機訪問下試試:
PS:telnet 默認不允許管理員登錄。
開始設置規則:拒絕0網段訪問,只允許192.168.0.1訪問:
編輯/etc/hosts.allow
in.telnetd: 192.168.0.1
編輯/etc/hosts.deny
in.telnetd: 192.168.0.
OK,這樣所有192.168.0網段的主機就只有192.168.0.1可以訪問了。
我們也可以在/etc/hosts.deny裏只寫一句就能實現上述功能,使用關鍵字except:
in.telnetd: 192.168.0. EXCEPT 192.168.0.1
except也可以嵌套,如:/etc/hosts.deny
in.telnetd: ALL EXCEPT 192.168.0. EXCEPT 192.168.0.3
拒絕所有訪問,但0網段除了192.168.0.3之外可以訪問。
可用options:
access control
ALLOW/DENY: 可以在/etc/hosts.deny或/etc/hosts.allow 中被當做一個選項來使用。
例:編輯/etc/hosts.allow
in.telnetd: 192.168.1.
in.telnetd: ALL: DENY
running other command
spawn:在匹配到規則時重新發起一個額外的命令來執行其他的動作,可使用特殊展開。
在子進程中執行,並不影響當前進程。
in.telnetd: ALL : spawn ehco "login attempt from %c to %s" | mail -s waring root
twist:啓動一個額外的命令來取代當前規則中定義的服務。
sshd: 192.168.0. twist /bin/echo "421 Connection prohibited."
通過一個例子來說明二者區別:
編輯/etc/hosts.allow
in.telnetd: 192.168.0.: spawn /bin/echo `date` %c accessd %d >> /var/log/tcpwrap.log
可以正常訪問,我們來查看下日誌:
[root@station39 xinetd.d]# cat /var/log/tcpwrap.log
Wed Mar 23 12:26:29 CST 2011 192.168.0.1 accessd in.telnetd
我們使用twist來試一下:/etc/hosts.allow
in.telnetd: 192.168.0.: twist /bin/echo "421 connetcion deny!"
使用物理機訪問,被拒絕:
logging
severity [facility.] priority
定義訪問某個服務時的日誌級別,默認authpriv.info級別
in.telnetd:ALL: serverity local7.info
banners
訪問某個服務時返回的信息
in.telnetd: ALL: banners /some/directory
編輯/etc/hosts.allow
in.telnetd: ALL: banners /var/tcpwrap
舉例:
[root@station39 xinetd.d]# mkdir /var/tcpwrap
[root@station39 xinetd.d]# vim /var/tcpwrap/in.telnetd
"Welcome to 192.168.0.39"
使用物理機訪問一下:
xinetd
xinetd 超級守護進程
主配置文件:/etc/xinetd.conf
includedir /etc/xinetd.d
啓動腳本:/etc/init.d/xinetd
PS:每一個非獨立守護進程是不需要啓動的,是由xinetd來代爲管理。
啓動一個非獨立守護進程:
chkconfig telnet on
service telnet restart
來看看超級守護進程中關於telnet的配置文件:
service telnet
{
disable = no //** 定義服務可否被訪問
flags = REUSE
socket_type = stream //**套接字類型 stream:基於數據流
(stream-based)(基於tcp服務)的連接; dgram:基於數據報文(UDP)服務的連接
wait = no //**確定當前服務是單/多線程服務;yes:單線程(必
須基於TCP) no:多多線程 (TCP/UDP)
user = root //**以指定的用戶身份去運行
server = /usr/sbin/in.telnetd //**啓動服務所對應的二進制程序
log_on_failure += USERID
}
server_args = -c -s /tftpboot //** 啓動服務的時候啓用一些選項
protocol 指定服務所使用的協議。有些服務有,有些沒有。
only_from 白名單,只允許來自哪些地址的客戶端來訪問當前服務,默認允許所有。
Example:
only_from = 192.168.0.0/24
only_from = 192.168.0.1
no_access 僅拒絕,不允許訪問的網段
使用最佳匹配,最接近的規則先生效
Example:
only_from = 10.0.0.0/8
no_access = 10.0.0.0/24
第二條規則生效
access_times 允許訪問的時間
Example:
access_times = 13:00-15:00
bind = 192.168.0.39 (IP地址或者網卡接口)只監聽192.168.0.39這個地址
banner = /path/to/some/file 向遠程客戶端返回提示信息
per_source = 10 每一個IP地址併發連接數的設定
cps = 50 10 <連接數> <等待時間> 在某一秒內只允許多少個併發連接,限制訪問速率
# Define general logging characteristics.
log_type = SYSLOG daemon info //** 定義日誌類型
log_on_failure = HOST //**啓動失敗的日誌
log_on_success = PID HOST DURATION EXIT //**成功啓動的日誌
+= :在默認基礎上增加一個屬性信息;
-= :在默認基礎上減去一個屬性信息。
客戶端匹配模式:
基於數字地址的模式
完全或部分IP地址;
使用0做通配符
Example:192.168.1.0 來自192.168.1網段的客戶機
基於網絡名稱或者NIS域:@mynetwork
基於主機名:.example.com
基於IP地址/子網掩碼:192.168.0.0//24