http://ipfuck.paulds.fr/
We've been recently getting hammered by this Firefox plug-in. It sends a fake IP in the headers so when our nginx web server picks up the IP it is a fake one.
Is there any way to get a real IP address or block out requests that have this plug-in installed?
There is actually no client IP entries in any HTTP Headers. There are only some un-official proxy headers which are added to a request, so that a proxy server can tell you the real ip of the connecting client (since the tcp socket will only reveal the IP address of the proxy server).
The plugin you linked to adds those proxy headers, to "fake" a proxy request, by adding a X-Real-IP: 1.2.3.4 or X-Forwarded-For: 1.2.3.4 header to the request. But no one forces you to use that IP address (which can be fake, like the 1.2.3.4 example here), you can always use the IP address of the socket that initiated the connection - which will be the client's real IP address if he uses the mentioned plugin.
Within the location section of your nginx configuration, you get the socket IP address through the $remote_addr variable. To retrieve the "fake" IP address, you can use $http_x_forwarded_for or $http_x_real_ip variable.
If you are using any application/cgi backend, you usually can examine the full headers and the socket IP address (i.e. in PHP you should check $_REQUEST and $_HEADERS variables)
Related
Researching on how a server can figure out a client's IP address, I see that one needs to inspect the X-Forwarded-For header chain.
I understand that the client, ISP, and then routers and proxies declare their IP addresses there.
However, the server handler also has access to req.RemoteAddr field to read the client's IP address. How is that RemoteAddr determined exactly? Is it based on a specific header in the request? If yes, which one(s)?
I have tried inspecting the usage of the field and how it is set but the implementation details are hidden behind an interface.
The net/http server sets RemoteAddr to the string form of the network connection's remote address. The string is typically in the format "IP:port".
In the case of a TCP connection (the typical scenario), the network connection remote address is taken from the IP source address and the TCP source port.
The address can be the address of the client or a proxy.
The net/http server does not consider the headers when setting RemoteAddr.
When source address field is empty, all runs fine. When I put in an IP, even if it is my actual IP, I get an error:
Response code: Non HTTP response code: java.net.SocketException
Response message: Non HTTP response message: Network is unreachable: connect
I run Windows... Also I have already tried all the Implementations.
There should be few pre-requisites met:
You need to have HTTPClient implementation (see HTTP Request sampler documentation)
Source address field[Only for HTTP Request with HTTPClient implementation]
In case of single IP address:
The IP address needs to be available in the underlying operating system, it may be either IP associated with NIC or an IP alias
Relevant Source address type needs to be specified, in case of single IP it should be IP/Hostname
See Using IP Spoofing to Simulate Requests from Different IP Addresses with JMeter guide for more detailed information on the domain.
Sinatra app.
<%= request.ip %>
gives 127.0.0.1 IP address if looked at from local server.
gives 83.245.226.68 IP address if looked at from Heroku server, no matter from which device.
So I guess it returns server's IP address and not client's. How do I find out what client's IP address is then? Did I misunderstand request.ip method?
This happens when the HTTP Server in front of the Rack HTTP Server (e.g. used for load balancing, ssl, etc) is not forwarding the client IP address to the Rack HTTP Server. In that case you get the IP address of the HTTP Server.
This can be configured on HTTP Servers like Nginx and Apache and you get the client IP address in request.ip.
As far as I know Heroku is doing it in a way that the client IP address is in a header called "x-forwarded-for", which is a comma separated list of IP addresses, the last element is the client ip.
Sinatra:
env['HTTP_X_FORWARDED_FOR'].split(',').last
Rails:
request.headers['x-forwarded-for'].split(',').last
I'm trying to use Fiddler to capture traffic that comes to my machine on its external ip address, and redirect it to the loopback interface without affecting the host header.
I have added the following to the OnBeforeRequest method:
if (oSession.HostnameIs("MyMachineName")){
oSession.bypassGateway = true;
oSession["x-overrideHost"] = "localhost";
}
This works fine for http traffic: I do indeed see a request to http://MyMachineName hit the loopback adaptor with its host header intact.
However, when intercepting https traffic I get the following in the response raw view:
fiddler.network.https> HTTPS handshake to auth.time-wise.net failed. System.IO.IOException The handshake failed due to an unexpected packet format.
I have Fiddler configured to capture and decrypt https traffic.
Does anyone know why this problem occurs and how it can be remedied?
Edit: in response to Eric's request for more information
Fiddler is running as a proxy (i.e. as standard), listening on port 8888.
The clients are (currently) web browsers on the same machine, and so are automatically using the Fiddler proxy, as they've picked up the change in default proxy.
You've left out some important details (e.g. what port is Fiddler running on, and how did you configure the remote client to send its traffic to Fiddler?)
Having said that, you will probably want to change your use of x-overrideHost to x-overrideHostname such that the port number of the traffic being retargeted is preserved.
I have a ruby server based on TCPSocket (non-HTTP).
I have 2 different domains, both pointing with an A-Record to my servers IP Address (the same one). So, there are clients connecting to one of those domains.
Is it possible to tell which domain a client was connecting to?
I saw that this is possible in other protocols, but I'm not sure if this is based on manually added headers or really extracted from the basic tcp/ip connection. E.g. in PHP there is $_SERVER["HTTP_HOST"] which shows to which domain a client was connecting.
At the TCP socket level, the only things that are known are the source and destination IP addresses (and ports) of the connection. How the IP address was resolved via DNS is not possible to know at this layer. Even though HTTP works on top of TCP, HTTP servers have to look at the HTTP headers from the client to know which domain they are making a request to. (That's how the HTTP_HOST value gets filled in.)
One possible solution is to configure your server to have an additional IP address. This can be by assigning an additional IP address to the NIC or adding an additional NIC. Then have each domain use a different IP address. Otherwise, this is not possible and you may want to consider your application protocol on top of TCP to convey this information.