前言
Nginx反向代理速度快,可以自定义各种转发规则,可以说是站长的好朋友。
acme.sh支持多个域名服务商的证书生成,让站长免费获取到ssl带来的安全性,也是不可或缺的好伙伴。
本文虾哥将本着DRY原则,让站长不需要记住部署nginx和acme的若干命令,快速搭建起安全实用的ssl反向代理服务器。
1. 准备
使用docker部署程序省去安装各种语言运行环境的麻烦,但docker本身还是需要准备一下。
下面介绍在centos7系统下安装docker 和 docker-compose的步骤。其他系统可以自行查找相关文档。
##1.1 安装docker
sudo yum install docker -y
安装完成后启动docker
sudo systemctl start docker
sudo systemctl enable docker
##1.2安装docker-compose
docker-compose是python包,通过docker-compose,docker运行镜像的各种配置可以直接写入文件,重启和修改都非常容易。
# 通过yum安装pip官方没有直接提供rpm包,可以通过epel-release库安装
sudo yum install epel-release
sudo yum isntall python2-pip
sudo pip isntall docker-compose
这样就安装完成了,运行docker-compose命令行
docker-compose --help
1.3 准备程序运行目录
在决定运行docker-compose的任意路径创建好目录,以后我们程序运行相关的文件都保存在该路径下,如/app
mkdir /app
cd /app
在运行目录下创建nginx
2. acme.sh 申请证书并定期更新
2.1 acme.sh 申请证书
在程序运行路径下创建docker-compose.yml,通过docker-compose启动docker镜像的所有参数信息都会写入到该文件中
# /app/docker-compose.yml
version: '3'
services:
acme.sh:
image: neilpang/acme.sh
volumes:
- "./acme.sh:/acme.sh:z"
environment:
- CF_Key="xxx"
- CF_Email="yyy"
command: daemon
本文以cloudflare申请证书为例,其他域名服务商可以根据要求将相关的身份信息写入environment环境变量
运行acme生成证书
sudo docker-compose run acme.sh --issue --dns dns_cf -d xxx.example.com
域名和dns服务商参数根据实际情况自行修改。要使用cloudflare创建证书,需要把域名的ns指向到cloudflare并在cloudflare网站上申请管理员的key。运行完成后证书会保存在.acme.sh/xxx.example.com/文件夹下。
2.2 自动更新证书
这样免费申请的证书 只有3个月的有效期,通过command: daemon参数运行后,该进程会定期自动去域名服务商更新证书,再也不用为证书过期苦恼了。
docker-compose up -d
2. Nginx
Nginx提供了官方镜像
直接使用官方镜像就可以启动nginx服务。但要想根据我们的要求运行反向代理,还得编写一个配置文件。
创建/app/nginx/conf文件夹
mkdir -p /app/nginx/conf
在该文件夹下创建proxy.conf文件
# /app/nginx/conf/proxy.conf
server {
listen 80;
server_name xxx.example.com;
return 301 https://$host;
}
server {
listen 443 ssl;
server_name xxx.example.com;
ssl_certificate /etc/nginx/certs/$server_name/fullchain.cer;
ssl_certificate_key /etc/nginx/certs/$server_name/$server_name.key;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://realserver;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
这个配置启动了HSTS,强制使用https,增强了web服务的安全性。
把xxx.example.com替换成实际的域名。 realserver是反代对应的真实服务器地址。
要禁用直接用ip地址访问可以增加一个server节:
server {
listen 80 default_server;
return 444;
}
nginx在docker-compose中配置如下:
nginx:
image: nginx
ports:
- "80:80"
- "443:443"
volumes:
- "./acme.sh:/etc/nginx/certs"
- "./nginx/conf:/etc/nginx/conf.d:z"
- "./nginx/log/:/var/log/nginx/:z"
environment:
- ENV=production
通过docker-compose启动一组容器
docker-compose up -d
大功告成。
最后完整版的docker-compose文件如下:
# /app/docker-compose.yml
version: '3'
services:
acme.sh:
image: neilpang/acme.sh
volumes:
- "./acme.sh:/acme.sh:z"
environment:
- CF_Key="xxx"
- CF_Email="yyy"
command: daemon
nginx:
image: nginx
network_mode: host
ports:
- "80:80"
- "443:443"
volumes:
- "./acme.sh:/etc/nginx/certs"
- "./nginx/conf:/etc/nginx/conf.d:z"
- "./nginx/log/:/var/log/nginx/:z"
environment:
- ENV=production