cgi 지원

10746 단어 nginx cgi
nginx 는 천성적으로 cgi 를 지원 하지 않 기 때문에 nginx 도 cgi 방면 의 빈틈 이 없어 안전성 을 높 였 다.즉, nginx 는 외부 실행 가능 한 프로그램 을 직접 실행 할 수 없습니다.nginx 는 cgi 를 지원 하지 않 지만 fastCGI 를 지원 합 니 다.따라서 cgi 를 지원 하기 위해 perl fcgi 를 설치 하 는 것 을 고려 할 수 있 습 니 다.
    ● perl fcgi 설치

[root@localhost ~]# cd /usr/local/
[root@localhost /usr/local]# wget http://www.cpan.org/modules/by-module/FCGI/FCGI-0.67.tar.gz
[root@localhost /usr/local]# tar -xzxf FCGI-0.67.tar.gz
[root@localhost /usr/local]# cd FCGI-0.67
[root@localhost /usr/local/FCGI-0.67]# cd FCGI-0.67
[root@localhost /usr/local/FCGI-0.67]# perl Makefile.PL
[root@localhost /usr/local/FCGI-0.67]# make && make install


    ● FCGI - ProcManager 설치

[root@localhost ~]# cd /usr/local/
[root@localhost /usr/local]# wget http://search.cpan.org/CPAN/authors/id/B/BO/BOBTFISH/FCGI-ProcManager-0.24.tar.gz
[root@localhost /usr/local]# tar -xzxf FCGI-ProcManager-0.24.tar.gz
[root@localhost /usr/local]# cd FCGI-ProcManager-0.24
[root@localhost /usr/local/FCGI-ProcManager-0.24]# cd FCGI-0.67
[root@localhost /usr/local/FCGI-ProcManager-0.24]# perl Makefile.PL
[root@localhost /usr/local/FCGI-ProcManager-0.24]# make && make install


        준비 작업 이 끝나 면 nginx 가 cgi 여행 을 지원 할 수 있 습 니 다.
        1. perl 로 daemon 프로그램 을 써 서 cgi 파일 을 처리 합 니 다.
        다음은 perl 로 쓴 daemon 프로그램 입 니 다. cgiwrap - fcgi. pl 이 라 고 명명 되 어 / usr / local / bin 에 넣 습 니 다.이 perl 코드 의 36 번 째 줄 과 37 번 째 줄 은 모두 perl CGI 의 요청 을 감청 하 는 것 을 표시 합 니 다.그 중:
        127.0.0.1: 8999 는 TCP / IP 프로 토 콜 응답 요청 을 표시 합 니 다.
        /var / run / nginx / giwrap - dispatch. sock 은 유 닉 스 소켓 을 사용 하여 CGI 요청 에 응답 하 는 것 을 표시 합 니 다.
        우리 의 예제 에 서 는 유 닉 스 socket 방식 으로 CGI 요청 에 응답 할 것 입 니 다.

#!/usr/bin/perl -w
use FCGI;
use Socket;
use FCGI::ProcManager;
sub shutdown { FCGI::CloseSocket($socket); exit; }
sub restart  { FCGI::CloseSocket($socket); &main; }
use sigtrap 'handler', \&shutdown, 'normal-signals';
use sigtrap 'handler', \&restart,  'HUP';
require 'syscall.ph';
use POSIX qw(setsid);

#&daemonize; we don't daemonize when running under runsv
#this keeps the program alive or something after exec'ing perl scripts
END()   { }
BEGIN() { }
{
    no warnings;
    *CORE::GLOBAL::exit = sub { die "fakeexit
rc=" . shift() . "
"; }; }; q{exit}; if ($@) { exit unless $@ =~ /^fakeexit/; } &main; sub daemonize() { chdir '/' or die "Can't chdir to /: $!"; defined( my $pid = fork ) or die "Can't fork: $!"; exit if $pid; setsid() or die "Can't start a new session: $!"; umask 0; } sub main { #$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #use IP sockets #$socket = FCGI::OpenSocket( "/var/run/nginx/cgiwrap-dispatch.sock", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx' folder!! #foreach $item (keys %ENV) { delete $ENV{$item}; } $proc_manager = FCGI::ProcManager->new( {n_processes => 5} ); $socket = FCGI::OpenSocket( "/var/run/nginx/cgiwrap-dispatch.sock", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx' folder!! $request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket, &FCGI::FAIL_ACCEPT_ON_INTR ); $proc_manager->pm_manage(); if ($request) { request_loop() } FCGI::CloseSocket($socket); } sub request_loop { while ( $request->Accept() >= 0 ) { $proc_manager->pm_pre_dispatch(); "cgiwrap-fcgi.pl" [dos] 164L, 6275C print STDERR $errbytes; } if ($!) { $err = $!; die $!; vec( $rin, fileno(PARENT_ERR), 1 ) = 0 unless ( $err == EINTR or $err == EAGAIN ); } } if ($r2) { while ( $bytes = read( CHILD_O, $s, 4096 ) ) { print $s; } if ( !defined($bytes) ) { $err = $!; die $!; vec( $rin, fileno(CHILD_O), 1 ) = 0 unless ( $err == EINTR or $err == EAGAIN ); } } last if ( $e1 || $e2 ); } close CHILD_RD; close PARENT_ERR; waitpid( $pid, 0 ); } else { foreach $key ( keys %req_params ) { $ENV{$key} = $req_params{$key}; } # cd to the script's local directory if ( $req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/]+$/ ) { chdir $1; } close(PARENT_WR); #close(PARENT_ERR); close(STDIN); close(STDERR); #fcntl(CHILD_RD, F_DUPFD, 0); syscall( &SYS_dup2, fileno(CHILD_RD), 0 ); syscall( &SYS_dup2, fileno(CHILD_ERR), 2 ); #open(STDIN, "<&CHILD_RD"); exec( $req_params{SCRIPT_FILENAME} ); die("exec failed"); } } else { print("Content-type: text/plain\r
\r
"); print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.
"; } } }

    2. / var / run / nginx / giwrap - dispatch. sock 관련
        cgiwrap - dispatch. sock 파일 은 CGI 요청 에 응답 하 는 데 사 용 됩 니 다.실제로 파일 이름 은 / var / run / ngin 에 없 을 수도 있 습 니 다.CGI 가 요청 한 파일 을 처리 하 는 것 은 완전히 자유롭다.물론, 우 리 는 / var / run / nginx / cgwrap - dispatch. sock [을 예 로 들 어 설명 합 니 다.
        우리 기계 에는 / var / run / nginx 와 같은 디 렉 터 리 가 존재 하지 않 습 니 다. mkdir 명령 을 통 해 이러한 계층 구조의 디 렉 터 리 를 만 들 수 있 습 니 다. / cgiwrap - dispatch. sock 파일 은 touch / cgiwrap - dispatch. sock 을 통 해 빈 파일 을 만 들 면 됩 니 다.
        nginx. cong 에서 설명 한 user 의 사용자 와 그룹 이 다음 과 같은 권한 을 가지 고 있 는 지 확인 하 십시오.
                / var / run / nginx 에 W 권한 이 있 습 니 다.
                cgiwrap - dispatch. sock 에 W 권한 이 있 습 니 다.
    3. 배경 에서 cgiwrap - fcgi. pl 실행

#        cgiwrap-fcgi.pl      
[root@localhost ~]# /usr/local/bin/cgiwrap-fcgi.pl
Useless use of a constant in void context at ./cgiwrap-fcgi.pl line 20.
FastCGI: manager (pid 2452): initialized
FastCGI: server (pid 2453): initialized
FastCGI: manager (pid 2452): server (pid 2453) started
FastCGI: manager (pid 2452): server (pid 2454) started
FastCGI: server (pid 2454): initialized
FastCGI: server (pid 2455): initialized
FastCGI: manager (pid 2452): server (pid 2455) started
FastCGI: server (pid 2456): initialized
FastCGI: manager (pid 2452): server (pid 2456) started
FastCGI: server (pid 2457): initialized
FastCGI: manager (pid 2452): server (pid 2457) started
FastCGI: manager (pid 2452): server (pid 2453) exited with status 2304
FastCGI: server (pid 5456): initialized
FastCGI: manager (pid 2452): server (pid 5456) started
FastCGI: manager (pid 2452): server (pid 2454) exited with status 2304
FastCGI: manager (pid 2452): server (pid 9471) started
FastCGI: server (pid 9471): initialized

        cgiwrap - fcgi. pl 을 실행 하면 콘 솔 에서 로 그 를 출력 합 니 다. 이 스 크 립 트 가 정상적으로 실행 되 고 있 는 지 확인 합 니 다. 나중에 로 그 를 출력 하지 않 으 려 면 cgiwrap - fcgi. pl 을 실행 할 수 있 습 니 다.

#        cgiwrap-fcgi.pl       
[root@localhost ~]# /usr/local/bin/cgiwrap-fcgi.pl > /dev/null 2>&1 &

#        cgiwrap-fcgi.pl                
#    /etc/rc.local   ,      :
/usr/local/bin/cgiwrap-fcgi.pl > /dev/null 2>&1 & 

    4. 웹 루트 디 렉 터 리 에 test. cgi 를 만들어 테스트 합 니 다.
        웹 디 렉 터 리 와 디 렉 터 리 를 / home / git 로 설정 하고 test. cgi 파일 을 만 들 며 ngix. cong 에서 설명 한 user 의 사용자 와 그룹 이 test. cgi 에 대한 실행 가능 한 권한 을 갖 도록 합 니 다.

[root@localhost ~]# vi /home/git/test.cgi
#!/usr/bin/perl
print "Content-type: text/html

"; print "Hello, world.";

    5. nginx. conf 에서 다음 설정 을 합 니 다.

location ~ .*\.cgi$ {
    fastcgi_pass   unix:/var/run/nginx/cgiwrap-dispatch.sock;
    fastcgi_index  index.cgi;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;
    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  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 이 설정 을 하나의 파일 로 독립 시 킬 수 있 습 니 다. 예 를 들 어 fastcgi params. conf 와 같은 다음 include 명령 을 통 해 포함 시 킬 수 있 습 니 다.
        여기까지 nginx 가 cgi 를 지원 하도록 했 습 니 다. 접근 할 수 있 습 니 다.http://localhost/test.cgi 설정 이 성 공 했 는 지 시험 해 보 세 요.

좋은 웹페이지 즐겨찾기