具有多个域的Apache虚拟主机

时间:2015-12-24 16:32:44

标签: redirect ssl dns apache2 virtualhost

我想弄清楚我的虚拟主机文件的最佳配置是什么,但我遇到了一些问题。

目前我有2个域名:domain1.com和domain2.com

我在IP 000.000.000.001有一台服务器,它实际上托管了所有需要的文件。在这些文件中,您有一个API(api.domain1.com)和实际的网站。

domain1.com正在使用Digital Ocean的名称服务器,并使用以下DNS记录:

A        @        000.000.000.001
CNAME    *        domain1.com.

出于搜索引擎优化的目的,我想将所有未发送到api子域的请求重定向到www.domain1.com。 但是,我也只希望用户能够通过SSL连接浏览我的网站(和API),我不希望用户能够通过HTTP使用它,所以我尝试重定向所有这些请求以使用HTTPS。证书由LetsEncrypt提供!他们的自动安装对我的虚拟主机文件进行了更改,目前我有4个:

  1. api.domain1.com.conf

    <VirtualHost *:80>
        ServerName api.domain1.com
    
        DocumentRoot /var/www/api.domain1.com/web
    
        RewriteEngine on
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,QSA,R=permanent]
    </VirtualHost>
    
  2. api.domain1.com勒ssl.conf中

    <IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName api.domain1.com
    
        DocumentRoot /var/www/api.domain1.com/web
    
        ExpiresActive On
        /* ... */
    
        <Directory /var/www/api.domain1.com/web>
            AllowOverride None
            Order Allow,Deny
            Allow from All
    
            <IfModule mod_rewrite.c>
                    Options -MultiViews
                    RewriteEngine On
                    RewriteCond %{REQUEST_FILENAME} !-f
                    RewriteRule ^(.*)$ app.php [QSA,L]
            </IfModule>
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    
        SSLCertificateFile /etc/letsencrypt/live/domain1.com/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/domain1.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateChainFile /etc/letsencrypt/live/domain1.com/chain.pem
    </VirtualHost>
    </IfModule>
    
  3. domain1.com.conf

    <VirtualHost *:80>
        ServerName domain1.com
    
        Redirect 301 / https://www.domain1.com
    </VirtualHost>
    
  4. domain1.com勒ssl.conf中

    <IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName www.domain1.com
        DocumentRoot /var/www/domain1.com
    
        ExpiresActive On
        /* ... */
    
        RewriteEngine On
        RewriteCond %{HTTP_HOST} ^https://domain1.com
        RewriteRule ^/(.*)$ https://www.domain1.com/$1 [L,R=301]
    
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    
        ErrorDocument 404 /404.html
    
        SSLCertificateFile /etc/letsencrypt/live/domain1.com/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/domain1.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateChainFile /etc/letsencrypt/live/domain1.com/chain.pem
    </VirtualHost>
    </IfModule>
    
  5. 当我尝试访问该网站时,会发生以下情况:

        http://test.domain1.com   -->    https://test.domain1.com   FAIL
        http://domain1.com        -->    https://www.domain1.com    SUCCESS
        http://www.domain1.com    -->    https://www.domain1.com    SUCCESS
        https://domain1.com       -->    https://domain1.com        FAIL
        https://www.domain1.com   -->    https://www.domain1.com    SUCCESS
    

    如您所见,第一个和第四个条目失败。他们都向我的访客返回404 Not Found,这对我来说是不可接受的。第一个甚至显示SSL警告(我不认为LetsEncrypt!支持通配符,所以我认为这个警告不能被阻止?)

    导致我测试的原因。没有重定向到www。?

    是什么导致我的第四个条目最终投放404?

    现在我还希望我的第二个域(domain2.com)指向此服务器/文件。此域名托管在不同的位置(我是从朋友那里获得的)并使用不同的域名服务器。我不能简单地更改名称服务器(我认为?),因为第二个域具有链接到它的电子邮件主机,它使用其他提供程序的名称服务器。暂时,这个域也有自己的Web服务器(但将来会消失),托管在000.000.000.002。现在,它使用

     <meta http-equiv="refresh" content="0; url=https://www.domain1.com" />
    

    标记在其index.html文件中以重定向到正确的服务器,将来必须在DNS记录中完成。

    我该怎么做?

    总结一下:

    1. 我认为CNAME *是所有子域名的全部内容?
    2. 我在虚拟主机文件中做错了什么?导致第四次重定向失败的原因。
    3. 我应该如何处理指向第一个IP的第二个域?
    4. 是否有其他方式只允许HTTPS连接? (这也应该强制在API虚拟主机上)。我听说过HSTS,我应该实现吗?
    5. 一些SEO测试也指出我需要IP重定向来进一步提高我的搜索引擎优化结果。他们以此为例:

          RewriteCond %{HTTP_HOST} ^000\.000\.000\.001
          RewriteRule (.*) http://www.domain1.com/$1 [R=301,L]
      

      我是否也应该为SEO目的实现这个?我还应该为我的其他IP地址实现这个吗?

      这么多问题......

      当然,如果您有任何其他建议,请分享您的意见!

1 个答案:

答案 0 :(得分:2)

那里有很多问题!让我们尝试解决它们:

  1. 不确定你在这里问的是什么,而不是CNAMES的专家,但会认为你需要&#39; * .domain1.com&#39;至少而不仅仅是&#39; *&#39;

  2. 如果您失败了,则不会在ServerName和ServerAlias中明确记下您的备用服务器名称。在这种情况下,它将默认为配置中找到的第一个服务器。这是api.domain.com吗?如果是这样可以解释404,因为SERVER_NAME(默认情况下)将是客户端提供的,因此api.domain1.com:80设置将只重定向到他们发送的https版本(这似乎正在发生) ,然后还会查看api.domain1.com:443配置,而不是找到名称。您需要将替代名称添加到主domain1.com配置的ServerAlias设置中,或者将该配置移动到第一位,使其成为默认值,并且仅在明确使用api.domain1.com名称时使用api one

  3. 由于您似乎想要将此直接重定向到新网站,我会更新DNS以指向您的新IP地址,以节省您为两台服务器付款(就资金和管理时间而言)。这可以在现有的DNS名称服务器上完成,以保持电子邮件,但显然可以更好地整合一个。在此期间,在服务器配置中实现适当的301重定向,因为元重定向不是搜索引擎的强烈信号,并且您似乎关心SEO。

  4. 主要方法是将http重定向到https。 HSTS主要是一种安全功能,可在浏览器发出请求之前自动将http重定向到https 。这很有用,因为默认为http(例如,在浏览器地址栏中键入www.example.com默认情况下会将您发送到http://www.example.com而不是https://www.example.com),这可以被截取以防止升级到https(这比较难以拦截)。它有一些缺点:并非所有浏览器都支持它,你需要访问网站至少一次加载HSTS设置(虽然有些浏览器允许预加载),如果没有访问该网站,该设置将过期maxAge时间(再次假设它没有预先加载)。因此,它不应该用作重定向的替代品,而应该用作支持HSTS的浏览器的强制执行。如果您想了解有关HSTS的更多信息,可以通过博客了解here

  5. 我还会说你有几种不同的重定向方法(api:80有Rewrite,domain1:80有Redirect,domain1:443有Rewrite - 但是有一个非常严格和不正确的RewriteCond)。就个人而言,我更喜欢使用一种方法,因为它不那么令人困惑,但这是个人问题(重定向也略快,但重写会给你更多的力量,所以我更喜欢那个)。所以我倾向于有这样的配置:

    <VirtualHost *:80>
        #This is the first host so is the default.
        #So although I've specified a ServerName and ServerAlias anything else not specified elsewhere will also end up here.
        ServerName www.domain1.com
        ServerAlias domain1.com
    
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    
        #Redirect everything to https:
        RewriteEngine on
        RewriteRule ^(.*)$ https://www.domain1.com$1 [R=301,L]
    </VirtualHost>
    <VirtualHost *:80>
        ServerName api.domain1.com
    
        ErrorLog ${APACHE_LOG_DIR}/api.error.log
        CustomLog ${APACHE_LOG_DIR}/api.access.log combined
    
        #Redirect everything to https:
        RewriteEngine on
        RewriteRule ^(.*)$ https://api.domain1.com$1 [R=301,L]
    </VirtualHost>
    

    然后对于443我会有这个:

    <VirtualHost *:443>
        #This is the first host so is the default.
        #So although I've specified a ServerName and ServerAlias anything else not specified elsewhere will also end up here.
        ServerName www.domain1.com
        ServerAlias domain1.com
    
        ErrorLog ${APACHE_LOG_DIR}/ssl.error.log
        CustomLog ${APACHE_LOG_DIR}/ssl.access.log combined
    
        #Redirect everything which is not already on the real www domain name to that:
        RewriteEngine on
        RewriteCond %{HTTP_HOST} !www.domain1.com
        RewriteRule ^(.*)$ https://www.domain1.com$1 [R=301,L]
    
        #all your other 443 config for www.domain1.com
    
    </VirtualHost>
    <VirtualHost *:443>
        ServerName api.domain1.com
    
        ErrorLog ${APACHE_LOG_DIR}/ssl.api.error.log
        CustomLog ${APACHE_LOG_DIR}/ssl.api.access.log combined
    
        #all your other 443 config for api.domain1.com
    
    </VirtualHost>
    

    请注意,我已为每个vhost添加了不同的日志文件,因此更明显的是哪个vhost被命中。

    另请注意,我重定向不是www.domain1.com的任何内容,而不是您的版本,只有当人们键入domain1.com时才会重定向(并且我不确定会将其用作可疑api.domain1.com配置首先来了。)

    这也将照顾通过IP地址或任何其他名称访问您网站的任何人,因为它将始终重定向到您真正的www.domain1.com服务器名称。这对于http请求来说很容易,但对于https请求,如果您的证书不包含所使用的服务器名称,它们可能确实会出现证书错误。

    LetsEncrypt不支持通配符,但它们允许在证书上使用多个名称,因此您可以轻松获得domain1.com和www.domain1.com的证书,因为这通常被认为是最佳做法。您还可以添加您认为可能使用的任何其他域。对于你api.domain1.com域你也可以添加到同一个证书,或者获得一个单独的证书,因为你有单独的配置(你的上面的配置不清楚你在做什么,因为它看起来一样配置,但不确定这是否是一个错字。)

    对于搜索引擎优化目的,最好只在一个网址下提供您的网站,并使用重定向来强制执行该网址,以上配置将执行此操作。这是为了防止Google认为您有相同的内容,如果您在www.domain1.com/page1.html和https://www.domain1.com/page1.html以及https://domain1.com/page1.htmlhttp://000.000.000.001/page1.html ...等服务相同的内容/ p>

    很多人都在那里,但希望能指出你正确的方向。