基于客户端证书的Nginx授权

jay*_*mar 3 ssl authorization nginx

我在nginx中启用了SSL,并在浏览器中启用了客户端证书。有了这个,我就能通过HTTPS通过端口443访问我的网站。

我现在正在寻找的是使用有关客户端的此信息来允许访问API(URL)的不同部分,但拒绝访问其他部分。我可以使用IP地址和ngx_http_access_module进行以下操作:

location /allowed/loc {
    allow 192.168.1.0/24;
}

location /protected/loc {
    allow 192.168.1.10;
    deny all;
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是一种基于客户端证书而不是IP地址的允许/拒绝的方法,即类似于以下内容:

location /authorize/by/cert {
    allow client-cert-serial;
    deny all;
}
Run Code Online (Sandbox Code Playgroud)

在nginx中有没有办法做到这一点,还是我需要使用其他东西?还是我在想这一切错了?

谢谢您的帮助。

Dmi*_*sIr 5

对于访问检查,可以使用if伪指令和ssl模块变量:$ssl_client_s_dn,$ssl_client_serial。例

location /not/for/jhon/ {
   if ($ssl_client_s_dn ~ Jhon) {
      return 403;
   }
}
Run Code Online (Sandbox Code Playgroud)

维护允许通过认证的map指令列表的好方法。例

map $ssl_client_s_dn $ssl_access {
default 0;
01 1;
02 1;
}

server {
  ...
  location /authorize/by/cert {
     if ($ssl_access = 0) {
        return 403;
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

或者,规则可能更复杂

map $ssl_client_s_dn $ssl_access {
default "";
01 -a-b-c-;
02 -b-e-;
}

server {
  ...
  location /authorize/by/cert/a {
     if ($ssl_access !~ -a-) {
        return 403;
     }
  }

  location /authorize/by/cert/b {
     if ($ssl_access !~ -b-) {
        return 403;
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

但是请在https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/之前阅读本文。if仅与return或rewrite ... last;指令一起使用。