zoukankan      html  css  js  c++  java
  • 用iptables将流量转发到另外一台机器

    目的:

    当客户端访问某一个服务器端口时,将流量转发到另外一台服务器的某一个端口。

    客户端->转发服务器->目的服务器->转发服务器->客户端

    理论:

    首先看一下iptables处理流程。

    dport-routing-02

    这些操作使是在转发服务器上完成的。

    数据包从网卡进入,首先会被PREROUTING这个内置的规则链处理。之后会进行路由判断。如果目的地址是本机,则会走INPUT规则链,然后提交给本机程序处理;如果目的地不是本机地址,且开启了转发功能,则会经过FORWARD规则链,然后准备将数据包发出。本机要发出的数据包和经过FORWARD的数据包,会经过路由判断,然后再经过POSTROUTING规则链,最后从网卡发出。这里的ethX和ethY 可以是同一个网卡。

    为了能让数据包转发到目的地址,需要在第一个路由判断之前将目的地址用DNAT改成目的服务器的地址,这样数据包就不会提交给上层程序。然后在数据包出网卡之前,将远来源地址改成转发服务器的地址。这样目的服务器返回时会返回给转发服务器,转发服务器会根据之前建立的映射表再返回给客户端。需要注意的是我们应该打开ipv4时的转发功能。

    具体实现:

    1. 假设转发服务器的地址192.168.1.20 。目的服务器的地址是 220.181.111.188 。在转发服务器上把8080端口转发到220.181.111.188的80端口。
    2.  打开ipv4时的转发功能
      1. 编辑"/etc/sysctl.conf",将net.ipv4.ip_forward改成1
      2. sysctl -p
    3. 在PREROUTING上修改目的地址
      1.  iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 220.181.111.188:80
    4. 在POSTROUTING上修改源地址
      1. iptables -t nat -A POSTROUTING -d 220.181.111.188 -p tcp --dport 80 -j SNAT --to 192.168.1.20
      2. 或者将用伪装的方式
      3. iptables -t nat -A POSTROUTING -d 220.181.111.188 -p tcp --dport 80 -j MASQUERADE
    5. 为了防止在FORWARD上面被丢弃,添加规则允许通过。
      1. iptables -I FORWARD -d 220.181.111.188 -p tcp --dport 80 -j ACCEPT
      2. iptables -I FORWARD -s 220.181.111.188 -p tcp --sport 80 -j ACCEPT
    6. 现在就可以在客户端上测试一下访问 192.168.1.20:8080 就会访问到 220.181.111.188:80

    最后提供一段脚本:

    #!/bin/bash -
    #===============================================================================
    #
    # FILE: iptable_redirect_port.sh
    #
    # USAGE: ./iptable_redirect_port.sh PROTOCOL SERVER_PORT DHOST DPORT [-d]
    #
    # DESCRIPTION: Redirect traffic to another server.
    #
    # OPTIONS: ---
    # REQUIREMENTS: ---
    # BUGS: ---
    # NOTES: ---
    # AUTHOR: Zhang Guangtong <zhgt123@gmail.com>
    # ORGANIZATION:
    # CREATED: 2015年08月05日 10:07
    # REVISION: ---
    #===============================================================================

    # example:
    #iptables -t nat -A PREROUTING -p tcp --dport 1111 -j DNAT --to-destination 192.168.1.10:8022
    #iptables -t nat -A POSTROUTING -d 192.168.1.10 -p tcp --dport 8022 -j MASQUERADE

    redirect_port()
    {
    PROTOCOL=$1
    SERVER_PORT=$2
    DHOST=$3
    DPORT=$4
    iptables -t nat -A PREROUTING -p $PROTOCOL --dport $SERVER_PORT -j DNAT --to-destination $DHOST:$DPORT
    iptables -I FORWARD -d $DHOST -p $PROTOCOL --dport $DPORT -j ACCEPT
    iptables -I FORWARD -s $DHOST -p $PROTOCOL --sport $DPORT -j ACCEPT
    iptables -t nat -A POSTROUTING -d $DHOST -p $PROTOCOL --dport $DPORT -j MASQUERADE
    }
    clean_redirect_port()
    {
    PROTOCOL=$1
    SERVER_PORT=$2
    DHOST=$3
    DPORT=$4
    iptables -t nat -D PREROUTING -p $PROTOCOL --dport $SERVER_PORT -j DNAT --to-destination $DHOST:$DPORT
    iptables -D FORWARD -d $DHOST -p $PROTOCOL --dport $DPORT -j ACCEPT
    iptables -D FORWARD -s $DHOST -p $PROTOCOL --sport $DPORT -j ACCEPT
    iptables -t nat -D POSTROUTING -d $DHOST -p $PROTOCOL --dport $DPORT -j MASQUERADE
    }
    usage()
    {
    echo "Usage: $0 PROTOCOL SERVER_PORT DHOST DPORT [-d]"
    echo ""
    echo "example1:"
    echo " $0 tcp 443 192.168.1.20 8043"
    echo " Visit this host on port 443 equal vist 192.168.1.20:443"
    echo "example2:"
    echo " $0 tcp 443 192.168.1.20 8043 -d"
    echo " Clean previous rules"
    echo "Notes: please make sure net.ipv4.ip_forward=1 in /etc/sysctl.conf and run "sysctl -p" to apply changes"
    }

    if [ $# -lt 4 ]; then
    usage
    exit
    fi
    if [ "$5" == "-d" ]; then
    clean_redirect_port "$@"
    else
    redirect_port "$@"
    fi

    用法:

    ./iptable_redirect_port.sh 协议(tcp或udp) 转发服务器端口 目的服务器IP 目的服务器端口

    示例

    将访问转发服务器上的443端口转到192.168.1.20:8043

    ./iptable_redirect_port.sh tcp 443 192.168.1.20 8043

    删除刚才的规则:

    ./iptable_redirect_port.sh tcp 443 192.168.1.20 8043 -d

    收工。

  • 相关阅读:
    文件操作
    join,列表和字典用for循环的删除,集合,深浅拷贝
    java多线程基础
    nginx应用及性能调优
    nginx 基本功能
    SpringBoot2.x 启动过程详解
    shell脚本的基本使用
    使用 maven 的 `wagon-maven-plugin`插件 快速部署 到不同的 环境
    Netty笔记(7)
    Netty笔记(6)
  • 原文地址:https://www.cnblogs.com/gaoyanbing/p/12781544.html
Copyright © 2011-2022 走看看