四、剖析一个完整的例子 

我们假定接口ppp0通往Internet,接口eth0通往内部网络。 

ppp0的IP地址是128.138.101.4,eth0的IP地址是10.1.1.1,两个接口的子网掩码都是255.255.255.0。 

这个例子使用无状态包过滤机制来保护IP地址为10.1.1.2的Web服务器,这是保护Internet服务器的标准方法。 

在这个例子的后面部分,我们将展示如何使用有状态的过滤机制来保护桌面用户。 

 

在您使用iptables之前,必须启用IP forwarding(IP转发)功能,并且确保内核里已经加载了各个iptables模块。 

要了解启用IP forwarding功能的更多知识,参见28.4节或者12.11.8节。 

带有iptables的所有发行版本也都有能够完成启用和加载的启动脚本。 


1. 第一组规则是对filter表进行初始化。 

首先,冲洗掉表中所有的链, 

然后将INPUT和FORWARD链的默认目标设为DROP。 

和其他任何网络防火墙一样,最安全的策略就是丢弃您没有明确允许的任何包。 

# iptables -F 

# iptables -P INPUT DROP       // 如果是用SSH连接进行设置,不要用这条命令,会导致SSH断开; 

# iptables -P FORWARD DROP 


2. 规则是按照它们出现在链中的顺序来进行匹配的,所以我们将用得最多的规则放在最前面 。 

FORWARD链中的前3条规则让去往10.1.1.2上网络服务的连接通过防火墙。 

确切地说,我们允许SSH(端口22)、HTTP(端口80)和HTTPS(端口443)能够连到我们的Web服务器。 

第一条规则允许来自可信网络的所有连接通过防火墙。 

# iptables -A FORWARD -i eth0 -p ANY -j ACCEPT 

# iptables -A FORWARD -d 10.1.1.2 -p tcp --dport 22  -j ACCEPT 

# iptables -A FORWARD -d 10.1.1.2 -p tcp --dport 80  -j ACCEPT 

# iptables -A FORWARD -d 10.1.1.2 -p tcp --dport 443 -j ACCEPT 


3. 我们允许流到防火墙主机(10.1.1.1)的唯一TCP流量是SSH,它用于管理防火墙。 

下面列出的第二条规则允许环回(loopback)流量,它留在防火墙主机的本地。 

我们的系统管理员在他们不能ping到默认路由时会感到紧张, 

所以这里的第三条规则允许从内部IP地址来的ICMP ECHO_REQUEST包。 

# iptables -A INPUT -i eth0 -d 10.1.1.1  -p tcp --dport 22     -j ACCEPT 

# iptables -A INPUT -i lo   -d 127.0.0.1 -p ANY                -j ACCEPT 

# iptables -A INPUT -i eth0 -d 10.1.1.1  -p icmp --icmp-type 8 -j ACCEPT  


4. 为了能让任何TCP/IP主机在Internet正常工作,必须允许某些类型的ICMP包通过防火墙。 

下面的8条规则就是让ICMP包既能送到防火墙主机,也能送到在它之后的网络的最小集合。 

# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT 

# iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT 

# iptables -A INPUT -p icmp --icmp-type 5 -j ACCEPT 

# iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT 

# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 0 -j ACCEPT 

# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 3 -j ACCEPT 

# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 5 -j ACCEPT 

# iptables -A FORWARD -d 10.1.1.2 -p icmp --icmp-type 11 -j ACCEPT 


5. 接下来向NAT表的PREROUTING链加入规则。虽然NAT表的目的并不是做包过滤, 

但是它的PREROUTING链对于反IP欺骗的过滤来说特别有用。 

如果我们在PREROUTING链中加入DROP项,它们就不需要出现在INPUT和FORWARD链里了, 

因为PREROUTING链会应用到所有进入防火墙主机的包上。 

将控制项放到一个地方比重复放置它们的做法条理性要好得多。 

# iptables -t nat -A PREROUTING -i ppp0 -s 10.0.0.0/8 -j DROP 

# iptables -t nat -A PREROUTING -i ppp0 -s 172.16.0.0/12 -j DROP 

# iptables -t nat -A PREROUTING -i ppp0 -s 192.168.0.0/16 -j DROP 

# iptables -t nat -A PREROUTING -i ppp0 -s 127.0.0.0/8 -j DROP 

# iptables -t nat -A PREROUTING -i ppp0 -s 224.0.0.0/8 -j DROP 

  

6. 最后,我们用一条禁止所有没有得到明确许可的包的规则来结束INPUT和FORWARD链。 

虽然我们在前面已经用iptables -P命令实施过这个做法,但是LOG目标(target)能让我们看到谁正在从Internet上敲我们的大门。 

# iptables -A INPUT -i ppp0 -j LOG 

# iptables -A FORWARD -i ppp0 -j LOG 


7. 我们还可以设置IP NAT来伪装在内部网络里使用的私用地址空间。 

参见12.12节了解更多有关NAT的知识。 


8. Netfilter带给Linux防火墙最强大的功能之一就是有状态包过滤机制。 

针对连到Internet的客户机的防火墙不是允许特定的传入服务,而是允许根据客户机的请求而传入的响应。 

下面这条简单的有状态FORWARD链允许离开我们网络的所有流量通过,但只允许和我们的主机发起的连接有关的入流量通过。 

# iptables -A FORWARD -i eth0 -p ANY -j ACCEPT 

# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 


要跟踪复杂的网络会话,比如FTP和IRC,必须加载某些内核模块来启动iptables。 

如果没有加载这些模块,iptables就会简单地禁止那些连接。虽然有状态包过滤器能够提高站点的安全性, 

但是它们也增加了网络的复杂性。所以在防火墙上实现它之前,要确信您的确需要有状态功能。 



五、调试iptables规则集 

调试iptables规则集最好的办法或许就是用命令: 

  iptables -L -v  


这些选项会告诉您链里面的每条规则匹配了多少个包。 

我们经常在想了解有关匹配包的更多信息时,增加带有LOG目标(target)的临时iptables规则。 

您可以经常通过使用像tcpdump这样的包探测器解决更棘手的问题。 


六、应用实例 

1. 禁止端口的实例 

1). 禁止ssh 端口 

只允许在192.168.62.1上使用ssh 远程登录,从其它计算机上禁止使用ssh 

# iptables -A INPUT -s 192.168.62.1 -p tcp --dport 22 -j ACCEPT 

# iptables -A INPUT -p tcp --dport 22 -j DROP 


2). 禁止代理端口 

# iptables -A INPUT -p tcp --dport 3128 -j REJECT 


3). 禁止icmp 端口 

除192.168.62.1外,禁止其它人ping 我的主机 

# iptables -A INPUT -i eth0 -s 192.168.62.1/32 -p icmp -m icmp --icmp-type echo-request -j ACCEPT 

# iptables -A INPUT -i eth0 -p icmp --icmp-type echo-request –j DROP 

或 

# iptables -A INPUT -i eth0 -s 192.168.62.1/32 -p icmp -m icmp --icmp-type 8 -j ACCEPT 

# iptables -A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j DROP 

注:可以用iptables --protocol icmp --help 查看ICMP 类型 


4). 禁止QQ 端口 

# iptables -D FORWARD -p udp --dport 8000 -j REJECT 


2. 强制访问指定的站点 

要使192.168.52.0/24网络内的计算机(这此计算机的网关应设为192.168.52.10)强制访问指定的站点, 

在做为防火墙的计算机(192.168.52.10)上应添加以下规则: 

1). 打开ip 包转发功能 

# echo 1 > /proc/sys/net/ipv4/ip_forward 


2). 在NAT/防火墙计算机上的NAT 表中添加目的地址转换规则: 

# iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 202.96.134.130:80 

# iptables -t nat -I PREROUTING -i eth0 -p udp --dport 80 -j DNAT --to-destination 202.96.134.130:80 


3). 在NAT/防火墙计算机上的NAT 表中添加源地址转换规则: 

# iptables -t nat -I POSTROUTING -o eth1 -p tcp --dport 80 -s 192.168.52.0/24 -j SNAT --to-source 202.96.134.10:20000-30000 

# iptables -t nat -I POSTROUTING -o eth1 -p udp --dport 80 -s 192.168.52.0/24 -j SNAT --to-source 202.96.134.10:20000-30000 


4). 测试:在内部网的任一台计算机上打开浏览器,输入任一非本网络的IP,都将指向IP 为202.96.134.130的网站. 


3. 发布内部网络服务器 

图4 


要使因特网上的计算机访问到内部网的FTP 服务器、WEB 服务器,在做为防火墙的计算机上应 

添加以下规则: 

1). 

# echo 1 > /proc/sys/net/ipv4/ip_forward 


2). 发布内部网web 服务器 

# iptables -t nat -I PREROUTING -p tcp -i eth1 -s 202.96.134.0/24 --dport 80 -j DNAT --to-destination 192.168.52.15:80 

# iptables -t nat -I POSTROUTING -p tcp -i eth0 -s 192.168.52.15 --sport 80 -j SNAT --to-source 202.96.134.10:20000-30000 


3). 发布内部网ftp 服务器 

# iptables -t nat -I PREROUTING -p tcp -i eth1 -s 202.96.134.0/24 --dport 21 -j DNAT --to-destination 192.168.52.14:21 

# iptables -t nat -I POSTROUTING -p tcp -i eth0 -s 192.168.52.14 --sport 21 -j SNAT --to-source 202.96.134.10:40000-50000 


4). 注意:内部网的计算机网关要设置为防火墙的ip(192.168.52.1) 

5). 测试: 

     用一台IP 地址为202.96.134.0段的计算机虚拟因特网访问, 

     当在其浏览器中访问http://202.96.134.10时, 实际应看到的是192.168.52.15的的web 服务; 

     当访问ftp://202.96.134.10时,实际应看到的是192.168.52.14上的的ftp 服务 


4. 智能DNS 

图5 


1). 

# echo 1 > /proc/sys/net/ipv4/ip_forward 


2). 在NAT 服务器上添加以下规则: 

在PREROUTING 链中添加目的地址转换规则: 

# iptables -t nat -I PREROUTING -i eth0 -p tcp --dpor 53 -j DNAT --to-destination 202.96.134.130 

# iptables -t nat -I PREROUTING -i eth0 -p udp --dpor 53 -j DNAT --to-destination 202.96.134.130 


在POSTROUTING 链中添加源地址转换规则: 

# iptables -t nat -I POSTROUTING -o eth1 -s 192.168.52.0/24 -p tcp --dpor 53 -j SNAT --to-source 202.96.134.10:40000-50000 

# iptables -t nat -I POSTROUTING -o eth1 -s 192.168.52.0/24 -p udp --dpor 53 -j SNAT --to-source 202.96.134.10:40000-50000 


3). 测试 

在内部网任一台计算机上,将DNS 设置为任意的外网IP,就可以使用DNS  

测试工具如nslookup来解析DNS 服务器202.96.134.130上的名称. 


5. 端口映射 

见上节透明代理设置 

# iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.62.0/24 --dport 80 -j REDIRECT --to-ports 3128 


6. 典型NAT 上网 

一般做为NAT 的计算机同时也是局域网的网关, 

假定该机有两块网卡eth0、eth1, 

eth0连接外网,  IP 为202.96.134.134; 

eth1连接局域网,IP 为192.168.62.10 


1). 先在内核里打开ip 转发功能 

# echo 1 > /proc/sys/net/ipv4/ip_forward 


2). 使局域网用户能访问internet 所要做的nat 

# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to?202.96.134.134 



如果上网的IP 是动态IP,则使用以下规则: 

# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.62.0/24 -j MASQUERADE 


如果是通过ADSL 上网,且公网IP 是动态IP,则使用以下规则: 

# iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.62.0/24 -j MASQUERADE 


3). 使internet 用户可以访问局域网内web 主机所要做的nat 

# iptables -t nat -A PREROUTING -p tcp -d 202.96.134.134 --dport 80 -j DNAT --to-destination 192.168.62.10 

注:局域网内的客户端需将默认网关、DNS 设为防火墙的IP 


7. 在我们的网络机房实现NAT 共享上网 

工作环境:上层代理192.168.60.6(4480),只授予教师机(192.168.62.111)使用该代理的权限 

目标:不使用squid 代理上网,而是使用NAT 的方式上网 

方法: 

1). 确保停止教师机(192.168.62.111)的squid 或其它代理服务 

2). 客户端网关、DNS 均指向192.168.62.111,浏览器代理设置为192.168.60.6(4480)。 

    测试在当前情况下能否上网 

3). 在教师机(192.168.62.111)上添加如下iptables 规则: 

# iptables -t nat -A POSTROUTING -p tcp -d 192.168.60.6/32 --dport 4480 -j SNAT --to-source 192.168.62.111:10000-30000 

解释:对于目的地为192.168.60.6、目的端口为4480的TCP 包, 

      在经过防火墙路由后,将其源地址转换为192.168.62.111,端口转换为10000-30000间的某个端口。 

4). 客户端测试能否上网 


8. 对流媒体服务器的服务做IP 限制 

1). 清空规则并放开SSH 

# iptables -F 

# iptables -A INPUT -s 10.1.1.11 -p tcp --dport 22 -j ACCEPT 


2). 对指定IP放开,可以推送流到这台服务器, 其余的IP都禁止 

A. 只对单个IP放开 

# iptables -A INPUT -s 10.2.1.54 -j ACCEPT 

# iptables -A INPUT -s! 10.2.1.54 -j REJECT 

或 

# iptables -A INPUT -s 10.2.1.54 -j ACCEPT 

# iptables -A INPUT   -i eth0 -j REJECT 


B. 对多个IP放开,即将要放开的IP插入到最后一条拒绝的规则之前 

# iptables -A INPUT -s 10.2.1.54 -j ACCEPT 

# iptables -A INPUT   -i eth0 -j REJECT 

# iptables -I INPUT 2 -s 10.2.1.13 -j ACCEPT 


3). 对指定IP段 放开,可以推送流到这台服务器,其余的IP都禁止 

A. 对单个IP段放开 

# iptables -I INPUT 2 -s 10.2.1.0/24 -j ACCEPT 

# iptables -A INPUT   -i eth0 -j REJECT 


B. 对多个IP段放开 

# iptables -I INPUT 2 -s 10.2.1.0/24 -j ACCEPT 

# iptables -A INPUT   -i eth0 -j REJECT 

# iptables -I INPUT 2 -s 10.2.2.0/24 -j ACCEPT 


其中: 

10.2.1.0/24 表示: A类地址主机为8位,表示10.2.1固定,后面是可变 

前面是IP地址10.2.1.0,是表示局域网地址。 

后而的24是指掩码,因为IP地址和掩码用二进制表示的话都是32位的。 

所以掩码的24表示那掩码前24位是1,后8位是0,转换成10进制就是表示掩码是255.255.255.0 

即, 255.255.255.0=11111111.11111111.11111111.0=24个1 

192.168.0.0/16 代表B类地址 主机为16,表示192.168固定,后面是可用.
  

4). 对指定IP拒绝, 

A. 对单个IP拒绝 

# iptables -A INPUT -s 10.2.1.11 -p tcp --dport 1935 -j REJECT