一,證書掛着宿主的nginx上html
這個很簡單,只須要修改宿主nginx的配置文件便可java
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 { } }
二,證書掛載到容器項目上python
這裏以nginx爲例,docker文件以下:linux
FROM alpine
#安裝nginx服務器 RUN apk add --update bash nginx #拷貝證書 COPY ./cert /usr/nginx/cert #拷貝項目文件 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 443 #切換到nginx目錄,啓動nginx WORKDIR /run/nginx ENTRYPOINT nginx -g "daemon off;"
或直接 from nginxnginx
#這裏咱們用alpine簡版就能夠 FROM nginx:alpine #拷貝證書 COPY ./cert /usr/nginx/cert #拷貝項目配置文件,配置文件主要是掛載證書開啓443監聽 COPY ./nginx/nginx.conf /etc/nginx/nginx.conf COPY ./nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf COPY ./www /usr/share/nginx/html/ WORKDIR /usr/share/nginx/html/ RUN chown -R daemon:daemon * && chmod -R 755 * EXPOSE 80 EXPOSE 443
nginx 配置文件web
1) nginx.conf算法
user nginx;
worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
2) conf.d/default.confspring
server {
listen 80; listen 443 ssl; 開啓443 ssl server_name www.abc.com; #你的域名 ssl_certificate "/usr/nginx/cert/cn.pem"; #證書文件 ssl_certificate_key "/usr/nginx/cert/cn.key"; #證書祕鑰 location / { root /usr/share/nginx/html; index index.html index.htm; } }
三,spingboot項目內部掛在證書docker
項目目錄結構以下:apache
即咱們在項目根目錄建立一個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詳細使用能夠參考這裏 http://www.javashuo.com/article/p-hxpcxuic-p.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+。 |
|
webroot |
Y |
N |
經過webserver的root目錄認證來獲取證書,適用於處於運行狀態的webserver。 |
|
nginx |
Y |
Y |
自動獲取和安裝證書,適用於Nginx。 |
|
standalone |
Y |
N |
經過letsencrypt自帶的standalone服務來獲取證書,standalone服務將佔用服務器的80或443端口,這就意味着服務器自己的webserver須要處於關閉狀態,除非它使用特殊端口。 |
http-01 (80) or tls-sni-01 (443) |
DNS plugins |
Y |
N |
經過修改DNS記錄來認證域名全部者以獲取證書,這是使用letsencrypt爲通配符域名獲取證書的惟一方式。 |
|
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 ejiyuan@263.com --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 you.domain.com
-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
#安裝nginx服務器
RUN apk add --update bash nginx
#拷貝項目文件
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
#掛在外部路徑方便查看生產的證書與容器內部nginx配置
VOLUME ["/etc/letsencrypt","etc/nginx"]
#切換目錄設置權限
WORKDIR /usr/share/nginx/html
RUN chown -R daemon:daemon * && chmod -R 755 *
EXPOSE 80
EXPOSE 443
#切換到nginx目錄,啓動nginx
WORKDIR /run/nginx
ENTRYPOINT certbot certonly --standalone -n --agree-tos --email ejiyuan@gmail.com --preferred-challenges http -d you.domain.com && nginx -g "daemon off;"
因一個Dockerfile不能同時FROM certbot又FROM nginx,因此這裏使用alpine(它一個小型的 linux髮型版本,想了解他看這裏:Alpine Linux 使用簡介)而後安裝 certbot和nginx
對應的nginx配置文件nginx.conf以下:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
conf.d/default.conf
server { listen 80; listen 443 ssl; server_name www.abc.cn; #配置的域名 ssl_certificate "/etc/letsencrypt/live/www.abc.cn/fullchain.pem"; #letsencrypt證書路徑,證書會自動生成在這個路徑下面 ssl_certificate_key "/etc/letsencrypt/live/www.abc.cn/privkey.pem"; #letsencrypt祕鑰路徑,證書祕鑰會自動生成在這個路徑下面 location / { root /usr/share/nginx/html; index index.html index.htm; } }
六,參考文檔