netfilter/iptables+squid综合案例分析
 
实验背景
     小诺公司内部搭建了web服务器和FTP服务器,为了满足公司需求,要求使用Linux构建安全、可靠的防火墙。具体要求如下:
1、 防火墙自身要求安全、可靠,不允许网络中任何人访问;防火墙出问题,只允许在防火墙主机上进行操作。
2、 公司内部的web服务器要求通过地址映射发布出去,且只允许外部网络用户访问web服务器的80端口,而且通过有效的DNS注册。
3、 公司内部的员工必须通过防火墙才能访问内部的web服务器,不允许直接访问。
4、 FTP服务器只对公司内部用户起作用,且只允许内部用户访问FTP服务器的21和20端口,不允许外部网络用户访问。
5、 公司内部的员工要求通过透明代理上网(不需要在客户机浏览器上做任何设置,就可以上网)
6、 内部用户所有的IP地址必须通过NAT转换之后才能够访问外网。
 
实验网络拓扑图
iptables+squid综合案例分析_iptables
实验原理:
----------------netfilter/iptables架构---------------------
 
iptables默认具有5条规则链:PREROUTING、POSTROUTING、FORWARD、INPUT、OUTPUT
 
iptables默认的规则表以及对应的规则链:
filter:INPUT、FORWARD和OUTPUT。
nat:PREROUTING、POSTROUTING和OUTPUT。
mangle:PREROUTING、POSTROUTING、INPUT、OUTPUT和FORWARD。
 
nat的主要用处是网络地址转换,即Network Address Translation,缩写为NAT。做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行的。属于一个流的包只会经过这个表一 次。如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作。也就是说,余下的包不会再通过这个表,一个一个的被 NAT,而是自动地完成。这就是我们为什么不应该在这个表中做任何过滤的主要原因,对这一点,后面会有更加详细的讨论。PREROUTING 链的作用是在包刚刚到达防火墙时改变它的目的地址,如果需要的话。OUTPUT链改变本地产生的包的目的地址。POSTROUTING链在包就要离开防火 墙之前改变其源地址。
 
mangle主要用来mangle数据包。我们可以改变不同的包及包头的内容, 比如 TTL,TOS或MARK。注意MARK并没有真正地改动数据包,它只是在内核空间为包设了一个标记。防火墙内的其他的规则或程序(如tc)可以使用这种 标记对包进行过滤或高级路由。这个表有五个内建的链: PREROUTING,POSTROUTING, OUTPUT,INPUT和 FORWARD。PREROUTING在包进入防火墙之后、路由判断之前改变包,POSTROUTING是在所有路由判断之后。 OUTPUT在确定包的目的之前更改数据包。INPUT在包被路由到本地之后,但在用户空间的程序看到它之前改变包。FORWARD在最初的路由判断之 后、最后一次更改包的目的之前mangle包。注意,mangle表不能做任何NAT,它只是改变数据包的 TTL,TOS或MARK,而不是其源目地址。NAT是在nat表中操作的。
 
filter是专门过滤包的,内建三个链,可以毫无问题地对包进行DROP、 LOG、ACCEPT和REJECT等操作。FORWARD 链过滤所有不是本地产生的并且目的地不是本地(所谓本地就是防火墙了)的包,而 INPUT恰恰针对那些目的地是本地的包。OUTPUT 是用来过滤所有本地生成的包的。
iptables+squid综合案例分析_职场_02
实验步骤:
 
实验思想:先将进出防火墙的策略设置到最严格,然后一步步添加需要放行的策略。
 
一、Linuxiptables的具体设置
 
1、 清空filter表和nat表中的配置策略。
清空所选的系统表filter中的默认链(不影响默认策略):iptables -F (INPUT OUTPUT FORWARD),不加参数,表示全部清除
清空所选的系统表nat中的默认链(不影响默认策略):iptables -F (PREROUTING、POSTROUING、OUTPUT) –t nat ,不跟参数,表示全部清除
删除表中的自定义规则链:iptables -X <自定义规则链名1、链名2....>
指定链的所有计数器归零:iptables -Z (INPUT OUTPUT FORWARD)
iptables+squid综合案例分析_职场_03
 
2、 放行filter表的默认OUTPUT链,阻止FORWARD链和INPUT链。全部放行nat表中的PREROUTING链、POSTROUTING链以及OUTPUT链。(设置完成之后,目前的状态是只允许数据从内网出去,不允许外网任何数据进来。)
设置默认策略规则: iptables -P -t (nat、filter、mangle) (INPUT OUTPUT FORWARD) <DROP、ACCEPT>
iptables+squid综合案例分析_休闲_04
iptables+squid综合案例分析_职场_05
 
3、 将内网web服务器的IP地址映射到防火墙连接外网接口的IP地址上。
设置完成之后,外网用户就可以通过80端口访问防火墙外网接口的IP地址。并能够将目的IP地址转换为内网web服务器的IP地址,但是还不能够访问web服务器。
格式:iptables -t nat -A PREROUTING -p tcp -d 防火墙对应外网的IP --dport 80 -j DNAT --to-destination web服务器的IP地址
iptables+squid综合案例分析_休闲_06
 
4、 放行转发访问内网web服务器的数据包
设置完成之后,外网用户就可以通过80端口访问防火墙外网接口的IP地址,并且能够将外网IP地址映射为内网web服务器的IP地址,进而访问内部web服务器。
格式:iptables –A FORWARD –p tcp –d 内网web服务器的IP地址 --dport 80 –j ACCEPT
iptables+squid综合案例分析_休闲_07
 
5、 将内网web服务器的IP地址映射到防火墙连接内网接口的IP地址上。
设置完成之后,内网用户就可以通过访问防火墙内网接口的IP地址来访问内部web服务器。为什么不直接让内网用户通过内网IP地址直接访问呢?是为了增加内网Web服务器的安全性。
格式:iptables -t nat -A POSTROUTING -p tcp -d http服务器的IP地址 --dport 80 -j SNAT --to-source 防火墙对应内网的IP地址
iptables+squid综合案例分析_职场_08
 
6、 在防火墙中添加透明代理设置的规则。
设置完成之后,内网用户访问外网的web服务器的80端口都转换为内网代理服务器squid的默认端口3128。只要代理服务器能够访问互联网,内网用户也就可以访问互联网。
格式:iptables –t nat –A PREROUTING –s 子网地址/子网掩码 -p tcp --dport 80 -j REDIRECT –to-posts 3128
iptables+squid综合案例分析_iptables_09
 
7、 设置Linux作为网关服务器。
设置完成之后,内网所有IP地址如果访问外网都映射为防火墙外网接口的IP地址。
格式:iptables –t nat –A POSTROUTING –s 子网地址/子网掩码 -o 外部接口 -j MASQUERADE
iptables+squid综合案例分析_休闲_10
 
8、 保存iptables的配置。
当管理员已经对Linux防火墙设置完毕,并且需要永久保存防火墙的设置时,需要使用iptable-save 命令将设置内容保存到一个指定的文件中。默认配置文件在/etc/sysconfig/iptables中。当重新启动系统之后,需要使用 iptables-restore命令将保存的文件重新恢复到/etc/sysconfig/iptables中。
iptables+squid综合案例分析_iptables_11
 
二、Linuxsquid的具体设置
 
1、squid服务器的初始化
第一次使用squid服务器之前需要先使用squid –z命令对squid服务器进行初始化。其主要作用是在squid服务器的工作目录“/var/spool/squid/”中建立需要的子目录。
只有在第一次启动squid服务器之前才需要进行服务器的初始化工作,如果不手动执行squid –z命令,squid服务脚本在第一次启动服务时也会自动完成相应的初始化工作,再启动squid脚本程序。
注意:在配置squid之前,要确保主机具有完整的域名。
iptables+squid综合案例分析_职场_12
 
1、编辑squid服务器的配置文件
iptables+squid综合案例分析_职场_13
 
修改服务端口,squid服务器的服务端口使用http_port配置项设置,其默认值是3128,为了用户使用方便,可以添加服务端口8080或其它端口。
iptables+squid综合案例分析_休闲_14
 
修改缓冲内存数量,squid服务器的性能和squid服务器使用的缓冲内存数量有很大关系,使用内存越多,squid服务器的性能会越好。一般设置cache_mem的值设置为服务器物理内存的三分之一到四分之一比较合适,cache_mem默认的设置只有8MB。
iptables+squid综合案例分析_休闲_15
 
设置squid的工作目录,squid服务器缓存的内容只有很少的一部分是保存在缓冲内存中的,而代理服务中使用的所有文件都会保存在squid的工作目录中。在squid.conf配置文件中使用cache_dir设置squid服务器的工作目录路径和属性。
“100 16 256”分别表示目录中最大的容量是100MB,目录中的一级子目录的数量为16个,二级子目录为256个。
squid工作目录的容量和子目录的数量也会在一定程度上影响squid服务器代理服务的性能,在实际应用中可根据实际情况适当扩大工作目录的总容量。
iptables+squid综合案例分析_休闲_16
 
在squid.conf配置文件中默认只允许本机使用squid服务器,这种策略也体现了squid服务器默认 设置的严谨。为了让局域网所有用户能够通过squid的代理服务访问外部网页,需要设置访问控制列表,在acl *条目下添加 “acl clients src 子网地址/子网掩码”
iptables+squid综合案例分析_职场_17
 
在squid.conf文件的http_access deny all设置行之前添加如下设置:http_access allow clients。并添加提供透明代理的相关功能,需要进行如下配置:
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
iptables+squid综合案例分析_职场_18
 
设置完成之后,重新启动squid服务,使squid.conf配置文件生效。
iptables+squid综合案例分析_职场_19
 
Squid服务启动后,使用netstat命令可以看到squid服务程序在3128端口进行代理服务的监听,这与通常的代理服务器使用8080端口是不同的。
iptables+squid综合案例分析_职场_20
 
测试略!!
 
附录:
---iptables命令总结---
在规则末尾添加一条规则: iptables -A INPUT(OUTPUT、FORWARD) <要添加的新规则>
删除某一个规则:iptables -D INPUT(OUTPUT、FORWARD) <规则序列号> <==> iptables -D INPUT(OUTPUT、FORWARD) <新规则>
替换某一条规则:iptables -R INPUT(OUTPUT、FORWARD) <规则序列号> <要替换的新规则>
在某一序列号上插入某一条规则:iptables -I INPUT(OUTPUT、FORWARD) <规则序列号> <要插入的新规则>
显示规则: iptables -L (INPUT OUTPUT FORWARD)
清空所选的系统表filter中的默认链(不影响默认策略):iptables -F (INPUT OUTPUT FORWARD)
删除表中的自定义规则链:iptables -X <自定义规则链名1、链名2....>
指定链的所有计数器归零:iptables -Z (INPUT OUTPUT FORWARD)
添加一条新链:iptables -N <链名>  删除添加的新链 iptables -X <链名> 重命名新链 iptables -E <旧链名> <新链名>
设置默认策略规则: iptables -P (INPUT OUTPUT FORWARD) <DROP、ACCEPT>
 
---通用匹配---
匹配指定的协议  -p tcp/udp/icmp   -p tcp,udp,icmp   -p ALL  --protocol ! tcp<==>-p udp,icpm
以IP源地址匹配包  -s 192.168.1.1   -s 192.168.1.0/24  -s 192.168.1.0/255.255.255.0 --source ! 192.168.1.0/24
以IP目的地址匹配包  -d 192.168.1.1   -d 192.168.1.0/24  -d 192.168.1.0/255.255.255.0 --destination ! 192.168.1.0/24
以包进入本地所使用的网络接口来匹配包  iptables -A <INPUT、FORWARD>  -i <eth0、ppp0>    -i +    -i eth+   -i ! eth0
以包离开本地所使用的网络接口来匹配包  iptables -A <INPUT、FORWARD>  -o <eth0、ppp0>    -o +    -o eth+   -o ! eth0
 
---TCP匹配---
基于TCP的源端口来匹配 --sport 22   -p tcp --source-port 22:80  --source-port :80  --source-port  22:
基于TCP的目标端口来匹配 --dport 22   -p tcp --destination-port 22:80  --destination-port :80  --destination-port  22:
---UDP匹配---
基于UDP的源端口来匹配 --sport 53  -p udp --source-port 53:69  --source-port :53  --source-port  53:
基于UDP的目标端口来匹配 --dport 53  -p udp --destination-port 53:69  --destination-port :53  --destination-port  53: 
---ICMP匹配---
-p icmp --icmp-type 8
 
---显示匹配---
基于包的MAC源地址匹配包  iptables -A <INPUT FORWARD> -m mac --mac-source 00:00:00:00:00:01
源端口多个不连续端口匹配 iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
目标端口多个不连续端口匹配 iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110
 
----target匹配---
-j ACCEPT 运行链中定义的数据包通过
-j DROP  丢弃链中定义的数据包
----DNAT target----
配置SNAT命令基本语法
iptables -t nat -A POSTROUTING -o 网络接口 -j SNAT --to-
source IP地址
配置DNAT命令基本语法
iptables -t nat -A PREROUTING -i 网络接口 -p 协议 --dport 端口 -j DNAT  --to-destiantion IP地址
 
-----iptables连接状态设置--------------------
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
连接跟踪存在四种数据包状态
NEW:想要新建连接的数据包
INVALID:无效的数据包,例如损坏或者不完整的数据包
ESTABLISHED:已经建立连接的数据包
RELATED:与已经发送的数据包有关的数据包
【【实例1】】:TCP的负载均衡(web服务器的负载均衡)
iptables -t nat -A PREROUTING -p tcp -d 22.22.22.22 --dport 80 -j DNAT  --to-destination  192.168.1.1-192.168.1.10
 
【【实例2】】:公司内部没有dns服务器,web服务器域名通过公网上一台DNS注册,要求内外包括防火墙在内都能访问内部web服务器。
地址映射:
外网用户访问内网web服务器
iptables -t nat -A PREROUTING -p tcp -d 防火墙对应外网的IP --dport 80 -j DNAT --to-destination http服务器的IP地址
内网用户访问内网web服务器
iptables -t nat -A POSTROUTING -p tcp -d http服务器的IP地址  --dport 80 -j SNAT --to-source 防火墙对应内网的IP地址
防火墙访问内网web服务器
 
放行DHCP数据:iptables  -A INPUT -i eth0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
 
------------开启路由转发功能------------------
外网IP地址为静态:开启IP地址转发功能:echo "1" &gt; /proc/sys/net/ipv4/ip_forward <==>vi /etc/sysctl.conf 修改 net.ipv4.ip_forward = 1
(注意:在防火墙策略做好之后再打开,否则会有安全隐患存在)
外网IP地址为动态获得:开启IP地址转发功能:echo "1" &gt; /proc/sys/net/ipv4/ip_dynaddr
iptables -P INPUT DROP
iptables -p tcp -s ALL -d 192.168.10.100 -j ACCEPT
iptables -A INPUT -j DROP