Nginx 配置 CGI 调用 shell

Nginx 配置 CGI 调用 shell

一. 系统环境

Distro: CentOS Linux release 7.9.2009 (Core)

Kernel: 3.10.0-1160.76.1.el7.x86_64

arch: x86_64 bits: 64

二.安装配置

1. 安装

1
2
3
yum update

yum install nginx fcgi fcgiwrap
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[localhost]#fcgiwrap -h
Usage: fcgiwrap [OPTION]
Invokes CGI scripts as FCGI.

fcgiwrap version 1.1.0

Options are:
  -f                    Send CGI's stderr over FastCGI
  						# 发送 CGI 的 错误输出到FastCGI
  -c <number>           Number of processes to prefork
  						# 预先创建进程数,可根据情况配置
  -s <socket_url>       Socket to bind toy -s help for help)
  						# 创建 socket 绑定地址,支持如下方式:
  						# unix:/path/to/socket 		for Unix sockets
						# tcp:dot.ted.qu.ad:port 	for IPv4 sockets
						# tcp6:[ipv6_addr]:port 	for IPv6 sockets

  -h                    Show this help message and exit
  -p <path>             Restrict execution to this script. (repeated options will be merged)
  						# 限制只允许指定脚本执行。(重复的选项将被合并)

Report bugs to Grzegorz Nosek <[email protected]>.
fcgiwrap home page: <http://nginx.localdomain.pl/wiki/FcgiWrap>
[localhost]#

2. 配置 fcgiwrap 开机启动

1
 vim /etc/systemd/system/fcgiwrap.service

PS: 普通用户无法写入 /var/run , 想兼顾安全, 可以自行配置 unix:/var/run/fcgiwrap.socketnginx 拥有权限的目录.,当然使用 /tmp 也是可以的 . 如下所示

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[Unit]
Description=fcgiwrap daemon
After=network.target

[Service]
User=nginx
Group=nginx
# 自行更改参数,定义 unix:/srv/www/run/fcgiwrap.socket 位置
ExecStart=/usr/sbin/fcgiwrap -f -c 2 -s unix:/srv/www/run/fcgiwrap.socket
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
1
2
3
4
# 重新加载配置
systemctl daemon reload
# 启动 fcgiwrap
systemctl start fcgiwrap.services

3. 配置 nginx

a. 检查创建 fastcgi_params

首先,在配置之前查看是否有 /etc/nginx/fastcgi_params 配置文件

如若没有,添加已下内容至 /etc/nginx/fastcgi_params

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
## /etc/nginx/fastcgi_params
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  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

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;

延伸: Docs-Link

SCRIPT_FILENAME 和 DOCUMENT_ROOT 中的 $document_root 替换成一个实际的路径,$document_root 变量是硬编码的,可能会导致 “找不到脚本 “的错误。

要使用 NGINX + 虚拟主机 + PHP ,你应该省略 SCRIPT_NAME 变量,以便让 PHP 选择正确的 DOCUMENT_ROOT 。

b. 配置nginx.conf

Port / server_name / root /

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
server {
    listen       9000;
    server_name  _;
    root         /srv/www/web/cgi/;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
    fastcgi_intercept_errors on;
    location  / {
        include             fastcgi_params;
        fastcgi_index       index;
        fastcgi_param       SCRIPT_FILENAME     "/srv/www/web/cgi/$fastcgi_script_name";
        # fastcgi_param       SCRIPT_FILENAME     "/srv/www/web/cgi/cgiinfo.sh";
        fastcgi_param       PATH_INFO           $uri;
        fastcgi_param       QUERY_STRING        $args;
        fastcgi_param       HTTP_HOST           $server_name;
        fastcgi_pass        unix:/srv/www/run/fcgiwrap.socket;
        try_files $uri  $uri/index /index  =404 ;
        }
}