Let’s Encrypt是一套新型证书管理器(简称CA),能够轻松帮助用户获取并安装免费TLS/SSL证书,并借此在Web服务器上实现HTTPS加密。其提供一套软件客户端,即letsencrypt,能够自动处理大部分必要操作步骤以简化使用流程。目前,Let’s Encrypt仍然处于beta测试阶段,因此其整个证书获取与安装流程还只能在Apache Web服务器上实现全面自动化。不过我们仍然可以利用其便捷获取免费SSL证书,以手动方式进行安装——无论大家具体选择哪种Web服务器软件。
在今天的教程中,我们将了解如何利用Let’s Encrypt获取免费SSL证书,并利用此证书在Ubuntu 14.04中保障Nginx安全。我们还将探讨怎样自动进行SSL证书续约。如果大家运行的是其它Web服务器,则可参照相关说明文档以将相关证书引入设置。
先决条件
在开始本教程之前,大家首先需要做点准备。
大家需要在Ubuntu 14.04服务器上创建一个拥有sudo权限的非root用户,具体方式可以参阅Ubuntu 14.04教程:服务器初始设置。
大家还需要拥有或者控制使用相关证书的已注册域名。如果大家还没有合适的已注册域名,则可以从注册商处购买一个(例如Namecheap以及GoDaddy等)。
另外,请确保创建一个A记录以将域名指向服务器的公共IP地址,这是因为Let’s Encrypt会验证我们所设定的需要为之分配证书的目标域名。举例来说,如果大家希望为example.com获取一份证书,则该域名必须解析至我们的服务器以完成验证。在本示例中,我们将使用example.com与www.example.com作为域名,相关DNS记录自然也不可或缺。
在完成了全部准备工作之后,让我们首先安装Let’s Encrypt客户端软件。
第一步——安装Let’s Encrypt客户端
要使用Let’s Encrpyt获取SSL证书,第一步是在服务器上安装letsencrypt软件。目前,安装Let’s Encrypt的最佳方式就是直接从其官方GitHub库中进行克隆。未来其可能还可通过软件包管理器实现安装。
安装Git与bc
现在安装Git与bc,这样我们就能够克隆之前提到的Let’s Encrypt库了。
使用以下命令更新我们的服务器软件包管理器:
- sudo apt-get update
1
2
而后利用apt-get命令安装Git与bc软件包:
- sudo apt-get -y install git bc
1
2
在Git与bc安装完成后,我们即可轻松从GitHub中克隆对应库以下载letsencrypt。
克隆Let’s Encrypt
现在我们可以利用以下命令克隆/opt中的Let’s Encrypt库:
- sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
1
2
现在大家已经能够在/opt/letsencrypt目录中找到letsencrypt库的副本了。
第二步——获取一份证书
Let’s Encrypt提供多种利用插件获取SSL证书的方式。与Apache插件不同,大家可以参阅另一篇教程了解其具体使用方法。Let’s Encrypt中的大部分插件用于获取证书,但我们必须手动配置Web服务器才能加以使用。这些只用于获取证书的插件无需安装,大家可直接将其引用为“验证器”,因为它们的作用就是验证目标服务器是否有资格获取证书。
下面来看如何利用Webroot插件获取一份SSL证书。
如何使用Webroot插件
Webroot插件会替换文件root内/.well-known目录下的一个特定文件,而此文件专门由Web服务器上的Let’s Encrypt服务用于验证。取决于实际配置,大家可能需要为访问/.well-known目录授权。
如果大家还没有安装Nginx,可运行以下命令:
- sudo apt-get install nginx
1
2
为了确保Let’s Encrypt能够访问该目录进行验证,我们需要对Nginx配置进行变更。默认情况下,其位于/etc/nginx/sites-available/default。我们将利用nano进行编辑:
- sudo nano /etc/nginx/sites-available/default
1
2
在此服务器block当中,添加以下位置block:
添加至SSL服务器block
location ~ /.well-known {
allow all;
}
1
2
3
4
大家还需要搜索root指令以查看自己的文档root设定,因为Webroot插件需要使用该路径。如果大家使用该默认配置文件,那么root将为/usr/share/nginx/html。
保存并退出。
利用以下命令重载Nginx:
- sudo service nginx reload
1
2
现在我们已经了解了webroot路径,接下来可以利用Webroot插件获取一份SSL证书。在这里,我们还需要使用-d来指定域名。如果大家希望利用单一证书配合多个域名(例如example.com与www.example.com),则请记得将全部域名纳入进来。另外,确保我们将命令内的高亮部分替换为正确的webroot路径与域名:
cd /opt/letsencrypt
./letsencrypt-auto certonly -a webroot –webroot-path=/usr/share/nginx/html -d example.com -d www.example.com
注意:Let’s Encrypt软件需要superuser权限,因此如果最近如未使用过sudo,则需要输入密码。
在letsencrypt初始化完毕后,大家将看到一些提示信息。确切的提示内容可能会根据大家原先是否使用过Let’s Encrypt而有所区别,但这里我们假定是第一次使用。
在提示符下,输入一个邮箱地址以用于接收通知及恢复丢失密钥:
接下来我们必须同意Let’s Encrypt的订阅协议。选择同意:
如果一切顺利,那么大家将看到以下输出信息:
输出结果:
重要提示:
- 如果大家丢失了账户凭证,则可通过向[email protected]发送邮件进行恢复。
- 祝贺大家!各位的证书与链都已被保存在/etc/letsencrypt/live/example.com/fullchain.pem当中。我们的证书有效期截至2016-03-15。未来要获取新的证书版本,只须再次运行Let’s Encrypt即可。
- 我们的账户凭证将被保存在Let’s Encypt配置目录/etc/letsencrypt之下。大家现在需要对其进行安全备份。此配置目录中还包含有获取自Let’s Encrypt的证书及专有密钥,因此请定期对该文件夹加以备份。
- 如果大家喜爱Let’s Encrypt,请考虑向其提供支持:
为ISRG / Let’s Encrypt提供资金援助: https://letsencrypt.org/donate
为EFF提供资金援助: https://eff.org/donate-le
大家还需要注意证书的路径与过期时间,其已经在本示例的输出结果中进行高亮显示。
防火墙提示:如果大家发现错误,例如“Failed to connect to host for DVSNI”,那么我们可能需要对服务器的防火墙进行配置以允许TCP流量流经端口80与443。
注意:如果大家的域名通过CloudFlare等DNS服务进行路由,则需要暂时禁用这项服务——直到证书获取完成。
证书文件
在证书获取完成后,大家将拥有以下几个PEM编码文件:
cert.pem: 我们的域名证书
chain.pem: Let’s Encrypt证书链
fullchain.pem: cert.pem加上chain.pem
privkey.pem: 证书的专有密钥
需要强调的是,大家必须牢记自己所创建证书文件的位置,这样才能在Web服务器配置中加以使用。这些文件本身位于/etc/letsencrypt/archive子目录当中。然而,Let’s Encrypt会创建加密的符号链接并指向/etc/letsencrypt/live/your_domain_name目录下的最新证书文件。由于这些链接永远指向最新的证书文件,因此我们应当使用该路径以引用证书文件。
大家可以运行以下命令以检查这些文件是否存在(替换其中的域名部分):
- sudo ls -l /etc/letsencrypt/live/your_domain_name
1
2
输出结果应该为我们之前提到的四个证书文件。接下来,我们需要配置Web服务器以使用fullchain.pem作为证书文件,而privkey.pem则充当证书密钥文件。
生成可靠的Diffie-Hellman组
为了进一步提升安全性,大家还需要生成一个可靠的Diffie-Hellman组。要生成一个2048位组,我们可使用以下命令:
- sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
1
2
整个过程可能需要几分钟,但在完成之后,我们将在/etc/ssl/certs/dhparam.pem当中拥有一个强大的DH组。
第三步——在Web服务器(Nginx)上配置TLS/SSL
现在我们已经拥有了SSL证书,接下来配置Nginx Web服务器以使用该证书。
编辑包含有服务器block的Nginx配置文件。再次强调,其默认位置为/etc/nginx/sites-available/default:
- sudo nano /etc/nginx/sites-available/default
1
2
找到服务器block,注释或者删除其中将此服务器block配置为监听端口80的几行。在默认配置中,以下两行应被删除:
需删除的Nginx配置:
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
1
2
3
我们需要将此服务器block配置为监听端口443且启用SSL。在server { block当中,添加以下命令行,但请注意将全部example.com替换为大家的实际域名:
需添加的Nginx配置——1之3
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
1
2
3
4
5
6
7
如此一来,我们的服务器就能够使用SSL,同时利用我们此前获取到的Let’s Encrypt SSL证书。
为了保证只使用安全度最高的SSL协议及密码,同时使用我们生成的强大Diffie-Hellman组,将以下命令行添加至同一服务器block:
需添加的Nginx配置——2之3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
1
2
3
4
5
6
7
8
9
10
最后,在原始服务器block(即监听HTTPS端口443)之外,将其设置为将HTTP(端口80)重新指向HTTPS。确保将以下命令中的全部高亮部分替换为大家的实际域名:
需添加的Nginx配置——3之3
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
1
2
3
4
5
6
保存并退出。
现在重载Nginx以应用各项变更:
- sudo service nginx reload
1
2
现在Let’s Encrypt TLS/SSL证书已经部署到位。现在,大家可以通过HTTPS在浏览器中访问自己的域名以测试TLS/SSL证书。
大家可以使用Qualys SSL Labs Report以查看自己的服务器配置评分:
在浏览器当中:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
1
2
现在我们的SSL设置应该拥有A+评分。
第四步——设置自动续约
Let’s Encrypt证书的有效期为90天,不过建议大家每60天更新证书以作为容错空间。截至本文发布时,客户端本身还无法直接提供自动续约功能,不过大家可以运行Let’s Encrypt客户端中的renew选项以进行手动续约。
要对全部已安装域名进行续约进程触发,运行以下命令:
- /opt/letsencrypt/letsencrypt-auto renew
1
2
由于我们刚刚安装证书,所以此命令只会检查过期数据并输出消息,表明目前没有任何证书需要续约。输出结果应如下所示:
Output:
Checking for new version...
Requesting root privileges to run letsencrypt...
/root/.local/share/letsencrypt/bin/letsencrypt renew
Processing /etc/letsencrypt/renewal/example.com.conf
The following certs are not due for renewal yet:
/etc/letsencrypt/live/example.com/fullchain.pem (skipped)
No renewals were attempted.
1
2
3
4
5
6
7
8
9
10
11
需要注意的是,如果大家将单一证书绑定至多个域名,那么输出结果中将只显示基础域名——不过续约操作将可作用于包含在此证书中的全部有效域名。
另一种确保证书不致过期的特殊方法是创建一个cron任务,并由其定期执行续约命令。由于该续约命令会首先检查证书有效期,并只对有效期不足30天的证书进行续约操作,因此我们可以在创建的cron任务中将执行频率设定为每周甚至每天。
首先编辑crontab以创建一个新任务,本示例计划要求其每周执行续约命令。运行以下命令进行crontab编辑:
- sudo crontab -e
1
2
添加以下命令行:
crontab entry
30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log
35 2 * * 1 /etc/init.d/nginx reload
1
2
3
4
5
保存并退出。这样我们就创建了新的cron任务,其将于每周一2:30 am执行lesencrypt-auto renew命令。该命令所生成的输出结果将被保存在/var/log/le-renewal.log日志文件当中。
欲了解更多与创建及调度cron任务相关的信息,大家可以参阅如何在VPS中使用Cron以实现自动化任务处理指南。
第五步——更新Let’s Encrypt客户端(可选)
当有可用更新时,大家可以利用git pull命令对Let’s Encrypt目录下的本地副本进行更新:
- cd /opt/letsencrypt
- sudo git pull
1
2
3
4
全部变更都将被下载至该库,用以更新我们的客户端。
总结
打完收工!现在我们的Web服务器已经能够使用免费的Let’s Encrypt TLS/SSL证书以安全提供HTTPS内容了。
本文来源自DigitalOcean Community。英文原文:How To Secure Nginx with Let’s Encrypt on Ubuntu 14.04 By Mitchell Anicas
翻译:diradw