当数据包传输到网关时,以编程方式获取TCP / IP的目标地址

时间:2017-08-30 12:36:16

标签: java networking tcp proxy netty

我已经阅读了Transparent Proxy to a Remote Box - 6.2 Second method (more complicated, but more general),在使用nat REDIRECT之后,我真的无法弄清楚这样的代理如何在没有Host头的情况下处理HTTP / 1.0连接,也就是说,如何知道原始服务器主机。

这是我的测试:

在我的电脑上,我创建了两个带有桥接网络的虚拟机,它们直接连接到我的电脑的物理网络。 然后我使用box@10.86.50.222作为代理服务器以及带有iptables的网关,并将默认网关box@10.86.50.224设置为10.86.50.222。

               +--- Others (10.86.50.x)
               |
Internet -- gateway (10.86.50.1) -- My PC (10.86.50.156)
               |                    / Bridged       \ Bridged
               +------ VirtualBox@10.86.50.222 -- VirtualBox@10.86.50.224
                      (act as gateway & porxy)   client 

On VirtualBox@10.86.50.222(充当网关和代理)

sysctl net.ipv4.ip_forward
sudo sysctl -w net.ipv4.ip_forward=1
sysctl -p /etc/sysctl.conf #

# proxy listens on the port 3128
iptables -A PREROUTING -t nat -i enp0s8 -p tcp --dport 80 -j REDIRECT --to-port 3128

On VirtualBox@10.86.50.224(充当客户端)

root@ubuntu-samm:~# netstat -rWn
root@ubuntu-samm:~# ip route show
default via 10.86.50.1 dev enp0s8 onlink 
10.0.2.0/24 dev enp0s3  proto kernel  scope link  src 10.0.2.15 
10.86.50.0/24 dev enp0s8  proto kernel  scope link  src 10.86.50.222 

root@ubuntu-samm:~# sudo ip route change default via 10.86.50.222 dev enp0s8

root@ubuntu-samm:~# (printf 'GET / HTTP/1.0\r\n\r\n'; sleep 1) | nc -v 93.184.216.34 80

无法在VirtualBox@10.86.50.224上执行GET请求,这是一个错误的请求。

我的理解如下:

请求数据与scapy中的a=Ether()/IP(dst="www.example.org")/TCP(dport=80)/"GET /index.html HTTP/1.0 \n\n"类似,然后网关从IP数据包的目标地址{{3}知道原始服务器主机(此处为93.184.216.34) }。

流程图如下

       --------------------------------------------
      / Packets                                   /
     /src: 10.86.50.224:6666                     /
    /dst: 93.184.216.34:80   <-- before change  /
    --------------------------------------------
        |
   +--------------------------+
   | Network iterface         |
   |  enp0s8 : 10.86.50.222   |
   +--------------------------+
        |
   ++==========================================================================================================================++
   || >PREROUTING                                                                                                              ||
   ||  iptables -A PREROUTING -t nat -i enp0s8 -p tcp --dport 80 -j LOG --log-level debug --log-prefix "iptables network in: " ||
+------iptables -A PREROUTING -t nat -i enp0s8 -p tcp --dport 80 -j REDIRECT --to-port 3128                                    ||
|  ++==========================================================================================================================++
?       |
?      -------------------------------------------
?     / Packets                                  /
?    /src: 10.86.50.224:6666                    /
?   /dst: 10.86.50.222:3128  <-- after change  /
?   -------------------------------------------
?       |
?   +----------------------------------------+
?  / Routing Decision                         \
?  \   dst.ip is not in one of local networks /
?   +----------------------------------------+
?       |
?  ++=======================================================================================================================++
?  || >INPUT                                                                                                                ||
?  || iptables -A INPUT -t nat -i enp0s8 -p tcp -s 10.86.50.224 -j LOG --log-level debug --log-prefix "iptables local in: " ||
?  ++=======================================================================================================================++
?       |
|  +------------------------------------+
+->| Local process                      |
   |   Netty Sever (listen port 80/443) |
   +------------------------------------+
        |                             
      >OUTPUT
        |
      >POSTROUTING
        |
      Network

我们应该能够使用代码来获取目标地址,它似乎无法访问,只能获得10.86.50.156。

private static void testSimpleHttpServer() {

    try (java.net.ServerSocket serverSocket = new java.net.ServerSocket(3128);) {
        System.out.println("server: " + serverSocket);
        System.out.println("--------");
        while (true) {
            try (java.net.Socket clientSocket = serverSocket.accept();
                    java.io.PrintWriter out = new java.io.PrintWriter(clientSocket.getOutputStream(), true);
                    java.io.BufferedReader in = new java.io.BufferedReader(
                            new java.io.InputStreamReader(clientSocket.getInputStream()));) {

                String inputLine;

                String info = String.format("Received: (%s, bound_local=%s:%d, connected_remote=%s:%d, connected_to=%s)", new Date(),
                        clientSocket.getLocalAddress(), clientSocket.getLocalPort(), clientSocket.getInetAddress(),
                        clientSocket.getPort(), clientSocket.getRemoteSocketAddress());
                System.out.println(info);

                while ((inputLine = in.readLine()) != null) {
                    out.println(inputLine);
                    System.out.println(inputLine);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                System.out.println("--" + new Date() + "-------------------------------------------------------------------------");
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

//
Received: (Mon Aug 28 20:54:05 CST 2017, bound_local=/10.86.50.156:3128, connected_remote=/10.86.50.222:53992, connected_to=/10.86.50.222:53992)

0 个答案:

没有答案