• 隐藏侧边栏
  • 展开分类目录
  • 关注微信公众号
  • 我的GitHub
  • QQ:1753970025
Chen Jiehua

Nginx反向代理WordPress 

Nginx作为一个性能强悍的 web 服务器,用来配置 wordpress 简直小菜一碟。不过,我们今天要聊的是另外一种场景……

常规配置

WordPress 是一个采用 php 语言开发的博客系统,它本身并不提供服务器的功能,因此我们一般会搭配 nginx 或 apache 进行部署。

以 nginx+php-fpm 为例,一个简单的配置示例:

server {
        listen 8080;
        server_name _;
        root /path/to/wordpress;
        index index.html index.htm index.php;
        location / {
                try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        }
}

假设 IP 为 10.0.0.54,这样子就可以通过 http://10.0.0.54:8080 进行访问了:

问题描述

现在考虑两种特殊情况:

  • 部署 wordpress 的是一台内部主机,外部无法直接访问?
  • 在不改动原有配置的情况,如何支持 https 访问?

这时候我们可能会考虑使用另外一台 nginx 服务器反向代理到该 wordpress 站点,同时配置 https 证书。

Nginx 反向代理的配置:

server {
        listen 443 ssl;
        server_name _;

        ssl_certificate /etc/letsencrypt/live/xxx/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem;

        error_page 497 https://$host:$server_port$request_uri;

        location / {
                proxy_pass http://10.0.0.54:8080;
                include proxy_params;
        }
}

然而,当我们访问 https://10.0.0.51 时就会发现,页面显示不正常 :

查看页面加载,可以发现静态资源是通过 http 请求的,会被浏览器的安全策略拦截:

解决方案

仔细检查 nginx 的配置,感觉配置没啥问题,查看页面源码:

虽然经过一层反向代理后可以用 https 访问,但 wordpress 页面渲染出来却是 http,也就是 proxy_pass http://10.0.0.54:8080 这里用的是 http。

经过一番搜索后发现 wordpress 可以根据 proxy_header 自动将 http 改为 https,在 wp-config.php 中添加:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
  $_SERVER['HTTPS'] = 'on';
} 

FYI:wp-config.php 需要安装完成 wordpress 后才会生成,可以先用 http 正常安装后在加入这段代码;之后可能还需要手动改一下数据库 wp-options 表的 siteurl home 这两行的值。

目录重定向

就在以为一切搞定时,访问 https://10.0.0.51/wp-admin 却又歇菜了:

如果是直接访问 https://10.0.0.51/wp-admin/ 则一切正常,而访问 /wp-admin(不带斜杠)会自动跳转到 /wp-admin/(目录),这时候 nginx 默认会使用绝对路径跳转,也就是 proxy_pass http://10.0.0.51:8080 。

查阅 nginx 文档最后发现可以用 absolute_redirect 将其改为相对路径重定向:

Syntax:	absolute_redirect on | off;
Default: absolute_redirect on;
Context: http, server, location

此外,相关的参数还有  server_name_in_redirect 和 port_in_redirect

总结

后来突然想到了,通过 docker 运行的 wordpress 如果要配置 https 访问,不就是我们上面的这个场景吗?

于是在官方的 docker 镜像中发现,默认的配置示例文件为 wp-config-docker.php,它包含了对 https 进行特殊处理。

参考:

码字很辛苦,转载请注明来自ChenJiehua《Nginx反向代理WordPress》

评论