【四火】 HTTPS 升级

昨晚花了几个钟头,把 blog 的 HTTP 升级成 HTTPS 了,虽然这件事做的晚了一点。为什么要升级,不是我说明的重点,想了解的朋友可以阅读 这篇文章 。我记录的是我升级的过程,踩到的坑。

备份

首先,文章中有许多以 http://www.raychase.net 开头的 URL,比如某些图片和链接,可以把它们改成 https 的,也可以全部改成相对路径,这样的适用性更广。

UPDATE xx_posts SET post_content = REPLACE(post-content, 'http://www.raychase.net', '/');

到浏览器里面访问看看,似乎没有什么问题。

安装

WordPress 管理台

在 Wordress 管理台的设置里面,把本站 URL 中的 http 替换成 https。

证书申请安装

certbot 申请证书,选好了代理和操作系统一个,照着 guide 操作。

wget https://dl.eff.org/certbot-auto
sudo mv certbot-auto /usr/local/bin/certbot-auto
sudo chown root /usr/local/bin/certbot-auto
sudo chmod 0755 /usr/local/bin/certbot-auto

接着自动安装,中途退出了:

sudo /usr/local/bin/certbot-auto --nginx
...
To use Certbot, packages from the EPEL repository need to be installed.
Enable the EPEL repository and try running Certbot again.

EPEL

既然是没有 EPEL,那就安装一个:

sudo yum install epel-release
Loaded plugins: fastestmirror
Setting up Install Process
Loading mirror speeds from cached hostfile
Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again

失败了,从错误中看是 mirror 地址上没法访问到,于是研究了一下,修改 /etc/yum.repos.d/epel.repo 和 /etc/yum.repos.d/epel-testing.repo ,注释掉全部以 mirrorlist= 开始的行,再还原全部以 baseurl= 开始的行。这样就去原始地址,而不是镜像地址下载了。

果然就安装成功了。

Nginx 配置

于是继续刚才失败的操作:

sudo /usr/local/bin/certbot-auto --nginx

挂在了真正安装配置的过程中:

Error while running nginx -c /etc/nginx/nginx.conf -t.
nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed

原来是找不到 nginx 的配置文件,因为 nginx 安装的路径并非/etc 下面。于是就干脆建立一个软链接:

ln -s /usr/local/nginx/conf /etc/nginx

这一步过了,结果又挂在了证书 challenge 的过程(challenge 是域名验证的一环,在 这里 有介绍):

Performing the following challenges:
http-01 challenge for www.raychase.net
Waiting for verification...
Challenge failed for domain www.raychase.net

研究一下发现,它需要占用 80 端口,因为这个 challenge 的路径是 http://www.raychase.net/.well-known/acme-challenge/xxxxx,而网站应用已经占了 80,于是把 lnmp 先停掉,再操作。

终于提示成功了,注意到它在 nginx 的配置文件目录下的子目录 vhost 下面生成了一个增量配置文件:www.raychase.net.conf,里面配置了一些 ssl_cewrtificate 之类的 key 的路径,把它放到 nginx 的配置目录里面。

验证

命令行验证

尝试了一下 curl http://bit.ly/2YN6zZB 可以访问,于是就在 SSL Labs 可以验证证书的情况,结果提示失败。

接着在外网使用上述的 curl HTTPS 命令,但是却 timeout,可是 curl http://www.raychase.net,得到了正确的 301 重定向的响应。

首先怀疑 nginx,仔细研究了 nginx 的配置,没发现有什么问题。接着就怀疑防火墙,查看 /etc/sysconfig/iptables 发现可能是防火墙的问题。于是命令行添加规则:

iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT

果然,可以访问了。

再 curl http://www.raychase.net,得到了 301 重定向的响应。

浏览器验证

接着再到浏览器里面访问验证,大致没问题,可是,我注意到访问网站首页的时候,URL 左侧的小图标不是一般 HTTPS 的“锁”的图标,而是一个圈“i”的图标,点击以后可以看到“Your connection to this site is not fully secure”这样的文字。

原来是因为网页上包含了“mixed content”,即有指向当前站的 http 的链接。查看源代码,原来在网站中还有一些其它配置包含有当前站的 http 链接,逐一修复,果然,小锁图标出来了,而文字变成了“Connection is secure”。

改进

HTTP2

在 nginx 中配置打开 http2:

listen 443 ssl http2;

可是在修改完毕,重新加载 nginx 的时候,它提示 http2 不认识,于是就检查了,发现是 nginx 版本太老的原因。

于是使用 yum 来升级,之后提示已经是最新版本了,还是不支持。

原来 yum 的默认 repo 版本还是太老,必须要使用 nginx 自己的 repo。于是增加文件:

/etc/yum.repos.d/nginx.repo

写入:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

再重启 nginx 就好了。

证书 renew 自动化

证书每几个月就会过期,因此必须自动续上,而不是手动登上服务器来操作。我尝试了一下 renew 证书的过程:

/usr/local/bin/certbot-auto renew

发现又出现了前面 challenge 的过程。当时我停掉了 lnmp,可是我总不能为了续个证书停掉网站吧?于是考虑解决 challenge 的端口冲突问题。发现其实可以用 HTTP 的 80 端口,但是 challenge 的 URI 冲突才是问题的核心。这样问题就好解决了,把导致冲突的 URI 放进来就好了,在 nginx 里面配置:

location /.well-known/acme-challenge/.* {
    proxy_pass http://127.0.0.1:80;
}

接着配置 cron task,使得这个过程自动化:

crontab -e

加入:

0 0 25 * * /usr/local/bin/certbot-auto renew
10 0 25 * * /sbin/service nginx restart

昨天是 25 号,因此我设置成每天的 25 号来尝试 renew。如果证书还远没到期,它会提示“Cert not yet due for renewal”并会退出这个过程,因此这个命令可以安全地运行。

可是我并不知道运行结果啊,总不能每次都登陆上来,跑到/var/log/cron 去看日志吧?

其中一个解决办法是发 email,把运行输出发 email 给我。

Email 通知结果

于是先要配置 ssmtp,编辑/etc/ssmtp/ssmtp.conf:

root=xxx@gmail.com
mailhub=smtp.gmail.com:587
RewriteDomain=gmail.com
Hostname=xxx
FromLineOverride=YES
UseTLS=Yes
UseSTARTTLS=Yes
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt
AuthUser=xxx@gmail.com
AuthPass=yyy
AuthMethod=LOGIN

接着把地址信息添加到/etc/ssmtp/revaliases。

我使用的是 Gmail 的 SMTP,为了让 gmail 允许这样的操作,还必须在账户选项的 security 里面,开启 less secure app access 的设置。

搞定以后尝试发一封邮件试试:

echo -n 'test' | sendmail -v raychase1986@gmail.com

没问题!那就可以配置 cron task 让它发邮件了,加上:

MAILTO=RayChase1986@gmail.com

这个变量加上以后,应该就可以自动发邮件了。

crontab 没有立即执行,从而验证的功能,于是为了立即验证,加了一行(每分钟都会执行一次):

* * * * * echo "test"

验证以后把这行删掉就好了。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

via 四火的唠叨 http://bit.ly/2HBt6CJ

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)
Share

发表评论

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

使用新浪微博登录