【教程】Let's Encrypt配置免费SSL证书建立HTTPS(Ubuntu+Apache)

时间:2024-04-15 18:04:39

前言

这段时间在开发微信小程序,需要一个后台服务器,KP小站刚好能够派上用上。不过,微信规定必须使用HTTPS链接,于是按照DigitalOcean的官方教程,利用Let\'s Encrypt配置免费SSL简书。过程还是很简单的,虽然遇到了一个小问题,不过Google后也顺利解决了,这里简单分享下心得。

 

一. 什么是HTTPS?

1. HTTP表示超文本传输协议(HyperText Transfer Protocol),用来传输客户端(浏览器)和WEB服务器之间的内容。当你访问kplayer.me时,服务器就把html,css,js以及图像等文件通过该协议传输到你的浏览器,你的浏览器解析后就展现主页的内容。

2. 但是HTTP协议有个问题就是它是明文的,这样就存在安全隐患,如传输内容会被偷窥和窃取;另外在HTTP中通信双方的身份没有进行验证,可能会出现伪装身份的情况,由于任何人都能对服务器发起请求,也使服务器易受DOS攻击;最后客户端无法确定接受报文的完整性,因为中途可能被篡改。

3. 那么HTTPS呢?它表示HTTP over SSL,其中的S表示SSL:Secure Socket Layer,中文叫“安全套接层”。SSL利用数据加密技术,防止数据在网络传输过程中不会被截取及窃听。它最早为网景公司Netscape所研发,在IETF(国际互联网工程任务组)进行标准化后改名为 TLS(Transport Layer Security),中文叫做“传输层安全协议”,现在我们常能看到二者的合称SSL/TLS。

4. HTTPS的具体原理是什么?

理解原理之前需要简单介绍几个相关的概念。

4.1 对称密钥和非对称密钥

对称密钥就是客户端和服务器都拥有一把相同的钥匙,用来对报文加解密。打个比方,我有个机密文件想要传给你,但又怕中间被人窃取了,所以我用WinRAR进行口令加密压缩,然后传输给你,你收到文件时输入口令解压即可,这就是对称密钥/口令。但是我怎么安全的告诉你口令是什么呢?至少第一次肯定需要传输口令,这似乎又回到了安全传输的困境,如果这个口令不能安全的传递给你,在过程中被窃取了,那么这种加密方式又有什么意义?

非对称密钥就是加解密使用不同的密钥。那怎么用呢?首先我作为服务器在本地生成一对密钥,一个是公有密钥,一个是私有密钥。我把公有密钥告诉你,你用来进行对文件加密传输,我收到文件后用我的私有密钥进行解密,获得最终文件。相比对称密钥,不必担心密钥的安全传输问题,因为即使公钥被截获,也无法被解密。

4.2 数字摘要与数字签名

有了非对称密钥,有助于客户端和服务端之间的数据不被偷窥和窃取。但是这似乎并不能防止传输的数据被篡改(对于客户端来说),另外如何保证数据是真实服务器发送的而不是被调包过的呢?于是,数字摘要和数字签名技术就被引入了。a) 服务器采用Hash函数对报文生成“摘要”;b) 服务器再用私钥对这个摘要进行加密,作为“数字签名”连同报文发给客户端;c) 客户端收到后,提取数字签名用服务器的公钥进行解密,如果能得到摘要,那说明是真实服务器发送的;d) 客户端再对接收的报文采用与服务器相同的Hash函数处理得到本地摘要,如果与刚刚解密出来的摘要完全一致,那说明报文没有被篡改过。

4.3 数字证书

有了数字签名,似乎安全性已经得到了保证。真的是这样么?任何存在不可信任风险的地方都有可能被利用。在数字签名中,客户端收到报文后需要用服务器的公钥进行解密,那么如果有不法者偷偷替换了服务器公钥为自己的公钥呢?那么该不法者就可以用自己的私钥生成数字签名发送报文给客户端。因此最大的问题就在于:对于客户端来说,如何确保它所得到的公钥一定是从目标服务器那里发布的,而且没有被篡改过呢?这时候就需要一个权威的第三方机构来统一对外发放公钥,就是所谓的证书权威机构(Certificate Authority, CA),由服务器管理者向CA申请,认证后CA会给服务器管理者颁发“数字证书”(含主机机构名称、公钥等文件),于是服务器在之后发送报文给客户端时只需要加上数字证书即可,客户用CA的公钥验证后就可确认来源的可靠性。

4.4 HTTPS

了解了以上的内容,现在我们来了解下HTTPS的流程:

a. 客户端使用HTTPS的URL链接向服务器发起请求,如https://kplayer.me

b. WEB服务器收到请求后将网站的证书信息(含公钥等)发送给客户端;

c. 客户端根据“证书管理器”判断证书是否被冒用,或者公钥是否有效,有问题则发出警告;

d. 如果证书和公钥有效,则客户端首先生成一个随机(对称)数串,并生成客户端版的共享密钥;

e. 客户端再用公钥对数串进行对称密钥加密,之后发送给服务器;

f. 服务器收到这个加密后的随机数串,只需要用私有密钥就能解密出该随机数串;

g. 服务器以随机数串生成服务器端的共享密钥;

h. 至此,客户端和服务端拥有相同共享密钥,则可以利用共享密钥进行安全通信。

从以上流程可以看出HTTPS采用HTTP+SSL的方式使得网站的访问更加安全,但它也使得通信信息量增加,速率降低,消耗更多的服务器资源,而且向认证机构购买证书也是一笔开销,因此在HTTP和HTTPS的选择上要视网站的功能和需求而定。

 

二、Let\'s Encrypt是什么?

SSL证书按大类一般可分为DV SSL、OV SSL、EV SSL证书,也叫做域名型、企业型、增强型证书。

域名型SSL证书(DV SSL):信任等级普通,只需验证网站的真实性便可颁发证书保护网站;

企业型SSL证书(OV SSL):信任等级强,须要验证企业的身份,审核严格,安全性更高;

增强型SSL证书(EV SSL):信任等级最高,一般用于银行证券等金融机构,审核严格,安全性最高,同时可以激活绿色网址栏。

对于个人博客和站点,申请个免费的DV型SSL证书最划算。Let\'s Encrypt 是一个免费、开放,自动化的证书颁发机构,由 ISRG(Internet Security Research Group)运作。

https://letsencrypt.org/

ISRG 是一个关注网络安全的公益组织,其赞助商从非商业组织到财富100强公司都有,包括 Mozilla、Akamai、Cisco、Facebook,密歇根大学等等。ISRG 以消除资金,技术领域的障碍,全面推进加密连接成为互联网标配为自己的使命。

 

三、如何使用Let\'s Encrypt配置SSL证书?

官方教程在此:

https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04

1. 安装Let\'s Encrypt客户端

a) 新增软件包目录:

sudo add-apt-repository ppa:certbot/certbot

并按回车ENTER确认

b) 更新新增的目录信息   

sudo apt-get update

 c) 安装官方客户端Cerbot

sudo apt-get install python-certbot-apache

 

2. 配置SSL证书

sudo certbot --apache -d kplayer.me

根据提示输入对应指令即可,过程中会要求提供Email用于丢失密钥恢复和相关通知,也会让你选择同时启用http和https访问,或者强制所有请求重定向到https。

另外,如果想要证书对对多个域名或子域名有效,可以增加参数,如下(建议第一个是主域名):

sudo certbot --apache -d kplayer.me -d www.kplayer.me

如果有多个域名的话,可以多次调用cerbot命令。

安装完成后,可以在浏览器输入以下地址,确认是否成功:

https://www.ssllabs.com/ssltest/analyze.html?d=kplayer.me&latest

成功的话,就可以使用https://kplayer.me来访问小站啦。


不过KP君在执行时收到如下报错信息:

Client with the currently selected authenticator does not support any combination of challenges that will satisfy the CA.

一阵Google后,原来由于安全问题,Let\'s Encrypt已经停止提供Certbot的Apache和Nginx插件所用的机制,计划在接下来的日子里发布一个新版本的Certbot,如果急需要用的话,可以采用临时的方法:

sudo certbot --authenticator standalone --installer apache -d kplayer.me --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2"

详情参见:https://github.com/certbot/certbot/issues/5405

  

3. 验证Certbot自动更新

Let\'s Encryp只提供加密90天的证书。然而,我们安装的certbot软件包通过一个systemd定时器每天运行两次certbot进行更新。在非systemd发行版中,此功能由位于/etc/cron.d中的cron脚本提供。 该任务每天运行两次,并将在续期30天内更新。

可以通过如下命令验证:

sudo certbot renew --dry-run

如果没有报错,那就大功告成。如有必要,Certbot将更新证书并重新加载Apache。如果自动更新失败,Let\'s Encrypt将向我们提供的电子邮件发送一封邮件,并在证书即将到期时发出警告。

 

后记

配置完HTTPS,兴奋地在微信小程序后台提交网址,结果提示需要域名备案。在我纠结了一天后,决心乖乖接受监督,可惜在备案的过程中告诉我.me域名暂时无法备案,欲哭无泪,那我就好好的用来写我的博客吧。

注:以上文字和图片部分整理自网络。