Nginx将客户端证书映射到REMOTE_USER以获取uWSGI并回退到基本身份验证?

Dis*_*ame 2 ssl mercurial cgi nginx uwsgi

我正在使用Nginx和uWSGI来服务Mercurial; 它通过SSL执行基本身份验证(Nginx是SSL终结器;它不会传递给Hg),但由于基本身份验证的安全性甚至超过SSL,如在包括此站点在内的各个地方所讨论的,我想允许用户也可以连接客户端证书,例如TortoiseHg支持的东西.

ssl_verify_client optional;
...
map $ssl_client_s_dn $ssl_client_s_dn_cn
{
    default "";
    ~/CN=(?<CN>[^/]+) $CN;
};
...
location /
{
    uwsgi_pass unix:/run/uwsgi/app/hgweb/socket;
    include uwsgi_params;
    uwsgi_param SERVER_ADDR $server_addr;
    uwsgi_param REMOTE_USER $ssl_client_s_dn_cn;
    #uwsgi_param REMOTE_USER $remote_user;
    #auth_basic "Mercurial repositories";
    #auth_basic_user_file /srv/hg/.htpasswd;
Run Code Online (Sandbox Code Playgroud)

}

所以我将CN视为用户名.但是,当没有客户端证书时,如何使其回退到基本身份验证(最好不是在有证书但验证失败时 - 在这种情况下只是错误)?我找到的一个例子是通过让一个单独的服务器块监听另一个端口,我想避免它:https://github.com/winne27/nginx-cert-and-basic-auth/blob/master/nginx-example .conf文件

此外,在一些例子中,我看到了以下检查location; 他们有必要吗?if ($ssl_client_verify != SUCCESS) { return 496; } if ($ssl_client_s_dn_cn !~ "^[a-z0-9]{1,10}$") { return 496; }鉴于http://wiki.nginx.org/IfIsEvil,我认为最好避免使用if.

小智 6

Nginx 1.11和1.12更改了$ ssl_client_s_dn_cn的引用.

如果你来到这里并且头疼,请试试这个正则表达式:

map $ssl_client_s_dn $ssl_client_s_dn_cn {
        default "should_not_happen";
        ~CN=(?<CN>[^/,\"]+) $CN;
}
Run Code Online (Sandbox Code Playgroud)