策略路由

--


tcpdump         

    tcpdump - dump traffic on a network


    参数的分类:
    协议 tcp udp arp icmp
    数据内容 端口,Ip  :  
        src port 80 --源
        dst port 22 --目标

    tcpdump tcp dst port 80 -n
    tcpdump -i eth1 tcp dst port 80 -n   --小写i参数指定哪个网卡

    tcpdump tcp dst port 80 -n -w tcpdump.txt  --把dump出来的信息保存到tcpdump.txt文件
    tcpdump -r tcpdump.txt --然后需要使用tcpdump -r去读取


    关系参数 :  !   and   or

    tcpdump tcp dst port 80 -n and src 10.2.2.4
    tcpdump tcp dst port 80 -n and ! src 10.2.2.4
    tcpdump tcp dst port 80 -n and  host  10.2.2.4


    -vv <---把数据包的详细内容都记录下来
    -w <---把数据保存到某个文件

======================================================================
    练习:
捕捉所有访问本机ftp服务器的连接,并且数据包是来自10.2.2.4
tcpdump tcp dst port 21 and src 10.2.2.4 -n


捕捉所有来自10.2.2.1的arp协议的数据包,并且捕捉的显示要求输出以太网数据帧的信息 -e    
tcpdump arp and src 10.2.2.1 -n -e


捕捉所有本机web服务回应10.2.2.4的数据包
tcpdump tcp src port 80 and dst 10.2.2.4



图形的抓包工具:wireshark

yum install wireshark*

===================================================================================

linux 高级路由  策略路由


lartc(linux advanced routing and traffic control)


http://www.lartc.org


# rpm -qa |grep iproute     --iproute2工具包软件
iproute-2.6.32-31.el6.x86_64

ip命令就属于iproute2软件包

ip addr
ip neigh
ip rule
ip route
ip tunnel


=============================================================


# ip rule list
0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default



# cat /etc/iproute2/rt_tables   
--上面的local对应数字255,在rhel5.7里ip rule list看到的不是local,而是255;这只是对应的两种名称而已
#
# reserved values
#
255 local
254 main
253 default
0   unspec
#
# local
#
#1  inr.ruhep



# ip route list/show table local/255
# ip route list/show table main/254
# ip route list/show table default/253



================================================================================



        50 内网用户    ----------》路由器1--》 猫1  (快网络)



        50 内网用户  ---------》路由器2 --》 猫2  (慢网络)




应用实例1:                 
                ----------》路由器1--》 猫1  (快网络)
                |   
                |   
    100  内网用户  ----linux路由
                |   
                |           
                 ---------》路由器2 --》 猫2  (慢网络)


linux路由器有两条上网线路,一个快,一个慢
有这样的需求:内网用户需要给钱共享上网,有人给钱多,需要快线路,有人给钱少,需要快线路,这样的话,我们就可以使用策略路由了



模拟的话使用下面的图:



                        10.1.1.8
                ----------》VM2(vmnet0)     线路一
                |   
    1.1.1.128       |       10.1.1.9  vmnet0    
      VM1(vmnet1)----linux路由1.1.1.1   vmnet1        公网
                |       2.2.2.1   vmnet2    
                |
                 ---------》VM3 (hostonly2)  线路二
                        2.2.2.128 


上图架构中:
1.把VM1网关指向1.1.1.1
2,把linux路由器的网关指向10.1.1.8
3.linux路由打开ip_forward
4,这四台的iptables都关闭


先测试:在VM1上ping一个外网IP(如 ping 8.8.8.8),这个时候在VM2和VM3上抓包,但只能在VM2上抓到相关的包,表示数据包从VM2出去
# tcpdump -i eth0  icmp and src 1.1.1.128

然后通过下面的策略让VM1ping的包从VM3出去


下面就是在linux路由上进行操作来实现:


操作命令:
echo 200 t1 >> /etc/iproute2/rt_tables
ip rule add from 1.1.1.128  table t1  
ip route add default via 2.2.2.128 dev vmnet2 table t1
ip route flush cache


--如果加错了规则,想删掉,就使用ip rule del table t1删除规则,再ip route del table t1删除t1路由表


操作完后,测试
1,在内网ping 8.8.8.8
2,在两个模拟外网路由器的机器上抓包
# tcpdump -i eth0  icmp and src 1.1.1.128
3,结果这次只能在VM3上抓到包,OK



应用实例2:

                        10.1.1.8    线路一
                ----------》VM2(vmnet0)
                |   
    1.1.1.128       |       10.1.1.9  vmnet0    
      VM1(vmnet1)----linux路由1.1.1.1      vmnet1        公网
                |       2.2.2.1   vmnet2    
                |
                 ---------》VM3 (hostonly2)  
                        2.2.2.128   线路二



要实现不同类型的包走不同的线路:如80的访问走一条线,其它的走另外一条线路
实现不同类型的包的策略路由,就要借助于iptables的mangle表的set mark功能



1,在linux路由器上使用策略路由实现


# iptables -t mangle -A PREROUTING -i vmnet1 -p tcp --dport 80 -j MARK --set-mark 1     --把从内网进来要出去的80的包打标记为1


# echo 100 http.out >> /etc/iproute2/rt_tables  --建一张叫http.out的表,表编号100

# ip rule add fwmark 1 table http.out pref 20000  --指定打了标记为1的所有包都走http.out这张路由表,并指定优先级为20000(这里优先级可以不指,因为只有这一条策略)
# ip route add default via 2.2.2.128 dev vmnet2 table http.out  --指定http.out表从vmnet8出去找2.2.2.128
# ip route flush cache      --刷新路由缓存




2,测试
测试一:在内网1.1.1.128客户端上
elinks 8.8.8.8

在模拟两个线路的机器上都执行下面的命令
tcpdump -i eth0 tcp port 80
--只有线路二上能抓到包,OK


测试二:在内网1.1.1.128客户端上
ping 8.8.8.8

在模拟两个线路的机器上都执行下面的命令
tcpdump -i eth0  icmp
--只有线路一上能抓到包,OK


--从上面就可以看到出去的80端口的包和其它的包走的路线不一致


iptables的mangle表打标记的应用举例:
1,刚讲的例二
2,iptables的mangle打标记+tc 做流量控制(这个课程不讨论,有兴趣上网去搜)
3,iptables的mangle打标记+LVS 做负载均衡



============================================================================


问题:

要求:写出这个电信用户访问到双线web服务器时的IP变化过程(只写源IP,目标IP,和做SNAT还是DNAT等)
你觉得有没有问题?


192.168.1.100                      192.168.2.100
        电信用户        网通用户
          |           | 
192.168.1.1   |       |            192.168.2.1
        电信用户家里路由器     网通用户家里路由器     
51.1.2.3      |      |      61.1.2.3
          |www.abc.com   |              
          |      |
71.1.2.3          |       |     81.1.2.3
         机房电信路由器   机房网通路由器
10.1.1.1      |           |     172.16.2.1
          |      |
          |      | 
10.1.1.100     eth0 双线web服务器 eth1       172.16.2.100


电信用户和网通用户通过智能DNS分别去访问电信或网通线路

SIP:192.168.1.100   DIP:71.1.2.3
到达电信用户家用路由器手动SNAT
SIP:51.1.2.3        DIP:71.1.2.3
到达公司电信路由器手动DNAT
SIP:51.1.2.3        DIP:10.1.1.100
到达web服务器返回(网关指向10.1.1.1)
SIP:10.1.1.100      DIP:51.1.2.3
返回到公司电信路由器自动SNAT
SIP:71.1.2.3        DIP: 51.1.2.3
到达电信用户家用路由器自动DNAT
SIP:71.1.2.3        DIP:192.168.1.100


问题是:
电信的用户回去时,把双线web服务器网关要指向10.1.1.1
网通的用户回去时,把双线web服务器网关要指向172.16.2.1
那么按前面所学的知识,同一个路由表只能有一个可用网关,如果可用网关为电信路由器内网IP;那么实现的是电信进来的包从电信回,网通进来的包也从电信回.问题出现了

如果在双线web服务器上不加网关,用加路由的方式来做的话,
那么
route add -net 51的网段 netmask  x.x.x.x dev eth0
route add -net 61的网段 netmask  x.x.x.x dev eth1
同理还得加网通的,但是这也有一个问题,实际情况电信和网通的用户网段太多了,
你不可能全加上去



应用实例3:

实际情况下的图示,如果做实现得需要七台虚拟机


192.168.1.100                      192.168.2.100
        电信用户        网通用户
          |           | 
192.168.1.1   |       |            192.168.2.1
        电信用户家里路由器  网通用户家里路由器    
51.1.2.3      |      |      61.1.2.3
          |www.abc.com   |              
          |      |
71.1.2.3          |       |     81.1.2.3
         公司电信路由器   公司网通路由器
10.1.1.1      |           |     172.16.2.1
          |      |
          |      | 
10.1.1.100     eth0 双线web服务器 eth1       172.16.2.100



精简一点可以使用下面的四台虚拟来做,并且要注意宿主机(真实机)不能在这里扮演角色,因为宿主机和任何虚拟机都是可以直接通的
下图中,电信客户端和网通客户端就没有使用去模拟路由器NAT,直接用一台虚拟机用两个网卡来模拟两个角色




172.16.2.51     vmnet0  客户端  vmnet2 2.2.2.129
          |      |
          |      |              
          |      |
172.16.2.41 vmnet0      vmnet2  2.2.2.128
         机房电信路由器1    机房网通路由器2
1.1.1.128   vmnet1      vmnet8  3.3.3.128
          |      |
          |      | 
1.1.1.129   vmnet1 双线服务器 vmnet8 3.3.3.129




--假设上图里的客户端为内网用户,服务器为公网服务器;
--因为是模拟环境,所以这里两个路由器打开ip_forward,但上面四台都不用指网关
--我们实现的是当客户端用电信线路访问,也只能从电信线路返回;网通线路访问,也只能从网通线路返回



先在电信路由器和网通路由器上做好SNAT和DNAT,这样就不用把电信客户端的外网IP的网关指向电信路由器的外网IP了
(因为实际的公网IP,不会把网关指向你的,这个在讲iptables的SNAT就讨论过)



电信路由器上写两条(还要打开ip_forward) --也可以只写DNAT,SNAT那条不写它包会自动回来SNAT的

iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 1.1.1.129
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.16.2.41

网通路由器上写两条(还要打开ip_forward)  --也可以只写DNAT,SNAT那条不写它包会自动回来SNAT的

iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 3.3.3.129
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 2.2.2.128


--上面四条当中的eth0自己换成对应的网卡名;电信路由器上的网卡名应该都为172.16.2.41的网卡名;网通路由器上的网卡名应该都为2.2.2.128的网卡名



做好上面四条和打开路由器的ip_forward后,并且默认上图所有的机器里现在都没有网关
在双线web服务器这台启动apache,随便做一个主页测试

验证:
1,在客户端elinks 172.16.2.41,得不到结果
  在客户端elinks 2.2.2.128,得不到结果
2,上面两个线路都得不到结果,是因为能到web服务器,但回不来
所以把web服务器网关指向1.1.1.128的话,则再测试,只有elinks 172.16.2.41能得到结果
    把web服务器网关指向3.3.3.128的话,则再测试,只有elinks 2.2.2.128能得到结果
3,也就是说,现在无法实现电信线路和网通线路都能访问成功;所以我们要借助于策略路由


1,在双线web服务器上使用策略路由实现

# ip rule
0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 


# echo 100 dianxin >> /etc/iproute2/rt_tables 
# echo 200 wangtong >> /etc/iproute2/rt_tables 

# ip rule add from 1.1.1.129 table dianxin
# ip rule add from 3.3.3.129 table wangtong

# ip route add default via 1.1.1.128 table dianxin
# ip route add default via 3.3.3.128 table wangtong



# ip rule
0:  from all lookup local 
32764:  from 3.3.3.129 lookup wangtong 
32765:  from 1.1.1.129 lookup dianxin 
32766:  from all lookup main 
32767:  from all lookup default



测试:
再在客户端
elinks 172.16.2.41,能访问到web
elinks 2.2.2.128,也能访问到web
说明电信线路的包只走电信线路,网通线路的包只走网通线路

如果要深入测试的话,可以在客户端elinks电信线路的172.16.2.41时,去双线web服务器上双线路网卡都去tcpdump,会发现只有电信的网卡有包;网通的没有
反之,亦然


===================================================================================


应用实例4:


有些情况一个服务器多张网卡配置成同一个网段(这种做法是不正确的),
因为同一个网段,那么这多张网卡使用的路由是同一条,无法将他们区分开来
(从不同网卡进来的包,一般都会从eth0出去)
如果你想要实现从哪里进,从哪里去,使用iproute2对多张网卡设定不同的网关就可以(优先级要高于main表,也就是route -n看到的)

做法参考实例3

=====================================================================




dns 视图(dns view)
Berkeley Internet Name Domain (BIND)  --伯克利网络名字域


CDN 内容分发网络  (content  distributed network)
将网站源服务器中的内容存储到分布于各地的CDN网络节点上,通过智能网络流量分配控制系统,
将终端用户的访问请求自动指向健康可用且距离本地最近的CDN专用服务器上,以提高用户访问
的响应速度和服务的可用性,改善互联网上的服务质量。


bind+squid  实现基本CDN

    分布式缓存服务器(只缓存常用的网站静态元素)  + 智能DNS(DNS view)

www.abc.com  --》 不同的IP


有判断功能的DNS

                内蒙电信用户

        新疆用户        北京


             成都 武汉    上海                


                广州              
               (网站源在深圳)




IP库如何获得?

IANA(互联网数字分配机构,internet assigned numbers authority)

ARIN (American registry for internet numbers)
北美,南美

RIPE
欧洲,中东,北非

APNIC
亚洲,大洋洲


www.apnic.net
这个网站上有一个叫whois数据库,可以查询所有的公网IP现在被分配到哪


参考网址:
http://bbs.chinaunix.net/thread-577601-1-1.html



--使用下面的脚本,就会在当前运行的目录下产生chinanet(电信),unicom(网通),others(其它)这三个IP库文件
# vim ripe.sh 
#!/bin/sh
mkdir /root/apnic -p
FILE=/root/apnic/ip_apnic
wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest -O $FILE
grep 'apnic|CN|ipv4|' $FILE | cut -f 4,5 -d'|'|sed -e 's/|/ /g' | while read ip cnt
do
echo $ip:$cnt
        mask=`cat << EOF | bc | tail -1
pow=32;
define log2(x) {
if (x<=1) return (pow);
pow--;
return(log2(x/2));
}
log2($cnt)
EOF`
       echo $ip/$mask>> cn.net
if whois $ip@whois.apnic.net | grep -i ".*chinanet.*\|.*telecom.*">/dev/null;then
echo $ip/$mask >> chinanet
elif whois $ip@whois.apnic.net | grep -i ".*unicom.*">/dev/null;then
echo $ip/$mask >> unicom
else
echo $ip/$mask >> others
fi
done

--注意:如果上面的脚本要在rhel6里执行的话,则yum install jwhois  -y(这个软件包包括了whois命令)


===============================================================

实践:上面我做的IP库是电信与网通的IP库


如果我现在是按地域来划分的,假设我划分成(北京,成都,上海,深圳,武汉)这五个CDN节点,请尝试把他们的IP库给做出来
(地域的划分情况随你自己,比如湖南离武汉和深圳都比较近,你要划分到哪一个区域自己定)


                北京


             成都 武汉    上海                


                广州              
               (网站源在深圳)

#!/bin/sh
mkdir /root/apnic -p
touch /root/apnic/ip_apnic
FILE=/root/apnic/ip_apnic
rm -f $FILE
wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest -O $FILE
grep 'apnic|CN|ipv4|' $FILE | cut -f 4,5 -d'|'|sed -e 's/|/ /g' | while read ip cnt
do
echo $ip:$cnt
        mask=`cat << EOF | bc | tail -1
pow=32;
define log2(x) {
if (x<=1) return (pow);
pow--;
return(log2(x/2));
}
log2($cnt)
EOF`
       echo $ip/$mask>> cn.net
if whois $ip@whois.apnic.net |grep descr:|head -1| grep -i ".*xinjiang.*\|.*tibet.*\|.*qinghai.*\|.*gansu.*\|.*yunnan.*\|.*sichuan.*">/dev/null;then
echo $ip/$mask >> chengdu
elif whois $ip@whois.apnic.net |grep descr:|head -1| grep -i ".*neimeng.*\|.*ningxia.*\|.*shanxi.*\|.*hebei.*\|.*beijing.*\|.*tianjin.*\|.*shandong.*\|.*liaoning.*\|.*jilin.*\|.*heilongjiang.*">/dev/null;then
echo $ip/$mask >> beijing
elif whois $ip@whois.apnic.net |grep descr:|head -1| grep -i ".*shannxi.*\|.*shaanxi.*\|.*henan.*\|.*chongqing.*\|.*hubei.*\|.*hunan.*\|.*jiangxi.*">/dev/null;then
echo $ip/$mask >> wuhan
elif whois $ip@whois.apnic.net |grep descr:|head -1|grep -i ".*guangxi.*\|.*guangdong.*\|.*hainan.*\|.*fujian.*\|.*hk.*\|.*macau.*">/dev/null;then
echo $ip/$mask >> shenzhen
elif whois $ip@whois.apnic.net |grep descr:|head -1| grep -i ".*anhui.*\|.*zhejiang.*\|.*jiangsu.*\|.*shanghai.*">/dev/null;then
echo $ip/$mask >> shanghai
else
echo $ip/$mask >> others
fi
done


--注意:上面的脚本产生的结果大部分应该是没问题的,但也有一些会存在分配的问题,改脚本或者是单独处理肯定是可以解决的;这里只是提供一个思路,不要把这个脚本直接用到真实环境


=====================================================================


DNS view 

根据你访问过来的IP对应ACL列表来判断,从而解析到不同的服务器主机
在CDN中应用很多,也是解决目前区域间带宽小和延迟大的问题的一种方法。



第一步:定义ACL文件  (用来放网段的文件,IP库)

# yum install bind* -y


[root@li ~]# vim /var/named/dianxin     --电信IP库
acl dx {
10.1.1.153;
10.1.1.101; --IP写法
200.11.22.0/24; --网段写法          
};


[root@li ~]# vim /var/named/wangtong    --网通IP库
acl wt {
10.1.1.73;
10.1.1.174;
100.10.20.0/24;
};



第二步:配置named.conf 


[root@li ~]# vim /etc/named.conf 


options {
    listen-on port 53 { any; }; --改为any
    listen-on-v6 port 53 { ::1; };
    directory   "/var/named";
    dump-file   "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
    allow-query     { any; };   --改为any
    recursion yes;

    dnssec-enable yes;
    dnssec-validation yes;
    dnssec-lookaside auto;

    bindkeys-file "/etc/named.iscdlv.key";

    managed-keys-directory "/var/named/dynamic";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

#zone "." IN {
#   type hint;
#   file "named.ca";        
#};

#include "/etc/named.rfc1912.zones";    --这里把上面的根域和子配置文件里所有域都注释掉;因为配置了视图,那么所有的域都得要配置才行,所以这里就直接注释不用
include "/etc/named.root.key";

--下面的就是在主配置文件上新加的


include "dianxin";
include "wangtong";


view "v1" {         --视图名,随便取
        match-clients {dx;};    --dx为acl名,而不是IP库文件名
        zone "cluster.com" IN {
                type master;
                file "data/dx.cluster.com.zone";
        };
};

view "v2" {
        match-clients {wt;};
        zone "cluster.com" IN {
                type master;
                file "data/wt.cluster.com.zone";
        };
};


view "v3" {
        match-clients {any;};       --any代表所有,这里一定要放在最后,匹配完了dx,wt,最后的所有都为others
        zone "cluster.com" IN {
                type master;
                file "data/others.cluster.com.zone";
        };
};



第三步:配置named.conf里定义的三个zone文件
# vim /var/named/data/dx.cluster.com.zone

$TTL 86400
@       IN      SOA     dx.     root.   (
                        2016012101
                        120
                        60
                        30
                        86400 )
        IN      NS      172.16.X.X. 
www     IN      A       1.1.1.1     --此为www.cluster.com域名的电信线路的IP,或者是在电信机房的服务器的IP


# vim /var/named/data/wt.cluster.com.zone

$TTL 86400
@       IN      SOA     wt.     root.   (
                        2016012101
                        120
                        60
                        30
                        86400 )
        IN      NS      172.16.X.X.
www     IN      A       2.2.2.2     --网通线路的


# vim /var/named/others.cluster.com.zone

$TTL 86400
@       IN      SOA     others.     root.   (
                        2016012101
                        120
                        60
                        30
                        86400 )
        IN      NS      172.16.X.X.
www     IN      A       3.3.3.3 --除了电信和网通外的用户指向的服务器IP,如果你只有电信和网通两个线路,可以随意指向其中一个。但这里是实验,我假设有三个线路,所以这里指向第三个IP 3.3.3.3


第四步: 重启服务
    /etc/init.d/named restart


第五步: 测试


问题:上面做的是单机单域,多地域多运营商都要区分如何做?


也就是IP库文件要分得更细,
比如广东附近几个省的电信的IP段要单独一个IP库
    广东附近几个省的网通的IP段要单独一个IP库
    其它的类似


课外扩展:
上网查查类似腾讯dnspod,阿里dns,百度dns这种智能DNS服务运营商


======================================================================


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值