Chinaunix首页 | 论坛 | 博客
  • 博客访问: 436967
  • 博文数量: 71
  • 博客积分: 26
  • 博客等级: 民兵
  • 技术积分: 1246
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-23 14:46
个人简介

linux --- 一切皆文件

文章分类

全部博文(71)

文章存档

2021年(1)

2019年(2)

2018年(4)

2017年(7)

2016年(11)

2015年(1)

2014年(2)

2013年(33)

2012年(10)

分类: LINUX

2018-02-03 21:01:20

 Linux应用流量和管理流量分离实战
=======================

本文主要介绍在Linux下使用高级路由功能,实现应用流量和管理流量分离。

## 场景简介

当这个网络设备作为转发设备使用时,设备会从NIC0,NIC1进行收包,在网络设备上进行处理,处理完之后,通过**默认路由**,再次回到应用业务网。但是应用业务网络流量比较大,不适合做ssh登录管理使用,而且业务网和应用网一般最好是隔离的。

因此我们使用服务器的千兆口MGT-NIC作为ssh登录管理口,链接到管理交换网。但是ssh到此台设备的IP地址可能是公司内任意网段,而且这个网段可能随时增加,因此去管理交换网的流量也需要一条**默认路由**指向管理交换网。

这样问题就来了,一台Linux服务器如何两个不同的默认网关,并且管理业务和应用业务完全正常呢?



## 网络服务器被动访问

#### 知识点

Linux其实有好几张路由表。默认我们通过命令**ip route list**看到的知识main域的路由表,其实linux默认有三张路由表,可通过**ip rule**查看,Linux在慢转的情况下,会去遍历如下所有域的路由(包括后续我们自己添加的域),直到第一个匹配为止,全部不匹配则丢包。分别如下:

    优先级0:优先级最高的local域路由
    优先级32766:优先级倒数第二的main域
    优先级32767:优先级最低的default域

可通过命令

    ip route list table [table name or table id]
    example: 
        ip rule list table local
        ip rule list table 0

正常情况下,通过ip route 命令添加的路由信息是放在main域的,因此我们把应用业务网的默认路由放在main域,通过如下命令添加:

    ip route add default nexthop via 1.1.1.1 dev nic0 weight 10  nexthop via 1.1.1.5 dev nic1 weight 10
    这样就会形成两条等价:
    default
        nexthop via 1.1.1.1  dev nic0 weight 10
        nexthop via 1.1.1.5  dev nic1 weight 10

**此时如果还在main域添加默认路由是添加不上的。**

此时问题就来了:

如果公司内任意IP访问192.168.1.10这个地址,并且Client IP的网段不在此服务器的明细路由中,这样回包路由就会走到main域的default路由,此时回包会送到应用业务网中,导致管理流量异常,无法管理此服务器。当然是可以在服务器上添加管理交换网的明细路由,但是管理交换网网段随时可能增加,此时需要人工去维护服务器上的管理网路由表,比较麻烦。

#### 问题解决方案

此时基于源IP的策略路由登场,我们可以配置基于源IP的策略路由:

    ip rule add pri 32765 from 192.168.1.10 table 8 
    ip rule查看路由域如下:
        0:      from all lookup local 
        32765:  from 192.168.1.10 lookup 8
        32766:  from all lookup main 
        32767:  from all lookup default 
    此命令的含义:
        添加一个规则,优先级为32765,如果源IP是192.168.1.10则去匹配table 8域中的路由。
        又因为这条规则优先级高于main域,所以如果报文的源IP是192.168.1.10的则会去table 8域中查找路由。

随后在table 8域中添加一条默认路由:

    ip route add default via 192.168.1.1 dev mgt-nic table 8
    查看路由表:
    ip route list table 8
        default via 192.168.1.1 dev mgt-nic

此时公司内部任意网段都可以ssh到此服务器进行管理了,流程大致如下:

1. client tcp 访问192.168.1.10
2. 服务器肯定以192.168.1.10为源IP返回给Client
3. 此时匹配了基于源IP的策略路由,并且去查找table 8域中的路由表
4. 在table 8域中有一条default路由,是从mgt-nic发出的,因此可以正常回到client处

## 服务器主动访问

当服务器要主动访问应用网中的其他业务,比如DNS,NTP,HTTP API,salt主动注册等业务时,如果只配置上一节提供的路由,则会出现问题的。**注意:此时主动访问的网段还是不在main域的明细路由中**

#### 知识点

首先要知道Linux主动请求时,如何选择发包的源IP。我们在写Linux Socket程序是,通常会指定目的IP,很少会指定源IP,**那么Linux是如何确定发包的源IP的呢?**

发包时,Linux会根据目的IP查找路由表(Linux只会匹配local、main、default这三个域),匹配了路由表,那么源IP则是这条路由表的出接口的IP,如果路由条目指定src,则使用指定的src作为源IP。查找源IP时不会去找table 8域的路由,因此进入main域查找。

最终目的IP会匹配到main域default路由,main域default路由的设备IP为1.1.1.1,1.1.1.5,则以1.1.1.1或1.1.1.5作为原IP,这样就不会匹配table 8域的默认路由,最终数据包会从nic0或nic1进入应用业务网,导致流量无法走入管理交换网。

#### 问题解决方案

在main域的default路由上指定src,这样主动请求时,匹配到main域的default路由,则会使用我们指定的src作为原IP,而不是设备接口地址,配置如下:

    ip route add default src 192.168.1.10 nexthop via 1.1.1.1 dev nic0 weight 10  nexthop via 1.1.1.5 dev nic1 weight 10

    ip route list显示如下:
        default src 192.168.1.10
            nexthop via 1.1.1.1  dev nic0 weight 10
            nexthop via 1.1.1.5  dev nic1 weight 10

此时发包流程如下:

1. Linux socket发包,根据目的IP查找路由,最后匹配main域default路由
2. 将main域default路由上指定的src 192.168.1.10作为源IP
3. 发包时则会匹配基于源IP的策略路由规则
4. 然后查找table 8,table 8中有去管理网的默认路由
5. 此时流量能正常进入应用网

**注意:在测试过程中,发现只有TCP能以源IP192.168.1.10从管理网出去,但是UDP和ICMP是以192.168.1.10为源IP从应用业务网出去了,这是大问题**

## 服务器主动访问--udp/ICMP选路异常

我们虽然在main域的default路由上指定了发包源IP,但是udp和ICMP使用的是快转,**在查找发包源IP的时候,直接选择main域的default路由的出接口作为发包接口,不会去再次查找路由表。**

#### 知识点

tcp在发包时,获取源IP之后,发包时还会去路由表查找出接口的,走的是慢转。但是udp和icmp走的是快转,发包时不会再查找。因此我们如何强制UDP和ICMP也走慢转呢?

#### 解决方案

Linux iptable mangle中可以给报文打MARK,打了mark之后,报文发包时会找所有域的路由表,并且匹配相应规则的mark号,然后查找相应的路由表。

首先在OUTPUT Hook点上给报文打MARK:

    /sbin/iptables -F -t mangle        #清空mangle规则
    /sbin/iptables -A OUTPUT -t mangle -p udp -j MARK --set-mark 1    #本地发出的udp报文打上mark1标记
    /sbin/iptables -A OUTPUT -t mangle -p tcp -j MARK --set-mark 1    #本地发出的tcp报文打上mark1标记
    /sbin/iptables -A OUTPUT -t mangle -p icmp -j MARK --set-mark 1    #本地发出的icmp报文打上mark1标记
    service iptables save        #保存规则到/etc/sysconfig/iptables中
    chkconfig iptables on        #设置开机启动

配置策略路由规则:

    源IP为192.168.1.10并且打上了mark1的报文去table 8域查找路由:

    /sbin/ip rule add pri 32764 from 192.168.1.10 fwmark 1 table 8

此时发包流程如下:

1. 从本地发出的报文,经过OUTPUT Hook点的报文,如果是UDP,TCP,ICMP的,全部打上mark1标签,并且走慢转
2. 在查找路由表时,匹配 from 192.168.1.10 fwmark 1
3. 查找table 8域中的路由表
4. table 8域中有去管理网的默认路由
5. 流量正确进入管理网

## 网络系统停运时,会删除main域default路由

服务器上正常运行的是网络转发系统会在main域添加default路由,并将src改成管理口IP,但是在网络系统停运后,会将main域的default路由删除,此时报文则无法找到default路由,并且主动访问时找不到源IP,从而导致发包异常。

#### 解决方案

在路由表中还有一个default域,我们可以在default域中添加一条去管理网的默认路由,这样即使main域中的default路由删除了,在发包时,也会去查找default域的路由的。因此可以解决main域default删除的问题。

命令如下:

    ip route add default via 192.168.1.10 dev mgt-nic table default
    查看命令:
    ip route list table default

## 完成配置命令

配置应用业务网默认路由,并且将src指定为管理口IP:

    ip route add default src 192.168.1.10 nexthop via 1.1.1.1 dev nic0 weight 10  nexthop via 1.1.1.5 dev nic1 weight 10

配置基于源IP的策略路由:

    ip rule add pri 32765 from 192.168.1.10 table 8 

配置table 8域的默认路由:

    ip route add default via 192.168.1.1 dev mgt-nic table 8

iptables给OUTPUT Hook点打mark:

    /sbin/iptables -F -t mangle        #清空mangle规则
    /sbin/iptables -A OUTPUT -t mangle -p udp -j MARK --set-mark 1    #本地发出的udp报文打上mark1标记
    /sbin/iptables -A OUTPUT -t mangle -p tcp -j MARK --set-mark 1    #本地发出的tcp报文打上mark1标记
    /sbin/iptables -A OUTPUT -t mangle -p icmp -j MARK --set-mark 1    #本地发出的icmp报文打上mark1标记

配置策略路由基于源IP,并且打mark1标记的报文进行策略:

    /sbin/ip rule add pri 32764 from 192.168.1.10 fwmark 1 table 8

最终配置default域默认路由:

    ip route add default via 192.168.1.10 dev mgt-nic table default
阅读(4430) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~