为博客添加了SSL证书

三四年前就听说了可以获得Let’s Encrypt签发的免费的SSL证书。但以前不怎么需要,也就没怎么折腾。不过现在博客开这么久了,也该上HTTPS了。这里就简单记述一下过程。

 

获得SSL证书

到Github上克隆了certbot项目。运行一下tools/venv.py创建一个虚拟的Python环境。(virtualenv)

git clone https://github.com/certbot/certbot.git
python tools/venv.py

运行完后,产生的venv目录就是包含certbot依赖的包的Python环境。运行venv/bin/activate(Windows中是venv/Script/activate.bat)启用这个环境。然后就可以使用certbot命令了。
. venv/bin/activate
sudo certbot certonly

实际上certbot提供自动为NGINX和Apache等Web服务配置HTTPS的功能。只要使用certbot-auto脚本并加上–nginx/–apache参数,程序就会自动安装插件申请SSL证书并配置。详细可以看Certbot网站。这里打算自行配置。

之后给了你16个选项,让你选择如何验证域名是你的。这里选了16。通过在你网站根目录放置文件,验证这个域名下的网站是否有这个文件。当然,验证成功后会删除文件。如果是没有网站目录的伪静态这种方式当然就没有了。

输入申请SSL证书的域名后,提示你输入网站根目录。之后就获得了证书。文件在/etc/letsencrypt/live/<domain>/ 可以使用certbot certificates 管理证书。

 

配置Apache

HTTPS

首先当然是启用SSL模块

# 在httpd.conf中添加或去除注释
LoadModule ssl_module module/mod_ssl.so

在conf.d创建一个配置文件单独配置HTTPS。当然,写在httpd.conf也是可以的:
<VirtualHost *:443>
    ServerName blog.wanfajie.com:443
    DocumentRoot "/webroot/path"
    SSLEngine on
    SSLCertificateFile "/etc/letsencrypt/live/blog.wanfajie.com/cert.pem"
    SSLCertificateKeyFile "/etc/letsencrypt/live/blog.wanfajie.com/privkey.pem"
    SSLCertificateChainFile "/etc/letsencrypt/live/blog.wanfajie.com/chain.pem"
</VirtualHost>

其他一些参数看着加吧。

 

混合内容(Mixed Content)

页上许多引用的资源都是HTTP协议的URL。这种HTTPS网页引用HTTP资源的情况就是混合内容了。出于安全考虑许多浏览器会禁用混合内容,这就使得网页显示不正常。

解决办法便是把网页上HTTP链接都换成HTTPS链接。

首先,在WordPress控制台中的 设置 -> 常规 中 “WordPress地址(URL)”修改成HTTPS的链接。网页上的样式文件和js文件都变为了HTTPS。

然后就是文章中的图片等。撰写文章时插入的图片,使用的是完整的URL。只要把开头的“http:”或“http://blog.wanfajie.com”去掉链接就能自适应了。文章少可以直接通过控制台编辑文章,多的话只能操作数据库wp_posts表了。

UPDATE wp_posts SET post_content = replace(post_content, 'http://blog.wanfajie.com','');

 

重定向

经上面的配置后就可以访问443端口的HTTPS服务了。但HTTP也可以访问。我们会希望访问网站HTTP服务时,自动跳转到HTTPS服务。这就要用到Rewrite模块了。

同样,启用Rewrite

LoadModule rewrite_module modules/mod_rewrite.so

在已有的VirtualHost标签下编写Rewrite规则
<VirtualHost *:80>
    ServerName blog.wanfajie.com
    # 省略...

    # 如果加载了Rewrite模块便会启用配置
    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1 [NC,R=301,L]
    </IfModule>
</VirtualHost>

这里细说一下,重定向规则RewriteRule

  1. 第一部分是一个正则表达式,它匹配所有内容,并将匹配的内容作为一个分组。
  2. 第二部分便是重定向的URL,$1表示的就是前面提到正则中匹配到的第一个分组(括号)的内容。%{SERVER_NAME}当然指的是域名了,这里等同于设置的ServerName。
  3. 第三部分是参数,NC大小写不敏感,R=301返回HTTP Code为301的重定向Response,L表示是最后一条重定向规则。

 

过期更新

通过certbot获得的证书有效期是90天。过期后可以使用certbot renew 命令更新证书。我相信多数人在90天后不会记得要更新证书。所以写个计划任务让系统自行更新。

0 2 1 * * /opt/certbot/renew.sh &> /dev/null &

#!/bin/bash

CERTBOT_HOME=/opt/certbot
CERTBOT_VENV=${CERTBOT_HOME}/venv
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

source "${CERTBOT_VENV}/bin/activate"
certbot renew
service httpd restart

deactivate

 

相关参考

https://certbot.eff.org/docs/

https://certbot.eff.org/lets-encrypt/ubuntutrusty-apache

http://httpd.apache.org/docs/current/mod/mod_rewrite.html

https://support.mozilla.org/zh-CN/kb/阻止混合内容