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 --- 编辑--首选项---高级---网络--设置--手工设置代理
使用squid+iptables实现透明代理
内网 |可以访问互联网
client<--> virbr6: Squid+iptables:br0---->
Squid+iptables
br0 是可以用来访问互联网的网卡 172.16.2.21/16
virbr6 是虚拟化中的hostonly的一个网卡 192.168.29.1
一、让安装squid和iptables的机器作为代理服务器,并且让其可以访问互联网
1、给机器的物理网卡设定172.16.2.0/16网络中的Ip,保证其可以上网
# ifconfig br0:1 172.16.2.21 netmask 255.255.0.0
# route add default gw 172.16.2.1
# vim /etc/resolv.conf
nameserver 8.8.8.8
2、设定代理服务器的iptables规则,实现源地址映射
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
马上生效
# sysctl -p
为了不让之前的规则影响本次实验,暂时把原有的规则清空
# iptables -t nat -A POSTROUTING -s 192.168.29.0/24 -o br0 -j SNAT --to-source 172.16.2.21
二、让内部网络客户机测试是否可以访问互联网
仅仅需要让客户机配置正确网络信息:
根据网络划分,配置IP : 192.168.29.0/24
GW: 192.168.29.1 <---代理服务器的该网络的IP
设定DNS: 8.8.8.8
备注:
如果在实际网络中,为了方便客户能够更灵活访问互联网,可以在网络假设DHCP服务器。
三、在代理服务器上配置squid,实现透明代理设定
安装:略
配置squid
# cd /usr/local/squid/etc
# vim squid.conf
....
http_port 3128 transparent <--- transparent 实现透明代理,代理服务器起到了请求的过滤作用
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
四、设定iptables规则,让所有目标端口为80的数据包都截取然后转交给squid过滤
# iptables -t nat -A PREROUTING -s 192.168.29.0/24 -p tcp --dport 80 -j REDIRECT --to-ports 3128
3128端口是本机的squid监听的端口
五、增加更多的访问控制规则
格式
# acl aclname acltype argument ...
# acl aclname acltype "file" ... <---如果是引用文件的话,必须双引号
常用的acltype
dstdomain 匹配访问的目标域名
time匹配访问时间
url_regex匹配访问用的url网址,例如: http://www.qq.com/test/logo.jpg
urlpath_regex匹配访问用的ulr中的path
http://www.qq.com/test/logo.jpg <---url
/test/logo.jpg <--path
browser匹配浏览器(user_agent)
maxconn匹配访问的并发连接数
acl baddomaindstdomain.qq.com .youku.com
acl badurlurl_regex -isex sexy music film
匹配: http://www.baidu.com/q=sex
http://sex.sina.com.cn
acl badurlurlpath_regex -isex sexy music film \.rar$ \.flv$ \.avi$ \.rmvb$ \.mp3$
匹配: http://www.baidu.com/q=sex
不能匹配:http://sex.sina.com.cn/bbs/
browser
类似:
Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.24) Gecko/20111104 Red Hat/3.6.24-3.el6_1 Firefox/3.6.24
acl okagentbrowser-i Mozilla Firefox Chrome IE
acl worktimetimeMTWHF 09:00-18:00
acl userconnmaxconn8<---每个IP的客户端只允许同时建立最多8个连接
实现:
禁止访问部分域名
acl baddomain dstdomain "/usr/local/squid/etc/baddomainlist"
文件中,一个域名一行
# vim /usr/local/squid/etc/baddomainlist
.qq.com
.youku.com
.xunlei.com
.tudou.com
.sina.com.cn
只能在部分的时间内访问网络受限资源,其余时间无限制(上班时间接受多所有规则的限制)
acl worktimetimeMTWHF 09:00-18:00
禁止访问某些类型的资源
acl badpostfix urlpath_regex \.exe$ \.mp3$ \.rmvb$ \.flv$
禁止访问url中带有敏感关键字的资源
acl badkeyword url_regex sex sexy movie audio mp3 mp4 film dianying
限制访问浏览器
acl okagentbrowser-i Mozilla Firefox Chrome IE
限制访问的并发连接数
acl userconnmaxconn8
应用规则,必须注意顺序,匹配顺序是从上往下,匹配了之后就停止往下匹配
http_accessallow!worktime
http_accessdeny baddomain
http_accessdenybadpostfix
http_accessdenybadkeyword
# http_accessdenyuserconn <----- 由于浏览器和服务器的连接配置问题,很多时候超过8个连接导致无法访问,所以不要用这条规则
http_accessdeny!okagent
http_accessallowall
如果把规则保存到squid.conf,结合它原来的规则:
acl baddomain dstdomain "/usr/local/squid/etc/baddomainlist"
acl worktime time MTWHF 09:00-18:00
acl badpostfix urlpath_regex \.exe$ \.mp3$ \.rmvb$ \.flv$
acl badkeyword url_regex sex sexy movie audio mp3 mp4 film dianying
acl okagent browser -i Mozilla Firefox Chrome IE
acl userconn maxconn 8
http_access allow !worktime
http_access deny baddomain
http_access deny badpostfix
http_access deny badkeyword
http_access deny userconn
http_access deny !okagent
http_access allow localnet <---把我们定义的控制放在这条规则上面
http_access allow localhost
http_access deny all
=========================================================================
反向代理
方式:
1、直接使用iptables
2、squid 缓存-“加速” <---缓存服务器
3、lvs,haproxy,nginx,
4、apache
外部网络客户端<--------->反向代理服务器 <-----------> 内部的服务器
例子1:使用iptables实现反向代理,允许外部网络访问内部网咯的服务器的web服务
互联网 |内部受保护的私有网络
外部网络客户端pc<---------> br0: iptables : virbr6 <-----------> 内部的web服务器
外部网络客户端pc10.1.1.88
iptables[宿主机]
br010.1.1.21<---模拟成互联网,www.upl.com
virbr6192.168.29.1
内部的web服务器
192.168.29.13
客户端使用域名或者IP访问 http://www.upl.com 或者 http://10.1.1.21
sp: 1028
dp: 80
sip: 10.1.1.88
dip: 10.1.1.21
---> 来到iptables的机器,会对数据包进行匹配,判断是否满足iptables规则
规则: 如果数据包的目标IP是10.1.1.21,目标端口是80,那么就映射到内部网络的192.168.29.13
sp: 1028
dp: 80<--- 满足 tcp:80
sip: 10.1.1.88
dip: 10.1.1.21 <---满足
进行目标地址映射DNAT
sp: 1028
dp: 80
sip: 10.1.1.88
dip: 192.168.29.13 修改成了内部网络的web服务器的IP
iptables服务器就会对修改完的数据包进行路由判断,决定把包路由到内部网络
一、部署内部的web服务器
设定IP: 192.168.29.13
网关: 192.168.29.1
部署apache服务,随便建立一个测试首页
启动服务器,使用iptables服务器访问测试http://192.168.29.13
二、部署iptables服务器【宿主机】
1、打开路由转发
略
2、添加iptables规则
规则: 如果数据包的目标IP是10.1.1.21,目标端口是80,那么就映射到内部网络的192.168.29.13
清空原来规则
# iptables -t nat -A PREROUTING -p tcp --dport 80 -d 10.1.1.21 -j DNAT --to 192.168.29.13
例子2:使用squid实现反向代理,允许外部网络访问内部网咯的服务器的web服务
优点:
起到缓存的作用,“加速”作用,把所有静态文件都缓存到squid服务器,客户端重复去访问这些被缓存的文件的时候,就直接返回这些文件,不会让内部web服务器去处理这些请求,减轻后端服务器的压力
使用squid简单的轮询功能,实现简单的负载均衡集群功能。
互联网 |内部受保护的私有网络
外部网络客户端pc<---------> br0: squid : virbr6 <-----------> 内部的web服务器
实现前:把上一个实验的iptables规则清空
http://www.upl.com/cccc
一、部署内部的web服务器
设定IP: 192.168.29.13
网关: 192.168.29.1
部署apache服务,随便建立一个测试首页
启动服务器,使用iptables服务器访问测试http://192.168.29.13
<h1 style="color:red">web server </h1>
<img src=\'#\'" /meizi.jpg" />
二、部署squid
安装略
配置:
# vim /usr/local/squid/etc/squid.conf
#http_access allow !worktime
#http_access deny baddomain
#http_access deny badpostfix
#http_access deny badkeyword
#http_access deny userconn
#http_access deny !okagent
#http_access allow localnet
#http_access allow localhost
http_access allow all <---允许所有请求
http_port 80 accel vhost vport
cache_peer 192.168.29.13 parent 80 0 originserver name=web1
cache_peer_domain web1 www.upl.com
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)
客户端验证:
注意:客户端必须在hosts文件绑定 www.upl.com 解析到 10.1.1.21(squid公网IP)
[root@www ~]# curl -I http://www.upl.com/test.jpg
HTTP/1.0 200 OK
Date: Sat, 03 Aug 2013 01:53:10 GMT
Server: Apache/2.2.3 (Red Hat)
Last-Modified: Sat, 03 Aug 2013 01:52:51 GMT
ETag: "2789f0-322f-4e301553742c0"
Accept-Ranges: bytes
Content-Length: 12847
Content-Type: image/jpeg
X-Cache: MISS from squid.upl.com <---缓存没有
X-Cache-Lookup: MISS from squid.upl.com:80
Via: 1.0 squid.upl.com (squid/3.1.19)
Connection: keep-alive
[root@www ~]# curl -I http://www.upl.com/test.jpg
HTTP/1.0 200 OK
Last-Modified: Sat, 03 Aug 2013 01:52:51 GMT
Accept-Ranges: bytes
Content-Length: 12847
Content-Type: image/jpeg
Date: Sat, 03 Aug 2013 01:53:42 GMT
Server: Apache/2.2.3 (Red Hat)
ETag: "2789f0-322f-4e301553742c0"
Age: 28802
X-Cache: HIT from squid.upl.com (缓存命中)
X-Cache-Lookup: HIT from squid.upl.com:80
Via: 1.0 squid.upl.com (squid/3.1.19)
Connection: keep-alive