nginx 反向代理及 https 证书配置
author: yunqimg(ccxtcxx0)
1. 编译安装nginx
- 从官网下载 nginx源码, 并编译安装.
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
- 编译时注意添加 SSL 模块, 否则配置 https 时会失败.
- 安装完成后, nginx 程序默认保存在 /usr/local/nginx/sbin/ 目录下, 启动 nginx 命令如下
/usr/local/nginx/sbin/nginx -c /home/nginx/nginx.conf
推荐使用指定 配置文件路径方式启动, 这样在 docker 方式部署时方便修改配置文件.
2. 反向代理配置
- 基本配置范例:
## Basic reverse proxy server ##
upstream backend {
server 127.0.0.1:8080; # local server
}
server {
location / {
proxy_pass http://backend;
}
}
upstream 节点记录后端服务器地址, backend 是节点名称.
Nginx 反向代理的指令不需要新增额外的模块,默认自带 proxy_pass 指令,只需要修改配置文件就可以实现反向代理。
- Nginx 反向代理模板
## Basic reverse proxy server ##
upstream tornado {
server 127.0.0.1:8080; # local server
}
server {
listen 80;
server_name example.com;
access_log /home/nginx/log/access.log main;
error_log /home/nginx/log/error.log;
root html;
index index.html index.htm index.php;
## send request back to tornado ##
location / {
proxy_pass http://tornado;
# Proxy Settings
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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_max_temp_file_size 0;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
nginx反向代理配置模块, 推荐使用独立的文件保存配置, 例如: 将上面提到的模板保存 到tornado.conf 文件中, 再在 nginx.conf 文件中添加 include /home/nginx/tornado.conf;
即可将两个配置文件关联.
添加位置如下
http {
include mime.types;
default_type application/octet-stream;
# xxx
# xxx
# ...
include /home/nginx/tornado.conf;
}
如何获取HTTPS证书
详情说明请参考 NGINX 配置 HTTPS 服务器
主要参考 使用 OpenSSL 生成 SSL Key 和 CSR 文件
这一段
HTTPS 基础配置
要开启 HTTPS 服务,在配置文件信息块(server block),必须使用监听命令 listen 的 ssl 参数和定义服务器证书文件和私钥文件,如下所示
server {
# ssl参数
listen 443 ssl;
server_name example.com;
# 证书文件
ssl_certificate example.com.crt;
# 私钥文件
ssl_certificate_key example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
#...
}
example.com.crt 和 example.com.key 可以是任意名称, 只要配置文件与实际文件名对应即可.
若只填写证书文件和私钥文件的文件名无法正常工作, 可尝试填写完整文件路径. 如: ssl_certificate /home/nginx/example.com.crt
证书文件会作为公用实体發送到每台连接到服务器的客戶端,私钥文件作为安全实体,应该被存放在具有一定权限限制的目录文件,并保证 Nginx 主进程有存取权限。
私钥文件也有可能会和证书文件同放在一個文件中,如下面情況:
ssl_certificate www.example.com.cert;
ssl_certificate_key www.example.com.cert;
这种情況下,证书文件的的读取权限也应该加以限制,尽管证书和私钥存放在同一个文件里,但是只有证书会被发送到客戶端
命令 ssl_protocols 和 ssl_ciphers 可以用来限制连接只包含 SSL/TLS 的加強版本和算法,默认值如下
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
加强 HTTPS 安全性
HTTPS 基础配置采取的默认加密算法是 SHA-1,这个算法非常脆弱,安全性在逐年降低,在 2014 年的时候, Google 官方博客就宣布在 Chrome 浏览器中逐渐降低 SHA-1 证书的安全指示,会从 2015 年起使用 SHA-2 签名的证书,可参阅 Rabbit_Run 在 2014 年发表的文章:《为什么Google急着杀死加密算法SHA-1》
为此,主流的 HTTPS 配置方案应该避免 SHA-1,可以使用 迪菲-赫尔曼密钥交换(D-H,Diffie–Hellman key exchange)方案。
首先在目录 /etc/ssl/certs 运行以下代码生成 dhparam.pem 文件
openssl dhparam -out dhparam.pem 2048
然后加入 Nginx 配置
#优先采取服务器算法
ssl_prefer_server_ciphers on;
#使用DH文件
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#定义算法
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
如果服务器夠強大,可以使用更为复杂的 4096 位进行加密。
一般情況下还应该加上以下几个增强安全性的命令
#减少点击劫持
add_header X-Frame-Options DENY;
#禁止服务器自动解析资源类型
add_header X-Content-Type-Options nosniff;
#防XSS攻击
add_header X-Xss-Protection 1;
这几个安全命令在 Jerry Qu 大神的文章《一些安全相关的HTTP响应头》有详细的介紹。
优化后的综合配置
worker_processes auto;
http {
#配置共享会话缓存大小,视站点访问情况设定
ssl_session_cache shared:SSL:10m;
#配置会话超时时间
ssl_session_timeout 10m;
server {
listen 443 ssl;
server_name www.example.com;
#设置长连接
keepalive_timeout 70;
#证书文件
ssl_certificate www.example.com.crt;
#私钥文件
ssl_certificate_key www.example.com.key;
#优先采取服务器算法
ssl_prefer_server_ciphers on;
#使用DH文件
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#定义算法
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
#减少点击劫持
add_header X-Frame-Options DENY;
#禁止服务器自动解析资源类型
add_header X-Content-Type-Options nosniff;
#防XSS攻擊
add_header X-Xss-Protection 1;
#...
强制使用 HTTPS
为了兼容原来80端口的HTTP方式的访问,可以将80端口的访问请求全部转发到443端口上,在 upstream 与 server 之间增加配置如下
## your-domain.com ##
server {
listen 80;
server_name your-domain.com;
location = / {
rewrite ^/(.*) https://your-domain.com/$1 permanent; # force redirect http to https
}
location / {
rewrite ^/(.*) https://your-domain.com/ permanent; # force redirect http to https
}
}
参考
https://www.cnblogs.com/ghjbk/p/6744131.html
HttpUpstream-Nginx中文文档
nginx反向代理原理和配置讲解
nginx反向代理
single_http_https_server
Nginx配置upstream实现负载均衡
Nginx安装部署之反向代理配置与负载均衡
Nginx 配置 HTTPS 服务器
Nginx+Https配置
一些安全相关的HTTP响应头
nginx强制使用https访问(http跳转到https)
Nginx配置HTTPS
nginx的location配置详解
解决Nginx报错The plain HTTP request was sent to HTTPS port
The plain HTTP request was sent to HTTPS port
SSL For Free网站获取Let's Encrypt免费SSL证书