没有 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=3000 --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 2048; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; client_max_body_size 10M; include /etc/nginx/conf.d/*.conf; }
然后创建 nginx/conf.d/default.conf 文件,内容如下:
upstream web{ server myweb:3000; } server { listen 80; listen [::]:80; 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 404; } 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 80:80 -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=$"text-align: center">![]()
然后去检查下 nginx/html 目录,发现多了一个隐藏的 .well-known 目录,这个目录就是在生成证书时创建的:
有了 SSL/TLS 证书,接下来我们就可以配置 https 站点了。
为站点配置 SSL/TLS 证书
有了 SSL/TLS 证书,接下来更新 nginx 的配置文件就可以了,更新 nginx/conf.d/default.conf 的内容如下:
upstream web{ server myweb:3000; } server { listen 80; listen [::]:80; 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 404; } return 301 https://$server_name$request_uri; } server { listen 443; listen [::]:443; server_name filterinto.com; # enable ssl ssl on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 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 404; } location / { proxy_pass http://web; } } server { listen 443; listen [::]:443; server_name www.filterinto.com; # enable ssl ssl on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 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 404; } location / { proxy_pass http://web; } }然后删除容器 gateway 并用下面的脚本重新创建:
$ docker run -d -p 80:80 -p 443:443 -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 带来的便利),在定时任务中添加下面两条记录就可以了:
0 0 1 * * /home/nick/certbot/renew_cert.sh /home/nick /home/nick/logs/cert.log 2 /home/nick/logs/cert.error.log 0 1 1 * * docker exec gateway nginx -s reload每月 1 号的 0 点更新证书,一个小时后 reload nginx 的配置。
总结
Let's Encrypt 是一个非常棒的网站,对于初学者和个人来说,能够帮助我们轻松的实现 HTTPS 站点(还是免费的)!在方便的同时,其隐患也是显而易见的:既然谁都可以无门槛的获得 SSL/TLS 证书,那么非法网站也可以通过它把自己伪装成看上去合法的站点。 所以千万不要片面的认为 HTTPS 站点就是安全的!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。