• tproxy透传用户ip方法和原理


    haproxy透传用户ip-方法和原理

    参考URL: https://blog.csdn.net/frockee/article/details/78641188

    为了透传用户ip到后端server, proxy机器需要解决两个问题:

    1.在创建到后端server的套接字时, 将用户ip作为套接字的源ip,从而让后端server看到;

    2.后端server在回包时, 能够将目的地为用户ip的回包,返回给proxy机器,而proxy机器能够将该包,从网卡驱动(链路层)收下来,并正确递交给应用层的haproxy进程

    为了解决这两个问题,haproxy进程和所在机器需要做三个事情:

    1.haproxy进程在创建到后端server的tcp套接字时,开启IP_TRANSPARENT选项, 并绑定用户ip为源ip;

    2.后端server修改路由规则,将目的地为用户ip的回包,路由给proxy机器;

    3.proxy机器在处理回包时, 在ip层, 由TProxy通过结合netfilter/iptables, 对该回包做一些小动作,将该回包的skb->sk = sk(sk为haproxy进程创建的对应套接字),从而让tcp层能够根据skb->sk, 将该回包递交给haroxy进程进行处理,最终返回给客户端

    上传一个经典问题配置:

     内网的客户机通过Linux主机连入Internet,而Linux主机与Internet连接时有两条线路,它们的网关如图所示。现要求对内网进行策略路由,所有通过TCP协议访问80端口的数据包都从ChinaNet线路出去,而所有访问UDP协议53号端口的数据包都从Cernet线路出去。

     这是一个策略路由的问题,为了达到目的,在对数据包进行路由前,要先根据数据包的协议和目的端口给数据包做上一种标志,然后再指定相应规则,根据数据包的标志进行策略路由。为了给特定的数据包做上标志,需要使用mangle表,mangle表共有5条链,由于需要在路由选择前做标志,因此应该使用PREROUTING链,下面是具体的命令。 

    iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 80 -j MARK --set-      mark 1  
    iptables -t mangle -A PREROUTING -i eth0 -p udp --dport 53 -j MARK --set-      mark 2 
    ip rule add from all fwmark 1 table 10  
    ip rule add from all fwmark 2 table 20 

    以上两条命令表示所有标志是1的数据包使用路由表10进行路由,而所有标志是2的数据包使用路由表20进行路由。路由表10和20分别使用了ChinaNet和Cernet线路上的网关作为默认网关,具体设置命令如下所示

    ip route add default via 10.10.1.1 dev eth1 table 10  
    ip route add default via 10.10.2.1 dev eth2 table 20 

      以上两条命令在路由表10和20上分别指定了10.10.1.1和10.10.2.1作为默认网关,它们分别位于ChinaNet和Cernet线路上。于是,使用路由表10的数据包将通过ChinaNet线路出去,而使用路由表20的数据包将通过Cernet线路出去

    PS:iptables中的mangle (修正)table 用于修改包的 IP 头。

      例如,可以修改包的 TTL,增加或减少包可以经过的跳数。

      这个 table 还可以对包打只在内核内有效的“标记”(internal kernel “mark”),后 续的 table 或工具处理的时候可以用到这些标记。标记不会修改包本身,只是在包的内核 表示上做标记。

    上述说明了一个问题:

    报文进入主机 过prerouteing的时候先过routing decide ;也就是先过netfilter框架在走路由;但是从本机发包时是先路由再走netfilter,如果走了netfilter后还需要过route

    以udp 发包为例: udp 首先路由,找到出口, 然后封装ip 层报文, 执行 ip_local_out 发送报文此时会遇到LOCAL_OUTPUT netfilter 节点;最后执行dst_output 函数hook 也就是:ip_output

    ip_route_output_flow->__ip_route_output_key->__mkroute_output,在__mkroute_output函数中设置rth->dst.output = ip_output;

     ip_output中会执行NF_INET_POST_ROUTING(有的内核版本在POST ROUTing 前会执行一次重新路由,因为之前的LOCAL_OUT可能替换DIP,代码见nf_nat_local_fn 函数)最后到ip_finish_output 发送报文 根据arp neighbor 表项组装L2 ;然后调用dev_queue_xmit 发送到驱动;

    目前遇到一个问题: 怎样直接更改内核协议栈 支持网桥模式和路由模式混合?

  • 相关阅读:
    详解瀑布流布局的5种实现方式及object-fit
    npm私服配置使用
    node快速计算md5
    ajax下载文件实现接受json数据和文件流两种形式
    mac items+sshpass实现服务器登录管理
    web前端私有化部署方案
    chrome devTool中请求各项参数含义
    electron-updater实现electron应用程序更新
    Electron-builder打包应用程序策略
    electron打包配置方案
  • 原文地址:https://www.cnblogs.com/codestack/p/15590038.html
Copyright © 2020-2023  润新知