How do I have a socket accept connections only from the localhost (in Java)?

11,372

Solution 1

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.

Solution 2

if (socket.getInetAddress().isLoopbackAddress()){
    //Your code goes here
}

Solution 3

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.

Solution 4

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.

Solution 5

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?

Share:
11,372

Related videos on Youtube

Kev
Author by

Kev

###Actively looking for freelance work ###About Me: I'm a professional software developer and have spent my time building provisioning and web based self-service systems for IIS, Apache and Citrix XenServer, amongst other things. My Curriculum Vitae can be viewed on Stack Overflow Careers (might be a bit out of date). Stuff I like to listen to at last.fm You can get in touch here: kevin.e.kenny #@# gmail.com (you know what to do with the # and spaces). No Survey Emails Please. Also not ashamed to admit I like trains, mostly diesels, late Era 8 (BR Sectorisation) and Era 9 onwards :) I'm also interested in signalling if anyone from Network Rail is looking this far down ;)

Updated on April 17, 2022

Comments

  • Kev
    Kev about 2 years

    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. Thanks in advance.


    Thank you all for your help. 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.

    • Stu Thompson
      Stu Thompson over 15 years
      Where did you get the information that 127.0.0.1 can be spoofed? I'm skeptical.
  • Jerub
    Jerub over 15 years
    The original poster has already said that he's doing that, but doesn't want to because the remote side can be 'spoofed' or something.
  • Brett
    Brett over 15 years
    Jerub: The OP doesn't understand the spoofing. Pax: Any old security manager will do, you just need to set a policy giving the code the correct permissions (permission java.net.SocketPermission "127.0.0.1" "listen,accept", or something like that - need to catch the SecurityException from accept).
  • edmz
    edmz almost 9 years
    Although the code expresses itself, code-only answers are discouraged. Consider adding documentation references, what it does and so on.