nginx 反向代理及 https 证书配置

nginx 反向代理及 https 证书配置

author: yunqimg(ccxtcxx0)

1. 编译安装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证书

上一篇:Android MultiDex应用程序在Android Studio 3.0上的低API上崩溃


下一篇:遗传算法初始种子多样性使用值编码C#