使用 VirtualDocumentRoot 在 SSL 中进行虚拟托管
Virtual Hosting in SSL with VirtualDocumentRoot
我在 ubuntu 16.04 VM
上进行开发工作
当我从事许多项目时,为了让我的生活更轻松,我使用 VirtualDocumentRoot 和主机文件从我的主文件夹使用 *.dev 域来服务器站点:
在 000-default.conf 我有:
<VirtualHost *:80>
VirtualDocumentRoot /home/steve/websites/%-2/%-2/public_html
ServerAlias *.dev
</VirtualHost>
然后在主机中我有我正在处理的各种站点:
127.0.0.1 somesite.dev
127.0.0.1 another.dev
127.0.0.1 athirdone.dev
127.0.0.1 blog.athirdone.dev
这样,当我添加一个新项目时,我只需要在网站目录中创建正确的文件夹结构并向主机添加一行,例如,如果我想处理一个新项目 somecoolproject.dev,我只是添加了一个文件夹:
/home/steve/websites/somecoolproject/somecoolproject/public_html
主机中有一行:
127.0.0.1 somecoolproject.dev
我准备好了。
无论如何,我现在所做的几乎所有工作都通过 https 运行,并且许多项目都有代码来强制执行此操作,无论是在源代码还是 htaccess 等中,这使得在开发副本上工作很痛苦。
我想在我的开发机器上创建一个自签名证书,理想情况下我不需要为每个项目生成一个新证书,所以某种通配符 *.dev 会很棒。
但即使我确实需要为每个项目创建一个新的项目,我仍然无法弄清楚如何使用我的设置安装它 - 我发现的所有内容都假定有一个固定的文档和硬编码的服务器名。
我们喜欢赏金,因为为您编写解决方案有点长 :) 您问题的真正答案是如何使其工作,而 VirtualDocumentRoot 不会在 SSL 中工作。我建议将来自默认 SSL 虚拟主机的请求代理到动态非 SSL 虚拟主机。这可以通过保留请求的主机名来实现。
首先,完成所有准备工作:1/ 生成您的私钥和证书(如果需要,可以使用通配符),有很多这方面的教程,2/ 在您的主要 httpd.conf 中激活包括 extra/httpd-ssl.conf
在httpd-ssl.conf中,你需要这个conf(我测试成功了):
UseCanonicalName Off
ProxyPreserveHost On
SetEnvIf Server_Addr "(.*)" sname=
RewriteEngine On
RewriteCond "%{HTTPS}" =on
RewriteRule ^/(.*)$ "http://%{ENV:sname}:80/" [P]
我也建议自定义Log格式,这样你会看的更清楚。这将有助于以后的调试,这里有一些使用请求的主机名进行记录的指令,您可以通过日志行的长度来识别 SSL 或非 SSL 流量。
在 httpd.conf 中,找到定义 LogFormat 的地方并添加:
LogFormat "%V %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" enhanced
LogFormat "%V %h %l %u %t \"%r\" %>s %b" enhancedSSL
CustomLog "logs/access_log" enhanced
在 httpd-ssl.conf 中,您只需要这个:
CustomLog "logs/access_log" enhancedSSL
告诉我们它是否按预期工作。
一旦工作,下一步可能是至少从远程禁用非 SSL 流量。要实现这一点,要么将本地防火墙配置为阻止端口 80 上的请求,要么(更好)将 VirtualHost 配置为仅在本地侦听(VirtualHost 127.0.0.1:80 而不是 *:80)。
如果我理解正确,你想知道:
- 如何为 *.dev 生成通配符 SSL 证书
- 如何使用允许在 SSL/TLS 上服务器任何 *.dev 域的配置在本地配置 apache w/o 在创建新的 *.dev 域时更改配置。
如果我理解正确的话,这当然是可行的。
它是如何工作的:SNI - 服务器名称指示,TLS 协议扩展,其中,主机名在建立 TLS 连接时传递,在 HTTP 数据之前(如主机 header) 可用。所有流行的网络浏览器,curl,所有流行的网络服务器都支持它。
步骤:
首先。生成证书:
mindaugas@mindaugas-ubuntu-14:/usr/local/apache2/conf$ sudo openssl req -newkey rsa:2048 -nodes -keyout domain.key -x509 -days 365 -out domain.crt
Generating a 2048 bit RSA private key
.............+++
..................+++
writing new private key to 'domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:*.dev
Email Address []:
关键部分是:
Common Name (e.g. server FQDN or YOUR name) []:*.dev
第二
服务器配置:
Listen 443
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile "/usr/local/apache2/conf/domain.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/domain.key"
VirtualDocumentRoot /home/mindaugas/websites/%-2/pubic/
ServerAlias *.dev
<Directory "/">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Allow from All
Require all granted
</Directory>
</VirtualHost>
启用 ssl 并重新启动 apache:
sudo a2enmod ssl
sudo service apache2 restart
您可以通过以下方式进行测试:
- 正在创建两个文档文件结构;
- 使用简单的 HTML 页面填充它们;
- 通过在主机文件中提供域 - ip 映射来发出请求,或者,正如我所做的那样,使用 "Modify headers" 插件,在需要时通过发出不同的主机 headers:
我在 ubuntu 16.04 VM
上进行开发工作当我从事许多项目时,为了让我的生活更轻松,我使用 VirtualDocumentRoot 和主机文件从我的主文件夹使用 *.dev 域来服务器站点:
在 000-default.conf 我有:
<VirtualHost *:80>
VirtualDocumentRoot /home/steve/websites/%-2/%-2/public_html
ServerAlias *.dev
</VirtualHost>
然后在主机中我有我正在处理的各种站点:
127.0.0.1 somesite.dev
127.0.0.1 another.dev
127.0.0.1 athirdone.dev
127.0.0.1 blog.athirdone.dev
这样,当我添加一个新项目时,我只需要在网站目录中创建正确的文件夹结构并向主机添加一行,例如,如果我想处理一个新项目 somecoolproject.dev,我只是添加了一个文件夹:
/home/steve/websites/somecoolproject/somecoolproject/public_html
主机中有一行:
127.0.0.1 somecoolproject.dev
我准备好了。
无论如何,我现在所做的几乎所有工作都通过 https 运行,并且许多项目都有代码来强制执行此操作,无论是在源代码还是 htaccess 等中,这使得在开发副本上工作很痛苦。
我想在我的开发机器上创建一个自签名证书,理想情况下我不需要为每个项目生成一个新证书,所以某种通配符 *.dev 会很棒。
但即使我确实需要为每个项目创建一个新的项目,我仍然无法弄清楚如何使用我的设置安装它 - 我发现的所有内容都假定有一个固定的文档和硬编码的服务器名。
我们喜欢赏金,因为为您编写解决方案有点长 :) 您问题的真正答案是如何使其工作,而 VirtualDocumentRoot 不会在 SSL 中工作。我建议将来自默认 SSL 虚拟主机的请求代理到动态非 SSL 虚拟主机。这可以通过保留请求的主机名来实现。
首先,完成所有准备工作:1/ 生成您的私钥和证书(如果需要,可以使用通配符),有很多这方面的教程,2/ 在您的主要 httpd.conf 中激活包括 extra/httpd-ssl.conf
在httpd-ssl.conf中,你需要这个conf(我测试成功了):
UseCanonicalName Off
ProxyPreserveHost On
SetEnvIf Server_Addr "(.*)" sname=
RewriteEngine On
RewriteCond "%{HTTPS}" =on
RewriteRule ^/(.*)$ "http://%{ENV:sname}:80/" [P]
我也建议自定义Log格式,这样你会看的更清楚。这将有助于以后的调试,这里有一些使用请求的主机名进行记录的指令,您可以通过日志行的长度来识别 SSL 或非 SSL 流量。 在 httpd.conf 中,找到定义 LogFormat 的地方并添加:
LogFormat "%V %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" enhanced
LogFormat "%V %h %l %u %t \"%r\" %>s %b" enhancedSSL
CustomLog "logs/access_log" enhanced
在 httpd-ssl.conf 中,您只需要这个:
CustomLog "logs/access_log" enhancedSSL
告诉我们它是否按预期工作。 一旦工作,下一步可能是至少从远程禁用非 SSL 流量。要实现这一点,要么将本地防火墙配置为阻止端口 80 上的请求,要么(更好)将 VirtualHost 配置为仅在本地侦听(VirtualHost 127.0.0.1:80 而不是 *:80)。
如果我理解正确,你想知道:
- 如何为 *.dev 生成通配符 SSL 证书
- 如何使用允许在 SSL/TLS 上服务器任何 *.dev 域的配置在本地配置 apache w/o 在创建新的 *.dev 域时更改配置。
如果我理解正确的话,这当然是可行的。
它是如何工作的:SNI - 服务器名称指示,TLS 协议扩展,其中,主机名在建立 TLS 连接时传递,在 HTTP 数据之前(如主机 header) 可用。所有流行的网络浏览器,curl,所有流行的网络服务器都支持它。
步骤:
首先。生成证书:
mindaugas@mindaugas-ubuntu-14:/usr/local/apache2/conf$ sudo openssl req -newkey rsa:2048 -nodes -keyout domain.key -x509 -days 365 -out domain.crt
Generating a 2048 bit RSA private key
.............+++
..................+++
writing new private key to 'domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:*.dev
Email Address []:
关键部分是:
Common Name (e.g. server FQDN or YOUR name) []:*.dev
第二
服务器配置:
Listen 443
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile "/usr/local/apache2/conf/domain.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/domain.key"
VirtualDocumentRoot /home/mindaugas/websites/%-2/pubic/
ServerAlias *.dev
<Directory "/">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Allow from All
Require all granted
</Directory>
</VirtualHost>
启用 ssl 并重新启动 apache:
sudo a2enmod ssl
sudo service apache2 restart
您可以通过以下方式进行测试:
- 正在创建两个文档文件结构;
- 使用简单的 HTML 页面填充它们;
- 通过在主机文件中提供域 - ip 映射来发出请求,或者,正如我所做的那样,使用 "Modify headers" 插件,在需要时通过发出不同的主机 headers: