I have an Amazon EC2 instance running Ubuntu 14.04 with Apache 2.4.
I have configured Apache with 3 virtual hosts, all for HTTPS only.
The problem is, when I try access the web server from the internet, the host name somehow gets lost and apache tries to serve the page from the default host, no matter by which hostname I accessed it.
/etc/apache2/sites-enabled/default-ssl.conf:
<VirtualHost *:80>
ServerName monitor.mydomain.net
Redirect / https://monitor.mydomain.net
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName monitor.mydomain.net
DocumentRoot /usr/share/nagios3/htdocs
<Directory />
Options FollowSymLinks
AllowOverride None
allow from all
</Directory>
<Directory /usr/share/nagios3/htdocs>
Options Indexes FollowSymLinks MultiViews
Options +ExecCGI
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/nagios3 /usr/lib/cgi-bin/nagios3
ScriptAlias /nagios3/cgi-bin /usr/lib/cgi-bin/nagios3
Alias /stylesheets /etc/nagios3/stylesheets
<DirectoryMatch (/usr/share/nagios3/htdocs|/usr/lib/cgi-bin/nagios3|/etc/nagios3/stylesheets)>
Options FollowSymLinks
DirectoryIndex index.php index.html
AllowOverride AuthConfig
<IfVersion < 2.3>
Order Allow,Deny
Allow From All
</IfVersion>
<IfVersion >= 2.3>
Require all denied
</IfVersion>
AuthName "Nagios Access"
AuthType Basic
AuthUserFile /etc/nagios3/htpasswd.users
<RequireAny>
Require valid-user
</RequireAny>
</DirectoryMatch>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/nagios_error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/nagios_access.log combined
SSLEngine on
SSLCertificateKeyFile /etc/ssl/private/a-wildcard.key
SSLCertificateFile /etc/ssl/certs/a-wildcard+dhparam.pem
SSLCertificateChainFile /etc/ssl/certs/gd_bundle-g2-g1.crt
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
/etc/apache2/sites-enabled/timetracker.conf:
<VirtualHost timetracker.mydomain.net:80>
ServerName timetracker.mydomain.net
Redirect / https://timetracker.mydomain.net
</VirtualHost>
<VirtualHost timetracker.mydomain.net:443>
ServerAdmin webmaster@mydomain.net
ServerName timetracker.mydomain.net
DocumentRoot /var/www/kimai
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/kimai>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/timetracker_error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/timetracker_access.log combined
SSLEngine on
SSLCertificateKeyFile /etc/ssl/private/a-wildcard.key
SSLCertificateFile /etc/ssl/certs/a-wildcard+dhparam.pem
SSLCertificateChainFile /etc/ssl/certs/gd_bundle-g2-g1.crt
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
The domain has been anonymized, of course.
Testing the URLs in the browser gives me:
monitor.mydomain.net
-> Nagios page from monitor.mydomain.net
timetracker.mydomain.net
-> ALSO the Nagios page from monitor.mydomain.net, while it is supposed to serve the Kimai page from timetracker.mydomain.net.
This is the log file nagios_acces.log after I access the page through monitor.mydomain.net:
188.194.164.71 - nagiosadmin [10/Oct/2016:19:08:35 +0000] "GET / HTTP/1.1" 200 6389 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"
188.194.164.71 - nagiosadmin [10/Oct/2016:19:08:36 +0000] "GET /side.php HTTP/1.1" 200 1429 "https://monitor.mydomain.net/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"
188.194.164.71 - nagiosadmin [10/Oct/2016:19:08:36 +0000] "GET /main.php HTTP/1.1" 200 1917 "https://monitor.mydomain.net/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"
When I access the site through timetracker.mydomain.com, I get these lines in the same logfile:
188.194.164.71 - nagiosadmin [10/Oct/2016:19:12:19 +0000] "GET / HTTP/1.1" 200 1018 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"
188.194.164.71 - nagiosadmin [10/Oct/2016:19:12:20 +0000] "GET /side.php HTTP/1.1" 200 1429 "https://timetracker.mydomain.net/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"
188.194.164.71 - nagiosadmin [10/Oct/2016:19:12:20 +0000] "GET /main.php HTTP/1.1" 200 1917 "https://timetracker.mydomain.net/" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"
188.194.164.71 - nagiosadmin [10/Oct/2016:19:12:20 +0000] "GET /images/favicon.ico HTTP/1.1" 200 1178 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.2.0"
Note that these lines also appear in the logfile for monitor; the actual logfile for timetracker stays empty.
Somebody suggested to me that Amazon EC2 instances might be behind a reverse proxy that somehow drops the host name to which the original HTTP request was made.
Is this true and if so, how can I work around it?
Thanks a lot in advance!
EDIT: This whole configuration has been migrated from another server where it was working perfectly as expected. The /etc/apache2 directories on both servers are completely identical, except for the 2nd level domain name of course. The only other difference is that the original server is Debian Jessie while the new server is Ubuntu 14.04.
Best Answer
It's because of network environment of AWS. Your EC2 instance looks like it has 2 IPs assigned (private one ane public one) but in reality EC2 has assigned only private ip. Public IP points into some huge NAT device which is in front of VPC and which knows how to map public IP to your EC2 instance. This is one of weirdness of AWS.
And this is root cause of your problem. As you can see, your default virtual host is declared as
<VirtualHost *:80>
or<VirtualHost *:443>
which means for apache something like "scan requests on every interfaces where apache is listening and look for request with Host header equal of monitor.mydomain.net (as set in ServerName directive)". This is ok, your requests are comming thru your private IP (due that NAT device) and everything is working.But in your second virtualhost, you have declared is as
<VirtualHost timetracker.mydomain.net:80>
resp. as<VirtualHost timetracker.mydomain.net:443>
, which means in apache language "scan all requests comming thru interface with IP timetracker.mydomain.net and looks for Host header timetracker.mydomain.net". Problem is that your EC2 has no interface with IP of timetracker.mydomain.net because that IP points to AWS NAT device, not your EC2 instance, so this rule is never used.You have to reconfigure all of your VirtualHosts to listen on *:80 and *:443 and just define your sites with
ServerName
directive. Unfortunatelly there is no way how you can have your public IP directly on your EC2. AWS has this because they want to dynamically change mapping of IPs and EC2 instances.