利用 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 协议》,转载必须注明作者和本文链接
认真,可以让事情变得出乎意料地好!
打赏
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

多说头像表情依旧http问题解决 :stuck_out_tongue:: https://www.cacher.cc/2016/12/31/duoshuo-h...

8年前 评论

感谢楼主分享,我博客网站也是引用多说的评论框,确实好用的一个评论系统,不过突然看到多说发布了这样一条新闻
file
感觉欠多说一个会员。哈哈!

8年前 评论

@happygeek 哎呀 好尴尬。。。。。哈哈

8年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!