亚马逊 EC2 实例上的多个虚拟主机:无法访问除默认虚拟主机之外的任何其他虚拟主机

亚马逊 EC2 实例上的多个虚拟主机:无法访问除默认虚拟主机之外的任何其他虚拟主机

我有一个运行 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 实例的映射。

相关内容