为 docker 中的 nginx 配置 https
没有 https 加持的网站会逐渐地被浏览器标记为不安全的,所以为网站添加 https 已经变得刻不容缓。对于商业网站来说,花钱购买 SSL/TLS 证书并不是什么问题。但对于个人用户来说,如果能有免费的 SSL/TLS 证书可用将会是非常幸福的事情!Let's Encrypt 就是一个提供免费 SSL/TLS 证书的网站,由于其证书期限只有三个月,所以需要我们用自动化的方式去更新证书。本文将介绍如何为通过 docker 运行的 nginx 中的站点添加 https 支持,并自动完成证书的更新。本文的演示环境为:运行在 Azure 上的 Ubuntu 16.04 主机(此图来自互联网):
准备环境
在 Azure 上创建 Ubuntu 类型的虚机事件非常容易的事情,安装 docker 也无须赘言。比较容易忽略的是配置合适的网络安全组规则,比如打开 80 和 443 端口:
还有就是配置 DNS:
创建一个普通的 http 站点
简单起见,直接使用一个镜像中的 nodejs 应用作为 web 站点:
$ docker pull ljfpower/nodedemo
$ docker network create -d bridge webnet
$ docker run -d --restart=always --expose= \
--network=webnet --name=myweb \
ljfpower/nodedemo
在用户的家目录下创建 nginx 目录及其子目录 conf.d、conf.crt 和 html,创建 logs 目录及其子目录 nginx 和 letsencrypt:
$ mkdir -p nginx/{conf.d,conf.crt,html}
$ mkdir -p logs/{nginx,letsencrypt}
说明,本文演示的示例中需要我们手动创建的文件和目录结构如下:
创建 nginx/nginx.conf 文件,内容如下:
user nginx;
worker_processes auto; error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; events {
worker_connections ;
} http {
include /etc/nginx/mime.types;
default_type application/octet-stream; sendfile on;
keepalive_timeout ;
client_max_body_size 10M; include /etc/nginx/conf.d/*.conf;
}
然后创建 nginx/conf.d/default.conf 文件,内容如下:
upstream web{
server myweb:;
}
server {
listen ;
listen [::]:;
server_name filterinto.com www.filterinto.com; location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/nginx/html;
}
location = /.well-known/acme-challenge/ {
return ;
}
location / {
proxy_pass http://web;
}
}
其中 /.well-known/acme-challenge/ 目录是 certbot 工具在生成证书时创建的。接下来创建文件 nginx/html/index.html 文件,内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Let's Encrypt First Time Cert Issue Site</title>
</head>
<body>
<h1>Hello HTTPS!</h1>
<p>
Just used for the very first time SSL certificates are issued by Let's Encrypt's
certbot.
</p>
</body>
</html>
这个页面也是 certbot 在生成证书时需要用到的。最后让我们启动容器(在用户的家目录下执行下面的命令):
$ docker run -d \
-p : \
-v $(pwd)/nginx/conf.d:/etc/nginx/conf.d:ro \
-v $(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-v $(pwd)/logs/nginx:/var/log/nginx \
-v $(pwd)/nginx/html:/usr/share/nginx/html \
--restart=always \
--name=gateway \
--network=webnet \
nginx:1.14
注意:这时没有映射 443 端口,也没有挂载存放证书的目录。只能以 http 协议访问访问我们的站点:
为站点生成 SSL/TLS 证书
Let's Encrypt 是一个提供免费 SSL/TLS 证书的网站,它为用户提供了 certbot 工具用来生成 SSL/TLS 证书。方便起见,我们把 certbot 简单的封装到容器中。在用户的家目录下创建 certbot 目录,进入 certbot 目录并把下面的内容保存到 Dockerfile 文件中:
FROM alpine:3.4
RUN apk add --update bash certbot
VOLUME ["/etc/letsencrypt"]
然后执行下面的命令创建 certbot 镜像:
$ docker build -t certbot:1.0 .
然后在 certbot 目录下创建自动更新证书的脚本 renew_cert.sh,内容如下:
#!/bin/bash
WEBDIR="$1"
LIST=('filterinto.com' 'www.filterinto.com')
LED_LIST=()
WWW_ROOT=/usr/share/nginx/html
for domain in ${LIST[@]};do
docker run \
--rm \
-v ${WEBDIR}/nginx/conf.crt:/etc/letsencrypt \
-v ${WEBDIR}/logs/letsencrypt:/var/log/letsencrypt \
-v ${WEBDIR}/nginx/html:${WWW_ROOT} \
certbot:1.0 \
certbot certonly --verbose --noninteractive --quiet --agree-tos \
--webroot -w ${WWW_ROOT} \
--email="nick.li@grapecity.com" \
-d "$domain"
CODE=$?
if [ $CODE -ne ]; then
FAILED_LIST+=($domain)
fi
done # output failed domains
if [ ${#FAILED_LIST[@]} -ne ];then
echo 'failed domain:'
for (( i=; i<${#FAILED_LIST[@]}; i++ ));
do
echo ${FAILED_LIST[$i]}
done
fi
在用户的家目录中执行 ./renew_cert.sh /home/nick 命令就可以生成新的证书(/home/nick 为当前用户的家目录)。生成的证书被保存在 /home/nick/nginx/conf.crt/live 目录下,以域名命名的目录下保存着该域名的证书:
然后去检查下 nginx/html 目录,发现多了一个隐藏的 .well-known 目录,这个目录就是在生成证书时创建的:
有了 SSL/TLS 证书,接下来我们就可以配置 https 站点了。
为站点配置 SSL/TLS 证书
有了 SSL/TLS 证书,接下来更新 nginx 的配置文件就可以了,更新 nginx/conf.d/default.conf 的内容如下:
upstream web{
server myweb:;
} server {
listen ;
listen [::]:;
server_name filterinto.com www.filterinto.com; location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/nginx/html;
}
location = /.well-known/acme-challenge/ {
return ;
}
return https://$server_name$request_uri;
}
server {
listen ;
listen [::]:;
server_name filterinto.com; # enable ssl
ssl on;
ssl_protocols TLSv1 TLSv1. TLSv1.;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; # config ssl certificate
ssl_certificate conf.crt/live/filterinto.com/fullchain.pem;
ssl_certificate_key conf.crt/live/filterinto.com/privkey.pem; location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/nginx/html;
}
location = /.well-known/acme-challenge/ {
return ;
}
location / {
proxy_pass http://web;
}
}
server {
listen ;
listen [::]:;
server_name www.filterinto.com; # enable ssl
ssl on;
ssl_protocols TLSv1 TLSv1. TLSv1.;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; # config ssl certificate
ssl_certificate conf.crt/live/www.filterinto.com/fullchain.pem;
ssl_certificate_key conf.crt/live/www.filterinto.com/privkey.pem; location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/nginx/html;
}
location = /.well-known/acme-challenge/ {
return ;
}
location / {
proxy_pass http://web;
}
}
然后删除容器 gateway 并用下面的脚本重新创建:
$ docker run -d \
-p : \
-p : \
-v $(pwd)/nginx/conf.d:/etc/nginx/conf.d:ro \
-v $(pwd)/nginx/conf.crt:/etc/nginx/conf.crt:ro \
-v $(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-v $(pwd)/logs/nginx:/var/log/nginx \
-v $(pwd)/nginx/html:/usr/share/nginx/html \
--restart=always \
--name=gateway \
--network=webnet \
nginx:1.14
现在就只能通过 https 来访问站点了:
自动更新证书
Let's Encrypt 提供的 SSL/TLS 证书期限只有三个月,每过三个月要手动更新一次证书也够呛的,下面我们介绍自动更新证书的方法。
其实我们的配置已经为自动化更新证书提供了最大的便利(其实是使用 docker 带来的便利),在定时任务中添加下面两条记录就可以了:
* * /home/nick/certbot/renew_cert.sh /home/nick >> /home/nick/logs/cert.log >> /home/nick/logs/cert.error.log
* * docker exec gateway nginx -s reload
每月 1 号的 0 点更新证书,一个小时后 reload nginx 的配置。
总结
Let's Encrypt 是一个非常棒的网站,对于初学者和个人来说,能够帮助我们轻松的实现 HTTPS 站点(还是免费的)!在方便的同时,其隐患也是显而易见的:既然谁都可以无门槛的获得 SSL/TLS 证书,那么非法网站也可以通过它把自己伪装成看上去合法的站点。 所以千万不要片面的认为 HTTPS 站点就是安全的!
参考:
Setting up HTTPS on Nginx using Let’s Encrypt
在 docker nginx 下使用 docker let's encrypt
How to Set Up Free SSL Certificates from Let's Encrypt using Docker and Nginx
为 docker 中的 nginx 配置 https的更多相关文章
- nginx配置https双向验证(ca机构证书+自签证书)
nginx配置https双向验证 服务端验证(ca机构证书) 客户端验证(服务器自签证书) 本文用的阿里云签发的免费证书实验,下载nginx安装ssl,文件夹有两个文件 这两个文件用于做服务器http ...
- Nginx 配置https 服务
一.HTTPS 服务 为什么需要HTTPS? 原因:HTTP不安全 1.传输数据被中间人盗用.信息泄露 2.数据内容劫持.篡改 HTTPS协议的实现 对传输内容进行加密以及身份验证 HTTPS加密校验 ...
- nginx配置https转发到tomcat(使用自签名的证书)
一.使用openSSL生成自签名的证书 1.生成RSA私钥 命令:openssl genrsa -des3 -out server.key 1024 说明:生成rsa私钥,des3算法,1024强度, ...
- RedHat 6.6下安装nginx,配置HTTPS
1.安装依赖包 yum -y install pcre-devel openssl-devel zlib-devel 2.下载nginx安装包到服务器上,当前使用版本nginx-1.15.5.tar. ...
- 解决docker中使用nginx做负载均衡时并发过高时的一些问题
# 解决docker中使用nginx做负载均衡时并发过高时的一些问题 1.问题产生原因: 由于通过nginx作为负载均衡服务,在访问并发数量达到一定量级时jmeter报错. nginx日志关键信息:a ...
- nginx 配置https并自签名证书
2016-10-28 转载请注明出处:http://daodaoliang.com/ 作者: daodaoliang 版本: V1.0.1 邮箱: daodaoliang@yeah.net 参考链接: ...
- [记录]NGINX配置HTTPS性能优化方案一则
NGINX配置HTTPS性能优化方案一则: 1)HSTS的合理使用 2)会话恢复的合理使用 3)Ocsp stapling的合理使用 4)TLS协议的合理配置 5)False Start的合理使用 6 ...
- 购买https证书以及nginx配置https
文章来源 运维公会:购买https证书以及nginx配置https 1.https的作用 https的全名是安全超文本传输协议,是在http的基础上增加了ssl加密协议.在信息传输的过程中,信息有可能 ...
- Nginx 配置 HTTPS(多域名)
平常开发要求比较低, 依然在用 HTTP, 但到了微信小程序就不行了, 腾讯和苹果都对 API 提出了 HTTPS 的要求. 尤其是苹果, 不仅要求 HTTPS, 还要求 TLS 协议版本要在 1.2 ...
随机推荐
- Address already in use: make_sock: could not bind to address 0.0.0.0:80
网上查了很多资料都是要杀进程,但是并没有找到占用的进程. 最后解决的方案是在apache配置文件下,去掉Listen 80 即可
- 显存充足,但是却出现CUDA error:out of memory错误
之前一开始以为是cuda和cudnn安装错误导致的,所以重装了,但是后来发现重装也出错了. 后来重装后的用了一会也出现了问题.确定其实是Tensorflow和pytorch冲突导致的,因为我发现当我同 ...
- Java和js操作json
Js中 Json字符串转json对象 //将json格式的字符串转为json对象 var t = JSON.parse('{"name":123}'); alert(t.name) ...
- XML语言2.约束
三.XML的约束 目的:编写一个文件用来约束另一个xml文件的书写规范. DTD 用来约束xml的文件格式,保证这个文件是有效的. 内部DTD:所有的约束都是直接定义在xml文件中的 内部的 DOCT ...
- 手动安装OpenCV下的IPP加速库
写在前面 安装opencv的时候,往往会卡在这里: IPPICV: Download: ippicv_2019_lnx_intel64_general_20180723.tgz 其实就是墙的原因,然后 ...
- TCPDF说明文档
TCPDF说明文档 一.首先调用TCPDF文件 require_once('tcpdf.php'); 二.实例化TCPDF类 页面方向(P =肖像,L =景观).测量(mm).页面格式 $pdf = ...
- 大数相加 Big Num
代码: #include<stdio.h>#include<algorithm>#include<iostream>#include<string.h> ...
- ASP.NET Core知多少(6):VS Code联调Angular + .NetCore
ASP.NET Core知多少系列:总体介绍及目录 1. 引言 最近在看<程序员的成长课>,讲到程序员如何构建技能树,印象深刻.作为一名后台开发的程序员,深感技能单一,就别说技能树了.作为 ...
- javascript 省市区三级联动 附: json数据
html: <label> <span>购买地址</span> <select name="PurchaseProvince" style ...
- &和&&的共同点和区别、Java字符含义和Java创建对象的几种方式
一.&和&&的共同点和区别 1.&和&&的联系(共同点): &和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定. 操 ...