HTTPS通訊安全及證書管理

HTTPS基礎

  • 基於安全套接字協議(TLS/SSL)之上的HTTP通訊協議
  • 可用於抵禦 竊聽、篡改、冒充、劫持 攻擊,實現 身份驗證、信息加密、完整性校驗
  • 其在TCP協議三次握手以後增長了四次握手

PKI體系原理

  1. CA機構審覈服務商身份信息後利用私鑰簽名其證書請求來簽發證書
  2. 客戶端利用CA機構公鑰校驗服務商證書上的簽名從而驗證其身份

SSL/TLS

SSL/TLSPKI 體系的一種實現node

  • TLS: 傳輸層安全協議(Transport Layer Security),基於RSA加密算法
  • SSL:TLS的上一代產品,已廢棄

SSL/TLS通訊流程python

  1. 客戶端請求創建加密通訊等 +隨機數1
  2. 服務器返回證書(內含非對稱加密公鑰)等 +隨機數2
  3. 客戶端校驗證書並從中取出公鑰,通知服務端握手結束等 +公鑰加密隨機數3
  4. 服務端私鑰解密隨機數3,並通知客戶端握手結束等
  5. 兩端各自基於三個隨機數生成對稱加密祕鑰session key,通訊進入常規http協議並用session key加密

證書概要

證書是CA爲服務商簽發的身份認證憑據nginx

  • 瀏覽器默認已內置了經常使用 CA根證書(CA的自簽名證書)
  • 咱們可選用免費的CA機構 Let's Encrypt 簽發的證書
  • 證書可經過信任鏈傳遞有效性
  • 證書內容包括
    • CA私鑰簽名、CA公鑰、簽發機構、域名、申請者等
    • 可能存在的信任鏈(若是不是CA根證書籤發的話)
  • 證書主要分兩類:
    • 自簽名證書
    • CA證書(可用於簽名其餘證書)
  • 有兩種方式吊銷證書:
    • CRL 文件
    • OCSP
  • 證書格式

常規證書籤發

openssl genrsa -out domain.key 4096  # 網站先生成 rsa加密的私鑰
openssl req -new -key domain.key -out domain.csr  # 基於 網站私鑰 生成 證書請求csr

# csr證書請求 被簽名後 轉換爲證書
# 證書可由商業CA機構簽發 或 如下方式自行簽發3種證書:
openssl x509 -req -in domain.csr -signkey domain.key -out domain.crt  # 基於網站私鑰 簽發 自簽名證書
openssl x509 -req -in domain.csr -signkey domain.key -extensions v3_ca -out domain_ca.crt  # 基於網站私鑰 簽發 自簽名CA證書
openssl x509 -req -in next_domain.csr -CA domain_ca.crt -CAkey domain_ca.key -CAcreateserial -extensions v3_usr -out next_domain_ca.crt  # 基於 CA證書、CAkey 簽發 派生域名的CA證書

自簽名證書

sudo mkdir /etc/certs
cd /etc/certs
sudo openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt  # 其中Common Name輸入域名
sudo openssl dhparam -out dhparam.pem 1024  # 生成DHE參數文件加強ssl加密
sudo chmod -R 777 /etc/certs

配置客戶機信任自簽名證書git

  • windows平臺
    • 自簽名證書會被瀏覽器標記爲不安全
    • 須要手動將自簽名證書導入到瀏覽器的根證書信任列表
    • Chrome根證書信任設置:設置 》 高級 》 HTTPS/SSL 》 管理證書 》 受信任的根證書頒發機構 》 導入
  • CentOs7平臺
sudo yum install ca-certificates
update-ca-trust enable
sudo cp 自簽名證書.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust extract

Let's Encrypt證書

Let's Encrypt是由ISRG互聯網安全小組開放的免費證書服務,基於ACME協議,證書有效期爲90天github

0.基於Docker建立證書web

sudo docker run -it --rm -p 443:443 -p 80:80 --name certbot \
            -v "/etc/letsencrypt:/etc/letsencrypt" \
            -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
            certbot/certbot certonly -n -v --standalone --agree-tos --email 郵箱 -d 域名1 -d 域名2

1.基於官方工具Certbot建立Let's Encrypt證書算法

sudo yum install certbot

# 使用工具內建web服務器模式,需臨時停用主機上的已有80端口服務
sudo certbot certonly -n -v --standalone --agree-tos --email 郵箱 -d 域名1 -d 域名2 \
 --pre-hook  "service nginxd stop"  --post-hook "service nginxd start"

Certbot執行成功後將在 /etc/letsencrypt/live/域名 路徑下導出如下文件:docker

  • cert.pem (網站證書)
  • chain.pem (cert.pem + 中間證書)
  • fullchain.pem (【網站證書 + 】 中間證書 + root證書)
  • privkey.pem (證書私鑰)

設置每個月一號凌晨1點自動更新證書CronJobwindows

0 1 1 * * certbot renew --quiet --pre-hook "service nginxd stop" --post-hook "service nginxd start"

2. 基於 acme-tiny 工具建立證書 GitHub地址瀏覽器

外部依賴:

  • openssl
  • python
sudo mkdir /etc/certs
cd /etc/certs

sudo openssl genrsa 4096 > account.key  # 建立帳戶私鑰
sudo openssl genrsa -out domain.key 4096  # 建立網站rsa私鑰

# 兩種方式建立csr證書請求
sudo openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:example.com,DNS:www.example.com")) > domain.csr  # 直接導出方式
sudo openssl req -new -sha256 -key domain.key -out domain.csr  # 交互命令行方式,Common Name指定爲網站域名

## 校驗服務配置 ##
# 1. 校驗服務目錄
mkdir /srv/ca_challenges
# 2. nginx配置
'server {
    listen 80;
    server_name www.example.com example.com;

    location ^~ /.well-known/acme-challenge/ {
        alias /srv/ca_challenges/;
        try_files $uri =404;
    }

    location / {
        rewrite ^/(.*)$ https://example.com/$1 permanent;
    }
}'

# acme-tiny工具生成證書
cd /etc/certs
sudo wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
sudo python acme_tiny.py --account-key ./domain.key --csr ./domain.csr --acme-dir /srv/ca_challenges/ > ./domain.crt

# 中間證書合併
sudo wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
sudo cat domain.crt intermediate.pem > chain.pem

# 證書信任鏈
sudo wget -O - https://letsencrypt.org/certs/isrgrootx1.pem > root.pem
sudo cat root.pem intermediate.pem > fullchain.pem

設置每個月一號凌晨1點自動更新證書CronJob

  1. 更新腳本renew_cert.sh
cd /etc/certs
python acme_tiny.py --account-key domain.key --csr domain.csr --acme-dir /srv/ca_challenges/ > signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chain.pem
service nginxd reload
  1. 加入定時任務:
0 0 1 * * /etc/certs/renew_cert.sh

服務器配置支持HTTPS

自動配置生成器:https://mozilla.github.io/server-side-tls/ssl-config-generator

典型的如nginx下配置

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name example.com, www.example.com;

    location ^~ /.well-known/acme-challenge/ {
        alias /srv/ca_challenges/;
        try_files $uri =404;
    }

    location / {
        # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
        return 301 https://$host$request_uri;        
    }

}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com, www.example.com;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/certs/chain.pem;
    ssl_certificate_key /etc/certs/domain.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;


    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /etc/certs/fullchain.pem;

    resolver <IP DNS resolver>;

    ....
}
相關文章
相關標籤/搜索