Tomcat uses IP 127.0.0.1 when talking to localhost. This will be correct in most cases but will not work on special setups, e.g. linux vserver guests where 127.0.0.1 is the host machine, the guest machine "localhost IP" can be any other (e.g. 127.0.0.2 or 10.0.0.1). Though unusual, such configuration seems to be ok according to the IP RFCs. The problem is that tomcat ignores this possibility and does not ask the OS for the localhost IP via getAddressByName("localhost"), it uses a hardcoded 127.0.0.1, e.g. ./java/org/apache/catalina/startup/Catalina.java: Socket socket = new Socket("127.0.0.1", server.getPort());
Created attachment 20989 [details] This patch changes hardcoded references of 127.0.0.1 Please review this patch, and ensure that there are no errors or potential regression issues. Apply accordingly.
Created attachment 21036 [details] Revised patch. Please review / vote.
I think this patch is invalid, for the end points, if I bind to an interface, then I can't unlock the accept by doing ("localhost",port), since the port wont be bound to localhost at all. granted, that the problem I'm describing is already existing, and not related to the localhost bug Filip
ignore my previous comment, I'm a retard, didn't look into it enough
Created attachment 21039 [details] Incl. Nio Added NIO connector to patch
Can we change the patch? See comment at STATUS File: -1: funkman InetAddress.getLocalHost() != localhost - it should be InetAddress.getByName("localhost").getHostAddress()
(In reply to comment #6) > Can we change the patch? > See comment at STATUS File: > -1: funkman InetAddress.getLocalHost() != localhost - it should be > InetAddress.getByName("localhost").getHostAddress() I will not claim to be an expert in IPv4 or IPv6. Granted, after tracing the actual InetAddress source code for both getLocalHost() and getByName(), I believe the original patch should stay, keeping getLocalHost(). If anyone disagrees with my choice, and feels that getByName("localhost") is better, I would have to further recommend that we use : getAllByName("localhost")[0], which is a shortcut to the new proposal. If I am completely incorrect, I apologize - please correct me in a separate email so that I have a better understanding. New Choices/My Votes : 1.) +1 - Keep : InetAddress.getLocalHost() and apply current proposed patch 2.) -1 - Change to new proposal : InetAddress.getByName("localhost") 3.) +1? - Change to new proposal 'shortcut' : InetAddress.getAllByName("localhost")[0] (In reply to comment #4) > ignore my previous comment, I'm a retard, didn't look into it enough Filip, did you get the same results I did? Why did you agree with me?
InetAddress.getLocalHost().getHostAddress() does not necessarily return localhost - it (can and usually) returns the IP address that other folks can see. This means that the shutdown listener by default would listen on a publicly addressable location - which means now ANYONE by default can shutdown tomcat instead of someone who has access to the machine.
(In reply to comment #8) Okay, I can see how that can definitely a problem. However, by using getByName("localhost") OR getAllByName("localhost")[0], the java.net API, seems to automatically use the "common" loopback address of 127.0.0.1, completely ignoring the system configuration. This brings us back to the original bug post which involves not being able to use any customized IP for the "localhost" (i.e. 127.0.0.2 or 10.0.0.1). Should we instead be looking to separate the shutdown listener somehow?
(In reply to comment #9) Instead of doing a refactor, and if no solution is best, why not just add a new property "org.apache.tomcat.localhost.ip" that defaults to "127.0.0.1" that whoever starts tomcat is able to override? Not an automagic solution, but will address the original issue and will not create any new security issues
(In reply to comment #10) > (In reply to comment #9) > Instead of doing a refactor, and if no solution is best, why not just add a new > property "org.apache.tomcat.localhost.ip" that defaults to "127.0.0.1" that > whoever starts tomcat is able to override? > Not an automagic solution, but will address the original issue and will not > create any new security issues +1 - That still requires slight refactoring, but it sounds like a worthy idea to me. ;)
(In reply to comment #8) > InetAddress.getLocalHost().getHostAddress() does not necessarily return > localhost - it (can and usually) returns the IP address that other folks can > see. > > This means that the shutdown listener by default would listen on a publicly > addressable location - which means now ANYONE by default can shutdown tomcat > instead of someone who has access to the machine. > For all the connectors: The correct way is doing InetAddress.getLocalHost().getHostAddress() we are not trying to get the IP of "localhost" here, we are trying to just get one of the interfaces that Tomcat listens to so that we can release the accept thread. What I would suggest, use InetAddress.getLocalHost().getHostAddress() wherever we need to access a port that is listening on 0.0.0.0, and file a separate bugzilla item for the other locations Filip
Proposed solution for StandardServer.java: Keep 127.0.0.1 as a default and enable an override 'address' field for a different default ip address. So that you can set the shutdown ip address like for the other connectors etc. in the server.xml. This is a very flexible and consistent way to configure the shutdown ip address.
This was fixed with http://svn.apache.org/viewvc?view=rev&revision=596761
*** Bug 44505 has been marked as a duplicate of this bug. ***