我有一个运行 Ubuntu 14.04 和 Apache 2.4 的 Amazon EC2 实例。我已为 Apache 配置了 3 个虚拟主机,全部仅用于 HTTPS。
问题是,当我尝试从互联网访问 Web 服务器时,主机名不知何故丢失了,并且无论我通过哪个主机名访问它,apache 都会尝试从默认主机提供页面。
/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 [email protected]
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>
当然,该域名已经匿名化。
在浏览器中测试 URL 得到以下结果:
monitor.mydomain.net
-> 来自 monitor.mydomain.net 的 Nagios 页面
timetracker.mydomain.net
->还有来自 monitor.mydomain.net 的 Nagios 页面,而它应该从 timetracker.mydomain.net 提供 Kimai 页面。
这是我通过monitor.mydomain.net访问页面后的日志文件nagios_acces.log:
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"
当我通过 timetracker.mydomain.com 访问该网站时,我在同一个日志文件中看到以下几行:
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"
请注意,这些行也会出现在监视器的日志文件中;实际的日志文件因为时间跟踪器保持空白。
有人向我建议,Amazon EC2 实例可能落后于反向代理这会以某种方式删除原始 HTTP 请求所针对的主机名。
这是真的吗?如果是,我该如何解决?
提前谢谢您!
编辑:整个配置已从另一台服务器迁移过来,该服务器运行正常,完全符合预期。两台服务器上的 /etc/apache2 目录完全相同,当然,二级域名除外。唯一的区别是原始服务器是 Debian Jessie,而新服务器是 Ubuntu 14.04。
答案1
这是因为 AWS 的网络环境。您的 EC2 实例看起来分配了 2 个 IP(一个私有 IP 和一个公共 IP),但实际上 EC2 已分配仅限私有 IP。公共 IP 指向 VPC 前面的某个大型 NAT 设备,该设备知道如何将公共 IP 映射到您的 EC2 实例。这是 AWS 的奇怪之处之一。
这就是问题的根本原因。如您所见,您的默认虚拟主机声明为<VirtualHost *:80>
或,<VirtualHost *:443>
对于 Apache 来说,这意味着“扫描 Apache 正在侦听的每个接口上的请求,并查找主机头等于 monitor.mydomain.net(如 ServerName 指令中设置)的请求”。这没问题,您的请求是通过您的私有 IP 发送的(由于 NAT 设备),一切正常。
但是在你的第二个虚拟主机中,你已经声明为<VirtualHost timetracker.mydomain.net:80>
,<VirtualHost timetracker.mydomain.net:443>
这意味着在 Apache 语言中“扫描所有传入的请求通过 IP timetracker.mydomain.net 接口并查找主机头 timetracker.mydomain.net”。问题是您的 EC2没有与 timetracker.mydomain.net 的 IP 接口因为该 IP 指向 AWS NAT 设备,而不是您的 EC2 实例,所以该规则从未使用过。
您必须重新配置所有 VirtualHosts 以监听 *:80 和 *:443,然后使用ServerName
指令定义您的站点。不幸的是,您无法直接在 EC2 上拥有公共 IP。AWS 之所以这样做,是因为他们希望动态更改 IP 和 EC2 实例的映射。