一、獲取證照的途徑
- 自簽名證照,適用於開發者測試HTTPS,最快速的途徑就是生成自簽名證照,非常方便。
- Let's Encrypt證照,可以使用免費CA機構簽發的證照。
- 使用收費CA機構簽發的證照,如果對證照安全性、相容性、功能有特殊需求,可以向CA機構申請證照。
二、自簽名證照
自簽名證照是我們自己簽發的,瀏覽器不會整合私有的CA機構的根證照,所以開啟頁面的時候會進行提示,使用者選擇信任證照之後,後續的通訊就會進行加密保護的。
自簽名證照的用途還是很廣泛的,對於一些企業內部系統,由於購買證照需要成本,可以生成自簽名證照,企業內部系統的使用者一般執行在同一個區域網下,由防火牆保護,風險相對可控,當瀏覽器提示使用者自簽名證照存在風險時,使用者可以選擇信任自簽名證照,等同於訪問了一個HTTPS網站。
生成自簽名證照的步驟如下
1.生成私鑰對和CSR
我們設定金鑰的長度為2048bit;
我們最終會得到flask_self_csr.pem和flask_self_key.pem兩個檔案;
CSR(Certificate Signing Request)表示證照籤名請求,裡面包含了伺服器的金鑰對,CA機構接收到請求會驗證CSR請求的簽名;
flask_self_csr.pem包含了我們的金鑰對;
執行命令之後,我們可以在互動式提示中,設定證照包含的一些資訊;
mango@mango-ubuntu:~/文件/blogs/web/證照$ openssl req -newkey rsa:2048 -nodes -keyout flask_self_key.pem -out flask_self_csr.pem
Generating a RSA private key
.........+++++
......+++++
writing new private key to 'flask_self_key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:mango
Organizational Unit Name (eg, section) []:mango
Common Name (e.g. server FQDN or YOUR name) []:cee1-110-251-30-176.ngrok.io
Email Address []:mango@163.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
- 生成自簽名證照
接下來通過CSR生成證照,對於自簽名證照,我們可以認為自己就是一個CA機構,輸入如下命令生成證照:
mango@mango-ubuntu:~/文件/blogs/web/證照$ openssl x509 -signkey flask_self_key.pem -in flask_self_csr.pem -req -days 365 -out flask_self_cert.pem
Signature ok
subject=C = CN, ST = Beijing, L = Beijing, O = mango, OU = mango, CN = cee1-110-251-30-176.ngrok.io, emailAddress = mango@163.com
Getting Private key
- 驗證證照
將生成的flask_self_cert.pem和flask_self_key.pem拷貝到站點根目錄下,並設定啟用ssl
from flask import Flask
app = Flask(__name__)
@app.route("/", methods=["GET"])
def hello():
return 'hello python'
if __name__ == "__main__":
app.run('0.0.0.0', ssl_context=('flask_self_cert.pem', 'flask_self_key.pem'))
# app.run('0.0.0.0', debug=True, ssl_context='adhoc')
三、使用Let's Encrypt證照
Let's Encrypt首先是一個CA機構,得到了很多大公司的支援,相容性非常不錯,同時它定義了ACME協議,將管理證照的流程進行了標準化、自動化,不用人工管理。可以使用基於ACME協議的客戶端在Let's Encrypt管理證照,官方推薦Certbot客戶端,使用非常方便。
1.安裝Certbot客戶端
mango@mango-ubuntu:~/文件/blogs/web/證照/certbot$ sudo snap install --classic certbot
certbot 1.21.0 from Certbot Project (certbot-eff✓) installed
2.手動生成證照和金鑰檔案
mango@mango-ubuntu:~/文件/blogs/web/證照$ sudo certbot certonly --manual -d 565c-110-251-30-176.ngrok.io
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for 565c-110-251-30-176.ngrok.io
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Create a file containing just this data:
csM3J5YGt3V-PQDeRpcDhjlpy7Hdf9tjh-NsIqqoA6A.eRfiNKPaGpDq-g1FefRl52GbfFeSDV_Qg8Gwe1KQP5M
And make it available on your web server at this URL:
http://565c-110-251-30-176.ngrok.io/.well-known/acme-challenge/csM3J5YGt3V-PQDeRpcDhjlpy7Hdf9tjh-NsIqqoA6A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/565c-110-251-30-176.ngrok.io/fullchain.pem
Key is saved at: /etc/letsencrypt/live/565c-110-251-30-176.ngrok.io/privkey.pem
This certificate expires on 2022-02-10.
These files will be updated when the certificate renews.
NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
為了通過CA對站點的驗證,我們需要新增對應的action來響應對應的請求
@app.route("/.well-known/acme-challenge/csM3J5YGt3V-PQDeRpcDhjlpy7Hdf9tjh-NsIqqoA6A")
def challenge():
return 'csM3J5YGt3V-PQDeRpcDhjlpy7Hdf9tjh-NsIqqoA6A.eRfiNKPaGpDq-g1FefRl52GbfFeSDV_Qg8Gwe1KQP5M'
- 驗證證照
將生成的證照和金鑰檔案拷貝到站點根目錄,並修改檔案許可權
mango@mango-ubuntu:~/文件/blogs/webhook$ sudo cp /etc/letsencrypt/live/565c-110-251-30-176.ngrok.io/fullchain.pem fullchain.pem
mango@mango-ubuntu:~/文件/blogs/webhook$ sudo cp /etc/letsencrypt/live/565c-110-251-30-176.ngrok.io/privkey.pem
mango@mango-ubuntu:~/文件/blogs/webhook$ sudo chown mango fullchain.pem
mango@mango-ubuntu:~/文件/blogs/webhook$ sudo chown mango privkey.pem
修改站點啟用ssl
from flask import Flask
app = Flask(__name__)
@app.route("/", methods=["GET"])
def hello():
return 'hello python'
@app.route("/.well-known/acme-challenge/csM3J5YGt3V-PQDeRpcDhjlpy7Hdf9tjh-NsIqqoA6A")
def challenge():
return 'csM3J5YGt3V-PQDeRpcDhjlpy7Hdf9tjh-NsIqqoA6A.eRfiNKPaGpDq-g1FefRl52GbfFeSDV_Qg8Gwe1KQP5M'
if __name__ == "__main__":
app.run('0.0.0.0', ssl_context=('fullchain.pem', 'privkey.pem'))
# app.run('0.0.0.0', ssl_context=('flask_self_cert.pem', 'flask_self_key.pem'))
# app.run('0.0.0.0', debug=True, ssl_context='adhoc')