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

bma*_*ets 2 ssl configuration nginx ssl-certificate

我有一个带有一些API的Rails 4项目。

该项目与运行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;
}
Run Code Online (Sandbox Code Playgroud)

问题

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

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

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

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

小智 6

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

    现在,您需要考虑的是如何解决ssl_client_certificatessl_verify_client指令不支持在位置块中使用的问题(例如,它们只能在http或服务器块中使用)。

    我建议为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;
    }
}
Run Code Online (Sandbox Code Playgroud)