Nginx条件客户端证书身份验证

时间:2017-12-28 17:19:43

标签: ssl nginx configuration ip certificate

我正在尝试使用Nginx代理流量。我在配置中监听HTTPS时有一个服务器块,它提供有效证书并检查客户端证书(双向ssl)。此设置有效,但我希望能够允许我们的开发人员在没有客户端证书验证的情况下访问服务器(因为他们显然不会拥有它)。我之前使用的配置是:

server {
    listen       443 ssl http2 default_server;
    server_name  api.website.com;
    root         /usr/share/nginx/html;
    underscores_in_headers on;

    ssl_certificate "/etc/pki/nginx/private/ServerCert.pem";
    ssl_certificate_key "/etc/pki/nginx/private/ServerCert.pem";
    ssl_client_certificate "/etc/pki/nginx/ClientCert.pem";
    ssl_verify_client on;
    ssl_verify_depth 2;
    ssl_dhparam "/etc/pki/nginx/dhparams.pem";
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  1m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP;
    ssl_prefer_server_ciphers on;
    include /etc/nginx/default.d/*.conf;

    location /tomcat/endpoint {
        proxy_pass http://localhost:8080/tomcat-war;
        proxy_pass_request_headers      on;
    }
}

同样,这可行,但有效锁定访问权限,但我添加到客户端证书存储区的证书除外。一种解决方案是制作内部签名证书并将其添加到商店,然后分发给我们的开发人员,但我宁愿让开发人员根据IP地址排除这些检查。我设法通过将ssl_client_verify更改为可选,将位置块更改为以下内容来实现此目的:

location /tomcat/endpoint {
  set $allowed 9;
  if ($ssl_client_verify != "SUCCESS") { set $allowed 1;}
  if ($not_internal_ip) { set $allowed  "${allowed}1"; }
  if ($allowed = 11) {
      return 403;
  }
  proxy_pass http://localhost:8080/tomcat-war;
  proxy_pass_request_headers      on;
}

其中$ not_internal_ip被设置为地理区块,如下所示:

geo $not_internal_ip {
  default 0;
  10.0.0.0/8 1;
  172.16.0.0/12 1;
  192.168.0.0/16 1;
}

即使这有效,我担心逻辑依赖于如此多的if语句,在Nginx配置文件中为notoriously dangerous

如果这种在位置块中使用if语句的方式安全吗?有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以在没有使用地图

的if语句的情况下执行此操作
geo $internal_ip {
  default no;
  10.0.0.0/8 yes;
  172.16.0.0/12 yes;
  192.168.0.0/16 yes;
}

map $internal_ip$ssl_client_verify $request_allowed {
  ~* "^yes" yes;
  "noSUCCESS" yes;
  default no;
}

map $request_allowed $proxy_pass_url {
   yes  "http://localhost:8080/tomcat-war/$request_uri";
   no   "/access-denied";
}

location /tomcat/endpoint {
   proxy_pass $proxy_pass_url;
   proxy_pass_request_headers      on;
}

location /access-denied {
   return 403;
}

PS:我没有测试过上面的配置,但我过去使用过类似的方法