Skip to main content

配置Nginx/Apache为WordPress开启基于HTTPS的Multisite模式(子域名与子路径)

By 2021-06-108月 8th, 2021WordPress, 网页服务器

前言

本文记录了在Nginx环境和在Apache环境下为WordPress开启Multisite的心得。因为计划中的博客同时包含了介绍我的兴趣爱好的生活博客,记录技术方面学习笔记的技术博客,和对所在行业的思考的行业博客,为了让几方相互之间的数据和设置进行一定程度的独立,我选择使用WP的Miltisite模式。我同时设置并尝试了子域名和子路径模式,最后选择采用了子域名模式。

注一:本文不包含如何在Nginx/Apache上设置HTTPS。关于如何在Nginx里开启HTTPS,请参考这篇文章。关于如何在Apache里开启HTTPS,请参考这篇文章

注二:第四章讲述了如何配置Nginx的Multisite,第五章讲述了如何配置Apache的Multisite。大家根据自己的WordPress具体使用的是哪个Websserver选一个操作即可,无需两个都操作。

开启Multisite模式(子域名)

1 登记二级域名

首先我们需要先定下来我们的二级域名,随后在DNS记录中登记他。

这里假设我们需要登记的域两个子域名是subdomain1.example.com和subdomain2.example.com。

为此,如果不考虑以后的可能的扩展配置,如CDN,我们可以直接用通配符*来重定向所有的流量至服务器,比如*.example.com。但是这里,我是为每个子域名都分别添加了A记录。当然,目的地都是我的服务器IP地址。

2 申请SSL证书

如果申请的是免费证书的话请注意,免费的证书是无法绑定二级域名的。因此如果有二级域名需要HTTPS,需要为每个二级域名都申请一个SSL证书。我为了开源节流,为每个子域名都申请了一个免费的SSL证书。不过这样有一个不好,就是理论上来说SSL证书是不支持通配符的。

2.1 曲线救国:解决免费SSL证书的通配符问题

我们可以通过利用DNS301转发和服务器 Web Server 的配合来解决该问题。具体来说,在DNS服务器上,将通配符解析*通过301永久重定向至你的IP地址。至于为什么是重定向到IP地址,因为这样可以通过IP直接访问服务器,然后我们可以通过服务器来实现针对IP的301永久转发重定向。这样通过服务器来解决的一个好处是,我们可以不用担心日后的一些服务配置,比如CDN。

这里扩展一下:如果是重定向到example.com的话,那日后针对example.com配置服务,比如CDN,时,针对不存在的子域名,比如non-existing-subdomain.example.com大概率会碰到SSL证书无效的问题。

3 配置Wordpress开启多站点模式

WordPress是本身就自带有多站点模式的。我们需要做的就是开启它。方法是:打开Wordpress跟目录下的wp-config.php,在里面加上这样一句话:

/* Multisite configuration */
define( 'WP_ALLOW_MULTISITE', true );

这样,我们就开启了WP的多站点模式。

4 配置Nginx/Apache Web Server

Nginx

在开启了多站点之后,我们需要配置我们的Nginx以确保它可以正确的处理每个子域名。

4.1-Nginx 不使用HTTPS,或者HTTPS使用的SSL证书可以支持所有需要的二级域名或支持通配符

请参考这篇文章对应修改开启SSL。只要在 default_server 的server_name里面加上*.example.com即可。剩下的就可以让 WordPress 来处理各个子域名之间的关系了。

4.2-Nginx 使用单域SSL证书及免费SSL证书

因为要启用 HTTPS,而且使用的是免费的 SSL 证书(即每个子站点都有自己的 SSL 证书),所以我们需要对每个子域名都配一个 Server。每个 Server 的配置其实大同小异,大部分情况下只需要添加对应的 SSL 文件并修改server_name即可。

关于多 Server 多 SSL 文件的服务器文件组织架构的建议,请参考本文第4.3-Nginx小节。

请参考这篇文章相应的设置每个 Server。

4.3-Nginx 可能的结构优化

因为可能未来会有很多的子域名,而且SSL证书需要不断的更新。因此,有一个好的结构来存储SSL证书很重要。我用的结构如下:

|- nginx root
    |- conf
        |- nginx.conf
        |- include
            |- wp-webserver
                |- subdomain1.example.com
                    |- 子域名subdomain1的SSL文件和配置文件(如:subdomain1.conf)
                |- subdomain2.example.com
                    |- 子域名subdomain2的SSL文件和配置文件(如:subdomain2.conf)

这样,只要在nginx.conf的http块里的最后加一句 include include/wp_webservers/*/*.conf;就能将现在的未来的所有的子域名的SSL及配置文件加载进去啦!

Apache

在开启了多站点之后,我们需要配置我们的Apache以确保它可以正确的处理每个子域名。

4.1-Apache 不使用HTTPS,或者HTTPS使用的SSL证书可以支持所有需要的二级域名或支持通配符

请参考这篇文章对应修改开启SSL。只要将Apache默认的vHost里的ServerNameServerAlias里面改成对应的通配符域名*.example.com即可。剩下的就可以让 WordPress 来处理各个子域名之间的关系了。

4.2-Apache 使用单域SSL证书及免费SSL证书

因为要启用 HTTPS,而且使用的是免费的 SSL 证书(即每个子站点都有自己的 SSL 证书),所以我们需要对每个子域名都配一个 Server。每个 Server 的配置其实大同小异,大部分情况下只需要添加对应的 SSL 文件并修改ServerName即可。

关于多 Server 多 SSL 文件的服务器文件组织架构的建议,请参考本文第4.3-Apache小节。

请参考这篇文章相应的设置每个 Server。

4.3-Apache 可能的结构优化

因为可能未来会有很多的子域名,而且SSL证书需要不断的更新。因此,有一个好的结构来存储SSL证书很重要。我用的结构如下:

|- apache2 root
    |- apache2.conf
    |- sites-available
        |- 000-example-com #主域名的HTTPS配置文件
        |- 001-subdomainA.example.com #子域名A的HTTPS配置文件
        |- 002-subdomainB.example.com #子域名A的HTTPS配置文件
    |- ssl-certificates
        |- example.com
            |- www-example-com
                |- 主域名的SSL文件
            |- subdomainA-example-com
                |- 子域名A的SSL文件
            |- subdomainB-example-com
                |- 子域名B的SSL文件

这样,可以直接通过a2ensite来分别开启各个站点。

关于Apache不同vHost之间的载入顺序请参考这篇文章

5 完成Wordpress Multisite的剩余配置

通过访问wp-admin的网络设置,我们就可以开始设置我们的多站点了。记得我们要选择的是多域名模式。然后,再次打开wp-config.conf,添加如下:

define( 'WP_ALLOW_MULTISITE', true );
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true);
define('DOMAIN_CURRENT_SITE', 'example.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

注:以上代码必须在全部完成前面步骤后再行添加。

如果是Apache,那么就在WordPress的根目录(一般位于/var/www/example-com/)下的.htaccess文件夹里写入如下配置:

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]

这里注意需要确保在vHost里开启对于.htaccess文件的权限:

<Directory /var/www/example-com/>
    AllowOverride All
</Directory>

至此,我们就成功开启了多站点的子域名模式啦!

开启Multisite模式(子路径)

子路径与子域名的配置类似。关于如何申请 SSL 证书以及如何配置 SSL 证书,请参考该文章。不过这里,我们只需要对我们的域名申请一个 SSL 证书即可。

开启 WordPress Multisite 的子路径模式比子域名配置要简单得多。大致的步骤如下:

在 wp-config.conf 下添加如下代码开启 WordPress Multisite:

/* Multisite configuration */
define( 'WP_ALLOW_MULTISITE', true );

回到Wordpress管理面板的网络管理界面,根据要求开启Multisite的子路径模式。

将如下配置加入到wp-config.conf里面:

define( 'WP_ALLOW_MULTISITE', true );
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true);
define('DOMAIN_CURRENT_SITE', 'example.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

如果是Nginx,那么就在 nginx.conf 里的Server 块添加如下代码:

# Rewrite requests to /wp-.* on subdirectory installs.
if (!-e $request_filename) {
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
        rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
        rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
}

如果是Apache,那么就在WordPress的根目录下的.htaccess文件夹里写入如下配置:

# BEGIN WordPress Multisite
# Using subfolder network type: https://wordpress.org/support/article/htaccess/#multisite

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

# END WordPress Multisite

这样,我们就成功地开启了多站点的子路径模式啦!

两种模式的对比总结

我是先配置好了子路径模式,倒腾了两天后,觉得不太好看(纯个人偏好),于是又弄了子域名模式。大家倒腾之前一定一定要记得备份哦!

Snapshot of Tencent Cloud snapshots for subdomain and subdirectory wp multisite mods

图 1: VPS控制台子路径和子域名模式的WP Multisite的快照的截图

总的来说,子域名和子路径两种方式在功能上没有任何区别。唯一的区别就是在 URL 上。看你是想要 subdomain.example.com 还是 example.com/subfolder/ 了。我个人是倾向于 subdomain.example.com 的。因为看起来更简洁。而且 subdomain 可以比 subfolder 更好地体现出更高一层的区别,可以更好的强调不同子网站之间的区别。

就配置而言,明显子域名会比子路径难很多。尤其是当你要为每个子域名分别分配 SSL 证书的时候,是很烦人的。所以,根据自己的喜好还有自己的技术实力选择对应的方法就好啦!

Reference:

[1] https://tonyteaches.tech/wordpress-multisite-nginx/

[2] https://wordpress.org/support/article/htaccess/

后语

谨以此文纪念我一天内将自带镜像删除改用Nginx然后再改用Apache的两次重装经历和这爱折腾的劲儿!

2021.06.09 于上海兴荣温德姆隔离酒店…

Leave a Reply