刚装好nagios,和cacti整合起来了。cacti使用的是nginx,所以现在想把nagios从apache平台上转到nginx上。

nginx需要perl cgi支持才能保证nagios的运行,所以要安装perl cgi环境

1、装PERL的FCGI模块

 
  
  1. #perl -MCPAN -e 'install FCGI' 
  2. #perl -MCPAN -e 'install FCGI::ProcManager' 

2、编写perl启动脚本,运行这个脚本生成的sock文件就是我们需要的。

 
  
  1. #vi /usr/local/bin/fastcgi.pl 

 
  
  1. #!/usr/bin/perl 
  2.  
  3. use FCGI; 
  4. #perl -MCPAN -e 'install FCGI' 
  5. use Socket; 
  6. use POSIX qw(setsid); 
  7. #use Fcntl; 
  8.  
  9. require 'syscall.ph'; 
  10.  
  11. &daemonize; 
  12.  
  13. #this keeps the program alive or something after exec'ing perl scripts 
  14. END() { } BEGIN() { } 
  15. *CORE::GLOBAL::exit = sub { die "fakeexit\nrc=".shift()."\n"; };  
  16. eval q{exit};  
  17. if ($@) {  
  18.     exit unless $@ =~ /^fakeexit/;  
  19. }; 
  20.  
  21. &main; 
  22.  
  23. sub daemonize() { 
  24.     chdir '/'                 or die "Can't chdir to /: $!"; 
  25.     defined(my $pid = fork)   or die "Can't fork: $!"; 
  26.     exit if $pid; 
  27.     setsid                    or die "Can't start a new session: $!"; 
  28.     umask 0; 
  29.  
  30. sub main { 
  31.         #$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #use IP sockets 
  32.         $socket = FCGI::OpenSocket( "/var/run/nginx/perl_cgi-dispatch.sock", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx' folder!! 
  33.         $request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket ); 
  34.         if ($request) { request_loop()}; 
  35.             FCGI::CloseSocket( $socket ); 
  36.  
  37. sub request_loop { 
  38.         while( $request->Accept() >= 0 ) { 
  39.              
  40.            #processing any STDIN input from WebServer (for CGI-POST actions) 
  41.            $stdin_passthrough =''
  42.            $req_len = 0 + $req_params{'CONTENT_LENGTH'}; 
  43.            if (($req_params{'REQUEST_METHOD'} eq 'POST') && ($req_len != 0) ){  
  44.                 my $bytes_read = 0
  45.                 while ($bytes_read < $req_len) { 
  46.                         my $data = ''
  47.                         my $bytes = read(STDIN, $data, ($req_len - $bytes_read)); 
  48.                         last if ($bytes == 0 || !defined($bytes)); 
  49.                         $stdin_passthrough .= $data; 
  50.                         $bytes_read += $bytes; 
  51.                 } 
  52.             } 
  53.  
  54.             #running the cgi app 
  55.             if ( (-x $req_params{SCRIPT_FILENAME}) &&  #can I execute this? 
  56.                  (-s $req_params{SCRIPT_FILENAME}) &&  #Is this file empty? 
  57.                  (-r $req_params{SCRIPT_FILENAME})     #can I read this file? 
  58.             ){ 
  59.         pipe(CHILD_RD, PARENT_WR); 
  60.         my $pid = open(KID_TO_READ, "-|"); 
  61.         unless(defined($pid)) { 
  62.             print("Content-type: text/plain\r\n\r\n"); 
  63.                         print "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n"; 
  64.             next; 
  65.         } 
  66.         if ($pid > 0) { 
  67.             close(CHILD_RD); 
  68.             print PARENT_WR $stdin_passthrough; 
  69.             close(PARENT_WR); 
  70.  
  71.             while(my $s = <KID_TO_READ>) { print $s; } 
  72.             close KID_TO_READ; 
  73.             waitpid($pid, 0); 
  74.         } else { 
  75.                     foreach $key ( keys %req_params){ 
  76.                        $ENV{$key} = $req_params{$key}; 
  77.                     } 
  78.                     # cd to the script's local directory 
  79.                     if ($req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/]+$/) { 
  80.                             chdir $1; 
  81.                     } 
  82.  
  83.             close(PARENT_WR); 
  84.             close(STDIN); 
  85.             #fcntl(CHILD_RD, F_DUPFD, 0); 
  86.             syscall(&SYS_dup2, fileno(CHILD_RD), 0); 
  87.             #open(STDIN, "<&CHILD_RD"); 
  88.             exec($req_params{SCRIPT_FILENAME}); 
  89.             die("exec failed"); 
  90.         } 
  91.             }  
  92.             else { 
  93.                 print("Content-type: text/plain\r\n\r\n"); 
  94.                 print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n"; 
  95.             } 
  96.  
  97.         } 

3、给文件加执行权限。

 
  
  1. chmod +x  /usr/local/bin/fastcgi.pl 

执行之前先确认/var/run/nginx/这个文件夹存在,没有mkdir /var/run/nginx/
否则执行会报错:bind/listen: 没有那个文件或目录

执行之后查看/var/run/nginx目录下是不是多了一个perl_cgi-dispatch.sock文件

4、到nginx配置文件里添加,下面是我的配置

 

 
  
  1. server 
  2.         listen 80; 
  3.         server_name nagios.zdworks.com; 
  4.         root /usr/local/nagios/share; 
  5.         index index.php;
  6. #设置编码方式,我没有加上这个的话界面部分乱码。很奇怪为什么不是全部乱码
  7.         charset utf-8; 
  8.  
  9.         location ~ .*\.(php|php5)?$ 
  10.         { 
  11.         #root /usr/local/nagios/share; 
  12.         fastcgi_pass 127.0.0.1:9000; 
  13.         fastcgi_index index.php; 
  14.         fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 
  15.         fastcgi_param HTTP_ACCEPT_LANGUAGE zh-cn; 
  16. #fastcgi_params文件以自己的路径为准,我使用了绝对路径
  17.         include      /etc/nginx/fastcgi_params; 
  18.         auth_basic "Nagios Login pain"; 
  19. #认证的文件名和路径按自己的修改
  20.         auth_basic_user_file /usr/local/nagios/etc/htpasswd.users; 
  21.         } 
  22.         location ~ .*\.cgi$ { 
  23.         root /usr/local/nagios/sbin; 
  24.         rewrite ^/nagios/cgi-bin/(.*)\.cgi /$1.cgi break; 
    #这个就是前面生成的sock文件,这个设置错误cgi文件就没有办法显示
  25.         fastcgi_pass unix:/var/run/nginx/perl_cgi-dispatch.sock; 
  26.         fastcgi_index index.cgi; 
  27.         fastcgi_param SCRIPT_FILENAME /usr/local/nagios/sbin/$fastcgi_script_name; 
  28.         include      /etc/nginx/fastcgi_params; 
  29.         fastcgi_param AUTH_USER $remote_user; 
  30.         fastcgi_param REMOTE_USER $remote_user; 
  31.         auth_basic "Nagios Login pain"; 
  32.         auth_basic_user_file /usr/local/nagios/etc/htpasswd.users; 
  33.         } 
  34.         location /nagios { 
  35.         alias /usr/local/nagios/share/; 
  36.         } 

 

 

没有装cgi前我nginx日志错误

 
  
  1. [error] 13964#0: *27 FastCGI sent in stderr: "PHP Warning:  Unexpected character in input:  ' in /usr/local/nagios/sbin/status.cgi on line 194 
  2. PHP Parse error:  syntax error, unexpected '<' in /usr/local/nagios/sbin/status.cgi on line 194" while reading response header from upstream, client: 192.168.1.180, server: nagios.com, request: "GET /nagios/cgi-bin/status.cgi?hostgroup=all&style=summary HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "nagios.com", referrer: "http://nagios.com/side.php" 

这个是cgi没有装好才会报的错。