nginx 反向代理及 https 证书配置

為{幸葍}努か 提交于 2021-02-09 00:07:21

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证书

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!