问题
It's come to my attention that the internal IP of ec2 instances behind an ELB, even when in a private subnet, are revealed when a particular type of request is issued. specifically one with an empty HOST value.
telnet site_url 80
GET / HTTP/1.0
And the returned headers:
HTTP/1.1 301 Moved Permanently
Cache-Control: max-age=1209600
Content-Type: text/html; charset=iso-8859-1
Date: Thu, 26 Mar 2015 18:47:22 GMT
Expires: Thu, 09 Apr 2015 18:47:22 GMT
Location: https://10.0.7.35/
Server: Apache
Content-Length: 226
Connection: Close
Naturally this occurs with an open ssl request on 443 as well.
Is anyone aware of a resolution or workout for this problem? I know IIS suffers from the same symptoms but my problem is specific to AWS ELBs.
EDIT:
Apache redirect to force HTTPS.
RewriteCond %{HTTPS} off
RewriteCond %{SERVER_ADDR} !^127\.0\.0\.1
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
回答1:
This really has nothing to do with the ELB and everything to do with Apache, which is clearly what is returning this information (hence the server: Apache
line in the output).
You obviously have some sort of a redirect defined in your Apache configuration to redirect traffic from port 80 to port 443. You should probably update your question to include the relevant portions of your Apache configuration file(s) including any Rewrite rules, ServerName, .htaccess settings, etc.
Edit:
You're using HTTP_HOST in your rewrite rule, and that corresponds to the host that's provided in the request. In the example you provided you're not providing a host, so try doing this instead:
$ telnet www.example.com 80
GET / HTTP/1.0
Host: www.example.com
The Host part of the request is necessary in the event that there are virtual hosts defined so that Apache knows which virtual host the request should be routed to.
You might also want to add another rewrite condition along these lines:
RewriteCond %{HTTP_HOST} !^www.example.com
RewriteRule ^(.*)$ https://www.example.com$1 [R=301,L]
That will ensure that if somebody tries to access your site without providing a full request containing a header that it will redirect to the proper domain.
回答2:
A friend posted this today, and despite there already being an answer out, I thought I'd put in the details I discovered.
Using the mechanism described in the original post, I was able to reproduce the scenario described, where the Location
header returned is indeed an https:// address.
However, upon much closer inspection, the address supplied is not any of my instances addresses - rather it appears to be the IP address from ELB Instance itself.
I further confirmed this by checking on one of the instances behind the ELB, and using a command sequence like this, I was able to confirm that the IP address returned by the GET /
command is indeed the ELB's.
# These commands are purely to assist in obscuring my own IPs. :)
$ export LOCALIP=$(ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}')
$ export DISCOVEREDIP=<the IP from the GET test>
# I'm also using `sed` here to replace real IPs with strings to demonstrate which node is which
$ ss -tn | grep $DISCOVEREDIP | sed -e "s/$LOCALIP/localip/" -e "s/$DISCOVEREDIP/discoveredip/" | head -n 3
ESTAB 0 0 localip:80 discoveredip:3950
ESTAB 0 0 localip:80 discoveredip:4157
ESTAB 0 0 localip:80 discoveredip:4148
So I can derive that the local IP address of my web server is listening on port 80, where the ELB is pointing to, and the ELB's IP is using a higher port to connect to my web server.
No exposure beyond ELB internal IP addresses, nothing to be concerned with. Happy clouding!
回答3:
We've been looking at this issue in recent day and have concluded that:
- When the ELB sees a request without a Host header, it must be deciding (in good faith) to add one on your behalf and is using its own private IP address as its value.
- This presents Apache with a (more) valid request and so any redirects it generates do so with an unmodified HTTP_HOST value.
We did find a solution that worked for us (we only needed to solve this in our "default" VirtualHost though), which you may like to consider, which was to add this to your VirtualHost:
UseCanonicalName On
In our assessment, this instructs some Apache behaviour to formally replace the HTTP_HOST in a response with the ServerName directive, which resolved the issue we were trying to solve.
回答4:
To solve this issue in Varnish Cache by rewriting the host field being a IP on our Public VPC subnet to our primary domain name.
if(req.http.host ~ "10.30.0") {
set req.http.host = "www.mydomain.com";
}
来源:https://stackoverflow.com/questions/29286569/stop-elastic-load-balancer-from-revealing-internal-private-ip