2024年4月19日

HYEOS

随事而为

Docker WordPress SSL添加开启

3 min read

本文不介绍 Docker WordPress 部署过程,也不介绍怎么申请 SSL 证书,只介绍 Docker WordPress 如何启用 HTTPS。

由于 docker 官方的 wordpress 镜像跑的是 apache2 ,所以我们只需要按照 Apache 配置 SSL 证书的方式引用证书就可以了,不过在此之前需要将 SSL 证书导入到 WordPress 容器内。

重新启动 wordpress 容器,追加443端口映射
大多数启动 wordpress 容器只映射了80端口,开启 https,需要追加 443 端口映射,否则还怎么玩,同时也要把申请的 SSL 证书拷贝到容器内,或者将证书挂载到容器内。

举个例子

docker run --name wordpress \
-p 80:80 \
-p 443:443 \
--link mysql:mysql \
-v /home/blog/wordpress:/var/www/html \
-v /etc/letsencrypt:/etc/letsencrypt \
-d wordpress:latest

这里我为什么要挂载/etc/letsencrypt路径呢?

因为我申请的是 Let’s Encrypt SSL 证书

方便容器内绑定证书

加载 OpenSSL 模块
进入 wordpress 容器,输入 openssl ,查看是否安装 ssl ,如果出现下面图情况说明已经安装过了

[root@test home]# docker exec -it blog bash
root@d38c40e54806:/var/www/html# openssl
OpenSSL>

输入 exit 退出 OpenSSL

加载 Apache SSL 模块
输入 a2enmod ssl,第一次加载,会提示重启 Apache,简单粗暴直接重启 wordpress 容器

root@d38c40e54806:/var/www/html# a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
service apache2 restart
root@d38c40e54806:/var/www/html#
修改 SSL 配置文件,绑定证书及打开 443 端口
Apache 加载 SSL 模块后,会在 /etc/apache2/sites-available 下生成 default-ssl.conf 文件,编辑该文件

SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
上述两行配置就是证书的存放位置,我们只需要把第三方第三方可信CA签发的证书相应的文件进行替换

从 apache 的配置文件 apache2.conf 可以看到,apache 只会读取 /etc/apache2/sites-enabled 目录的配置文件,所以需要把 /etc/apache2/sites-available 下的 default-ssl.conf 文件链接到 /etc/apache2/sites-enabled 目录下。

ln -s /etc/apache2/sites-available/default-ssl.conf \
/etc/apache2/sites-enabled/default-ssl.conf
http 请求强制跳转到 https
编辑 /etc/apache2/sites-available/000-default.conf

标签中增加下面的配置


RewriteEngine on
RewriteBase /

FORCE HTTPS

RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

效果如下

The ServerName directive sets the request scheme, hostname and port that

the server uses to identify itself. This is used when creating

redirection URLs. In the context of virtual hosts, the ServerName

specifies what hostname must appear in the request's Host: header to

match this virtual host. For the default virtual host (this file) this

value is not decisive as it is used as a last resort host regardless.

However, you must set it for any further virtual host explicitly.

#ServerName www.example.com

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html


RewriteEngine on
RewriteBase /

FORCE HTTPS

RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

Available loglevels: trace8, ..., trace1, debug, info, notice, warn,

error, crit, alert, emerg.

It is also possible to configure the loglevel for particular

modules, e.g.

#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

For most configuration files from conf-available/, which are

enabled or disabled at a global level, it is possible to

include a line for only one particular virtual host. For example the

following line enables the CGI configuration for this host only

after it has been globally disabled with "a2disconf".

#Include conf-available/serve-cgi-bin.conf

vim: syntax=apache ts=4 sw=4 sts=4 sr noet

修改完之后,重启 wordpress 容器,一切都变成了 https

docker restart wordpress
收尾
虽然已经配置 SSL 证书,并且开启了 https 协议,但是站点还是无法用 https 访问的,因为 wordpress 还需要修改配置,及数据库路径地址修改。

修改 wordpress 访问地址
注意:一定要保证 https 和 http 两种方式都能正常访问网站,才能改这个配置,否则可能导致网站无法访问。

直接登陆后台,通过 “设置” → \rightarrow→ “常规” 里面把 WordPress 地址(URL)、站点地址(URL) 两个地址的 http 修改为 https 并保存。

修改数据库的绝对路径地址
同时为了保证 WordPress 站点之前添加的各个链接或者多媒体文件把 http 协议改成 https 协议,我们还需要通过数据库 SQL 查询执行一条替换命令。

将 `example.com` 换成自己的域名

update wp_posts set post_content = replace(post_content, 'http://example.com','https://example.com');

Over!

后记
通常我们不会只在服务器上装一个应用/容器,一般的解决方案都是装一个 nginx (占用 80、443 端口),将请求转发到各个服务。

如果你像我一样,wordpress 容器非 80 、443端口,那么下面一段 nginx 配置可供参考

运行 wordpress 容器
docker run --name wordpress \
-p 8080:80 \
-p 8443:443 \
-v /home/wordpress:/var/www/html \
-v /etc/letsencrypt:/etc/letsencrypt \
-d wordpress:latest
nginx 配置
upstream wordpress {
server localhost:8443;
}

server {
listen 80;
server_name www.example.com;

跳转到 https 站点

rewrite ^(.*)$ https://$host$request_uri;
}

Normal HTTP host

server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # 证书文件路径
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # 证书文件路径
server_name www.example.com; ## 修改成自己的域名

配置服务器可使用的加密算法

ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;

指定服务器密码算法在优先于客户端密码算法时,使用 SSLv3 和 TLS 协议

ssl_prefer_server_ciphers on;

ssl 版本 可用 SSLv2,SSLv3,TLSv1,TLSv1.1,TLSv1.2

ie6 只支持 SSLv2,SSLv3 但是存在安全问题, 故不支持

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

See app/controllers/application_controller.rb for headers set

Individual nginx logs for this GitLab vhost

access_log /var/log/nginx/access.log; # 根据实际情况修改
error_log /var/log/nginx/error.log; # 根据实际情况修改

location / {
proxy_redirect off; # 禁止跳转
proxy_set_header Host $host; # 域名转发
proxy_set_header X-Real-IP $remote_addr; # IP转发
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://wordpress;
}

}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注