FreeBSD下也有“看门人”--浅谈tcpwrapper的基本使用方法

发表于:2007-07-01来源:作者:点击数: 标签:
曾几何时,不知道你是否与笔者小神一样,有在FreeBSD下实现与WIN2000中的IPSec 安全 策略实现访问控制的一样功能的想法呢?也许这对刚刚接触FreeBSD的朋友来说是一种奢望,不仅是因为FreeBSD与 WINDOWS 系统的配置方式截然不同(特别是像小神这种喜欢跑shell的
曾几何时,不知道你是否与笔者小神一样,有在FreeBSD下实现与WIN2000中的IPSec安全策略实现访问控制的一样功能的想法呢?也许这对刚刚接触FreeBSD的朋友来说是一种奢望,不仅是因为FreeBSD与WINDOWS系统的配置方式截然不同(特别是像小神这种喜欢跑shell的人)。不过不用失望,只要阁下用几分钟的时间专心看完下面的这篇文章的话,相信会有意外的收获的:)。

首先我要为大家讲解一下什么是tcpwrapper。tcpwrapper是传统Unix系统的主要安全组件之一,通过使用它我们能够监控大多数的网络服务进程,从而达到网络服务访问控制(形象点说它的功能就像一个看门人,当有请求进入时,它就会将请求内容分解,并与相应的设置规则进行配对,一旦找到相应的规则时就会自动调入相应的操作了)。在现在主流的FreeBSD4.x中它已经成为了内核中的基本“设施”,且使用的方法也有了一定的改变。今天我们就以te.netd为实验对象来完成一次网络服务访问控制操作吧。

实验环境:
一台普通的586,跑FreeBSD4.7,使用PPPoE并做成ADSL网关,开了telnetd服务进行客户端管理(外网内网都可以访问)。

实验目的:
使用tcpwrapper监控telnetd服务,使外网无法登陆telnetd。

操作基本过程:

首先需要配置一下tcpwrapper的访问控制规则文件hosts.allow(需要注意,以前的传统的tcpwrapper都是用两个配置文件的,hosts.allow与hosts.deny,通过使用它们进行交配式的规则管理。这样非常烦琐也不够直观,在FREEBSD3.2以后这个问题得到了新的改良,现在系统默认只需要使用hosts.allow一个文件就可以了,当然,hosts.deny你也可以自行建立,这是很自由的)。打开hosts.allow的配置来看看吧:
alex# cat /etc/hosts.allow
看出规则的基本配置语法了吗?最基本的语法就是: 服务对象 : 客户端对象地址 : 行为
当然,除此之外还有多种的语法演变方式,大家可以在默认存在的/etc/hosts.allow的注释文本中找到相关的资料。

现在我们要做的就是编写自己的规则。在修改规则文件前还是先备份原来的规则文件吧。
alex# cp hosts.allow hosts.allow.bak
用ee打开hosts.allow:
alex# ee /etc/hosts.allow
在文档的开始部分找到ALL : ALL : allow这句规则(这句规则是允许所有的服务与客户端地址的),在它的前面加上#符号,也就是改成:
#ALL : ALL : allow

在hosts.allow中默认是没有针对telnetd服务的配对规则的,所以这里我们需要自行加上。找到下面的语句段:
# The rest of the daemons are protected.
ALL : ALL \
: severity auth.info \
: twist /bin/echo "You are not welcome to use %d from %h."
这个是整个规则群中最后的“保险”规则(当tcpwrapper在规则群中找不到相关的配对规则时就会根据这个规则进行处理了)。
---------------------------------------------------------------------------------------------
小提示:
也许有人会问:如果我把这个“保险”规则给停了(删除了该规则语句或在前面加“#”号),而tcpwrapper又找不到相应的规则,那tcpwrapper会如何处理呢?这样的话inetd(超级网络服务进程)会跳过tcpwrapper功能而直接把执行权交给相应的网络服务进程的。
---------------------------------------------------------------------------------------------

在这个规则的上方加上下列的规则语句:
telnetd : 192.168.1.0/255.255.255.0 : allow #192.168.1.0/255.255.255.0是小神家中其他机器所
#使用的IP段
telnetd : ALL : deny #禁止其他所有的客户端地址访问本机的telnetd服务

有一点是需要注意的:hosts.allow中的规则群使用的方法与我们通常所使用的防火墙规则群的原理都是一样的,都是上下之分,越处于上方的规则它的优先执行权就越高。所以这里我们必须把:
telnetd : 192.168.1.0/255.255.255.0 : allow
这条规则放在
telnetd : ALL : deny
规则之上,否则允许192.168.1.0/24访问的这条规则就等于“空规则”了。

OK,保存退出。规则配置完成了。如何得知自己配置的规则群有无逻辑错误(如出现“空规则”等)或其他错误呢?关于这个问题tcpwrapper的作者也考虑到了,所以他另外写了两个附带的工具:tcpdchk与tcpdmatch,默认这两个程序都是在/usr/sbin/目录下的。tcpdchk是一个检查工具,直接运行它就可以查出配置文件中的多种错误问题了。其经常使用方法为:
alex# tcpdchk

alex# tcpdchk -v
无参数运行tcpdchk可以直接得到该配置文件的错误提示(如果真的有错误存在的话);加上参数-v可以立刻得到所有规则的参数配对列表(这里无论规则是否有误,都会一概显示出来的)。如果我的规则群中有几十、几百、甚至几千条规则呢?哪能知道哪条打哪条啊?嘿嘿,还有办法,这里就要用到第二个程序----tcpdmatch了,它是一个简单的规则数据库查询工具。使用它进行查询的基本格式是:
alex# tcpdmatch 服务名 访问的客户端地址或者机器名

现在打个比方,我们想查看该服务器提供的telnetd服务是否允许IP地址为192.168.1.10的客户端机器访问呢?在SHELL中敲入:
alex# tcpdmatch telnetd 192.168.1.10
client: address 192.168.1.10 #提示你所查询的客户端机器地址为192.168.1.10
server: process telnetd #查询的服务是telnetd
matched: /etc/hosts.allow line 2 #规则建立在/etc/hosts.allow的第2行
option: allow #管理者设置的行为是“允许”
aclearcase/" target="_blank" >ccess: granted #批准该规则

大伙如果觉得规则群中某些规则的设置问题上是比较含糊的话,不妨使用一下这两个工具,它们可以帮助你很快地整理并建立起属于自己的规则群。

现在关于规则的设置问题就已经告一段落了。既然规则设置好了,如何能让它们实施起来呢?大家应该知道,在FreeBSD中大多数INTERNET网络服务都是通过inetd(超级网络服务进程)来启动与调节的,因此我们的tcpwrapper也应该从这里下手。以前大多数的UNIX系统在使用tcpwrapper时都是通过使用tcpd守护进程来代替其他服务运行从而实现监控其他网络进程的目的的,不过在现在的FreeBSD4.x中这个操作问题已经有了新的改良,现在我们只需要在启动inetd时加入-w、-W这两个参数就可以启用tcpwrapper功能了。那关于日志的问题又如何解决呢?如何你经常使用inetd的话也应该清楚-l参数了吧?
alex# inetd -w -W -l

加了-l后我们就可以直接在/var/log/auth.log中找到相关的日志记录了。FreeBSD的日志比WINDOWS的更加直观,大家已经自己找找:)...像这条:
xxx 24 xx:xx:xx alex inetd[255]: refused connection from 218.20.121.161, service telnetd (tcp)
一看就知道是IP为218.20.121.161的客户端机器企图访问本机的telnetd服务,被本机拒绝了...

说说预启动的问题吧。如何在启动机器时使自动执行tcpwrapper呢?使用ee编辑/etc/rc.conf,写入:
inetd_enable="YES"
inetd_flags="-w -W -l"

保存退出,重新启动机器试试:)。

是时候确认一下实验后的“战果”情况了,在服务器的SHELL中敲:
alex# sockstat -4
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
root inetd 77 4 tcp4 *:23 *:*
root syslogd 70 5 udp4 *:514 *:*

PID为77的inetd进程证明telnetd是在提供正常服务的(如果想再进一步地确认telnetd是否在提供正常的服务的话,你可以直接用内网的机器登陆上去看一下)。现在使用规则“允许”范围以外的其他地址的客户端机器telnet上去,看看会如何,很快你就会看到:

遗失对主机的连接。
C:\>

不错吧?其实这种操作是触类旁通的,你可以把它的操作套在其他任何的网络服务(无论是使用tcp的或是使用udp的,是external services还是internal services都是可以的)的进程上去。

最后谈谈最近针对tcpwrapper进行操作实验后得到的一些个人观点吧(有误之处还请指出):
使用tcpwrapper的优点:属于FreeBSD的“基本设施”程序,无需安装,而且绝对绿色;轻量级,无须占用大量资源;支持所有inetd的网络服务进程。
使用tcpwrapper的缺点:在进行登陆过程时inetd进程的运行速度会相对减慢(包括客户端与服务端);监控能力只局限于一些传输层的服务/协议(若是一些低层协议,如ICMP等的它就无能为力了)。

原文转自:http://www.ltesting.net