如何让套接字仅接受来自本地主机的连接(在 Java 中)?

发布于 2024-07-04 16:37:18 字数 495 浏览 7 评论 0原文

我有一个 java 应用程序(不在任何应用程序容器中运行),它监听 ServerSocket 的连接。 我希望它只接受来自本地主机的连接。 目前,在接受连接后,它会检查对等 IP,如果不是环回地址则拒绝它,但我知道对等 IP 地址可能会被欺骗。 因此,如果可能的话,我更愿意绑定到仅侦听环回接口的套接字; 这可能吗?

我尝试了一些不同的方法(例如在调用 bind() 时指定“127.0.0.1”作为本地地址),但没有成功。


更新:

我很尴尬地承认这都是我的错误。 我们的应用程序侦听两个不同的端口,我将一个端口绑定到环回接口,但对另一个端口进行测试。 当我实际尝试远程登录到正确的端口时,一切正常(即绑定到“127.0.0.1”完全符合预期)。

至于欺骗环回地址,你们是对的。 我不应该把它说成是首要问题。 实际上,所需的行为是仅采用本地连接,并且仅绑定到本地接口是实现该目标的更直接的方法,而不是接受所有连接然后关闭非本地连接。

I have a java app (not running in any application container) which listens on a ServerSocket for connections. I would like it to only accept connections which come from localhost. Currently, after a connection is accepted, it checks the peer IP and rejects it if it is not the loopback address, but I know that peer IP addresses can be spoofed. So, if possible, I'd prefer to bind to a socket that only listens on the loopback interface; is this possible?

I've tried a few different things (such as specifying "127.0.0.1" as the local address when calling bind()) with no luck.


Update:

I'm embarrassed to admit that this was all my mistake. Our application listens on two different ports, and I was binding one to the loopback interface but testing against the other. When I actually try to telnet to the correct port, everything works fine (i.e., binding to "127.0.0.1" does exactly what it's supposed to).

As for spoofing the loopback address, you guys are right. I shouldn't have made it sound like the primary concern. Really, the desired behavior is to only take local connections, and binding to only the local interface is a more direct way of achieving that than accepting all connections and then closing non-local ones.

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

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

发布评论

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

评论(5

眼中杀气 2024-07-11 16:37:18

对等 IP 地址不能以这种方式进行欺骗,您不必担心使用检查对等点并决定在建立过程中断开连接的技术。

但是:绑定到 127.0.0.1 应该可以工作,并导致操作系统告诉连接主机,如果它们连接到系统的其他 IP 地址之一,则没有任何监听。 你能用一个可编译的例子修改这个问题吗? 也许你犯了一个简单的错误。

Peer IP addresses cannot be spoofed in this manner, have you nothing to fear from using the technique of inspecting the peer and deciding to drop the connection during establishment.

However: binding to 127.0.0.1 should work, and cause the operating system to tell the connecting host that there is nothing listening if they connect on one of the systems other ip addresses. Can you amend this question with a compilable example? Perhaps you've made a simple error.

油饼 2024-07-11 16:37:18

如果对等地址被欺骗,则您无能为力。

然而,欺骗 127.0.0.1 并不容易。 您必须有一个足够愚蠢的 TCP/IP 堆栈才能接受这样的数据包。 欺骗者无法接收回数据包。 在良好的 TCP/IP 堆栈上,它不应该能够猜测序列号,因此它无法跟上预期的对话。

If the peer address is spoofed, then there is nothing further that you can do.

However, to spoof 127.0.0.1 is not easy. You would have to have a TCP/IP stack dumb enough to accept such a packet. There would be no way of the spoofer receiving packets back. On a good TCP/IP stack, it should not be able to guess the sequence numbers so it can't keep up with the expected conversation.

变身佩奇 2024-07-11 16:37:18

正如您似乎已经在做的那样,无论如何,您都可以接受()连接,然后使用 getInetAddress() 来确保该地址是经过授权的地址。 如果没有,只需立即 close() 套接字即可。 127.0.0.1 不是一个可以被欺骗的地址。

或者,您可以安装自己的安全管理器,该管理器将使用远程站点的地址和端口调用其 checkAccept() 方法。 这有点难 - 我从未尝试过,因为第一个解决方案对我来说已经足够了。

You could, as you already seem to be doing, accept() the connection anyway then use getInetAddress() to ensure the address is an authorized one. If not, simply close() the socket straight away. 127.0.0.1 is not an address that can be spoofed.

Alternatively, you could install your own security manager which will have its checkAccept() method called with the address and port of the remote site. Thet's a little harder - I've never tried since the first solution has always been adequate for me.

享受孤独 2024-07-11 16:37:18
if (socket.getInetAddress().isLoopbackAddress()){
    //Your code goes here
}
if (socket.getInetAddress().isLoopbackAddress()){
    //Your code goes here
}
栖竹 2024-07-11 16:37:18

当您绑定 ServerSocket 时,指定 localhost 应该会使 TCP/IP 堆栈拒绝连接。 即使这在您的系统上不起作用,本地主机也不能(好吧,也许有人入侵了您的 TCP/IP 堆栈和默认网关路由器)被欺骗,因为该地址不是通过物理接口路由的。

我很好奇为什么你的绑定不成功,你的操作系统、Java 版本等是什么?

When you bind your ServerSocket, specifying localhost should make the TCP/IP stack reject the connection. Even if this isn't working on your system, localhost can't (okay, maybe if someone hacked your TCP/IP stack and the default gateway router) be spoofed, since that address isn't routed through the physical interface.

I am curious as to why your binding doesn't succeed, what is your OS, Java version, etc?

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