最近想搞一个网站玩玩,发布网站用https协议已经是大势所趋了。例如微信小程序,不使用https协议根本不让接入。所以,分享一下我尝试过的三种方法。
- Linux自签(OPENSSL生成SSL自签证书)
- 阿里云免费证书
- Let’s Encrypt永久免费SSL证书【墙裂推荐】
一、Linux自签(OPENSSL生成SSL自签证书)
第1步:生成私钥
执行如下命令生成一个RSA私钥
//生成rsa私钥,des3算法,1024位强度,ssl.key是秘钥文件名。
openssl genrsa -des3 -out ssl.key 1024
然后他会要求你输入这个key文件的密码,由你随便设置。
由于以后要给nginx使用。每次reload nginx配置时候都要你验证这个PAM密码的。
但是生成时候必须输入密码。如果不想以后那么麻烦,生成之后可以执行如下命令再删掉。
openssl rsa -in ssl.key -out ssl.key
第2步:生成CSR(证书签名请求)
根据刚刚生成的key文件来生成证书请求文件,操作如下:
openssl req -new -key ssl.key -out ssl.csr
说明:执行以上命令后,需要依次输入国家、地区、城市、组织、组织单位、Common Name和Email。其中Common Name应该与域名保持一致。
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GuangDong
Locality Name (eg, city) []:ShenZhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:tsy
Organizational Unit Name (eg, section) []:tsy
Common Name (e.g. server FQDN or YOUR name) []:selfssl.hxkj.vip 这一项必须和你的域名一致
Email Address []:t@tsy6.com
第3步:生成自签名证书
根据以上2个文件生成crt证书文件,执行下面命令:
//这里3650是证书有效期(单位:天)。这个大家随意。最后使用到的文件是key和crt文件。
openssl x509 -req -days 3650 -in ssl.csr -signkey ssl.key -out ssl.crt
需要注意的是,在使用自签名的临时证书时,浏览器会提示证书的颁发机构是未知的。
第4步:安装私钥和证书
打开conf目录中的nginx.conf配置文件修改443端口监听配置。一般nginx配置文件默认路径为 /etc/nginx/nginx.conf,执行如下命令打开并修改:
vim /etc/nginx/nginx.conf //路径是你的nginx配置文件路径
Nginx默认配置是将443端口的监听配置注释掉了的,如下:
# Settings for a TLS enabled server.
# server {
# listen 443;
# server_name localhost;
#ssl on;
#root /usr/share/nginx/html;
#ssl_certificate "";
#ssl_certificate_key "";
#ssl_session_cache shared:SSL:1m;
#ssl_session_timeout 5m;
#ssl_protocols SSLv2 SSLv3 TLSv1;
#ssl_ciphers HIGH:!aNULL:!MD5;
#ssl_prefer_server_ciphers on;
#
# Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
#}
将注释打开,并对其中部分内容进行修改,修改后如下:
# Settings for a TLS enabled server.
server {
listen 443;
server_name selfssl.hxkj.vip; //此处填写你自己的域名
ssl on;
root /usr/share/nginx/html;
ssl_certificate "/home/ssl/ssl.crt"; //此处填写刚刚生成的ssl.crt文件路径
ssl_certificate_key "/home/ssl/ssl.key"; //此处填写刚刚生成的ssl.key文件路径
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
修改配置并保存后,执行以下命令:
nginx -s reload
可使nginx重新加载配置,使配置生效。
tips:自签证书因为安全性很低,会被谷歌浏览器拦截
下面是证书检测详情
二、阿里云免费证书
第1步:登陆阿里云账号,选择证书服务
第2步:选择DV SS
第3步:选择Symantec
第4步:选择OV SSL
第5步:选择免费型DV SSL
第6步:好,经过曲折的选择完毕之后,购买,需要支付0元(免费的啦)
第7步:购买成功之后会返回证书控制台,然后点击补全信息
第8步:需要填写证书绑定的域名,根据自己的需求填写就OK
第9步:填写申请人的个人信息,如实填写就好
第10步:补全成功之后,会返回域名配置引导页,如图所示
第11步:打开自己的域名控制台,添加解析
第12步:给域名添加TXT记录,此处填写的是第10步的信息,如图所示
第13步:确认完毕之后,会自动返回证书配置页,可以进行配置检测
如果配置正确,左边会显示“DNS配置记录正确,请耐心等候”。否则的话,就是域名TXT记录配置错误,返回检查第12步的信息是否填写正确
第14步:一般10分钟之内就出结果了,配置正确的话,会自动返回这个页面,下载证书
第15步:安装证书,阿里教程挺详细的,就不做赘述了
下面是我的nginx配置内容,可供参考:
server {
listen 443;
server_name alissl.hxkj.vip;
ssl on;
root /usr/share/nginx/html;
ssl_certificate "/home/alissl/214715369370158.pem";
ssl_certificate_key "/home/alissl/214715369370158.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
修改配置并保存后,执行以下命令:
nginx -s reload
可使nginx重新加载配置,使配置生效。
下面是证书检测详情
三、Let’s Encrypt免费证书
Let’s Encrypt简介
Let’s Encrypt作为一个公共且免费SSL的项目逐渐被广大用户传播和使用,是由Mozilla、Cisco、Akamai、IdenTrust、EFF等组织人员发起,主要的目的也是为了推进网站从HTTP向HTTPS过度的进程,目前已经有越来越多的商家加入和赞助支持。
Let’s Encrypt免费SSL证书的出现,也会对传统提供付费SSL证书服务的商家有不小的打击。到目前为止,Let’s Encrypt获得IdenTrust交叉签名,这就是说可以应用且支持包括FireFox、Chrome在内的主流浏览器的兼容和支持,虽然目前是公测阶段,但是也有不少的用户在自有网站项目中正式使用起来。
Let’s Encrypt 的最大贡献是它的 ACME 协议,第一份全自动服务器身份验证协议,以及配套的基础设施和客户端。这是为了解决一直以来 HTTPS TLS X.509 PKI 信任模型,即证书权威(Certificate Authority, CA)模型缺陷的一个起步。在客户端-服务器数据传输中,公私钥加密使得公钥可以明文传输而依然保密数据,但公钥本身是否属于服务器,或公钥与服务器是否同属一个身份,是无法简单验证的。证书权威模型通过引入事先信任的第三方,由第三方去验证这一点,并通过在服务器公钥上签名的方式来认证服务器。第三方的公钥则在事先就约定并离线准备好,以备访问时验证签名之用。这个第三方就称为证书权威,简称CA。相应的,CA验证过的公钥被称为证书。问题是,如果服务器私钥泄露,CA无法离线使对应的证书无效化,只能另外发布无效记录供客户端查询。也就是说,在私钥泄露到CA发布无效记录的窗口内,中间人可以肆意监控服-客之间的传输。如果中间人设法屏蔽了客户端对无效记录的访问,那么直到证书过期,中间人都可以进行监控。而由于当前CA验证和签发证书大多手动,证书有效期往往在一年到三年。Let’s Encrypt 签发的证书有效期只有90天,甚至希望缩短到60天。有效期越短,泄密后可供监控的窗口就越短。
1.Nginx环境下使用Python与Git部署Let’s Encrypt证书
1.1 检查服务器是否安装Python与Git
检测Python指令
#检查Python的版本是否在2.7以上
python -v //2.7版本
如果没有安装Python的话,执行以下命令进行安装(如果检测到已安装则略过)
#安装python所需的包
yum install zlib-devel
yum install bzip2-devel
yum install openssl-devel
yum install ncurses-devel
yum install sqlite-devel
#获取到Python
cd /usr/local/src
wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz
#解压Python2.7.12
tar -xvf Python-2.7.12.tar.xz
#编译python
cd Python-2.7.12/
./configure --prefix=/usr/local/python2.7
make && make install
#建立link
ln -s /usr/local/python2.7/bin/python2.7 /usr/local/bin/python
#解决系统 Python 软链接指向 Python2.7 版本后,因为yum是不兼容 Python 2.7的,所需要指定 yum 的Python版本
# vim /usr/bin/yum
将头部的
#!/usr/bin/python
改成
#!/usr/bin/python2.6.6
检测Git指令
#检查系统是否安装git
git --version
如果没有安装Git的话,执行以下命令进行安装(如果检测到已安装则略过)
#git 安装
yum install git
1.2 快速获取Let’s Encrypt免费SSL证书
相较于第一种自签生成证书的方法,Let’s Encrypt肯定是考虑到推广HTTPS的普及型会让用户简单的获取和部署SSL证书,所以可以采用下面简单的一键部署获取证书。
#获取letsencrypt
git clone https://github.com/letsencrypt/letsencrypt
#进入letsencrypt目录
cd letsencrypt
#生成证书 --email后填写自己的邮箱 -d 后面填写需要配置证书的域名(支持多个哦)
./letsencrypt-auto certonly --standalone --email t@tsy6.com -d hxkj.vip -d www.hxkj.vip
Let’s Encrypt是支持绑定多域名的,上述两种方法都是只支持单域名。
1.3 Let’s Encrypt免费SSL证书获取与应用
在完成Let’s Encrypt证书的生成之后,我们会在”/etc/letsencrypt/live/hxkj.vip/“域名目录下有4个文件就是生成的密钥证书文件。
cert.pem - Apache服务器端证书
chain.pem - Apache根证书和中继证书
fullchain.pem - Nginx所需要ssl_certificate文件
privkey.pem - 安全证书KEY文件
因为我的是Nginx环境,那就需要用到fullchain.pem和privkey.pem两个证书文件。修改nginx配置的详细过程,上面两种方法都提到了,这里不再赘述,以下我修改好的配置文件:
server {
listen 443;
server_name hxkj.vip www.hxkj.vip;
ssl on;
root /usr/share/nginx/html;
ssl_certificate "/etc/letsencrypt/live/hxkj.vip/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/hxkj.vip/privkey.pem";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
下面是证书检测详情
从上图可以看出,Let’s Encrypt证书是有效期90天的,需要我们自己手工更新续期才可以。但是,身为程序员,可以自动执行的事,坚决不手动搞。
1.4 Let’s Encrypt证书自动续期,实现真正的永久免费使用
1.4.1 编写shell脚本
执行以下命令,在”/etc/letsencrypt/live/hxkj.vip/“域名目录下创建脚本,方便管理
vim /etc/letsencrypt/live/hxkj.vip/updatessl.sh //创建一个名字为updatessl的脚本
然后在脚本里添加如下代码
#!/bin/sh
/usr/local/src/Python-2.7.12/letsencrypt/certbot-auto renew --force-renew --pre-hook "service nginx stop" --post-hook "service nginx start"
#第一行是指此脚本使用/bin/sh 来执行
#第二行中--force-renew参数代表强制更新
退出并保存,然后给脚本添加可执行权限
// 这里的文件路径填写你自己的文件路径
chmod +x /etc/letsencrypt/live/hxkj.vip/updatessl.sh
1.4.2 创建定时任务
打开crontab文件
crontab -e
然后在文件末尾添加一行以下内容
0 0 28 * * root /etc/letsencrypt/live/hxkj.vip/updatessl.sh //我这里代表每月28号更新一次证书文件,文件路径填写你自己的文件路径
具体格式如下:
Minute Hour Day Month Dayofweek command
分钟 小时 天 月 天每星期 命令
每个字段代表的含义如下:
Minute 每个小时的第几分钟执行该任务
Hour 每天的第几个小时执行该任务
Day 每月的第几天执行该任务
Month 每年的第几个月执行该任务
DayOfWeek 每周的第几天执行该任务
Command 指定要执行的程序
在这些字段里,除了“Command”是每次都必须指定的字段以外,其它字段皆为可选字段,可视需要决定。对于不指定的字段,要用“*”来填补其位置。
记得重启crontab服务哦。
2.docker环境下使用certbot部署Let’s Encrypt证书
certbot
是用于从 Let’s Encrypt 获取证书的命令行工具,代码开源在github上。
使用certbot
命令行工具可以轻松的实现HTTPS证书
签发,在签发证书之前,需要证明签发的域名是属于你控制的,目前certbot
有两种验证方式:
- HTTP方式就是
certbot
会生成一个特定的文件名和文件内容,要求放在你对应域名下对应路径(/.well-known/acme-challenge/
)下,然后certbot
再通过 HTTP 请求访问到此文件,并且文件内容与生成时候的一致。
例如:certbot
生成文件名check
和内容!@#$%^
,你需要申请的域名为baidu.com
,则certbot
访问http://baidu.com/.well-known/acme-challenge/check
来校验是否与生成的内容一致。
- DNS则是
certbot
生成一段特定的文本,要求在你对应域名中配置一条对应子域名(_acme-challenge
)的TXT
类型解析记录。
例如:certbot
生成内容!@#$%^
,你需要申请的域名为baidu.com
,则需要添加一条_acme-challenge.baidu.com
的TXT
类型解析记录,值为之前生成的内容。
在域名验证通过之后,certbot
就可以签发HTTPS
证书了,注意在此验证步骤基础上,certbot
提供了很多开箱即用的自动验证方案,但是都不符合我的需求,原因是我需要支持通配符
域名的证书,但是这种证书只支持DNS
验证方式,而官方提供的DNS
插件中并没有支持我用的阿里云DNS
,所以只能自己去实现 阿里云的 DNS 自动校验。
通过官网教程可以选择对应操作系统,并获取安装步骤:
这里我选择的Debian 9
,根据官网的提示进行安装:
sudo apt-get install certbot -t stretch-backports
注:如果install失败可以先执行下 apt-get update
开始签发证书
certbot certonly --cert-name pdown.org -d *.pdown.org,*.proxyee-down.com --manual --register-unsafely-without-email --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
这里签发了一个支持*.pdown.org
和*.proxyee-down.com
通配符域名的证书,注意如果是通配符域名证书需要指定--server https://acme-v02.api.letsencrypt.org/directory
示例:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Registering without email!
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for pdown.org
dns-01 challenge for proxyee-down.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.pdown.org with the following value:
Axdqtserd184wvJc86Dxen386UXqbK2wrgb-*******
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
这里会生成一串随机字符并阻塞住,需要去设置一条对应的 TXT 类型的 DNS 解析记录再继续,在设置好之后可以用nslookup
进行本地验证:
nslookup -type=txt _acme-challenge.pdown.org
服务器: UnKnown
Address: 192.168.200.200
非权威应答:
_acme-challenge.pdown.org text =
"Tit0SAHaO3MVZ4S-d6CjKLv6Z-********"
本地验证通过之后按回车键继续,接着 Let’s Encrypt 就会校验这个 DNS 解析记录是否正确,校验通过后就会进行下一个域名的验证直到全部验证通过。
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/pdown.org/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/pdown.org/privkey.pem
Your cert will expire on 2019-12-02. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
当验证通过的时候会输出证书生成的目录,里面会包含证书和对应的私钥,这里目录是/etc/letsencrypt/live/pdown.org/
。
证书截图:
这样证书就生成好了,之后只需要把证书和私钥配置到nginx
中就可以用https
访问了。
使用 certbot hook 自动续签
上面证书虽然是生成好了,但是证书的有效期只有三个月,意味着每过三个月就得重新签发一个新的证书,一不注意证书就过期了,而且每次手动签发都非常的繁琐需要去手动设置 DNS 解析,所以certbot
提供了一种自动续签的方案:hook
在创建证书的时候certbot
提供了两个hook
参数:
- manual-auth-hook
指定用于验证域名的脚本文件 - manual-cleanup-hook
指定用于清理的脚本文件,即验证完成之后
通过自定义这两个脚本就可以做到自动续签了,文档参考pre-and-post-validation-hooks。
在此基础上,官方已经提供了很多云厂商的自动续签方案,但是我用的阿里云官方并没有提供,于是参照官网文档,写了一个基于阿里云的自动续签脚本,在验证域名的脚本中通过阿里提供的 DNS API 添加一条域名解析记录,在验证完成之后再把刚刚那条域名解析记录删除,命令行调用如下:
certbot certonly --cert-name pdown.org -d *.pdown.org,*.proxyee-down.com --manual --register-unsafely-without-email --manual-auth-hook /path/to/dns/authenticator.sh --manual-cleanup-hook /path/to/dns/cleanup.sh --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
为了方便使用,提供了一个docker镜像
,通过环境变量将阿里云 API 调用的 AK 传递就可以生成和续签证书了。
- 启动容器
docker run \
--name cert \
-itd \
-v /etc/letsencrypt:/etc/letsencrypt \
-e ACCESS_KEY_ID=XXX \
-e ACCESS_KEY_SECRET=XXX \
liwei2633/certbot-aliyun
- 首次创建证书
docker exec -it cert ./create.sh *.pdown.org
创建过程中会等待一段时间,来确保 dns 记录生效,完成之后在/etc/letsencrypt/live
目录下可以找到对应的证书文件
- 续签证书
docker exec cert ./renew.sh
好了,自动更新证书已经配置完了,再也不用担心证书过期啦!这也是我推荐使用这种方式生成证书的原因之一。
四、总结
- 通过Linux自签方式生成签名文件,这种方式操作繁琐,安全性低,反正就是吃力不讨好,不推荐使用。
- 使用阿里云的免费证书,配置方便,唯一的缺点就是有效期只有一年,万一忘记更新就炸了。但是一年的时间也还好,可以考虑使用。
- 使用Let’s Encrypt证书,安全性优良,各大厂商都支持,还能实现自动更新有效期,这种方式强烈推荐!!!
以上文章来自: