关于linux下面配置iptables防火墙的讨论,

 

Iptablesnetfilter模块关系

linux下面的防火墙并不是一个服务,而是一个加载到内核中的模块。这个模块就是netfilter模块(网络过滤模块),我们使用iptables工具来管理这个netfilter模块。

 

Iptables的模式

Enabled默认拒绝所有

Disabled默认允许所有

我们可以通过system-config-securitylevel这条命令通过图形界面修改,

 wKioL1MUhgrTB8BaAAD4oNBNAEQ878.jpg

spacer.gif
spacer.gif

这里可以选择enabled模式和disabled模式。

 

关于netfilter表和netfilter

wKiom1MUhl_BwcLRAADNRyxUaB8874.jpg

这张图就很清楚的显示了netfilter表和netfilter链。

Filter table里面有三条链:

INPUT目的地是访问防火墙本身的数据包

OUTPUT源地址是防火墙出去的数据包

FORWARD数据包的源地址和目的地址都不是防火墙的数据包

Nat table里面也有三条链:

OUTPUT数据包在出网关之前被丢给代理服务器

PREROUTING做目的NAT转换(路由判断之前)

POSTROUTING  做源NAT转换(路由判断之后)

Mangle talbe里面有五条链:

INPUT

OUTPUT

FORWARD

PREROUTING

POSTROUTING

 

关于iptables数据包的流程

wKioL1MUhnHiFggUAADRSOaYRZE682.jpg

 

这张图就显示了整个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链,

现在我们拒绝服务器ssh192.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 ~]#

现在我们是可以ssh192.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--stateESTABLISHEDRELATED-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(SNATMASQUERADE)

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