在我的 apache 服务器上,我希望能够将所有传入的 http 请求重定向到等效的 https 请求。问题是我希望能够在不指定
ServerName
的情况下为我的默认虚拟主机执行此操作,并让重定向与请求 url 中出现的任何服务器名称一起工作。我希望有这样的事情:
NameVirtualHost *:80
<VirtualHost *:80>
RedirectPermanent / https://%{SERVER_NAME}/
...
</VirtualHost>
这可以使用
Redirect
还是我必须求助于 Rewrite
?
尝试将其添加到您的 VirtualHost 配置中:
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
<VirtualHost>
两者都工作正常。但根据 Apache 文档,您应该避免使用
mod_rewrite
进行简单重定向,而使用 Redirect
代替。因此,根据他们的说法,您最好应该这样做:
<VirtualHost *:80>
ServerName www.example.com
Redirect / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
/
之后的第一个Redirect
是url,第二部分是应该重定向的地方。
您还可以使用它将 URL 重定向到子域:
Redirect /one/ http://one.example.com/
这也是省略不需要的重定向的完整方法;)
这些规则旨在用于 .htaccess 文件,因为 *:80 VirtualHost 条目中的 RewriteRule 不需要条件。
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]
平面化:
RewriteEngine on
==> 完全启用引擎
RewriteCond %{HTTPS} off [OR]
==> 匹配非 https 连接,或者(不设置 [OR] 将导致隐式 AND!)
RewriteCond %{HTTP:X-Forwarded-Proto} !https
==> 匹配转发连接(代理、负载均衡器等)无 https
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R=301,L]
==> 如果两个条件之一匹配,则重写整个 URL,发送 301 以使客户端“学习”此内容(有些学习,有些不学习),并发送 L 表示最后一条规则。
就我而言,为了将
http://jaimemontoya.com
重定向到 https://jaimemontoya.com
,我转到 /etc/apache2/sites-available/jaimemontoya.com.conf
并添加了这两行:
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
/etc/apache2/sites-available/jaimemontoya.com.conf
的最终版本变成了这样:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName jaimemontoya.com
ServerAlias www.jaimemontoya.com
DocumentRoot /var/www/jaimemontoya.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
最后我重新启动了Apache:
# service apache2 restart
然后,所有对
http://jaimemontoya.com
的访问都会将访客重定向至 https://jaimemontoya.com
。
我使用 mkcert 创建无限 *.dev.net 子域和具有有效 HTTPS/SSL 证书的本地主机(Windows 10 XAMPP 和 Linux Debian 10 Apache2)
我使用 mkcert v1.4.0 在 Windows 上创建证书(以管理员身份执行 CMD):
mkcert -install
mkcert localhost "*.dev.net"
这会在 Windows 10 中创建此文件(我将首先在 Windows 10 XAMPP 中安装它)
localhost+1.pem
localhost+1-key.pem
覆盖 XAMPP 默认证书:
copy "localhost+1.pem" C:\xampp\apache\conf\ssl.crt\server.crt
copy "localhost+1-key.pem" C:\xampp\apache\conf\ssl.key\server.key
现在,在 Debian 10 的 Apache2 中,激活 SSL 和 vhost_alias
a2enmod vhosts_alias
a2enmod ssl
a2ensite default-ssl
systemctl restart apache2
对于 vhost_alias 添加此 Apache2 配置:
nano /etc/apache2/sites-available/999-vhosts_alias.conf
此内容:
<VirtualHost *:80>
UseCanonicalName Off
ServerAlias *.dev.net
VirtualDocumentRoot "/var/www/html/%0/"
</VirtualHost>
添加站点:
a2ensite 999-vhosts_alias
通过 SSH 将证书复制到 /root/mkcert 并覆盖 Debian 的:
systemctl stop apache2
mv /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert-snakeoil.pem.bak
mv /etc/ssl/private/ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert-snakeoil.key.bak
cp "localhost+1.pem" /etc/ssl/certs/ssl-cert-snakeoil.pem
cp "localhost+1-key.pem" /etc/ssl/private/ssl-cert-snakeoil.key
chown root:ssl-cert /etc/ssl/private/ssl-cert-snakeoil.key
chmod 640 /etc/ssl/private/ssl-cert-snakeoil.key
systemctl start apache2
编辑 SSL 配置
nano /etc/apache2/sites-enabled/default-ssl.conf
首先编辑包含以下内容的文件:
<IfModule mod_ssl.c>
<VirtualHost *:443>
UseCanonicalName Off
ServerAlias *.dev.net
ServerAdmin webmaster@localhost
# DocumentRoot /var/www/html/
VirtualDocumentRoot /var/www/html/%0/
...
上次重启:
systemctl restart apache2
注意:不要忘记在 /var/www/html/ 中为子域创建文件夹
/var/www/html/subdomain1.dev.net
/var/www/html/subdomain2.dev.net
/var/www/html/subdomain3.dev.net