1. 程式人生 > >docker項目ssl 安全證書的種種

docker項目ssl 安全證書的種種

gin cert hpa 9.png 只需要 切換 dns info 方法

一,使用nginx代理,將證書掛著宿主的nginx上

這個很簡單,只需要修改宿主nginx的配置文件即可

server {
        listen 443 ssl default;
        server_name www.abc.com; #項目域名
        ssl_certificate "cert/ssl_certificate.pem"; #證書文件
        ssl_certificate_key "cert/ssl_certificate.key"; #秘鑰文件
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers ECDHE
-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #SSL算法加密選項 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr
; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:9001; #指向本機docker 容器端口 } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }

二,spingboot項目內部掛在證書

項目目錄結構如下:

技術分享圖片

即我們在項目根目錄創建一個cert目錄裏面存放證書,然後我們修改項目配置文件application.yml掛上證書

server:
  ssl:
    key-store: classpath:cert/ssl_certificate.pfx #證書文件
    key-store-password: 123456 #證書密碼

打包成docker image

 docker build -t springio/demo-docker .

運行

 docker run -t -p 8433:8080 springio/demo-docker

本地輸入http://www.abc.com:8433 會提示

Bad Request
This combination of host and port requires TLS.

直接改為 https://www.abc.com:8433 訪問正常

三,使用openssl生成不受信任的證書

上面兩種方法都是在我們有證書的情況,如果你沒有證書,可以使用openssl生產一個測試證書,在我們的Dokcerfile中加入證書生成

FROM openjdk
VOLUME /tmp
ADD demo-docker-0.0.1-SNAPSHOT.war app.war
RUN sh -c touch /app.war
RUN echo "Asia/Shanghai" > /etc/timezone
ENV JAVA_OPTS=""
ENV spring.profiles.active="prod"

#以下是生成證書
#定義簽名密碼
ENV certPassword 123456 
RUN openssl genrsa -des3 -passout pass:${certPassword} -out server.key 2048
RUN openssl rsa -passin pass:${certPassword} -in server.key -out server.key
RUN openssl req -sha256 -new -key server.key -out server.csr -subj /CN=www.abc.com #這裏是證書綁定的域名
RUN openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
RUN openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile server.crt -passout pass:${certPassword}
#將證書文件綁定到項目中
ENV key-store="server.pfx"
#將證書密碼傳遞給項目
ENV key-password=${certPassword}
#編譯選項
ENTRYPOINT ["java", "-jar", "/app.war"]

這裏有兩點要註意,dockerfile文件中FROM 不能來源於簡化版即不是“FROM openjdk:8-jdk-alpine” ,因為alpine版本的jdk中不包含openssl,關於openssl詳細使用可以參考這裏 https://www.cnblogs.com/yangxiaolan/p/6256838.html

對應的項目配置文件application.yml內容如下

server:
  ssl:
    key-store: ${key-store} #接收證書文件
    key-store-password: ${key-password} #接收證書密碼

啟動docker項目,瀏覽器輸入 https://www.abc.com,會提示證書不受信任

技術分享圖片

登錄到docker bash 會看到對應的證書文件

技術分享圖片

四,使用Let‘s Encrypt 生成受信任的證書

Let‘s Encrypt生成證書有多種方式:

Plugin

認證

安裝

備註

認證方式 (端口)

apache

Y

Y

自動獲取和安裝證書,適用於Apache2.4 on OSes with libaugeas0 1.0+。

tls-sni-01 (443)

webroot

Y

N

通過webserver的root目錄認證來獲取證書,適用於處於運行狀態的webserver。

http-01 (80)

nginx

Y

Y

自動獲取和安裝證書,適用於Nginx。

tls-sni-01 (443)

standalone

Y

N

通過letsencrypt自帶的standalone服務來獲取證書,standalone服務將占用服務器的80或443端口,這就意味著服務器本身的webserver需要處於關閉狀態,除非它使用特殊端口。

http-01 (80) or tls-sni-01 (443)

DNS plugins

Y

N

通過修改DNS記錄來認證域名所有者以獲取證書,這是使用letsencrypt為通配符域名獲取證書的唯一方式。

dns-01 (53)

manual

Y

N

以用戶自定義的方式獲取證書,根據提示指令,用戶自己來完成域名認證。即使用交互式或腳本鉤子的方式獲取證書。

http-01 (80), dns-01 (53) or tls-sni-01 (443)

使用,Let‘s Encrypt生成證書必須在你的服務器上完成,而且必須確認你的域名已經解析到服務器上,否者無法完成驗證,會提示沒有權限“ urn:ietf:params:acme:error:unauthorized” ,這裏介紹兩種比較常用方式

必須保證你在網站在運行,可以通過域名的80端口正常訪問,需要在你的服務器上安裝 certbot,最好不要使用yum install certbot 安裝 這裏會有依賴問題,因為Certbot是Python程序,最好先創建一個Python虛擬環境,然後再安裝Certbot,具體步驟如下:

sudo yum install python-virtualenv #安裝虛擬環境軟件包(針對於Python2.7)
sudo virtualenv /usr/local/python-certbot #創建虛擬環境
source /usr/local/python-certbot/bin/activate #激活虛擬環境
pip install certbot #安裝Certbot
pip install certbot-nginx #安裝nginx插件,如果不使用 nginx模式生成證書可不需要

也可以不安裝certbot,使用“quay.io/letsencrypt/letsencrypt”鏡像完成只需要在你的服務器上 docker pull quay.io/letsencrypt/letsencrypt 然後通過下面命令啟動

1,webroot方式:

執行證書生成命令

certbot certonly --webroot -w /usr/share/nginx/html -d www.abc.com -m ejiyuan@163.com --agree-tos

docker 鏡像方式

docker run --rm -p 8770:80 -v /etc/letsencrypt:/etc/letsencrypt -v /usr/share/nginx/html:/usr/share/nginx/html quay.io/letsencrypt/letsencrypt auth --webroot -w /usr/share/nginx/html -d q.meylink.cn -m [email protected] --agree-tos

-w 指定網站項目目錄,這個項目必須是可用的,而且是通過你的域名80端口能正常訪問的

-d 指定生成蒸魚的域名 這個域名必須已經解析到執行命令的本服務器上

-m 指定一個email 最好是真實的電郵地址

webroot方式,必須你的服務的 80 端口上運行一個能處理靜態文件的 web 服務,我這裏 nginx 為例 (註意,webroot + nginx 與 nginx 是完全不同的兩種方式)

    server {
        listen       80 default_server;  # 必須是80端口
        server_name  www.abc.com;  # 必須能夠解析到本機
        root         /usr/share/nginx/html; #項目所在目錄
        location / {
           index index.html;
        }
    }

在執行命令後,certbot 會向指定的 webroot 目錄中添加一個隨機文件,隨後 letsencrypt 會通過 http 訪問那個文件,比如 http://www.abc.com/.well-known/acme-challenge/gdEMr7ZXOiZE51he9QwuvnbrrTnkwlpFhNAcArBt2uE, 如果能返回正確的數據則通過認證,否則認證失敗,執行結果如下:

技術分享圖片

2,standalone方式:

這個方式不需要先部署項目,但是必須保證你的域名能解析到服務器上

certbot certonly --standalone -n --agree-tos --email you@gmail.com --preferred-challenges http -d you.domain.com

docker 鏡像方式

docker run --rm -p 80:80 -p 443:443 -v /etc/letsencrypt:/etc/letsencrypt  quay.io/letsencrypt/letsencrypt auth --standalone -m ejiyuan@email.com --agree-tos -d www.meylink.cn

-n 非交互式
--email 指定賬戶
--agree-tos 同意服務協議
--preferred-challenges http 使用http模式 必須保證80端口沒有被占用
--preferred-challenges tls-sni:使用443端口必須保證80端口沒有被占用

默認 standalone 是使用 443 端口,也就是說要停止服務器現在占用 443 端口的進程,我們也可以將其改為使用 80 端口,同樣道理,這時需要停止 80 端口的占用,執行結果

技術分享圖片

3,apache與nginx模式,可是非常簡單的生成並掛在證書這裏以nginx為例

保證你的域名可以解析到本機,並且nginx已安裝,設置nginx配置文件

server {
        server_name you.domain.com;
}

然後執行

certbot --nginx -d a.abc.com

執行結果如下:

技術分享圖片

nginx配置文件修改如下:

server {
  server_name a.abc.com;
  ....
  #一下內容是 Certbot 加入
  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/a.abc.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/a.abc.com/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

4,生成證書部署docker image

FROM alpine
#安裝證書生成工具
RUN apk add --update bash certbot
RUN apk add --no-cache libressl
#掛在一個外部路徑
VOLUME ["/etc/letsencrypt"]

RUN apk add --update bash nginx
#拷貝證書
#COPY ./cert /etc/letsencrypt/live
#拷貝項目文件
COPY ./www /usr/share/nginx/html
#拷貝項目配置文件
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
#切換目錄設置權限
WORKDIR /usr/share/nginx/html
RUN chown -R daemon:daemon * && chmod -R 755 *
EXPOSE 80
EXPOSE 433
#切換到nginx目錄,啟動nginx
WORKDIR /run/nginx  
#ENTRYPOINT nginx -g "daemon off;"
ENTRYPOINT certbot certonly --standalone -n --agree-tos --email [email protected] --preferred-challenges http -d www.meylink.cn && nginx -g "daemon off;"

參考文檔

全民https時代,Let‘s Encrypt免費SSL證書的申請及使用(Tomcat版)

https 證書工具 Letsencrypt 簡單教程

Certbot 自動化生成 https 證書

Letsencrypt SSL免費證書申請(Docker)

CentOS7運行Certbot提示:ImportError: ‘pyOpenSSL‘ module missing required functionality. Try upgrading to v0.14 or newer.

Docker:使用Dockerfile構建Nginx鏡像

通過Laradock學Docker-HTTPS

給Docker中的Nginx搭建HTTPS環境

docker項目ssl 安全證書的種種