wordpress HTTPS修正

前文:迁移wordpress到HTTPS

前文提到,使用docker部署,因为前后https模式不同步(前面是https后面是http://ip:port)导致需要修改配置文件,所以我决定把wordpress从docker迁移出来,因为docker挂载目录的其实就是wordpress本体在的位置


server {
  listen  443;
  server_name wpdev.endercaster.lan;#记得改掉
 #SSL证书配置参照前文
  root /opt/wordpress;#记得改掉
  location / {
      try_files $uri $uri/ /index.php?$is_args$args; #这里需要注意一下,不要少打
      index index.php;
  }
  # 这里替换为:在设置->固定连接->改为任意一个非朴素型
  #location ~ ^/wp-json/ {
  #    rewrite ^/wp-json/(.*?)$ /?rest_route=/$1 last;
  #}
  location ~ \.php$ {
        fastcgi_pass unix:/run/php/wp-test.sock;
        include fastcgi.conf;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }
}

然后把前文中wp-config.php加的代码都删掉。

配置php-fpm,如果只有这一个项目,可以把上面的fastcgi_pass改掉,跳过这步


[wordpress]#从www改为wordpress
user = www-data
group = www-data
listen = /run/php/wp-test.sock
listen.mode = 0666


# 重启php-fpm
systemctl restart php7.2-fpm
#现在可以重新读取nginx配置文件了
nginx -t 
# 如果上面的输出是successful的话
systemctl reload nginx

然后登录查看工具->站点健康,看看有没有少一些依赖,给它装上。

至此,我的站点终于完美的迁移到https啦!

环境部署踩坑日记

一、lnmp

最近有个项目需要用lnmp环境,于是用一键脚本安装了一下

先是按照一般的nginx部署流程走了一下,结果报500[Laravel项目],很巧,大家都有这个问题,在lnmp官网就能找到,是由于lnmp默认配置禁止跨目录访问,而框架需要读取自动加载脚本[autoload.php],所以我们需要把这个功能停掉

1.编辑/home/wwwroot/default/.user.ini


sudo chattr -i .user.ini
sudo vi .user.ini


open_basedir=$document_root/:/tmp/:/proc/
#改为
#open_basedir=$document_root/:/tmp/:/proc/

2.编辑/usr/local/nginx/conf/fastcgi.conf


fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/";
# 注释掉
#fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/";

二、Nginx

其实这个是我的问题,直接复制原项目的配置文件,通过修改成不符合语法的配置可以看到测试不通过,也就是说这个文件本身是生效了的,但是通过虚拟域名并未访问到,一开始我以为因为”-“字符的原因server_name没有匹配到,后来发现是监听端口写错了。


listen [::]:80;
# 改为
listen 80;

迁移wordpress到HTTPS

鸽了四个月之后我终于想起来配置HTTPS环境了

好的现在不止四个月了,一直以来都懒得写,这不是最近终于有时间了,所以补上。

第一步先把https证书扔上去


#
server {
    listen       80;
    server_name  wordpress.endercaster.com;
    rewrite ^(.*) https://$host$1 permanent;# 强制跳转
    # 这下面其实已经没有执行了
    location / {
        proxy_pass http://127.0.0.1:docker 暴露的端口;

        proxy_redirect off;
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
server {
    listen       443;# ssl默认端口
    server_name  wordpress.endercaster.com;
    ssl on;# 开启ssl
    ssl_certificate cert/wordpress.pem;# nginx下的cert目录
    ssl_certificate_key cert/wordpress.key; # nginx下的cert目录
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    #ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_protocols TLSv1.2;# 有个站长工具可以测ssl配置,设置成1.2是支付级安全
    location / {
        proxy_pass http://127.0.0.1:docker 暴露的端口;#下文会提到,因为这里用的是http

        proxy_redirect off;
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

由于我的站是用nginx反向代理+docker 实现的,所以访问后台的时候实际上用的还是http,又由于我在nginx里配置的所有http请求全部跳转到https ,因此需要加上下面的配置才不会出错


/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
	define('ABSPATH', dirname(__FILE__) . '/');
// 这下面是加的
$_SERVER['HTTPS']='ON';// 强行开启https
define('FORCE_SSL_LOGIN',true);
define('FORCE_SSL_ADMIN',true);
define('CONCATENATE_SCRIPTS',false);
// 这上面是加的
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

然后是替换站点url和固定连接,这一步需要操作数据库,执行下面的sql把固定连接和文章内容中的http://wordpress.endercaster.com/换成https://wordpress.endercaster.com/


-- 替换内容
update wp_posts set post_content=replace(post_content,'http://wordpress.endercaster.com/','https://wordpress.endercaster.com/');
-- 替换固定连接
update wp_posts set guid=replace(guid,'http://wordpress.endercaster.com/','https://wordpress.endercaster.com/');
-- 更新站点URL
update wp_options set option_value=replace(option_value,'http://wordpress.endercaster.com','https://wordpress.endercaster.com');

我记得当时配置的时候挺麻烦的,这看上去好像也没那么麻烦

使用vmware搭建开发环境

前言

  • VBox的操作差不多
  • windows下docker操作太麻烦,所以没有采用全docker的解决方案

准备材料

  • Vmware Workstation
  • CentOS 8 (为了方便,选择的Desktop)
  • VS Code + remote插件

布置环境

先把系统装上,相信大家都会,这步略过

为了方便, 编辑/etc/selinux/config 关闭selinux,重启。相应的,我们这台机器不连外网。

安装服务器及其他需要的软件


sudo yum install -y nginx php php-cli php-fpm php-mysqlnd php-xml php-mbstring php-gd

“安装”Docker(可替换)


# centos自带的
which podman
# /usr/bin/podman
sudo ln -sf /usr/bin/podman /usr/bin/docker

安装Docker(可替换)


#卸载自带的podman
sudo yum remove podman
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# nobest 解决依赖问题
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io --nobest

配置Docker、镜像


# mysql
sudo docker run -itd --name mysql \
  -v /opt/mysql:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=nothing \
  --restart always \
  -p 3306:3306 \
  mysql:5.7
# redis
sudo docker -itd --name redis \
  -p 6379:6379 \
  --restart always \
  redis
# 开机自启
sudo systemctl enable docker.service

配置固定IP

点击桌面右上角-有线连接-设置-IPV4

挂载共享文件夹

vmware-设置-选项-共享文件夹


sudo vmhgfs-fuse -o allow_other .host:/ /mnt/hgfs/

配置nginx


upstream php-fpm {
        # 这里是安装完php-fpm自带的,默认的一个接口
        # 其他distro可能是通过HTTP监听9600端口
        server unix:/run/php-fpm/www.sock;
}
server{
    listen 80;
    server_name wordpress.endercaster.lan;
    root /mnt/hgfs/workspace/wordpress;
    index index.php;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        fastcgi_pass php-fpm;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

配置php-fpm


sudo yum install php-pear php-devel make
sudo pecl channel-update pecl.php.net
sudo pecl install redis
# 创建/etc/php.d/40-redis.ini
# 40这个数字只要比json插件的大即可
# 输入 extension=redis
# 重启php-fpm
sudo systemctl restart php-fpm.service


[www]
;找到下面两个键,修改
php_value[session.save_handler] = redis
php_value[session.save_path]    = tcp://127.0.0.1:6379

配置HOSTS

宿主机,也就是windows这边配置C:\Windows\System32\drivers\etc\hosts,格式如下


你刚才填写的固定IP wordpress.endercaster.lan

结语

原则上来讲到这里就已经能正常访问了,特别说明一下,因为.lan不是正经域名后缀,Chrome的默认选项是搜索,所以需要在前面手动添加http://前缀,这个流程上遇到了什么问题可以给我留言。

PHP文件无读写权限

平台:CentOS + nginx + php-fpm

首先说明出现场景:权限修改为777依旧提示没有权限/文件未找到

解决方案:


setenforce 0
# [/your/path/here] 支持正则表达式写法,想要递归的话请使用正则表达式 [/your/path/here(/.*)?]
semanage fcontext -a -t httpd_sys_rw_content_t [/your/path/here]
# 或
semanage fcontext -m -t httpd_sys_rw_content_t [/your/path/here]
restorecon
setenforce 1

事情是这样的,客户的服务器是CentOS,我上传图片的时候需要先存本地然后上传到云,测试站测没问题,预发布站出问题了(因为是新系统,预发布站和生产站这个时候都部署好了),我当时就惊了。

第一件事想到的就是权限问题,于是检查一下:
drwxrwxrwx
?????????小老弟你怎么回事
总之之后通过修改代码的方式定位到了是在复制文件的时候没有成功从/tmp复制到项目文件夹下,这个时候我已经怀疑是有其他权限控制这里了(是的,当时并没想到selinux,平常没接触过这层),但是时间比较紧急,所以先去确认了一下生产站上传功能是否正常,结果是正常的,这时候我就很迷惑,因为预发布和测试站结果不同很合理,毕竟操作系统和服务器(apache/nginx)都不一样,但是预发布和线上站应该是一样的啊?(作为开发人员我的原则是不碰线上站的东西,所以没见过线上站的服务器,结果它还真【此处自主规制】不一样,太打脸了)
由于线上没有问题,这个问题就先告一段落了

本来想着反正部署本来就不是我的活,就算了,然后上班路上突然想起来一件事:结合vmware的共享文件夹功能是不是可以实现windows下开发,生产环境调试?于是我准备了一个laravel项目,在虚拟机上打开共享,考虑到在Centos上踩过坑,系统就选用的CentOS 8,安装nginx+php-fpm,配置好之后,很好,访问404,查看nginx日志显示 *16 stat() “/mnt/hgfs/workspace/laravel/public/favicon.ico” failed (13: Permission denied) ,这个没跑了,肯定是权限问题,chmod,chown一气呵成,刷新网页一看,很好,根本没有效果,于是把代码文件复制到虚拟机磁盘上,修改配置文件重启nginx,至少php解析没问题了,但是提示写日志失败,没有权限,那就给权限呗,于是从455到777试了一遍还是不行,不行咋整啊?上网搜吧,转了一圈,基本都是在说权限没给够,都777了肯定不是权限没给够了,然后我看到了一篇文件无法写入的文[1],提到了selinux,我记得这是一个独立的权限系统,那事情就简单了,百度:selinux 配置

先看到了怎么配置关闭,我信了你的邪,我去服务器上还能把selinux关了是咋的,走你,下一个。

之后是selinux配置说明[2],很长,看到那个fcontext的命令,我就知道怎么整了 ,但是得有理有据是不是,比如那个-t后面的参数是怎么来的?

再之后看到了以Apache举例配置selinux的[3],都是服务器软件,理论上是一样的,既然能看进程的selinux context,那就好说了


ps -eZ | grep php
# 可以看到context是httpd_t
# 既然可以查看selinux 开放的端口列表,应该可以查看上下文列表吧,于是我试了一下
semanage fcontext --list
# 的确,输出了好多东西,我来找一下看看
semanage fcontext --list | grep :httpd_
# 出现了很多context,命名很有规则,可以看到httpd_sys_rw_content_t应该就是我想要的了
# httpd所属 rw权限
# 如果还没有context的话,添加
semanage fcontext -a -t httpd_sys_rw_content_t '/opt/endercaster/laravel(/.*)?'
# 如果有context的话,修改
semanage fcontext -m -t httpd_sys_rw_content_t '/opt/endercaster/laravel(/.*)?'
# 然后让设置立即生效
restorecon /opt/endercaster/laravel
# 记得确认一下
ls -Z /opt/endercaster/laravel

等等,刚才的vmhgfs的问题是不是也是这个导致的?于是我采用了最简单暴力的方法:把selinux关掉(编辑/etc/selinux/config)事实证明真的是selinux的问题,但是vmware共享不能修改标签……

你以为还有下文?至此两个问题都已经解决了。是的,都解决了

部署不会用vmware共享文件夹,而不用共享文件夹的selinux设置已经解决了。

而使用vmware共享文件夹做环境测试只需要关闭selinux即可。

[1] linux下文件权限777了,file_put_contents()却不能写入,为什么?

[2]如何配置selinux

[3]SELinux中Apache的配置