关于linux下面配置iptables防火墙的讨论,
Iptables与netfilter模块关系
在linux下面的防火墙并不是一个服务,而是一个加载到内核中的模块。这个模块就是netfilter模块(网络过滤模块),我们使用iptables工具来管理这个netfilter模块。
Iptables的模式
Enabled默认拒绝所有
Disabled默认允许所有
我们可以通过system-config-securitylevel这条命令通过图形界面修改,
![spacer.gif](/e/u/themes/default/p_w_picpaths/spacer.gif)
![spacer.gif](/e/u/themes/default/p_w_picpaths/spacer.gif)
这里可以选择enabled模式和disabled模式。
关于netfilter表和netfilter链
这张图就很清楚的显示了netfilter表和netfilter链。
Filter table里面有三条链:
INPUT目的地是访问防火墙本身的数据包
OUTPUT源地址是防火墙出去的数据包
FORWARD数据包的源地址和目的地址都不是防火墙的数据包
Nat table里面也有三条链:
OUTPUT数据包在出网关之前被丢给代理服务器
PREROUTING做目的NAT转换(路由判断之前)
POSTROUTING 做源NAT转换(路由判断之后)
Mangle talbe里面有五条链:
INPUT
OUTPUT
FORWARD
PREROUTING
POSTROUTING
关于iptables数据包的流程
这张图就显示了整个iptables防火墙在工作时候的数据包流程。
关于iptables的访问控制规则
当数据包要经过iptables防火墙,首先读取第一条策略,如果第一条策略匹配,则执行,不在读取下面的策略。如果第一条策略没有匹配,则读取第二条策略,如果匹配到第二条策略,则执行,不在读取下面的策略。如果数据包没有匹配到任何策略,则匹配默认策略。默认策略是允许或者拒绝可以由用户自己定义。
关于iptables的匹配规则
-s192.168.0.0/24
源地址为192.168.0.0/24的网段
-d192.168.0.10
目的地址为192.168.0.10的主机
-ieth0
从eht0进来的数据包
-oeth0
从eth0出去的数据包
‘!’192.168.0.10
反向选择
-ptcp--dport80
协议的类型,目标端口是80
-pudp--sport53
协议类型,源端口是53
关于iptables的规则目标
DROP拒绝
ACCEPT允许
LOG日志,匹配到这条策略后,还是会继续往下面读取策略。
REJECT拒绝,但是会给用户回应的信息。
关于iptables基本链操作
Iptables-L
查看iptables table(默认显示filter table)
Iptables-nL
以IP地址的方式显示
Iptables-L--line-numbers
显示策略条目的行号
Iptables-vL
查看iptables table(显示更具体的信息)
Iptables-A
追加iptables的策略条目(默认会追加策略的最后面)
Iptables-I
插入iptables的策略条目(默认插入到策略的最前面)
Iptables -IINPUT2
插入成iptables策略条目的第二条策略
Iptables-DINPUT2
删除iptables策略条目的第二条策略
Iptables-F
清空所有的策略,但是不会清空链的默认策略。
Iptables-Z
清空计数器
Iptables-N
添加用户自定义链
Iptables-X
清空用户自定义链
关于iptables的默认的链策略
Iptables-PINPUTDROP
改变INPUT链的默认策略,拒绝只可以用DROP,不可以用REJECT。(这条策略最后被执行)
Iptables-POUTPUTDROP
改变OUTPUT链的默认策略
Iptables-PFORWARDDROP
改变FORWARD链的默认策略
下面我们来做试验,写几个简单的策略。
[root@localhost ~]#
[root@localhost ~]# lftp 192.168.0.254
lftp 192.168.0.254:~> ls
drwxrwxrwx23 004096 Mar 25 07:29 pub
lftp 192.168.0.254:/> cd pub/
lftp 192.168.0.254:/pub>
可以看到,现在我们的192.168.0.10这台主机访问服务器上面的ftp服务是没有问题的,现在我们写个策略拒绝这台主机访问。
[root@server1 ~]#
[root@server1 ~]# iptables -t filter -A INPUT -s 192.168.0.10 -p tcp --dport 21 -j REJECT
[root@server1 ~]#
[root@server1~]# iptables -nL
Chain INPUT (policy ACCEPT)
targetprot opt sourcedestination
REJECT tcp--192.168.0.100.0.0.0/0tcp dpt:21 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
targetprot opt sourcedestination
Chain OUTPUT (policy ACCEPT)
targetprot opt sourcedestination
[root@server1~]#
OK,这条简单的策略就写成功了。
现在我们来测试下,
[root@server1 ~]#
[root@server1 ~]# ssh 192.168.0.10
root@192.168.0.10's password:
Last login: Thu Mar 25 21:52:37 2010 from ftp.example.com
[root@localhost ~]# lftp 192.168.0.254
lftp 192.168.0.254:~> ls
`ls' at 0 [Delaying before reconnect:30]
刚才写的那条策略就生效了。现在192.168.0.10就不可以访问服务器ftp服务了。
刚才使用的INPUT链,现在我们使用OUTPUT链,
现在我们拒绝服务器ssh到192.168.0.20上面,
[root@server1 ~]# ssh 192.168.0.10
root@192.168.0.10's password:
Last login: Thu Mar 25 22:04:53 2010 from server1.example.com
[root@localhost ~]#
现在我们是可以ssh到192.168.0.10这台主机上面去的。
[root@server1 ~]#
[root@server1 ~]# iptables -t filter -A OUTPUT -d 192.168.0.10 -p tcp --dport 22 -j REJECT
[root@server1 ~]#
[root@server1 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
targetprot opt sourcedestination
Chain FORWARD (policy ACCEPT)
targetprot opt sourcedestination
Chain OUTPUT (policy ACCEPT)
targetprot opt sourcedestination
REJECTtcp--0.0.0.0/0192.168.0.10tcp dpt:22 reject-with icmp-port-unreachable
[root@server1 ~]#
OK,这条策略就写完成了。
现在我们再来测试下,
[root@localhost ~]#
[root@localhost ~]# ssh 192.168.0.10
ssh: connect to host 192.168.0.10 port 22: Connection refused
[root@localhost ~]#
OK,现在就连接被拒绝了,说明刚才那条策略生效了。
现在还有个特殊的策略,
#iptables-AINPUT-jDROP/ REJECT
这个策略我们一般写在最后面,所有没有匹配到的用户全部拒绝。
这条策略会有一个副作用,就是服务器自己反而会访问不到自己。
现在我们来测试下,
首先来访问下自己的ftp服务,
[root@server1 ~]#
[root@server1 ~]# lftp localhost
lftp 192.168.0.254:~> ls
drwxrwxrwx23 004096 Mar 25 07:29 pub
lftp 192.168.0.254:/> cd pub/
lftp 192.168.0.254:/pub>
OK,现在访问是没有问题的。
现在我们来加上刚才的那条策略。
[root@server1 ~]#
[root@server1 ~]# iptables -A INPUT -j REJECT
[root@server1 ~]#
[root@server1 ~]#
[root@server1 ~]# iptables -L
Chain INPUT (policy ACCEPT)
targetprot opt sourcedestination
REJECTall--anywhereanywherereject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
targetprot opt sourcedestination
Chain OUTPUT (policy ACCEPT)
targetprot opt sourcedestination
[root@server1 ~]#
添加策略就完成了,现在我们再来访问下本地ftp服务,
[root@server1 ~]#
[root@server1 ~]# lftp localhost
lftp 192.168.0.254:~> ls
可以看到,现在就访问不了。
ls' at 0 [Connecting...]
这个是因为没有开启本地回环,所以必须写条策略开启本地回环。
[root@server1 ~]#
[root@server1 ~]# iptables -I INPUT -i lo -j ACCEPT
[root@server1 ~]#
[root@server1 ~]# iptables -L
Chain INPUT (policy ACCEPT)
targetprot opt sourcedestination
ACCEPTall--anywhereanywhere
REJECTall --anywhereanywherereject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
targetprot opt sourcedestination
Chain OUTPUT (policy ACCEPT)
targetprot opt sourcedestination
[root@server1 ~]#
现在我们插入了一条策略,再来测试下现在能否访问本地的ftp服务。
[root@server1 ~]#
[root@server1 ~]# lftp localhost
lftp localhost:~> ls
drwxrwxrwx23 004096 Mar 25 07:29 pub
lftp localhost:/> cd pub/
lftp localhost:/pub>
OK,当我们允许了本地回环访问,现在就可以访问本地的ftp服务了。
默认的链策略也会有这个副作用。
写完iptables策略以后,重启计算机这些策略就都不会生效了。
可以使用这条命令,
#serviceiptablessave
[root@localhost ~]#
[root@localhost ~]# service iptables save
Saving firewall rules to /etc/sysconfig/iptables:[OK]
[root@localhost ~]#
敲完这条命令以后,系统会将iptables的策略自动写入到/etc/sysconfig/iptables。
我们只是对数据包的源地址和目的地址进行过滤。下面我们对数据包的状态进行过滤。这个叫做链接跟踪。
在使用状态过滤的时候,我们必须先加载相应的模块,
Modprobeip_conntrack_ftp
Modprobeip_conntrack_tftp
Modprobeip_nat_ftp
Modprobeip_nat_tftp
关于数据包的状态
NEW第一次发起连接请求的数据包状态
ESTABLISHED已经建立三次握手的数据包状态
RELATED发送出去得到回应的数据包状态
INVALID无效的数据包状态
关于连接跟踪的示例:
Iptables-AINPUT-mstate--stateESTABLISHED,RELATED-jACCEPT
Iptables-AINPUT-mstate--stateNEW-ptcp--dport25-jACCEPT
Iptables-AINPUT-mstate--stateNEW-jDROP
现在我们以FTP为例,测试下,
正常情况下面,现在我们是可以访问服务器上面的ftp服务的,
[root@localhost ~]#
[root@localhost ~]# lftp 192.168.0.254
lftp 192.168.0.254:~> ls
drwxrwxrwx23 004096 Mar 25 07:29 pub
lftp 192.168.0.254:/>
可以看到,现在访问的确没有问题的,
现在我们来写几条策略,
[root@server1 ~]#
[root@server1 ~]# iptables -A INPUT -s 192.168.0.10 -p tcp --dport 21 -j ACCEPT
[root@server1 ~]#
[root@server1 ~]# iptables -A INPUT -j REJECT
[root@server1 ~]#
[root@server1 ~]# iptables -L
Chain INPUT (policy ACCEPT)
targetprot opt sourcedestination
ACCEPTtcp--192.168.0.10anywheretcp dpt:ftp
REJECTall--anywhereanywherereject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
targetprot opt sourcedestination
Chain OUTPUT (policy ACCEPT)
targetprot opt sourcedestination
[root@server1 ~]#
现在我们再到192.168.0.10上面去测试下,
[root@localhost ~]#
[root@localhost ~]# lftp 192.168.0.254
lftp 192.168.0.254:~> ls
`ls' at 0 [Delaying before reconnect: 20]
可以看到,现在就访问不到服务器的ftp服务了。
因为我只开放了21号端口,而ftp服务的21号端口是用来传输命令通道的,现在客户端与服务器是建立不起三次握手的。
现在我们就只能够使用状态防火墙来允许建立三次握手。
使用状态防火墙首先要加载模块,
[root@server1 ~]#
[root@server1 ~]# modprobe ip_conntrack_ftp
[root@server1 ~]#
[root@server1 ~]# iptables -I INPUT 2 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@server1 ~]#
[root@server1 ~]# iptables -L
Chain INPUT (policy ACCEPT)
targetprot opt sourcedestination
ACCEPTtcp--192.168.0.10anywheretcp dpt:ftp
ACCEPT all--anywhereanywherestate RELATED,
ESTABLISHED
REJECTall --anywhereanywherereject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
targetprot opt sourcedestination
Chain OUTPUT (policy ACCEPT)
targetprot opt sourcedestination
[root@server1 ~]#
现在我们再到192.168.0.10上面去测试下,
[root@localhost ~]#
[root@localhost ~]# lftp 192.168.0.254
lftp 192.168.0.254:~> ls
drwxrwxrwx23 004096 Mar 25 07:29 pub
lftp 192.168.0.254:/>
OK,现在就可以访问了,
这个就是状态防火墙的用法。
关于NAT(网络地址转换)
网络地址转换的类型:
目的地NAT(DNAT)
在PREROUTING链中进行设置,
源NAT(SNAT,MASQUERADE)
在POSTROUTING链中进行设置
DNAT示例:
INBOUND(进入)
Iptables-tnat-APREROUTING-ptcp--dport80-jDNAT--to-dest192.168.0.10
OUTBOUD(输出,带有端口重定向)
Iptables-tnat-AOUTPUT-ptcp--dport80-jDNAT--to--dest192.168.0.100:3128
SNAT示例:
MASQUERADE(地址伪装)
Iptables-tnat-APOSTROUTING-oeth0-jMASQUERADE
SNAT
Iptables-tnat-APOSTROUTING-jSNAT--to-source1.2.3.45