基于httpd的wordpress站点升级为https

目录

从2018年开始,Chrome浏览器会将所有没有使用https加密传输的站点都标记为不安全的。个人博客是搭建在httpd上,一直没有升级到https,所以也会标记为“不安全”。这个周末,花了几个小时“折腾”,终于让站点变得“安全”了。

Snip20200329_1

因为证书有效期只有三个月,所以,本文https的基本原理和配置做个介绍和记录,便于后续持续维护。

配置

首先,证书机构选择了Let’s Encrypt,使用了对应的开源工具certbot生成秘钥,并获得证书。详细的使用方法参考:certbot instructions

我使用的EC2的Amazon Linux,certbot对这个发行版支持还不是很好。所以没有使用全自动的配置方法,而是,用certbot生成秘钥、证书后,再手动配置httpd。因为证书有效期只有三个月,所以,经常需要过来手动更新。等下个周末再来研究一下是否可以实现全自动配置。

Snip20200328_3

certbot instructions页面上有非常详细的说明,基本上可以step by step的完成配置。这里记录一下配置过程中的异常点。

关于Linux发行版

第一个与“instructions”不一样的是:EC2使用Amazon Linux发行版并不在页面上的OS支持列表中,根据使用习惯应该这RedHat系列的系统(使用上都是按照RedHat或者CentOS方式),Linux内核是4.19初步判断是CentOS 7或者8版本。于是试探性的按照CentOS 7进行配置。

第二个与“instructions”不一样的是:在安装过程中,会因为缺少augeas包而执行报错,而安装这个包,需要使用EPEL源,对于EC2可以参考如下页面启用EPEL:How do I enable the EPEL repository for my Amazon EC2 instance running CentOS, RHEL, or Amazon Linux?

使用certbot生成证书与秘钥

接着,参考instructions,使用certbot命令行工具生成证书与秘钥。过程中需要输入站点的域名和管理员的邮件地址。

$ sudo /usr/local/bin/certbot-auto certonly --apache Saving .... Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): xxxxxxxx@gmail.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at ...... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (A)gree/(C)ancel: A - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, ...... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: Y Which names would you like to activate HTTPS for? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: www.orczhou.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel): 1 ...... IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/www.orczhou.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/www.orczhou.com/privkey.pem Your cert will expire on 2020-06-26. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew" ......

配置apache的httpd

配置站点的https访问,需要指定数据证书文件与私钥文件,具体如下

<VirtualHost _default_:443> # General setup for the virtual host, inherited from global configuration # DocumentRoot "/var/www/html" DocumentRoot "/var/www/orczhou.com" ServerName www.orczhou.com:443 SSLCertificateFile /etc/httpd/conf/server.crt SSLCertificateKeyFile /etc/httpd/conf/server.key

还需要将原来80端口的请求全部转发到https请求下:

<VirtualHost *:80>...... ServerName www.orczhou.com Redirect permanent / https://www.orczhou.com/ ......

然后重启httpd就可以了。

wordpress的一些配置改动

在Wordpress后台将“WordPress地址(URL)”和“站点地址(URL)”修改为“ https://www.orczhou.com ” ,修改地点为:“设置->常规”。

概述https原理

How-HTTPS-Works
在文章“How Does HTTPS Work? RSA Encryption Explained”中有较为详细的描述。这里结合本网站的证书信息做一个概述。

概述https通信过程

在用户使用自己浏览器(客户端)访问网站www.orczhou.com:443的时候,服务端的httpd服务会先将站点的公钥发送给客户端。

客户端(通常是浏览器)会自己随机生成一个session key(用于通信过程中的对称加密),并使用刚刚获得公钥对session key进行加密,再发送给服务端。

服务端再利用私钥对加密后的session key编码进行解密后,就可以获得对应的session key。

然后,客户端和服务端所有的通信内容都通过session key进行对称加密。

为什么要用session key而不是公钥直接加密呢? 猜测的原因应该是RSA加密/解密的成本都太高了,会较大程度的降低客户端和服务器的性能。

概述数字证书

这样通信过程中的信息都是加密好的,即便截获通信信息也不知道里面的内容是什么,一切都看起来比较完美。但是,这种通信方式很容易被中间人攻击。简单来说,中间人在获得客户端请求时,假装自己是服务端,返回一个假的公钥(中间人的公钥),然后中间人再伪装成客户端与真正的服务端通信,就这样完成整个会话。这种情况下,客户端可能将重要信息都发送给中间人了。

要解决中间人攻击,需要再引入一个第三方“权威机构”来证明客户端收到的公钥真的是属于服务端的。在这里,也就是说访问www.orczhou.com网站的客户端需要确认,收到的公钥真的是属于www.orczhou.com所在httpd服务端。这里的做法是,在发送公钥的时候,不仅仅是发送一个公钥,而是发送一个带数字签名的数字证书。签名由专门的“认证机构”颁发。

例如,该网站(www.orczhou.com)的证书内容如下:

Snip20200330_11

证书中包含了认证站点的基本内容,包括站点域名、有效期、站点公钥、CA(认证机构)签名等。具体的,站点公钥是内容如下:

D0 81 AC 79 D5 40 6E 88 25 06 39 D4 82 F2 58 DB EE CA A4 8E 89 AE D1 9F EA 6F BA 8F 07 E4 D8 AD AB AB
41 9D 3B 05 9F 7E 0D C6 05 E0 AA 76 97 E4 79 90 28 37 7E 2C 22 68 D6 43 93 BB B8 D0 03 82 B1 62 4E 1D 88 AE 2B FF
85 FB 63 F4 07 2E D7 DF 4C C5 18 B7 45 9E 06 B1 68 6D 21 39 85 44 B6 BE F1 1C 71 6B 4E F7 9A C7 27 63 BB 6A 06 96
E7 C3 3E 16 46 A6 76 A6 EC DF B6 39 1F 7B 36 E9 04 AF BA 47 81 F7 32 BB 81 B4 DE BD B8 7E 94 07 6C EE 10 CB 40 09
B9 94 17 0D C9 5D A6 C9 D3 CC C8 0B 06 56 53 AF 0C BC C0 0B FC 7F 7A 32 65 5C 73 77 73 31 0C 90 82 15 E8 A6 1D A2
5B F5 1B 66 BB 7F F2 30 9F 30 D6 5B E4 59 51 FD C9 8A 36 1E 8D 17 6E 78 0E EF 46 2A 82 86 E0 22 0D 3D DC 5E 02 26
AC 2B E8 52 BC B1 4D 80 35 C8 50 AF 29 3F 51 6B 2D CB BD 24 AF 6D 00 3C 08 B3 2E 75 FD 31 0C 83

CA会对证书的主要内容做一个“签名”,签名可以简单的理解为对主要信息先进行哈希散列,然后对散列信息使用私钥进行加密计算,密文则为具体的签名内容。该网站的CA签名具体内容如下:

51 BC 54 8A 48 8C 51 7D 9A C1 14 60 7B 8C B3 24 A8 18 D1 77 59 74 0D 06 48 FE D7 BF 67 BD D2 E9 E6 AF
1B A2 89 B3 63 CE E0 98 47 BE DE 66 C6 63 4F CB 26 56 0A 15 3F D1 C8 B9 BB C6 8A 32 3D DA B9 78 9D 40 4A 07 F5 41
B3 FA FD C1 B2 36 14 E6 02 F0 3C 9D C2 1D 3B 09 80 09 98 4B E5 9B CC 26 CD 53 86 2F 85 73 AD 9A CC 76 77 1B A1 F1
9F 3A 30 08 8F 24 3B 77 EC 9C 6F 4D 91 77 62 8D 0D 61 41 54 2F 11 AA EE F4 70 53 85 10 B8 D0 EF 05 33 05 32 37 CA
0B D9 70 B1 93 31 7D C3 18 CF 3B F9 88 B7 33 B7 9F 08 43 02 B2 B1 EC 7D DF C3 C5 4C F9 58 BB F9 02 11 CC 78 5F EA
C9 8C 5E 60 08 B3 8E A1 82 76 AA A2 02 B2 3E 2A CD F0 0A 0C 51 74 FB 13 8E 1D 8C 7F 25 94 9E 55 C0 D8 83 FF 37 BC
E3 27 21 7C B3 1F EE F0 65 19 8E 23 96 2E 5D 17 F8 73 9E F0 A4 CD AC A4 6C 67 8E A3 4E 49 FC 7B

概述数字签名

有了CA的签名,可以理解为www.orczhou.com这个站点提供的证书是由该CA机构(这里是Let’s Encrypt Authority X3)来背书(认证)的。

当然,浏览器获得这些信息之后,需要自己亲自验证这个签名是不是真的由CA机构签发的。校验的方法也很简单,先用CA机构的公钥对签名进行加密计算,会获得一个散列信息串。浏览器再自己亲自对证书信息进行一次哈希散列计算,如果计算结果与签名解密的信息一致,那我们就认为这个证书(主要是里面公钥信息)是可靠的。

如果这里展开,还有一些非常有意思的问题可以去考究:(a) 浏览器如何拿到真实的CA的公钥;(b) CA机构的私钥是如何生成如何保护的?(c) 线上各种网站这么多,有根CA、有中级CA,他们关系是怎样的? 这些问题也非常有意思,下次有空再考究一下,再写一写。

证书更新

更新@202303

直接运行如下命令,即可:

sudo certbot --apache

升级Amazon Linux 2后@202109

安装软件:

sudo yum install certbot sudo yum install python-certbot-apache

直接运行:

sudo su - sudo certbot --apache

更新@20210507

httpd需要重新启动,所以,更新命令如下:

sudo /usr/local/bin/certbot-auto certonly --apache sudo service httpd restart

[更新@20200628]

Let’s Encrypt的免费证书有效期是3个月,所以,这两天应该是第一次到期了。这里详细记录证书更新命令与操作。

使用原来的命令,直接生成新证书:

sudo /usr/local/bin/certbot-auto certonly --apache

详细内容:

sudo /usr/local/bin/certbot-auto certonly --apache Upgrading certbot-auto 1.3.0 to 1.5.0... ...... Which names would you like to activate HTTPS for? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: www.orczhou.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel): 1 ....... IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: ......

生成的证书相关的文件都保持在了目录“ /etc/letsencrypt/live/www.orczhou.com/ ”

为了简化配置,将httpd的配置相关中相关的配置直接指向上述目录中的文件,这样后续更新证书后,就不再需要重新配置了:

SSLCertificateFile /etc/letsencrypt/live/www.orczhou.com/cert.pem ...... SSLCertificateKeyFile /etc/letsencrypt/live/www.orczhou.com/privkey.pem

下一次更新证书,则直接执行以下命令,然后重启httpd即可:

sudo /usr/local/bin/certbot-auto certonly --apache

[更新结束]

Leave a Reply

Your email address will not be published. Required fields are marked *