使用 Jpcap 创建反向代理

发布于 2024-08-21 21:11:00 字数 3752 浏览 9 评论 0原文

我需要创建一个程序来接收 HTTP 请求并将这些请求转发到 Web 服务器。

图表 http://img269.imageshack.us/img269/1862/h98trsly.jpg

我仅使用 Java Sockets 成功完成了此任务,但客户端需要在 Jpcap 中实现该程序。我想知道这是否可行以及我应该为这个项目阅读哪些文献。

这就是我现在通过将 Jpcap 教程中的片段拼接在一起得到的:

import java.net.InetAddress;
import java.io.*;
import jpcap.*;
import jpcap.packet.*;


public class Router {
    public static void main(String args[]) {
        //Obtain the list of network interfaces
        NetworkInterface[] devices = JpcapCaptor.getDeviceList();

        //for each network interface
        for (int i = 0; i < devices.length; i++) {
            //print out its name and description
            System.out.println(i+": "+devices[i].name + "(" + devices[i].description+")");

            //print out its datalink name and description
            System.out.println(" datalink: "+devices[i].datalink_name + "(" + devices[i].datalink_description+")");

            //print out its MAC address
            System.out.print(" MAC address:");
            for (byte b : devices[i].mac_address)
                System.out.print(Integer.toHexString(b&0xff) + ":");
            System.out.println();

            //print out its IP address, subnet mask and broadcast address
            for (NetworkInterfaceAddress a : devices[i].addresses)
                System.out.println(" address:"+a.address + " " + a.subnet + " "+ a.broadcast);
        }

        int index = 1;  // set index of the interface that you want to open.

        //Open an interface with openDevice(NetworkInterface intrface, int snaplen, boolean promics, int to_ms)
        JpcapCaptor captor = null;
        try {
            captor = JpcapCaptor.openDevice(devices[index], 65535, false, 20);
            captor.setFilter("port 80 and host 192.168.56.1", true);
        } catch(java.io.IOException e) {
            System.err.println(e);
        }

        //call processPacket() to let Jpcap call PacketPrinter.receivePacket() for every packet capture.
        captor.loopPacket(-1,new PacketPrinter());

        captor.close();
    }
}

class PacketPrinter implements PacketReceiver {
    //this method is called every time Jpcap captures a packet
    public void receivePacket(Packet p) {
        JpcapSender sender = null;
        try {
            NetworkInterface[] devices = JpcapCaptor.getDeviceList();
            sender = JpcapSender.openDevice(devices[1]);
        } catch(IOException e) {
            System.err.println(e);
        }


        IPPacket packet = (IPPacket)p;

        try {
            // IP Address of machine sending HTTP requests (the client)
            // It's still on the same LAN as the servers for testing purposes.
            packet.dst_ip = InetAddress.getByName("192.168.56.2");
        } catch(java.net.UnknownHostException e) {
            System.err.println(e);
        }

        //create an Ethernet packet (frame)
        EthernetPacket ether=new EthernetPacket();
        //set frame type as IP
        ether.frametype=EthernetPacket.ETHERTYPE_IP;
        //set source and destination MAC addresses

        // MAC Address of machine running reverse proxy server
        ether.src_mac = new MacAddress("08:00:27:00:9C:80").getAddress();
        // MAC Address of machine running web server
        ether.dst_mac = new MacAddress("08:00:27:C7:D2:4C").getAddress();

        //set the datalink frame of the packet as ether
        packet.datalink=ether;

        //send the packet
        sender.sendPacket(packet);

        sender.close();

        //just print out a captured packet
        System.out.println(packet);
    }
}

任何帮助将不胜感激。谢谢。

I need to create a program that receives HTTP request and forwards those requests to the web servers.

Diagram http://img269.imageshack.us/img269/1862/h98trsly.jpg

I have successfully made this using only Java Sockets but the client needed the program to be implemented in Jpcap. I'd like to know if this is possible and what literature I should be reading for this project.

This is what I have now by stitching together pieces from the Jpcap tutorial:

import java.net.InetAddress;
import java.io.*;
import jpcap.*;
import jpcap.packet.*;


public class Router {
    public static void main(String args[]) {
        //Obtain the list of network interfaces
        NetworkInterface[] devices = JpcapCaptor.getDeviceList();

        //for each network interface
        for (int i = 0; i < devices.length; i++) {
            //print out its name and description
            System.out.println(i+": "+devices[i].name + "(" + devices[i].description+")");

            //print out its datalink name and description
            System.out.println(" datalink: "+devices[i].datalink_name + "(" + devices[i].datalink_description+")");

            //print out its MAC address
            System.out.print(" MAC address:");
            for (byte b : devices[i].mac_address)
                System.out.print(Integer.toHexString(b&0xff) + ":");
            System.out.println();

            //print out its IP address, subnet mask and broadcast address
            for (NetworkInterfaceAddress a : devices[i].addresses)
                System.out.println(" address:"+a.address + " " + a.subnet + " "+ a.broadcast);
        }

        int index = 1;  // set index of the interface that you want to open.

        //Open an interface with openDevice(NetworkInterface intrface, int snaplen, boolean promics, int to_ms)
        JpcapCaptor captor = null;
        try {
            captor = JpcapCaptor.openDevice(devices[index], 65535, false, 20);
            captor.setFilter("port 80 and host 192.168.56.1", true);
        } catch(java.io.IOException e) {
            System.err.println(e);
        }

        //call processPacket() to let Jpcap call PacketPrinter.receivePacket() for every packet capture.
        captor.loopPacket(-1,new PacketPrinter());

        captor.close();
    }
}

class PacketPrinter implements PacketReceiver {
    //this method is called every time Jpcap captures a packet
    public void receivePacket(Packet p) {
        JpcapSender sender = null;
        try {
            NetworkInterface[] devices = JpcapCaptor.getDeviceList();
            sender = JpcapSender.openDevice(devices[1]);
        } catch(IOException e) {
            System.err.println(e);
        }


        IPPacket packet = (IPPacket)p;

        try {
            // IP Address of machine sending HTTP requests (the client)
            // It's still on the same LAN as the servers for testing purposes.
            packet.dst_ip = InetAddress.getByName("192.168.56.2");
        } catch(java.net.UnknownHostException e) {
            System.err.println(e);
        }

        //create an Ethernet packet (frame)
        EthernetPacket ether=new EthernetPacket();
        //set frame type as IP
        ether.frametype=EthernetPacket.ETHERTYPE_IP;
        //set source and destination MAC addresses

        // MAC Address of machine running reverse proxy server
        ether.src_mac = new MacAddress("08:00:27:00:9C:80").getAddress();
        // MAC Address of machine running web server
        ether.dst_mac = new MacAddress("08:00:27:C7:D2:4C").getAddress();

        //set the datalink frame of the packet as ether
        packet.datalink=ether;

        //send the packet
        sender.sendPacket(packet);

        sender.close();

        //just print out a captured packet
        System.out.println(packet);
    }
}

Any help would be greatly appreciated. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘香 2024-08-28 21:11:00

为什么?他的理由是什么?他真的愿意为你已经做过的同样的事情支付十倍的费用吗?

您不需要 Jpcap 来实现 HTTP 代理。它可以完全在 java.net 或 java.nio 中完成。

Why? What are his reasons? Does he really want to pay ten times the cost for the same thing you've already done?

You don't need Jpcap to implement HTTP proxies. It can be done entirely within java.net or java.nio.

ま柒月 2024-08-28 21:11:00

我认为你不可能做到这一点,至少在 Windows 机器上是这样。 Jpcap 只是 Winpcap 的包装器,这种底层机制不能丢弃观察到的数据包:

http://www.mirrorservice.org/sites/ftp.wiretapped.net/pub/security/packet-capture/winpcap/misc/faq。 htm#Q-17

所以,我不明白如何“在线”构建反向代理。您是否必须执行以下操作:

  1. 通过实时拼凑数据包并阻止目标主机接收它们来观察传入的 HTTP 请求。

  2. 根据您正在实施的任何代理规则发出备用 HTTP 请求。

  3. 从您的请求中获取响应,并在网络上推送数据包,从而伪造来自原始主机的响应?

由于您无法丢弃入站数据包,因此目标主机不会尝试处理请求并将其自己的数据包扔到线路上作为响应吗?由于我不是网络专家,可能还有更多我不知道的事情。这个问题让我很好奇使用这样的“垫片”会发生什么。

I don't think you can make this happen, at least on a Windows box. Jpcap is just a wrapper for Winpcap, and this underlying mechanism can not drop observed packets:

http://www.mirrorservice.org/sites/ftp.wiretapped.net/pub/security/packet-capture/winpcap/misc/faq.htm#Q-17

So, I don't see how you can build a reverse proxy "on the wire." Wouldn't you have to do the following:

  1. Observe an incoming HTTP request by piecing together packets in real-time AND dropping them from being received by the intended host.

  2. Make the alternate HTTP request based on whatever proxy rules you are implementing.

  3. Grab the response from your request and push out packets on the wire which fake a response from the original host?

Since you can't drop the inbound packets, won't the intended host attempt to handle the request and throw packets of its own onto the wire in response? There's probably even more that I don't know about as I'm no networking expert. This question just made me curious about what would be possible using such a "shim".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文