利用 acme-tiny 实现 HTTPS 加密通信 (CentOS & Apache)
Hello,我是Shelter,好久没来PHPHub发文章了,哈。一时兴起,来一发。
看到有小伙伴发博客上https,但是不能自动续签整数,就发了这个上来。不适合之处,多谢指出!
之前Jason跟我装逼他的博客上了https的时代,于是我也上了。
参考了网上挺多的文章,发现很多都是基于nginx的,Apache的资料基本都不是很详细。
这里是基于 CentOS & Apache,利用acme-tiny实现HTTPS加密通信 ,权当自己的个人笔记,也跟大家分享下。
环境:CentOS、Apache
HTTPS简介
首先,先理解HTTPS是做什么的。(请自行了解对称加密与非对称加密)
最直观的:HTTPS = HTTP + 认证 + 加密 + 完整性保护
一次HTTPS交互的流程是这样子的:
-
Client --> Server: Hey!我要和你通信.
-
Server --> Client: OK,这是我的数字证书(本文章将要介绍如何生成的CA签发的证书).
Client收到后,使用浏览器内置的CA的公钥进行解密 —— 认证是否安全的服务器,得到数字证书中Server的公钥。再生成一个随机字符串x,并根据这个随机字符串x生成一把对称加密密钥
-
Client --> Server: 好的,我已经确认你是我想要通信的服务器了,接下来我们使用对称加密来进行通信,这是密钥种子 随机字符串x. [Server公钥|RSA加密]
Server 接受后通过Server密钥解密,得到随机字符串x,并生成一把对称加密密钥
-
Server --> Client: OK!我们开始通信吧.[对称加密密钥|对称加密]
-
Client --> Server: 告诉我银行卡的余额.[对称加密密钥|对称加密]
-
Server --> Client: 余额为xxx.[对称加密密钥|对称加密]
因为非对称性加密代价比较大,所以HTTPS采用在非对称性加密的掩护下交换对称性加密密钥的混合模式。
实现思路
上面的交互流程中,我们主要就是要得到数字证书,其它的都是由 Apache 的 mod_ssl 帮我们完成了。
这里通过开源的 Acme Tiny (A tiny script to issue and renew TLS certs from Let's Encrypt) 来签发证书。
acme-tiny脚本会生成验证文件并写入到你指定的目录下,然后通过http来访问 "yoursite.com/.well-known/acme-challenge/" 这个URL来访问验证文件,以证明你对该域名有访问权限,因此你需要保证服务器80端口能够访问.并且能够通过认证。(请认真理解这句话.)
另外,一个证书可以签订多个域名(目前最多支持100个),也就是说,只需要签发一个证书,然后安装到Apache的SSL模块,那么这些域名全部可以通过HTTPS访问了!
具体步骤
获取证书
1. 创建工作目录(生成和存放证书的地方)
//我选择同ssh证书存放在同一个目录
cd /usr/share/httpd
//clone acme-tiny项目
git clone https://github.com/diafygi/acme-tiny.git
//进入工作目录
cd acme-tiny
2. 创建CSR(Certificate Signing Request,证书签名请求) 文件
//创建Let's Encrypt私钥
openssl genrsa 4096 > account.key
openssl genrsa 4096 > domain.key
接下来需要使用openssl.cnf文件,先查找自己该文件的位置
locate openssl.cnf
CentOS下的文件位置在/etc/pki/tls/openssl.cnf
//创建请求文件
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:blog.yangxitian.cn,DNS:wyucloud.cn")) > domain.csr
3. 设置回调认证文件URL
实现思路中已经提到,申请证书的时候,Let's Encrypt 将回回调"yoursite.com/.well-known/acme-challenge/xxxxx(认证文件名)",来读取的acme脚本生成的认证文件。
这里我将存放认证文件的位置设置为/var/www/https_challenges/(http能够访问到的位置)
//创建该目录,该目录一直保留,后面自动更新证书将会使用到。
cd /var/www/
mkdir https_challenges
sudo chown apache https_challenges/ -R //更改所有者
需要为之配置虚拟目录:
//vim /etc/httpd/conf.d/vhost.conf
<VirtualHost *:80>
ServerAdmin root@Monster
ServerName blog.yangxitian.cn
ServerAlias blog.yangxitian.cn
DocumentRoot /var/www/hexo_blog
Alias /.well-known/acme-challenge/ /var/www/https_challenges/
</VirtualHost>
<VirtualHost *:80>
ServerAdmin root@Monster
ServerName wyucloud.cn
ServerAlias wyucloud.cn
DocumentRoot /var/www/WYUCloud/public/view/
Alias /.well-known/acme-challenge/ /var/www/https_challenges/
</VirtualHost>
重启Apache
sudo systemctl restart httpd.service
4. 申请证书
将往/var/www/https_challenges/ 里面写入一个回调用认证文件xxxxx
回调验证后,文件会自动删除
cd /usr/share/httpd/acme-tiny
sudo chmod +x acme_tiny.py
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/https_challenges/ > ./signed.crt
此时得到证书 signed.crt
很多人会遇到错误
ValueError: Wrote file to /var/www/https_challenges/xAHQx39iAe1W4IoENWD-PHYyqzPYdcQLouxl-rnVWWs, but couldn't download http://blog.yangxitian.cn/.well-known/acme...
此时为回调出错,请检查虚拟目录是否配置成功。
5. 将 Let's Encrypt 的中间件证书 intermediate.pem 内容附加在签名证书signed.crt之后
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
恭喜!证书申请制作完毕.
安装证书
1. 检查 是否安装了ssl
检查/etc/httpd/modules 目录下是否有mod_ssl.so,没有的话 进行安装:
yum install mod_ssl openssl
//会生成 配置文件/etc/httpd/conf.d/ssl.conf 跟 vim /etc/httpd/conf.modules.d/00-ssl.conf
2. 安装证书到apache
//vim /etc/httpd/conf.modules.d/00-ssl.conf
LoadModule ssl_module modules/mod_ssl.so
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin root@Monster
ServerName blog.yangxitian.cn
ServerAlias blog.yangxitian.cn
DocumentRoot /var/www/hexo_blog
<Directory /var/www/hexo_blog>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order allow,deny
allow from all
</Directory>
SSLEngine on
SSLCertificateFile /usr/share/httpd/acme-tiny/chained.pem
SSLCertificateKeyFile /usr/share/httpd/acme-tiny/domain.key
</VirtualHost>
<VirtualHost _default_:443>
ServerAdmin root@Monster
ServerName wyucloud.cn
ServerAlias wyucloud.cn
DocumentRoot /var/www/WYUCloud/public/view
<Directory /var/www/WYUCloud/public/view>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order allow,deny
allow from all
</Directory>
SSLEngine on
SSLCertificateFile /usr/share/httpd/acme-tiny/chained.pem
SSLCertificateKeyFile /usr/share/httpd/acme-tiny/domain.key
</VirtualHost>
</IfModule>
注意:https是通过443端口访问的,因此这里需要重新配置类似虚拟主机一样的配置。
重启apache
sudo systemctl restart httpd.service
发现 https://blog.yangxitian.cn & https://wyucloud.cn 已经可以成功访问了!
3. (可选)强制http 切换到https访问
另外,可以在项目目录下创建.htaccess 来强制http 访问到https访问
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
自动更新证书
Let’s Encrypt 签发的证书只有90天的有效期,因此,需要利用crontab来定时更新
1. 编写自动更新工作目录中文件的脚本
cd /usr/share/httpd/acme-tiny
touch renew_cert.sh
vim renew_cert.sh
内容如下:
//renew_cert.sh
python /usr/share/httpd/acme-tiny/acme_tiny.py --account-key /usr/share/httpd/acme-tiny/account.key --csr /usr/share/httpd/acme-tiny/domain.csr --acme-dir /var/www/https_challenges/ > /usr/share/httpd/acme-tiny/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > /usr/share/httpd/acme-tiny/intermediate.pem
cat /usr/share/httpd/acme-tiny/signed.crt /usr/share/httpd/acme-tiny/intermediate.pem > /usr/share/httpd/acme-tiny/chained.pem
sudo systemctl restart httpd.service
2. 添加到定时任务中
crontab -e
//添加任务
0 0 1 * * /usr/share/httpd/acme-tiny/renew_cert.sh
sudo systemctl restart crond.service
最后
写得比较乱,但是比较详细吧!
最后,恭喜进入HTTPS时代!
参考文章
怎样部署Let’s Encrypt证书签发体系>>阿蒙的礼物
APACHE2站点支持HTTPS加密
Let's Encrypt,站点加密之旅
Let's Encrypt,免费好用的 HTTPS 证书
本作品采用《CC 协议》,转载必须注明作者和本文链接
多说头像表情依旧http问题解决 :stuck_out_tongue:: https://www.cacher.cc/2016/12/31/duoshuo-h...
感谢楼主分享,我博客网站也是引用多说的评论框,确实好用的一个评论系统,不过突然看到多说发布了这样一条新闻

感觉欠多说一个会员。哈哈!
@happygeek 哎呀 好尴尬。。。。。哈哈