防火墙:
代理防火墙
工作在应用层,能够对应用层数据进行辨别。
状态检测防火墙
是包过滤防火墙的升级版本,能够记录数据包的状态,根据状态辨别数据包,提高效率。
包过滤防火墙
工作在第四层和第三层,一般仅仅至此对数据包中的协议(tcp/udp/icmp)、端口、IP地址等信息进行辨别。效率不高,因为它会对流过防火墙的所有数据包都做相同的过滤辨别。
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
Iptables是一个包过滤防火墙,可以通过添加特殊参数的规则,成为状态检测防火墙,还能安装第三方模块就能成为代理防火墙。
iptables防火墙的组成:
内核模块netfilter + 应用程序iptables命令
netfilter模块是linux内核默认就会编译,所以如果不是故意把该功能取消的话,Linux内核肯定会自带该功能。它是防火墙中真正起到对数据过滤的部分。
iptables命令是提供接口,让管理员使用该命令添加、维护规则,管理防火墙。
# man iptables
功能是通过4个表(table)来体现:
filter:专门实现对数据包的过滤:允许通过、拒绝通过、记录日志
INPUT,OUTPUT,FORWARD
nat:专门实现地址映射(修改数据包中的IP地址)
PREROUTING,POSTROUTING,OUTPUT
mangle:主要是对数据包打标志或修改数据包的标记
raw :对非常底层的数据包做处理。
链(chain):
把具有同一类性质的规则放在一起,就组成一个链。链中有多条防火墙规则。这些形性质默认是由iptables自定义好了,当然可以由管理员自定义新的链。
默认有以下几个链:
INPUT:专门存放一些针对流进本机的数据包进行过滤的规则。
OUTPUT:专门是存放一些对于本机发送到其他机器的数据包进行过滤的规则
FORWARD:专门对经过防火墙的数据包做过滤的。
PREROUTING:存放路由前对数据包进行处理的规则
POSTROUTING:存放路由后对数据包进行处理的规则
iptables命令的常见参数:
-F 清空规则,默认是清空filter表的规则
-t 指定要操作的是哪个表,如果省略该参数就是filter表
-A 追加一条规则(在原有的规则之后添加一条新规则)
-I 在指定的位置中插入一条新规则,如果省略了I后面的数字编号,那么默认在最前面插入新规则。
-D 删除规则
-L 列出规则
-n 直接输出数字IP,而不会对IP进行反向解析
-Z 重置规则的统计数据
-v 显示规则的详细统计数据
-P 添加默认策略(当所有规则都不匹配的时候,就按默认策略来处理数据包)
-j 定义处理动作。
实验前:先包原来的规则清空。
# service iptables save
# :> /etc/sysconfig/iptables
# service iptables restart
# iptables -L -n
例子:不允许任何人ping本机
该需要是用到防火墙的过滤功能,规则将会保存到filter表
该需求应该当数据包进来本机的时候,就由该由防火墙对它过滤掉,所以规则应该放在INPUT
# iptables -t filter -A INPUT -p icmp -jDROP
-p定义协议。支持icmp,tcp,udp
-j支持 DROP,REJECT,LOG,ACCEPT
例子:不允许任何人ping本机,但允许本机使用环回地址127.0.0.1 ping本机
# iptables -t filter -A INPUT -p icmp -jDROP
# iptables -t filter -I INPUT -p icmp -i lo-j ACCEPT
-i数据包进来的时候是通过哪个网卡进来的
查看规则的详细情况
# iptables -L -n -v --line-number
删除规则:
可以通过详细的参数产出对应的规则
# iptables -t filter -D INPUT -p icmp -j DROP
可以通过规则的编号删除某条规则
#iptables -D INPUT 2
例子:只允许本地网络10.1.1.0/24通过ssh登录本机,其他的一律拒绝。
sp: 1024
dp: 22
sip: 10.1.1.88
dip: 10.1.1.21
# iptables -A INPUT -p tcp --dport 22 -s 10.1.1.0/24-j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -jDROP
-s指定源IP
--dport指定数据包中的目标端口
规则的匹配是从上往下判断,大多数的处理动作的结果都是:只要匹配了就停止继续往下匹配。
sp: 1024
dp: 22
sip: 192.168.1.8
dip: 10.1.1.21
例子:假设本机是web服务器,允许任何人访问本机的web服务,只允许本地网络10.1.1.0/24通过ssh远程登录本机. 其他任何通信都拒绝,只允许本机通过lo接口访问本机任何服务
# iptables -A INPUT -i lo -j ACCEPT <---一般在防火墙中都会添加该规则
# iptables -A INPUT -p tcp --dport 80 -jACCEPT
# iptables -A INPUT -p tcp --dport 22 -s 10.1.1.0/24 -j ACCEPT
# iptables -t filter -P INPUT DROP
总结:
但只是允许少数的通讯,拒绝其他任何通讯,就应该在规则中添加少数允许规则,最后添加默认策略。
例子:本机是一个DNS服务器,允许任何人访问本机的DNS服务,允许任何人通过ssh远程登录本机。其余访问一概拒绝。
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -p udp --dport 53 -jACCEPT
# iptables -A INPUT -p tcp -m multiport--dports 53,22 -j ACCEPT
# iptables -P INPUT DROP
例子:假设本机是web服务器,允许任何人访问本机的web服务,只允许本地网络10.1.1.0/24通过ssh远程登录本机. 其他任何通信都拒绝。允许本机对外的一切通讯
要实现允许本机对外一切通信就必须引入状态检测功能:
iptables对数据包分成以下状态:
NEW 连接中第一个数据包
ESTABLISHED同一个连接中NEW之后的数据包
RELATED 同一个连接中后续的所有数据包
INVALID 无法识别的、错误的数据包
# iptables -A INPUT -m state --stateESTABLISHED,RELATED -j ACCEPT <---一般在防火墙中都会添加该规则
# iptables -A INPUT -i lo -j ACCEPT <---一般在防火墙中都会添加该规则
# iptables -A INPUT -p tcp --dport 80 -jACCEPT
# iptables -A INPUT -p tcp --dport 22 -s 10.1.1.0/24 -j ACCEPT
# iptables -t filter -P INPUT DROP
sp: 1024
dp: 8081
sip: 10.1.1.88
dip: 10.1.1.21
web服务器回应包:
sp: 8081
dp: 1024
sip: 10.1.1.21
dip: 10.1.1.88
例子:禁止10.1.1.0/24访问本机的sshd服务和web服务,其他没有任何限制
# iptables -A INPUT -p tcp -m multiport--dports 22,80 -j DROP
# iptables -P INPUT ACCEPT
适合拒绝少数,允许大部分访问。
例子:记录本机对外的主动访问
# iptables -A OUTPUT -m state --stateNEW -j LOG --log-prefix "hacker"
例子:仅仅开放本机的SSHD服务和 NFS 服务,其他服务一些拒绝。
默认nfs服务端的端口是随机的,不是固定,随意很难固定端口写规则放行通信
客户端 NFS服务端
mount -t nfs ... portmap portmap nfs-server
rpcbind rpcbind
方法:把端口固定下来
# vim /etc/sysconfig/nfs <---把所有的PORT的行前面的#好去掉
RQUOTAD_PORT=875
LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
MOUNTD_PORT=892
STATD_PORT=662
STATD_OUTGOING_PORT=2020
RDMA_PORT=20049
# service rpcbind restart 或 rhel5: portmap
# service nfs restart
特别注意必须另外放行
nfsd: 2049
portmap/rpcbind: 111
# iptables -A INPUT -m state --stateESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -p tcp -m multiport--dports 875,32803,32769,892,662,2020,20049,2049,111,22 -j ACCEPT
# iptables -A INPUT -p udp -m multiport--dports 875,32803,32769,892,662,2020,20049,2049,111,22 -j ACCEPT
# iptables -P INPUT DROP
例子:开放本机的ftp服务,其他都拒绝
两种工作模式:
ftp服务器端会默认监听21号端口,使用该端口和客户端进行命令交互。例如:登录信息处理,各种文件操作命令的处理等等。
ftp> get ./file.txt
被动模式:
传输实际数据的时候,服务端会告诉客户端服务器已经打开了某个随机端口,客户端可以主动连接该端口去把相关的数据下载回来或者上传上去。
主动模式:
传输实际数据的时候,服务端回主动使用本机20号端口,主动连接客户端,然后开始数据的传输。
# iptables -A INPUT -m state --state ESTABLISHED,RELATED-j ACCEPT
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -p tcp -m multiport--dports 20,21 -j ACCEPT
rhel6:
# modprobe nf_conntrack_ftp
rhel5:
# modprobe ip_conntrack_ftp
练习:
本机是一个web服务器,并且部署了一个BBS论坛程序,客户在注册会员的时候,服务器主动给它的注册邮箱发送一个激活邮件。程序员会通过ftp管理web服务器上的网站的源代码。论坛程序使用的数据库是本机的mysql数据库。
要求:在开启iptables的前提下,保证web服务的所有功能能够正常使用。允许来自所有私有IP端的客户端ssh登录本机。
web: 80,443
mail: 25
ftp: 20,21 考虑到被动模式
mysql: 3306 本机开放lo接口
ssh : 22 10.0.0.0/8 ,172.16.0.0-172.31.255.255 /12 ,192.168.0.0/16
由于需要发邮件,发邮件的时候需要解析域名的邮件记录,所以必须保证web服务器可以对发发送查询域名的请求
# iptables -A INPUT -m state --stateESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -p tcp -m multiport--dports 80,443,25,20,21 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8-j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -s172.16.0.0/12 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -s192.168.0.0/16 -j ACCEPT
# iptables -P INPUT DROP
如果想记录本机主动对外连接的信息,那必须区分哪些连接是正常,跳过记录
# iptables -A OUTPUT -p udp -mmultiport ! -o lo --dports 53,25 -jACCEPT
# iptables -A OUTPUT -p tcp -mmultiport ! -o lo --dports 53,25 -jACCEPT
# iptables -A OUTPUT -m state --state NEW-j LOG --log-prefix "hacker "
============================================================================
NAT
网络地址转换(网络地址映射)
就是把数据包的源IP或者目标IP进行修改。
作用:
修改源IP,叫源地址映射,一般为了实现让私有网络的机器能够访问互联网
修改目标IP,叫目标地址映射,一般为了实现让互联网的机器能够访问私有网络的机器。
可以保护内网的资源。
clients <---- eth0:Router:eth1-----> 互联网
clients
eth0 10.1.1.88
gw 10.1.1.1
Router
eth0 10.1.1.1
eth1 210.38.224.128
假设现在客户端需要访问互联网的web服务器http://www.baidu.com <--- 61.3.2.4
sp: 1028
dp: 80
sip: 10.1.1.88 <--- 源IP和目标不是同一个网段,所以数据包会交给网关10.1.1.1
dip: 61.3.2.4
Router收到客户端发送过来的数据包,会判断该数据包是否是被路由本身还是要求路由转发
sp: 1028
dp: 80
sip: 10.1.1.88
dip: 61.3.2.4 <---路由器发现数据包的目标IP不是路由器设备配置的IP,路由器判断该数据包是需要路由把它转发出去。
路由在把数据包转发到公网的时候,必须把数据包中的源IP修改成公网IP
sp: 1028
dp: 80
sip: 210.38.224.128 <---把原来的10.1.1.88修改成路由的公网IP。并且做好相应的记录
dip: 61.3.2.4
NAT
网络地址转换(网络地址映射)
就是把数据包的源IP或者目标IP进行修改。
作用:
修改源IP,叫源地址映射,一般为了实现让私有网络的机器能够访问互联网
修改目标IP,叫目标地址映射,一般为了实现让互联网的机器能够访问私有网络的机器。
可以保护内网的资源。
clients<---- eth0:Router:eth1 -----> 互联网
clients
eth010.1.1.88
gw10.1.1.1
Router
eth010.1.1.1
eth1210.38.224.128
假设现在客户端需要访问互联网的web服务器 http://www.baidu.com <--- 61.3.2.4
sp: 1028
dp: 80
sip: 10.1.1.88 <--- 源IP和目标不是同一个网段,所以数据包会交给网关10.1.1.1
dip: 61.3.2.4
Router收到客户端发送过来的数据包,会判断该数据包是否是被路由本身还是要求路由转发
sp: 1028
dp: 80
sip: 10.1.1.88
dip: 61.3.2.4 <---路由器发现数据包的目标IP不是路由器设备配置的IP,路由器判断该数据包是需要路由把它转发出去。
路由在把数据包转发到公网的时候,必须把数据包中的源IP修改成公网IP
sp: 1028
dp: 80
sip: 210.38.224.128 <---把原来的10.1.1.88修改成路由的公网IP。并且做好相应的记录
dip: 61.3.2.4
=======================================================================
例子1:使用iptables直接实现软路由功能,实现正向代理
正向代理: 利用源地址映SNAT射实现让内部网络的客户访问互联网
拓扑图:
内网|可以访问互联网
client<--> virbr6: Router:br0---->
Router
br0 是可以用来访问互联网的网卡 172.16.2.21/16
virbr6 是虚拟化中的hostonly的一个网卡 192.168.29.1
client
192.168.29.11
gw: 192.168.29.1
sp: 2535
dp: 80
sip: 192.168.29.11
dip: 210.38.244.8
部署:
一、配置router(宿主机)
1、确保router本身可以访问互联网
172.16.2.0/16
GW: 172.16.2.1
2、打开路由转发
默认情况,Linux操作接受到的数据包中目标IP 如果不是本机的设备上绑定的IP,就会丢弃。如果是要Linux 软路由,路由的功能就是可以转发数据包的。所以需要打开路由转发功能,才能让Linux转发这些不属于它的所有数据包。
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
。。。。
马上生效
# sysctl -p
马上生效,但临时的,下次重启系统就失效
# echo "1" > /proc/sys/net/ipv4/ip_forward
3、添加iptables规则,实现SNAT
# iptables -t nat -A POSTROUTING -s 192.168.29.0/24 -o br0 -j SNAT --to-source 172.16.2.21
二、部署客户机
1、设定正确IP,DNS
2、设定正确网关,网关根据拓扑图应该设定为Router's virbr6的IP : 192.168.29.1
验证:
1、使用客户端访问互联网。
2、通过抓取数据包验证原理
顺着数据包的流通方向去抓包
# tcpdump -n tcp port 80 -i virbr6
# tcpdump -n tcp port 80 -i br0
如果需要iptables实现对转发的请求做过滤,应该是把规则放在filter表中FORWARD链
# iptables -t filter -A FORWARD -d www.baidu.com -j DROP
先会把域名www.baidu.com解析成IP。如果存在多个IP就会自动添加多个规则。
结果: 使用iptbales实现对七层协议的过滤非常不方便,而且不够准确,所以一般不是用iptables直接实现7层过滤
为了能够更好实现7七层过滤,实现更多过滤功能,使用iptables是很难实现的,所以建议使用7层代理软件, 比较出名的有squid,varnish等。
实现: 域名的过滤,以及文件类型的过滤等,实现限速,限制ip,限制MAC等等。
squid能够非常好的支持http协议的代理,而且还有缓存的功能,能够“加速”访问,默认支持缓存静态文件: js,html,图片,swf,电影文件等。
内网|可以访问互联网
client<--> virbr6: Squid:br0---->
例子:使用squid实现正向代理
原理: 客户端所有的http访问请求都交给了squid,由squid理解了请求之后,亲自代理客户端去访问相应的资源,然后再把资源返回给客户端,其实是“squid去上网,把结果告诉客户端”。
只需要保证客户端可以与squid正常通讯就能让客户端上网,而客户端根本不需要设定网关,dns。
内网|可以访问互联网
client<--> virbr6: Squid:br0---->
Router
br0 是可以用来访问互联网的网卡 172.16.2.21/16
virbr6 是虚拟化中的hostonly的一个网卡 192.168.29.1
client
192.168.29.11
gw: 192.168.29.1 <---可选。如果只是为了访问http的资源,可以不设定网关
一、部署squid
先把上个实验的iptables规则清空,把iptables恢复到最原始的状态
1、给squid设定正确IP和网关,保证squid服务器可以上网
2、安装源码包的squid
# groupadd -g 23 squid
# useradd -g 23 -u 23 squid
# tar xvf squid-3.1.19.tar.gz -C /usr/src
# ./configure --prefix=/usr/local/squid --enable-disk-io --enable-async-io=12 --enable-storeio="ufs,aufs,diskd" --enable-icmp --enable-delay-pools --enable-useragent-log --enable-referer-log --enable-arp-acl --enable-ssl --enable-cache-digests --enable-linux-netfilter --enable-linux-tproxy --with-large-files
# make -j2 && make install
3、配置squid
# cd /usr/local/squid/etc
# vim squid.conf
....
acl badweb dstdomain .qq.com
http_access deny badweb
http_access allow localnet <--原来具有
http_access allow localhost <--原来具有
http_access deny all <--原来具有
cache_dir ufs /usr/local/squid/var/cache 2000 16 256
access_log /usr/local/squid/var/logs/access.log squid
cache_effective_user squid
cache_effective_group squid
visible_hostname squid.upl.com
dns_nameservers 8.8.8.8
cache_mem 1024 MB
maximum_object_size 200 MB
# mkdir -p /usr/local/squid/var/cache
# chown squid:squid /usr/local/squid/var/cache
# chown squid:squid /usr/local/squid/var/logs/
首次运行之前必须对缓存目录进行初始化
# /usr/local/squid/sbin/squid -z
启动:首次启动,建议使用调试模式
# /usr/local/squid/sbin/squid -N -d 1
以后如果先直接放在后台运行服务
# /usr/local/squid/sbin/squid
# lsof -i:3128
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
squid 15499 squid 13u IPv6 164214 0t0 TCP *:squid (LISTEN)
二、客户端
客户端仅仅保证可以与squid能够正常通信。
然后设定浏览的代理
firefox --- 编辑--首选项---高级---网络--设置--手工设置代理