tcp wrappers为由xinetd这支superdaemon管理的服务提供了安全性。由xinetd super daemon管理的服务以及支持libwrap模块的服务都可以使用它tcp wrappers进行安全控制。
可以通过使用tcp wrappers结合防火墙(iptables)提供更加安全的系统保护。
tcp wrappers的配置文件有两个,一个是/etc/hosts.allow,一个是/etc/hosts.deny。
/etc/hosts.allow:允许指定的客户端对指定的服务访问。
/etc/hosts.deny:拒绝指定的客户端对指定的服务访问。
在Linux系统下面并不是所有的服务都支持tcp wrappers,由xinetd管理的服务都支持tcp wrappers,其他的服务可以通过ldd指令来查看。ldd指令用于查看二进制指令所需要的动态链接库,如果服务有支持libwrap.so这个动态链接库,则表示该服务支持TCP Wrappers。
[root@server1 ~]#ldd $(which sshd) | grep libwrap
libwrap.so.0 => /lib64/libwrap.so.0(0x00002b5edee66000)
[root@server1 ~]#
上述表明sshd这个服务是支持tcp wrappers的。
如果没有libwrap,则表示该服务不支持tcp wrappers。
/etc/hosts.allow:允许指定的客户端对指定的服务访问。
/etc/hosts.deny:拒绝指定的客户端对指定的服务访问。
修改完成之后,不需要重新启动服务经会立即生效。
匹配规则如下:
1./etc/hosts.allow和/etc/hosts.deny无匹配记录时,访问可以通过。
2./etc/hosts.allow有匹配记录时访问可以通过。
3./etc/hosts.allow和/etc/hosts.deny都匹配时访问可以通过。
总结起来就是:
1.默认策略是允许,即没有在hosts.allow和hosts.deny中出现的,允许通过。
2.先查看hosts.allow,在查看hosts.deny。
访问控制规则:
每一个控制文件都可以包含多行,按照定义的顺序处理每一行,找到匹配后就跳出该规则。以#开始的表示注释,如果一行写不完可以使用反斜线(\),进行脱跳,表示上一行的延续。
hosts.allow和hosts.deny定义格式如下:
daemon_list : client_list [ : shell_command ]:deny|allow
daemon_list:指定由TCP wrappers需要控制的服务名称。如果该服务是由xinetd管理的服务,要写启动脚本的名称,如/etc/xinetd.d/telnet,否则的话则直接写服务名称,如sshd。
下述为tftp服务的配置文件:/etc/xinetd.d/tftp
如果要想使用tcp wrappers控制tftp的话,需要在hosts.allow或hosts.deny文件中,写上tftp的启动脚本:/use/sbin/in.tftpd
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
client_list:指定tcpwrappers需要控制哪些客户端对哪些服务的访问。
可以用如下方法表示:
单一主机:192.168.0.1,表示的是192.168.0.1这台主机。
指定网段:192.168.0.或者是192.168.0.0/255.255.255.0表示的是192.168.0.0/24整个网段。
指定DNS后缀:.frame.com,所有DNS后缀为.frame.com的主机。
指定FQDN:server.frame.com ,表示的是FQDN为server.frame.com的主机。
所有客户端:ALL
操作符:
EXCEPT:除……之外。如list1 EXCEPTlist2,匹配list1里面的机器,除了list2.
EXCEPT可以用在daemon_list和client_list中。
shell_command:
shell command最好使用绝对路径。在执行shellcommand时,系统会启动一个/bin/sh的子进程去执行这些指令,所有的输入、输出、错误输出都被送到/dev/null里面。如果想在背景下执行的话,可以加上&。
shell command中的变量:
%a (%A): The client (server)host address.
%c: Client information: user@host,user@address, a host name, or just an address, depending on how much information is available.
%d:The daemon process name
%h (%H):The client (server) host name oraddress, if the host name is unavailable.
%n (%N):The client (server) host name(or "unknown" or "paranoid").
%p:The daemon process id.
%s:Server information: daemon@host, daemon@address, or just a daemon name, depending on howmuch information is available.
%u:The client user name (or"unknown").
%%:Expands to a single ‘%′ character.
执行外部指令:spawn
spawn的格式为:
spawn (shell command)
可以使用spawn执行一些外部指令,可以实现日志的记录以及其他的一些信息,如:
[root@server1 tmp]#cat /etc/hosts.allow
#
# hosts.allow This file describes the names of the hostswhich are
# allowed to use the local INETservices, as decided
# by the '/usr/sbin/tcpd' server.
#
sshd:172.17.100.1:spawn(/bin/echo %a from %h attempted to access %d >> /tmp/sshd.log ) :allow
[root@server1 tmp]#cat sshd.log
172.17.100.1from 172.17.100.1 attempted to access sshd
[root@server1 tmp]#
twist:使用 twist 选项发送消息给被拒绝的客户端。twist 选项的基本格式是:
twist shell command
Twist 的实际动作是拒绝访问。Twist 实际上使用指定的操作替换当前服务。在以下示例中,使用 echo 命令将拒绝消息发送给被拒绝的客户端。如果 IP 为 192.168.9.14 的客户端试图用 telnet 或 ssh 连接,那么该示例会发送消息给它。
sshd,telnetd:192.168.9.14:twist /bin/echo "Your connection has been refused\
\nAccess denied andthe event is logged"
注意:twist必须写在最后,后面不能有allow或deny。
iptables实现不同的功能,是通过不同的表来实现的。默认情况下有3张表:filter表、nat表、mangle表,每一张表又包含若干链(chain)。
filter表:对经过(进出)防火墙的数据包进行过滤。
nat表:进行地址转换。
mangle表:对数据包进行修改。
每一个chain都是一个检查清单,它会利用预先设置好的规则对数据包进行检查,如果判断的结果与定义的结果不符合,则交由链中的下一个规则继续判断,如果判断到最后都没有与定义的规则进行匹配的话,则与默认的规则进行匹配,从而决定是放行还是拒绝。通常情况下,默认规则都是拒绝。
Iptables的工作流程如下:
NAT表的3条链:
PREROUTING:修改即将到来的数据包,路由判断前,DNAT
OUTPUT:修改在路由之前本地生成的数据包,路由判断前,DNAT
POSTROUTING:修改即将出去的数据包,路由判断后,SNAT
1.filter表
filter表主要用于对数据包进行过滤。可以进行的动作有:ACCEPT/REJECT/DROP/LOG/RETURN,filter表也是默认操作的表。
INPUT链:过滤所有目标地址是本机的数据包。
OUTPUT链:过滤所有由本地所产生的数据包,源地址是本地的数据包。
FORWARD链:过滤所有经过本地的数据包。源地址和目的地址都不是本机的数据包。
2.nat表
nat表用于网络地址转换。属于一个流的数据包只会经过这个表一次,如果第一个数据包被允许进行NAT或masquerade,那么其他的数据包都会自动的进行同样的动作。
DNAT:改变数据包的目的地址,使数据包重路由到某台主机。
SNAT:改变数据包的源地址。
MASQUERADE:和SNAT一样,只有一个可用的IP地址,端口复用。
3条链:
PREROUTING:路有前,做的是DNAT
POSTROUTING:路由后,做的是SNAT
OUTPUT:DNAT,改变本地产生数据包的目的地址。
3.mangle表
用于对数据包进行修改,不常用。
四种状态:NEW、ESTABLISHED、RELATED、INVALID
INVALID意味着这个包没有已知的流或连接与之关联,也可能是它包含的数据或包头有问题。
ESTABLISHED意思是包是完全有效的,而且属于一个已建立的连接,这个连接的两端都已经有数据发送。
NEW表示包将要或已经开始建立一个新的连接,或者是这个包和一个还没有在两端都有数据发送的连接有关。是防火墙收到的第一个数据包。
RELATED说明包正在建立一个新的连接,这个连接是和一个已建立的连接相关的。比如,FTP data transfer,ICMP error 和一个TCP或UDP连接相关。注意NEW状态并不在试图建立新连接的TCP包里寻找SYN标记,因此它不应该不加修改地用在只有一个防火墙或在不同的防火墙之间没有启用负载平衡的地方。
启动iptables:/etc/init.d/iptables start
[root@server1 ~]#/etc/init.d/iptables start
Flushing firewallrules: [ OK ]
Setting chains topolicy ACCEPT: nat filter [ OK ]
Unloading iptablesmodules: [ OK ]
Applying iptablesfirewall rules: [ OK ]
Loading additionaliptables modules: ip_conntrack_netbios_ns [ OK ]
[root@server1 ~]#
设置开机自动启动:chkconfig iptables --level 35 on
[root@server1 ~]#chkconfig iptables --level 35 on
[root@server1 ~]#
定义iptables策略:
iptables [-t table] command [match][target|jump]
-t table:指明需要操作的表。默认为filter表。
command:iptables所做的操作。比如新增一条规则、删除一条规则等
match:详细的描述一个数据包的特点,五元组,协议、源IP、目标IP、源端口、目标端口
target|jump:对符合指定的数据包进行的动作,如ACCEPT、REJECT、DROP、LOG、RETURN。
默认情况下,Linux系统是不允许进行数据包的转发的,如果要启用该功能的话,可以用如下两种方式:
1.echo 1 >/proc/sys/net/ipv4/ip_forward
这种方式设置的是临时有效。
[root@server1 ~]#echo 1 > /proc/sys/net/ipv4/ip_forward
[root@server1 ~]#
2.vim /etc/sysctl.conf
这种方式设置的是永久有效。
将net.ipv4.ip_forward = 0改为net.ipv4.ip_forward= 1,保存退出,并使用sysctl �Cp使配置生效。
# Controls IPpacket forwarding
net.ipv4.ip_forward= 1
[root@server1 ~]#sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter= 1
net.ipv4.conf.default.accept_source_route= 0
kernel.sysrq = 0
kernel.core_uses_pid= 1
net.ipv4.tcp_syncookies= 1
kernel.msgmnb =65536
kernel.msgmax =65536
kernel.shmmax =68719476736
kernel.shmall =4294967296
[root@server1 ~]#
iptables所做的操作:
-L:查看所选链的所有策略。如果没有指定链,则显示指定表中的所有链。如果没有指定表,则查看filter表。
常用的是:iptables �CL �Cn --line
-A 链名称:在指定的表的指定链末尾增加一条新的规则。
[root@server1 ~]# iptables -t filter -A INPUT -ilo -j ACCEPT
[root@server1 ~]#iptables -t filter -L INPUT -n --line
Chain INPUT (policyACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
[root@server1 ~]#
-D 链名称策略内容|策略序号:从所选表的指定链中删除策略。
[root@server1 ~]#iptables -t filter -L INPUT -n --line
Chain INPUT (policyACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
[root@server1 ~]# iptables -D INPUT 1
[root@server1 ~]#iptables -t filter -L INPUT -n --line
Chain INPUT (policyACCEPT)
num target prot opt source destination
[root@server1 ~]#
-R 链名称策略序号:替换指定表中指定链中的某一条策略。
[root@server1 ~]#iptables -L INPUT -n --line
Chain INPUT (policyACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
[root@server1 ~]# iptables -R INPUT 1 -i lo -j REJECT
[root@server1 ~]#iptables -L INPUT -n --line
Chain INPUT (policyACCEPT)
num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
[root@server1 ~]#
-I 链名称策略序号:在指定策略的前面插入一条策略,如果没有指定策略序号,则默认为1,也就是插入在第一个策略的前面,新插入的策略称为第一条策略。
[root@server1 ~]#iptables -I INPUT -i eth0 -j ACCEPT
-F 链名称:清空指定链中的所有策略,如果没有指定链名称,则清空所选表中的所有链中的策略。
[root@server1 ~]# iptables -F
[root@server1 ~]#iptables -L INPUT -n --line
Chain INPUT (policyACCEPT)
num target prot opt source destination
[root@server1 ~]#
-Z 链名称:将指定链的所有计数器值归零,如果没有指定链名,则为所选表的所有链。
-N 链名称:创建一个新的链。新链的名字不能和已经存在的链的名字相同。
用户新定义的链会被优先匹配。
[root@server1 ~]# iptables -N ZHANG
[root@server1 ~]#iptables-save
# Generated byiptables-save v1.3.5 on Fri Feb 716:15:33 2014
*filter
:INPUT ACCEPT[919:74594]
:FORWARD ACCEPT[0:0]
:OUTPUT ACCEPT[1118:111592]
:ZHANG - [0:0]
COMMIT
# Completed on FriFeb 7 16:15:33 2014
[root@server1 ~]#
-X 链名称:删除用户自定义的链。如果没有指定链名称,则为所选表中所有自定义的链。
[root@server1 ~]#iptables -X
-E old-chain-name new-chain-name:对链进行重命名。
[root@server1 ~]# iptables -N ZHANG
[root@server1 ~]# iptables -E ZHANG FRAME
[root@server1 ~]#iptables-save
# Generated byiptables-save v1.3.5 on Fri Feb 716:18:25 2014
*filter
:INPUT ACCEPT[1025:83322]
:FORWARD ACCEPT[0:0]
:OUTPUT ACCEPT[1200:119484]
:FRAME - [0:0]
COMMIT
# Completed on FriFeb 7 16:18:25 2014
[root@server1 ~]#
-P 链名称:为链设置默认策略。
[root@server1 ~]#iptables -P INPUT DROP
[root@server1 ~]#
match:详细的描述数据包的特点。
-p tcp|udp|icmp……:匹配指定的协议,如果没有指定-p,则表示匹配TCP/UDP/ICMP协议。
-p !tcp:!表示的是排除,除了tcp之外的所有协议。
-s:指定源IP地址。可以是192.168.0.0,192.168.0.0/24,192.168.0.0/255.255.255.0这种格式。
-d:指定目标IP地址。和-s的格式一样。
-i:指定进来的网络接口,可用在INPUT、PREROUTING、FORWARD链中。如lo表示loopback口,eth0,ppp0等,如果是eth+则表示的是所有的eth接口。
-o:出去的网络接口。可以用在OUTPUT、POSTROUTING、FORWARD链中。
--sport:源端口。表示端口范围:A:B,表示从A端口到B端口。:B表示从0到B端口。A:表示从A到65535端口.
--dport:指定目标端口,格式和―sport一样。
-m multiport --sport:指定多个不连续的源端口,最多15个。
-m multiport --dport:指定多个不连续的目标端口,最多15个。
-m multiport --port:指定多个不连续的端口,源端口和目标端口一样,最多15个。
--tcp-flags 检查标记列表条件列表:对特定的TCP标记进行匹配。列表内部用逗号隔开,列表之间用空格分开。第一个参数指定需要检查的TCP标记,第二个参数指定在第一个列表中出现过的,且必须为1的。可以识别SYN/ACK/FIN/RST/PSH/URG标记。还可以用ALL和NONE,ALL表示匹配所有的标记,NONE表示不匹配任何标记。
--syn:匹配syn标记被设置,而ACK和RST没有设置的数据包。
--icmp-type 数值类型:根据icmp的类型进行匹配。
--limit 匹配次数/时间:需要使用-mlimit。时间可以是/second、/minute、/day、/hour,默认为3/hour。
--limit-burst 次数:定义了―limit的峰值,默认为5.也就是单位时间内匹配的数据包的最大数量,每匹配一个,数值就减去1,知道为0为止。新来的数据包将不会在匹配。
--mac-source:对数据包的源mac地址进行过滤,需要使用-mmac
--uid-owner uid:按生成数据包的UID进行过滤。需要-mowner
--gid-owner gid:按生成数据包的GID进行过滤。需要-mowner
--pid-owner pid:按生成数据包的PID(进程ID)进行过滤。需要-mowner
--sid-owner sid:按生成数据包的SID(会话ID)进行过滤。需要-mowner
--state 状态列表,对数据包的状态进行过滤。有四种状态,NEW/RELATED/INVALID/ESTABLISHED,不同的状态之间用逗号隔开。需要用-mstate
ACCEPT:放行匹配的数据包。
DROP:丢弃匹配的数据包,不会产生任何信息。
REJECT:丢弃匹配的数据包,但是会返回错误消息。可以用―reject-with控制返回错误消息的类型。
DNAT:用在PREROUTING和OUTPUT链中。需要使用--to-dest指定转换后的目标地址。
如:iptables �Ct nat �CA PREROUTING �Cp tcp �Cd 202.102.192.68 �Cdport 80 �CjDNAT �Cto-dest 192.168.0.1-192.168.0.10
SNAT:用在POSTROUTING链中。修改数据包的源IP地址。需要使用―to-source
LOG:匹配的数据包记录到日志中。有如下几个参数:
--log-level:指定日志等级。
--log-prefix:指定日志前缀,便于查看。
MASQUERADE:与SNAT相同,用于只有一个IP地址的情况下,为多端口复用。有一个选项,--to-ports指定端口范围,如:--to-ports 10000:20000.该选项不是必须的。
REDIRECT:重定向。比如把所有去往80端口的数据包去往HTTP代理。本地生成的数据包会被映射到127.0.0.1。只能用在PREROUTING和OUTPUT链中,只有一个选项―to-ports,指定端口,可以是一个端口,也可以是一个端口范围。如―to-ports 8080
保存iptables规则:/etc/init.d/iptables save
另一种常用的是将所有的iptables规则写入到脚本文件中,然后开机的时候,自动执行该脚本就可以了(/etc /rc.d/rc.local)。
如:/bin/bash iptables-scripts.sh
iptables策略的导入和导出:
导出:iptables-save �Cc > 文件名
-c:指定导出数据包和字节计数器的值。
导入:iptables-restore �Cc �Cn < 文件名
-c:指定导入数据包和字节计数器的值。
-n:指定在导入时不覆盖已有的表或表内的策略。