如何在 Nginx 中为自定义位置设置双向 SSL?

How to set up two-way SSL in Nginx for custom location?

我有一个 rails 4 项目,其中有一些 API。

此项目在 nginx v.1.6.3https 的生产环境下运行。

Nginx 配置:

upstream app {
    # Path to Unicorn SOCK file, as defined previously
    server unix:/tmp/unicorn.my_domain.sock fail_timeout=0;
}

server {
       listen         80;
       server_name    my_domain.com;
       return         301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;

    ssl_certificate /etc/nginx/ssl/public.crt;
    ssl_certificate_key /etc/nginx/ssl/private.rsa;    

    server_name my_domain.com;

    root /var/www/current;

    location /assets {
        root /var/www/current/public;
        gzip_static on;
        expires max;
        add_header Cache-Control public;
    }

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

问题

API 请求(POST /api/some_path/create 等)应使用双向 SSL 进行保护。

只有一项服务会使用此 API(只有 1 个客户端有一个证书)

问题

  1. nginx 可以处理 two-way SSL 吗?
  2. two-way SSL 应该在 nginx 层上实现,而不是在网络应用程序逻辑中。我说得对吗?
  3. 如何设置 nginx 以捕获向 /api/... url 发送请求的客户端并使用 two-way SSL 对其进行身份验证?

我只需要一个基本示例,以了解它应该如何工作。

  1. 是(参见 ssl_client_certificate and ssl_verify_client 指令)。
  2. 取决于您的应用程序,但在这种情况下,您只需要验证证书是否由某个 CA 签名,这是正确的。
  3. 您需要创建一个 CA 和一个由所述 CA 签名的客户端证书,并使用该 CA 在服务器端验证客户端证书。

    现在,您需要考虑的是如何解决 ssl_client_certificate and ssl_verify_client 指令不支持在 location 块中使用的问题(例如,它们只能在 http 或 server 块中使用) ).

    我建议为 API 创建一个自己的子域(例如 api.my_domain.com)并使用该地址从服务访问 API。

示例配置:

server {
    listen 443 ssl;

    ssl_certificate /etc/nginx/ssl/public.crt;
    ssl_certificate_key /etc/nginx/ssl/private.rsa;

    ssl_client_certificate /etc/nginx/ssl/client_ca.pem;
    ssl_verify_client on;

    server_name api.my_domain.com;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app/api;
    }
}

This example 带您进入相互认证的世界。本教程将引导您完成使用 NGINX 服务器配置双向安全并连接网站的步骤。因此,我假设您对上述技术以及使用 Bash 和 Docker.

有一定的了解
┌─────────┐       ┌─────────┐       ┌─────────┐       ┌─────────┐
│         │       │         │       │         │       │         │
│ Browser ├──────►│ nginx 1 ├──────►│ nginx 2 ├──────►│ Website │
│         │ HTTPS │         │ mTLS  │         │ HTTPS │         │
└─────────┘       └─────────┘       └─────────┘       └─────────┘