1.什么是SSL和CA证书
互联网的http协议是通过明文传输的,很容易造成信息的泄漏。为了在网上实现信息安全,Netscape开发了ssl协议(https)用以保障在Internet上数据传输之安全。
CA证书顾名思义就是由CA(Certification Authority)机构发布的数字证书。要对CA证书完全理解及其作用,首先要理解SSL。SSL(security sockets layer,安全套接层)是为网络通信提供安全及数据完整性的一种安全协议。SSL3.0版本以后又被称为TLS。
SSL如何保证网络通信的安全和数据的完整性呢?就是采用了两种手段:身份认证和数据加密。首先身份认证就需要用到CA证书了,解决了”我是谁?”的问题。
证书分三种:
- 域名型https证书(DVSSL):信任等级一般,只需验证网站的真实性便可颁发证书保护网站;
- 企业型https证书(OVSSL):信任等级高,须要验证企业的身份,审核严格,安全性更强;
- 增强型https证书(EVSSL):信任等级最高,一般用于银行证券等金融机构,审核严格,安全性最好,同时可以激活绿色网址栏
2.SSL协议的建立和传输
需要理解SSL的加密机制,在使用SSL的网络通讯过程中,消息在请求和响应中都是加密传送的。首先要知道加密算法分为两种:对称加密和非对称加密。对称加密就是发送双发使用相同的密钥对消息进行加解密,常见的对称加密为DES、3DES,AES等。非对称加密是发送双方各自拥有一对公钥私钥,其中公钥是公开的,私钥是保密的。当发送方向接收方发送消息时,发送方利用接收方的公钥对消息进行加密,接收方收到消息后,利用自己的私钥解密就能得到消息的明文。其中非对称加密方法有RSA、Elgamal、ECC等。由于非对称加密的速度比较慢,所以它一般用于密钥交换,双方通过公钥算法协商出一份密钥,然后通过对称加密来通信。
密钥协商过程作为一种互联网安全加密技术,原理较为复杂,枯燥而无味。这里我们用个形象的比喻,我们假设A与B通信,A是SSL客户端,B是SSL服务器端,加密后的消息放在方括号[]里,以突出明文消息的区别。双方的处理动作的说明用圆括号()括起。
- A:我想和你安全的通话,我这里的对称加密算法有DES,RC5,密钥交换算法有RSA和DH,摘要算法有MD5和SHA。
- B:我们用DES-RSA-SHA这对组合好了。 这是我的证书,里面有我的名字和公钥,你拿去验证一下我的身份(把证书发给A)。 目前没有别的可说的了。
- A:(查看证书上B的名字是否无误,并通过手头早已有的CA的证书验证了B的证书的真实性,如果其中一项有误,发出警告并断开连接,这一步保证了B的公钥的真实性) (产生一份秘密消息,这份秘密消息处理后将用作加密密钥,加密初始化向量(IV)和hmac的密钥。将这份秘密消息-协议中称为per_master_secret-用B的公钥加密,封装成称作ClientKeyExchange的消息。由于用了B的公钥,保证了第三方无法窃听) 我生成了一份秘密消息,并用你的公钥加密了,给你(把ClientKeyExchange发给B) 注意,下面我就要用加密的办法给你发消息了! (将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥) [我说完了]
- B:(用自己的私钥将ClientKeyExchange中的秘密消息解密出来,然后将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥,这时双方已经安全的协商出一套加密办法了) 注意,我也要开始用加密的办法给你发消息了! [我说完了]
- A: [我的秘密是…]
- B: [其它人不会听到的…]
3.如何部署HTTPS网站
部署HTTPS网站的时候需要证书,证书由CA机构签发,大部分传统CA机构签发证书是需要收费的,这不利于推动HTTPS协议的使用。
Let’s Encrypt 也是一个CA机构,但这个CA机构是免费的!!!也就是说签发证书不需要任何费用。当然他的证书属于DVSSL。
Let’s Encrypt设计了一个ACME协议。那为什么要创建ACME协议呢,传统的CA机构是人工受理证书申请、证书更新、证书撤销,完全是手动处理的。而ACME协议规范化了证书申请、更新、撤销等流程,只要一个客户端实现了该协议的功能,通过客户端就可以向 Let’s Encrypt 申请证书,也就是说 Let’s Encrypt CA完全是自动化操作的。任何人都可以基于ACME协议实现一个客户端,官方推荐的客户端是Certbot。
4.Certbot客户端安装和命令
除非您有非常特别的要求,建议您使用您操作系统的包管理工具提供的Certbot包(参见certbot.eff.org)。如果这个包不可用,我们建议使用certbot-AUTO,它自动在您的系统上安装Certbot。Certbot客户端支持两种用于获取和安装证书的两种类型的插件:身份验证和安装程序。
份验证与certonly命令一起使用的插件,用于获取证书。身份验证验证您是否控制了请求证书的域,获得了指定域的证书,并将证书放置在计算机上的/etc/letscrypt目录中。身份验证器不安装证书(它不编辑服务器的任何配置文件以提供所获得的证书)。如果指定要进行身份验证的多个域,则所有域都将在单个证书中列出。要获得多个单独的证书,您需要多次运行Certbot。
安装程序是与install命令一起使用的插件,用于安装证书。这些插件可以修改Web服务器的配置,使certbot获得的证书通过HTTPS为您的网站提供服务。官方有支持不同web服务器的列表
比如debain以nginx为例的安装命令(其他环境参考官网):
$ sudo apt-get install certbot python-certbot-nginx
命令说明:
不写任何子命令时,默认使用 run 命令。certbot-auto –nginx -d xx.com 等价于 certbot-auto run –nginx -d xx.com。
列表只涉及获取、安装、更新证书部分,完整的命令文档请参考官方用户手册。
- (default) run 为当前服务器获取并安装一个证书
- certonly 只获取或更新证书,不安装
- renew 更新所有快要过期的证书
- -d DOMAINS 指定要获取证书的域名,一个证书支持多个域名,用逗号分隔
- –apache 使用Apache服务器插件来认证和安装证书
- –standalone certbot 会自己运行一个 web server 来进行验证
- –nginx 使用 Nginx 服务器插件来认证和安装证书,可以读取 Nginx 配置文件并自动更改。
- –webroot 会利用既有的 web server,在其 web root目录下创建隐藏文件, Let’s Encrypt 服务端会通过域名来访问这些隐藏文件,以确认你的确拥有对应域名的控制权
- –manual 交互式获取证书,或者使用钩子脚本
- -n 非交互式运行
- –test-cert 从 staging server 获取一个测试证书
- –dry-run 测试 “renew” 和 “certonly” 命令,不保存证书到磁盘上
5.获取安装单域名证书
客户在申请Let’s Encrypt证书的时候,需要校验域名的所有权,证明操作者有权利为该域名申请证书,目前支持三种验证方式:
- dns-01:给域名添加一个 DNS TXT 记录。有时候我们想为内网的某台主机设置HTTPS,内网的主机无法被letsencrypt的服务器访问到,可以使用DNS记录来验证域名
- http-01:在域名对应的 Web 服务器下放置一个 HTTP well-known URL 资源文件。
- tls-sni-01:在域名对应的 Web 服务器下放置一个 HTTPS well-known URL 资源文件。
比如下命令获取证书(不安装):
$./certbot certonly --standalone --email 58472399@qq.com -d quqianzhao.top -d www.quqianzhao.top此处需要注意:
- (1)执行此命令必须使用 root用户获得文件夹的权限
- (2)域名能访问并且有绑定的公网IP
- (3)必须在此域名绑定的服务器上运行
- (4)会使用80断端口,如果nginx监听80端口,把nginx先关掉(nginx -s stop) 命令采用内置web server来验证给出的域名,并在/etc/letsencrypt/live/quqianzhao.top下生成此域名证书(不安装),目录下有4个文件就是生成的密钥证书文件。
- cert.pem - Apache服务器端证书
- chain.pem - Apache根证书和中继证书
- fullchain.pem - Nginx所需要ssl_certificate文件
- privkey.pem - 安全证书KEY文件
如下命令获取证书并安装(通过nginx验证,并修改nginx配置):
$./certbot --nginx --email 58472399@qq.com -d quqianzhao.top -d www.quqianzhao.top此命令采用ngnix服务器验证并在/etc/nginx/site-enable/目录下生成default的配置文件(会自动导入nginx配置),注意此时要保持nginx运行。有时候服务器响应慢执行失败可以多试几次。 在执行之前可以用
certbot delete -d quqianzhao.top删除已经安装的证书
如果配置文件有问题,可以重新安装nginx:$ sudo apt-get --purge remove nginx $ sudo apt-get --purge remove nginx-common $ sudo apt-get install nginx
6.获取和安装通配符证书
对于个人用户来说,主机并不是太多,使用单域名证书(证书仅仅包含一个主机)也没什么问题,但是对于大公司来子域名非常多,而且过一段时间可能就要使用一个新的主机。注册域也非常多。Let’s Encrypt 通配符证书通配符证书就是证书中可以包含一个通配符,比如.example.com、.example.cn,这样大型企业也可以使用通配符证书了,一张证书可以防护更多的主机了。这个功能可以说非常重要,从功能上看 Let’s Encrypt和传统CA机构没有什么区别了。
而申请通配符证书,只能使用 dns-01 的方式进行验证
申请证书命令:
./certbot certonly -d *.newyingyong.cn --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
介绍下相关参数:
- certonly,表示安装模式,Certbot 有安装模式和验证模式两种类型的插件。
- –manual 表示手动安装插件,Certbot 有很多插件,不同的插件都可以申请证书,用户可以根据需要自行选择
- -d 为那些主机申请证书,如果是通配符,输入 *.newyingyong.cn(可以替换为你自己的域名)
- –preferred-challenges dns,使用 DNS 方式校验域名所有权
- –server,Let’s Encrypt ACME v2 版本使用的服务器,不同于 v1 版本,需要显示指定
安装过程中,有两个交互式的提示:是否同意 Let’s Encrypt协议要求询问是否对域名和机器(IP)进行绑定确认同意才能继续。继续查看命令行的输出,非常关键:
-------------------------------------------------------------------------------Please deploy a DNS TXT record under the name_acme-challenge.newyingyong.cnwiththe following value:2_8KBE_jXH8nYZ2unEViIbW52LhIqxkg6i9mcwsRvhQBefore continuing, verify the recordisdeployed.-------------------------------------------------------------------------------Press Enter to ContinueWaitingforverification...Cleaning up challenges要求配置 DNS TXT 记录,从而校验域名所有权,也就是判断证书申请者是否有域名的所有权。上面输出要求给 _acme-challenge.newyingyong.cn 配置一条 TXT 记录,在没有确认 TXT 记录生效之前不要回车执行。然后进入你的DNS的提供方网站,增加txt记录,值为:2_8KBE_jXH8nYZ2unEViIbW52LhIqxkg6i9mcwsRvhQ
然后输入下列命令确认 TXT 记录是否生效:$ sudo apt-get install dnsutils $debian 安装dig工具 $ dig -t txt _acme-challenge.newyingyong.cn @8.8.8.8确认生效后,回车执行。恭喜您,证书申请成功,证书和密钥保存在下列目录:/etc/letsencrypt/live/newyingyong.cn
注意:之前设置了一个CNAME域名,执行后会发生错误:Detail: CAA record for *.xxx.xxx prevents issuance的错误提示,删除CNAME记录就可以了。
最后校验证书信息,输入如下命令:openssl x509 -in /etc/letsencrypt/liev/newyingyong.cn/cert1.pem -noout -text关键输出如下:X509v3SubjectAlternativeName:DNS:*.newyingyong.cn完美,证书包含了扩展的值就是 *.newyingyong.cn
openssl的使用可以参考openssl用法详解
修改nginx配置文件(/etc/nginx/nginx.conf)。
最后将域名配置成https访问server { listen 443 ssl http2; listen [::]:443 ssl http2 ; server_name maomao.run; ssl on; ssl_certificate /etc/letsencrypt/live/newyingyong.cn/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/newyingyong.cn/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:8001; } }将80端口重定向到443端口。用户无论如何输入域名,都将使用https访问。
server { listen 80; listen [::]:80; server_name maomao.run; rewrite ^(.*)$ https://${server_name}$1 permanent; }设置后重启nginx,可以在SSL Labs输入域名进行验证测试。
7.证书的自动更新
证书有效期只有三个月,所以更新域名非常关键。更新操作其实和初次申请差不多,只是命令不同,参数都一样。所以智能的 Certbot 在初次申请完成以后就把所有参数都保存下来,方便更新的时候使用。更新的参数保存在 /etc/letsencrypt/renewal/newyingyong.cn。 既然参数都还在,那更新证书只需要一条简单的命令就可以了:
$ sudo certbot renew
Linux 的定时任务有两种方法:cron 和 systemd/timers,任何一种都能实现定时的更新任务,可爱的 Certbot 两种都设置了,我们分别看看。
*cron
$ vim /etc/cron.d/certbot
打开文件可以看到 Certbot 设定的任务记录,如果使用Timers方式,则将这条规则注释到。 *Timers Certbot 在 /lib/systemd/system/ 下生成了两个文件:certbot.service 和 certbot.timer,一个是服务,一个是定时器。 certbot.service:
[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true
可以看到也是运行 certbot -q renew 命令。
certbot.timer:
[Unit]
Description=Run certbot twice daily
[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true
[Install]
WantedBy=timers.target
每天 0 点和 12 点激活 certbot.service。其实不需要这么频繁的更新证书,而且在更新证书的时候我们加了钩子来关闭和开启 Nginx 服务,所以最好是在凌晨没人访问网站的时候更新证书,我们稍微修改一下:
[Unit]
Description=Run certbot every 05:00
[Timer]
OnCalendar=*-*-* 05:00:00
Persistent=true
[Install]
WantedBy=timers.target
保存修改以后需要重启定时器:
$ systemctl daemon-reload
$ systemctl restart certbot.timer
至此就算大功告成了!
参考1:certbot User Guide
参考2:https://www.jianshu.com/p/da6803c5ab57
参考3:理解服务器证书 CA&SSL
参考4:在CentOS7上使用Certbot申请Wildcard证书
参考5:Nginx 实现 HTTPS(基于 Let’s Encrypt 的免费证书)