ssl_client_verify上的nginx位置匹配

时间:2016-03-17 14:10:40

标签: php nginx

我正在尝试设置nginx以匹配授予条件访问权限的服务器上的某些URL(即只允许那些拥有有效客户端证书的URL访问此区域)。

现在,简单的位置块可以很好地防止未经授权的用户访问:

location ~ ^/protected/ticketing {
         if ($ssl_client_verify != SUCCESS) { return 401; }
#need treatment of php files here after SUCCESS = $ssl_client_verify ?!
}

因此,没有人可以访问/ protected / ticket / anyThingHere

BUT。 当您实际提供有效证书,并且此返回401未触发时,/ protected / chips / index.php不会被上游FPM服务器解析,而是呈现下载(即内容处置设置为默认八位字节流)。

这样做有一种优雅的方法吗?

我的上游定义为:

upstream backend {
server unix:/var/run/php5-fpm.sock;
}

PHP处理程序位置块:

location ~ [^/]\.php(/|$) {
 fastcgi_split_path_info ^(.+?\.php)(/.*)$;
 if (!-f $document_root$fastcgi_script_name){return 404;}
 fastcgi_pass backend; #pass request to the upstream
 fastcgi_index index.php;
 include fastcgi_params;
}

2 个答案:

答案 0 :(得分:1)

实际上,nginx工作人员在if使用locationconsidered evil。 可以选择在这里使用maps。例如

map $uri $secured_url {
        default false;
        "~*/secret" true;
}

map "$secured_url:$ssl_client_verify" $return_unauthorized {
        default 0;
        "true:FAILED" 1;
        "true:NONE" 1;
        "true:" 1;
}

"~*/secret"是您要保护的位置(在您的情况下将是"~/protected/ticketing")。

然后你可以在if ($return_unauthorized) { return 401; }指令级添加server

答案 1 :(得分:0)

我最终得到了嵌套的位置解决方案。它很脏,我相信必须有比这更好的解决方案。

location ~ [^/]\.php(/|$) {
# 
#... other PHP related settings 
#... other PHP related settings 
#

fastcgi_pass backend;

location ~ ^/protected/ticketing {
        #check X.509
        if ($ssl_client_verify != SUCCESS) {return 401;}

fastcgi_pass backend; #this was still mandatory even though parent (.php) block already had this directive, but w/o putting pass here PHP won't get interpreted?!

}

}