利用 acme-tiny 實現 HTTPS 加密通訊 (CentOS & Apache)

ShelterYa發表於2017-04-02

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 協議》,轉載必須註明作者和本文連結

認真,可以讓事情變得出乎意料地好!

相關文章