Strange IP addresses in tomcat [duplicate] - java

This question already has answers here:
How do I get the remote address of a client in servlet?
(11 answers)
Closed 7 years ago.
Some where I have this in some generic class.
public static String getRequestIp (HttpServletRequest request){
String ipaddr = request.getHeader("X-FORWARDED-FOR");
if (ipaddr == null)ipaddr = request.getRemoteAddr();
return ipaddr;
}
For every request i call that method and in a certain moment i insert a record in a mysql database.
In most cases it works normally and i can see a record for every request with a valid ip address in the right field. But sometimes where the IP should be there is something like this. "unknown, 93.186.30.120" or "10.0.1.169, 186.38.84.3"
Apache is at the front listening at port 80 and used as proxy to Tomcat that listens at port 8081.
My router config would not allow to pass any conection that come by any port other than 80.
Any Help?
Thanks in advance.

The format for X-FORWARDED-FOR HTTP header is:
X-Forwarded-For: client, proxy1, proxy2, ...
Thus
unknown, 93.186.30.120
means request coming from proxy at 93.186.30.120, originating from unknown local address; and
10.0.1.169, 186.38.84.3
similarly means, request from 186.38.84.3 proxy, coming from local ip 10.0.1.169

The "unknown" X-Forwarded-For entry may have been inserted by a proxy that is configured not to insert the originating client IP address into the field.
The Squid configuration directive forwarded_for", for instance, has various options and If set to "on", will append the client IP address. If set to "off", it will appear as "X-Forwarded-For: unknown"

Related

How to get Client IP with ktor

Hey i tried to get the ip of the client with ktor.
I used the method
this.context.request.local.remoteHost
(this.context is an Instance of ApplicationCall)
How can i get the real ip an not something like "********.dip0.t-ipconnect.de"
You can also get a remote host from the request's origin: call.request.origin.remoteHost but it returns IP address in not every case too.
I've created an issue in Ktor's bug tracker to address this problem.

SCTP INIT missing IPv4 address parameter

I have been testing the SCTP support on Java + lksctp.
I wrote a simple client in order to see just the inital setup of a SCTP association which is basically the "INIT" and "INIT ACK".
I have tested 2 ways for a Client to send the "INIT" to a SERVER which is basically:
create the SctpChannel object with "open(SocketAddress)"
try {
InetSocketAddress socketAddress = new InetSocketAddress("192.168.52.197", 2905);
SctpChannel sctpChannel = SctpChannel.open(socketAddress,1,1);
sctpChannel.bind(new InetSocketAddress("192.168.1.251",2906));
sctpChannel.connect(socketAddress, 1 ,1);
so in this way, I can see in Wireshark that I have the "IPv4 Address parameter" for all my network interfaces (3 as you can see bellow), but the Source Port is getting a aleatory port number instead the 2906 as I would like to have and it's in the bind.
So... once the bind of local IP/Port is happening after the "open"... so I have changed the code to:
create the SctpChannel object which just "open()"
binding the local client IP and Port
"connect" to the remote Server IP and Port
try {
InetSocketAddress socketAddress = new InetSocketAddress("192.168.52.197", 2905);
SctpChannel sctpChannel = SctpChannel.open();
sctpChannel.bind(new InetSocketAddress("192.168.1.251",2906));
sctpChannel.connect(socketAddress, 1 ,1);
In this way, I can see in wireshark that Source/Destination ports are expected (2906/2905), but the INIT does not have the "IPv4 Address parameter".
So does anyone know why the 2nd code I'm missing the "IPv4 address parameter" in the INIT ? Do I miss something?
Any help would be really welcome.
Thanks.
IP addresses within INIT/INIT_ACK chunks are optional parameters. In case your endpoints are signglehomed IP address might not be included in the INIT/INIT_ACK chunk. The remote end still can retrieve information about peer address from the IP header.
Fundamentally the reason of this behaviour is what parameters you pass to open(). Open() without any parameters and open() with remote address specified works in a different way.
If you call SctpChannel.open(socketAddress,1,1) with socket address for the remote end it effectively open channel and connects to remote end (see open documentation. Your bind() and connect() calls in this case are pretty useless. So since there were no bind() call prior to establishing the connection you are sort of using "default" endpoint with random port (56044) and IP addresses of all available interfaces.
In second case, when you don't specify socketAddress for open() it just open the channel but does not connect to remote end at this stage. So your bind() call successfully specify endpoint details (port and IP address) and when you call connect() it is actually using the endpoint you just created (192.168.1.251:2906) to setup connection with remote end.

Getting client static IP address

I am deplyong a web application in the Internet and I am checking whether the user's login is valid by checking its client IP address (e.g. 192.168.2.XXX). Actually, I have found a working code (below). This code was completely working before, but after some time, its output is not the same anymore. Now, this code only gives me 1 IP address which is the server's IP address. What is wrong with my code? How can I get the client's static IP address rather than the server's IP address? I have also tried other solutions such as getRemoteAddr() and request.getHeader("PROXY-CLIENT-IP") but it is not working.
Java:
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if(ipAddress == null)
ipAddress = InetAddress.getLocalHost().getHostAddress();
Your are mixing two levels of abstractions and that is rarely a good thing.
The header X-FORWARDED_FOR is inserted by a load balancer or proxy. If the client reaches the server directly, then this header isn't present and you are executing this code InetAddress.getLocalHost().getHostAddress();. Which does exactly what you say: It is retrieving the IP address of the host where this piece of code is running, i.e. the web server.
See also here: Getting the client IP address: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, what else could be useful?

Specify RMI endpoint address when having two interfaces

I have an rmi server on a box with two public interfaces. When a client connects, it always returns the wrong ip address in the UnicastServerRef2 [liveRef: [endpoint:[192.x.x.x:xxxx .... The connection from the client goes to the other interface with ip 10.x.x.x. Does anybody know how to solve this? I do not want to specify the ip when binding the stub. It works then, but I would like it to listen on all interfaces (0.0.0.0).
If I specify java.rmi.server.hostname=myhostname and use a RMIServerSocketFactory to create a ServerSocket[addr=myhostname/10.x.x.x,localport=xxxx], it still returns the 192.x.x.x adress to the client as remote endpoint. Weird enough I have two UnicastRemoteObjects objects on diffrerent ports and one of them returns the right address, the other not.
Any Ideas how to make it to return the endpoint with the ip of the interface the connection was made to?
That's what the java.rmi.server.hostname property is for. Set it at the exporting JVM to whatever IP address you want the clients to use to connect to it.

In which case the getRemoteHost method returns an IP address instead of the hostname?

On a server of our private network we have an HttpServlet which is contacted by a PC of the same network.
We need to know the hostname of the client which contacts the server. To do this we call the
getRemoteHost method of the HttpServletRequest.
Some times this method returns the PC name of the client (wanted behavior) and some other the method returns the IP address. (same client, same server, same private network)
The API says:
java.lang.String getRemoteHost()
Returns the fully qualified name of the client or the last proxy that sent the request. If the engine cannot or chooses not to resolve the hostname (to improve performance), this method returns the dotted-string form of the IP address. For HTTP servlets, same as the value of the CGI variable REMOTE_HOST
Returns:
a String containing the fully qualified name of the client
I see that for HTTP servlet that value is the same of the CGI variable REMOTE_HOST. What does it mean? Is it up to the server to decide to resolve the address or not? Is there a way to force this behavior?
In Tomcat, for example, the connector has a setting "enableLookups" which is disabled by default for performance reasons. See http://tomcat.apache.org/tomcat-7.0-doc/config/http.html
Other containers may have different methods of doing the same thing.

Categories