Nginx – PHP脚本的基本httpauthentication

我添加了一个用作“cgi-bin”的PHP脚本,
组态:

location ~^/cgi-bin/.*\.(cgi|pl|py|rb) { gzip off; fastcgi_pass 127.0.0.1:9000; fastcgi_index cgi-bin.php; fastcgi_param SCRIPT_FILENAME /etc/nginx/cgi-bin.php; fastcgi_param SCRIPT_NAME /cgi-bin/cgi-bin.php; fastcgi_param X_SCRIPT_FILENAME /usr/lib/$fastcgi_script_name; fastcgi_param X_SCRIPT_NAME $fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; fastcgi_param REMOTE_USER $remote_user; } 

PHP脚本:

 <?php $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr is a file to write to ); $newenv = $_SERVER; $newenv["SCRIPT_FILENAME"] = $_SERVER["X_SCRIPT_FILENAME"]; $newenv["SCRIPT_NAME"] = $_SERVER["X_SCRIPT_NAME"]; if (is_executable($_SERVER["X_SCRIPT_FILENAME"])) { $process = proc_open($_SERVER["X_SCRIPT_FILENAME"], $descriptorspec, $pipes, NULL, $newenv); if (is_resource($process)) { fclose($pipes[0]); $head = fgets($pipes[1]); while (strcmp($head, "\n")) { header($head); $head = fgets($pipes[1]); } fpassthru($pipes[1]); fclose($pipes[1]); fclose($pipes[2]); $return_value = proc_close($process); } else { header("Status: 500 Internal Server Error"); echo("Internal Server Error"); } } else { header("Status: 404 Page Not Found"); echo("Page Not Found"); } ?> 

它认为的问题是,我不能添加基本身份validation。
只要我启用它的location ~/cgi-bin ,当我尝试查找它时,它会给我一个404错误。

我该如何解决这个问题?

我想过只限制访问我的第二台服务器,然后我通过代理添加基本的身份validation,但必须有一个更简单的解决scheme。

对不起,不好的标题,我想不出一个更好的。

编辑:我的解决scheme,感谢WerkkreWs的答案 ,最后看起来像这样:

CGI-bin.conf:

 location ~^/.*\.(cgi|pl|p<|rb) { [...] } 

vhost.conf:

 server { [...] location ~^/cgi-bin { auth_basic "Restricted"; auth_basic_user_file htusers; include cgi-bin.conf; } [...] } 

这可能是不安全的,因为cgi-bin.conf可能被意外地包含在服务器标签中(并且因此使得每个客户端能够在每个位置执行脚本),但是因为我只用了一次,我会坚持使用这个解决scheme。

我相信你的问题可能已经在这里得到解答,但是我会尽力描述我认为的问题。

首先,为了便于使用,您应该考虑将所有的fastcgi参数放在一个可供nginx访问的configuration文件中(例如/etc/nginx/conf.d/fastcgi_params)。

其次,根据你如何为auth和php部分设置位置块,你可能需要指示nginx如何在受保护位置第二次处理php文件,或者确保auth_basic指令位于与上面粘贴的位置块相同的位置块(取自上述post):

 server { listen 80; server_name my-awesome-php.site; root /path/to/root; # Normal files (blank location is OK, just means serve from root) location / { } # PHP for normal stuff location ~ \.php$ { include fastcgi.conf; fastcgi_pass 127.0.0.1:9000; } # The protected location location /protected { auth_basic "Give me codes."; auth_basic_user_file /path/to/.htpasswd; location ~ \.php$ { include fastcgi.conf; fastcgi_pass 127.0.0.1:9000; } } } 

在我的个人安装nginx我使用php-fpm和我的php脚本不限于cgi-bin所以我的configuration是非常不同的,但它可能会提供一些额外的见解。 我有基本的身份validation工作,因为我想你是期待它,虽然在下面的例子中,一个完整的虚拟主机是基本的身份validation,而不仅仅是一个文件夹:

fastcgi_params

 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200; 

基于服务器/主机的身份validation示例(已删除不相关的部分)

 server { server_name dev.foo.com; error_log /app/www/dev.foo.com/logs/error.log error; root /app/www/dev.foo.com/htdocs; index index.php index.html; auth_basic "Secret Files"; auth_basic_user_file /app/www/dev.foo.com/conf/htpasswd; location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/var/run/foo.com.sock; } location ~ /\.ht { deny all; } } 

基于位置的身份validation示例(已删除不相关的部分)

 server { server_name foo.com; error_log /app/www/foo.com/logs/error.log error; root /app/www/foo.com/htdocs; index index.php index.html; location /protected { auth_basic "Secret Files"; auth_basic_user_file /app/www/foo.com/conf/htpasswd; location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/var/run/foo.com.sock; } } location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/var/run/foo.com.sock; } location ~ /\.ht { deny all; } }