使用Let's Encrypt保护你的数据包
【过年了,每天发一篇以前的存货,一共七篇。】
Let's Encrypt是去年底推出的一个免费SSL证书,且申请这个证书基本没有任何限制,只要你证明你是域名的所有者,你就可以为你的域名申请一个SSL证书。
我今天就来为我的 wiki.ioin.in 申请一个时髦的Let's Encrypt证书。
首先,我利用到的是acme-tiny,这是第三方人士开发的一个扩展。因为Let's Encrypt官方给出的方法比较麻烦,而acme-tiny这个小工具可以让用户敲几条命令即可生成好我们需要的证书。
下载acme-tiny: https://github.com/diafygi/acme-tiny
首先,生成一个用户私钥: account.key,acme-tiny通过这个证书来登录Let's Encrypt。再生成一个域名私钥,domain.key
openssl genrsa 4096 > account.key
openssl genrsa 4096 > domain.key
然后利用ACME协议,将domain.key生成domain.csr。如果你只有一个域名需要ssl,只需执行下面的语句:
openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr
如果你有多个域名,比如www.xxx.com和xxx.com,你就执行下面的语句:
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr
我的 wiki.ioin.in 是单域名证书,所以执行下面语句即可:
Let's Encrypt有多种方法来验证你是否是域名的所有人,而acme-tiny这个小工具用的是最简单的方法,也就是利用http文件验证。
简单来说,就是生成一个验证文件,放在http://example.com/.well-known/acme-challenge/
下,Let's Encrypt官方验证这个文件是否存在、内容是否正确。如果一切正确,说明域名是你所有。
所以我这里,新建了一个/home/www/challenges/目录,将它别名指向 /.well-known/acme-challenge/ 。这样,我在challenges目录里写入的文件,即可通过 http://xxxx.com/.well-known/acme-challenge/ 访问了。nginx配置如下:
然后,运行acme_tiny.py脚本:
python acme_tiny.py --account-key /etc/ssl/letsencrypt/account.key --csr /etc/ssl/letsencrypt/domain.csr --acme-dir /home/www/challenges/ > /etc/ssl/letsencrypt/signed.crt
其中,将--account-key的值改为你生成的account.key的路径;--csr的值改成你生成的domain.csr的路径;--acme-dir的值改为我要写入验证文件的文件夹。 最后成功生成signed.crt,这就是我的域名证书:
在nginx里,还需要将Let's Encrypt的中间证书放到自己的证书后面,构成一个证书链chained.pem:
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
另外,还需要生成一个较强的dh。(位数不要太多!我生成了一个4096位的dh,半个小时还没生成好)。关于dh的安全性,可以关注这个网站: https://weakdh.org ,这篇文章:https://weakdh.org/sysadmin.html
openssl dhparam -out dhparam.pem 2048
生成好以后,将以上生成的私钥、证书、dh等写入nginx的配置文件:
server
{
listen 80;
listen 443 ssl;
#listen [::]:80;
server_name wiki.ioin.in;
index index.html index.htm;
ssl on;
ssl_certificate /etc/ssl/letsencrypt/chained.pem;
ssl_certificate_key /etc/ssl/letsencrypt/domain.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DH$
ssl_session_cache shared:SSL:50m;
ssl_dhparam /etc/ssl/letsencrypt/dhparam.pem;
ssl_prefer_server_ciphers on;
...the rest of your config
}
重启nginx,一切万事大吉: https://wiki.ioin.in
另外,我们看证书的过期日期。算一下这个证书其实只有3个月,也就是一个季度。当证书快要过期的时候,我们还需要重新颁发一下证书。 重新颁发证书的过程就比较简单了,只需要重新执行acme_tiny.py即可。
我们可以将重新颁发的过程写在一个脚本里:
#!/usr/bin/sh
python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem
cat /tmp/signed.crt intermediate.pem > /path/to/chained.pem
service nginx reload
然后将这个脚本加入cron,每月执行一次:
#example line in your crontab (runs once per month)
0 0 1 * * /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log
就不需要人工操作了~
最后,测试一下SSL质量: https://www.ssllabs.com/ssltest/
- Windows Server AppFabric Caching
- zepto 基础知识(2)
- DeepMind回顾2017年:除了战胜柯洁还有哪些大事
- [认证授权] 1.OAuth2授权
- 机器学习(四)——梯度下降算法解释以及求解
- 在Windows上运行单节点的Cassandra
- Mono技术规格
- 如何站在使用者的角度来设计SDK-微信公众号开发SDK(消息处理)设计之抛砖引玉
- 机器学习(三)——k-近邻算法基础
- 利用Windows性能计数器(PerformanceCounter)监控
- zepto 基础知识(1)
- [C#7] 1.Tuples(元组)
- 防止“rm-rf/”误删除的5种方法
- 基于DotNetOpenAuth实现OpenID 服务提供者
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 递归解决全排列问题
- Codeforces Round #622 (Div. 2)A~~C1
- AtCoder Beginner Contest 156 A~~D
- AtCoder Beginner Contest 155
- Codeforces Round #620 (Div. 2) A~~D
- DFS+记忆化搜索 -- 简单练习
- AtCoder Beginner Contest 154
- map + pair用法练习
- 蛇形矩阵
- 【SpringBoot WebFlux 系列】 header 参数解析
- URL 去重的 6 种方案!(附详细实现代码)
- 原生JS封装拖动验证滑块你会吗?
- 企业远程视频会议云服务EasyRTC-SFU版本支持 https 功能设计逻辑
- python之编码解码、字符串常用方法
- python之列表