利用 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 协议》,转载必须注明作者和本文链接
认真,可以让事情变得出乎意料地好!
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

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

7年前 评论

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

7年前 评论

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

7年前 评论

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