本篇文章是教大家如何在docker部署的nginx上通过acme.sh安装ssl/https 证书。
由于文中例子是通过acme.sh的http验证方式生成证书,所以在此之前,必须保证你的网站能通过http访问。
目录&流程
[toc]
1.服务器环境介绍
首先介绍我当前的服务器环境。
1) 阿里云ecs,系统:centos 7
2) 使用docker-compose 配置的php+mysql+nginx环境,nginx直接拉取官方最新版本。
其中nginx容器向外映射
端口:80(http)、443(https)
路径:- /home/www:/var/www/html (项目文件路径)
- /home/docker/lnmp/nginx/conf:/etc/nginx/conf.d (配置文件)
- /home/docker/lnmp/nginx/ssl:/etc/nginx/ssl。(存放ssl证书路径)
- /home/docker/lnmp/nginx/log:/var/log/nginx。 (日志路径)
3) 域名:nuomiphp.com,http能正常访问。
以上配置只是作为参考,原理都一样,请大家因地制宜,不一定要跟我的配置相同。
2.准备工作
2.1 开通阿里云端口
默认情况下,阿里云服务器的80(http)、443(https)端口是关闭。需要在安全组和系统防火墙开启。
具体可参考文章
2.2 映射容器端口
将本地 80、3306 端口映射到nginx容器内部的 80、3306端口
2.3 挂载容器目录 (选配)
将主机中项目的目录ssl挂载nginx容器的/etc/nginx/ssl,用于存放ssl证书。如:- /home/docker/lnmp/nginx/ssl:/etc/nginx/ssl。(存放ssl证书路径)
- /home/docker/lnmp/nginx/log:/var/log/nginx。 (日志路径,方便调试)
2.4 配置顶级域名的解析
由于acme.sh的http认证过程,需要访问配置域名的顶级域名。如www.nuomiphp.com 会访问nuomiphp.com这个顶级域名。所以需要在阿里云设置顶级域名的解析。如图:
3.使用acme.sh生成证书
acme.sh有http 和 dns 两种验证安装,本文使用的是http安装。相关资料可参考acme.sh介绍
3.1 安装 acme.sh
1) 安装很简单, 一个命令:curl https://get.acme.sh | sh
2) 把 acme.sh 安装到你的 home 目录下:~/.acme.sh/
并创建 一个 bash 的 alias, 方便你的使用: alias acme.sh=~/.acme.sh/acme.sh
3.2 生成证书acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
注意:
1) 本文使用的是http方式验证生成。
2) 假设你的域名是nuomiphp.com,那边必须保证nuomiphp.com和www.nuomiphp.com能通过浏览器正常访问,因为在acme.sh认证过程中,会在网站目录下生成验证文件,格式类似:http://nuomiphp.com/.well-known/acme-challenge/_sw4yO3tQM11kAmppJaGPuZwuW4xUFlHfva5-VVgqtQ 必须保证这样的路径能访问。
成功后的截图:
3.3 copy/安装 证书
前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.
注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.
正确的使用方法是使用 --installcert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置,
例如:acme.sh --installcert -d .com \
--key-file /etc/nginx/ssl/.key \
--fullchain-file /etc/nginx/ssl/fullchain.cer \
--reloadcmd "service nginx force-reload"
前面这几段是官方的说明,但由于我们的nginx是docker里的,配置有稍微不同。
1) 前面说了,主机映射到容器的目录是/home/docker/lnmp/nginx/ssl,所以copy的证书应该都放到这都这个目录西下。
2) reloadcmd命令是设置acme.sh自动续费后重启nginx用的,由于我们的nignx是docker里运行的,需要改成docker restart lnmp_nginx_1,其中lnmp_nginx_1是容器名称,通过docker ps可查看得到
最后,修改后的命令应该是这样:acme.sh --installcert -d nuomiphp.com \
--key-file /home/docker/lnmp/nginx/ssl/nuomiphp/nuomiphp \
--fullchain-file /home/docker/lnmp/nginx/ssl/nuomiphp/fullchain.cer \
--reloadcmd "docker restart lnmp_nginx_1"
注意:这里ssl/nuomiphp是考虑到一个服务器可能有多个域名,所以我在ssl目录另建nuomiphp目录。
4.检查nginx是否安装ssl模块
由于我拉取的是官方最新nginx镜像,默认是已安装ssl模块。
大家不确定的话,可以通过docker exec it 容器ID /bin/bash进入nginx容器
然后输入命令nginx -V 查看
如果发现含有onfigure arguments:里含有 http_ssl_module说明已安装ssl模块
5.配置nginx
5.1 备份原配置
如果原来有网站的话,可以通过cp xxx.conf xxx.bx 备份
5.2 配置nginx
开启ssllisten 443 ssl;
server_name nuomiphp.com www.nuomiphp.com ww.nuomiphp.com;
root /var/www/html/nuomiphp/public;
index index.html index.htm index.php default.html default.htm default.php;
ssl_certificate /etc/nginx/ssl/nuomiphp/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/nuomiphp/nuomiphp.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
其中 ssl_certificate、ssl_certificate_key 对应上一步骤copy过来的cer和key
这是完整配置,可作参考server {
#开启ssl
listen 443 ssl;
server_name nuomiphp.com www.nuomiphp.com ww.nuomiphp.com;
root /var/www/html/nuomiphp/public;
index index.html index.htm index.php default.html default.htm default.php;
ssl_certificate /etc/nginx/ssl/nuomiphp/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/nuomiphp/nuomiphp.key;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
#开启gzip压缩
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 9;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
#日志
access_log /var/log/nginx/nuomiphp.access.log main;
error_log /var/log/nginx/nuomiphp.error.log error;
#隐藏index.php
location / {
index index.html index.htm index.php;
#主要是这一段一定要确保存在
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
break;
}
#结束
#autoindex on;
}
#php解析配置
location ~ \.php(.*)$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
#对http请求重定向到https
server {
listen 80;
server_name nuomiphp.com www.nuomiphp.com ww.nuomiphp.com;
rewrite ^(.*)$ https://$host$1 permanent;
location / {
index index.html index.htm;
}
}
配置完后,重启nginx,这是如果能通过https访问网站,则代表配置成功。
6.总结
总的来讲,由于acme.sh自动化配置,配置下来并没有复杂的操作。
主要多注意些细节,比如:
1) 443端口忘了开放
1) 顶级域名忘了解析
1) 等等等
运用点小技巧,比如
1) 在配置nginx过程中,可能需要频繁的重启nginx。这时可以通过docker exec -it 容器ID /bin/bash 命令进入容器,通过nginx -s reload来快速刷新nginx配置,好处就是快速,并且哪怕配置错了,也不会影响之前的已生效的配置。
最后,感想letsencrypt 和 acme.sh ~!为我们提供了免费的ssl方案!:clap: