nagios+nginx从环境搭建到配置
nagios是一个开源免费的系统监控工具,官网地址
截止2011-07-27 nagios的最新版本是3.x,基于c语言编写,并提供了一个基于php和cgi的web管理界面
环境搭建
nagios需要一个web容器+php的运行环境,由于现在的公司统一使用nginx作为web容器,在这里我选择了nginx+php
nginx官网地址为
php官网地址为
如果对于nagios的web界面,需要根据用户配置相应的访问权限的话,那还得安装一个apache,没别的用途,就是用htpassword生成账户信息。
apache官网地址
我所准备的jar包如下,其中spawn-fcgi是用于nginx重定向到php用的
lighttpd-1.4.28.tar.gz
nginx-1.0.5.tar.gz
php-5.3.6.tar.gz
spawn-fcgi-1.6.2.tar.gz
安装nginx
tar nginx-1.0.5.tar.gz cd nginx-1.0.5/ ./configure --prefix=/usr/local/nginx make && make install
注意--prefix是在指定软件的安装路径,可以根据个人情况自行修改
安装php之前最好参考张宴的这篇博客 http://blog.s135.com/post/297/ 安装对应的图形和xml等lib,当然稍后安装也行
tar zxvf php-5.3.6.tar.gz cd php-5.3.6/ ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc l --with-zlib --disable-debug --disable-rpath --enable-discard-path --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-force-cgi-redirect make && make install cp php.ini-dist /usr/local/php/etc/php.ini cd ../
注意,一定要带上--enable-fastcgi --enable-force-cgi-redirect,如果执行 ./configure时 提示缺少某个包,比如zlib,gd等等,安装上即可
解压缩并安装 spawn-fcgi,与张宴博客不同的是,在我写这篇博客时spawn-fcgi已经作为单独的包提供使用了
tar spawn-fcgi-1.6.2.tar.gz cd spawn-fcgi-1.6.2/ ./configure --prefix=/usr/local/spawn-fcgi make && make install
然后仅仅是把spawn-fcgi这个文件copy去php的bin目录下,为什么仅仅只要一个文件呢?好吧,我也不知道。
cp spawn-fcgi /usr/local/php/bin chmod +x /usr/local/php/bin/spawn-fcgi
启动php cgi进程
/usr/local/php/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -C 250 -u www -f /usr/local/php/bin/php-cgi
这样一来环境就搭建的差不多了,这中间容易出问题的就是php安装的时候可能会报缺某些工具包
安装nagios及其插件nagios-plugin
tar nagios-3.2.3.tar.gz cd nagios-3.2.3/ ./configure --prefix=/usr/local/nagios --with-gd --with-libpng --with-libjpeg make && make install
注意,在安装gd,libpng,libjpeg时还需要安装对应的devel包才行,即gd-devel,libpng-devel,libjpeg-devel
tar nagios-plugins-1.4.15.tar.gz cd nagios-plugins-1.4.15/ ./configure --prefix=/usr/local/nagios --with-gd --with-libpng --with-libjpeg make && make install
安装fast-cgi
tar FCGI-ProcManager-0.19.tar.gz cd FCGI-ProcManager-0.19/ ./configure --prefix=/usr/local/fcgi make && make install
在很多nginx+nagios的搭建教程中都提到一个 nginx-fcgi的脚本文件,下载地址是 但当我写这篇博客时该地址已经失效了,脚本文件作为附件奉上
然后启动fcgi
./nginx-fcgi -l /usr/local/logs/nginx-fcgi.log -pid /tmp/nginx-fcgi.pid -S /tmp/nginx-fcgi.sock
注意, -pid用于指定nginx-fcgi的进程pid, 需要执行以下命令更改运行权限
chmod 777 /tmp/nginx-fcgi.sock
配置nginx
cd /usr/local/nginx/conf vi nginx.conf
添加如下设置
server {
listen 80;
server_name nagios.test.com;
root /usr/local/nagios/share;
index index.html index.htm index.php default.html default.htm default.php;
location ~ .*\.php?$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php; include fastcgi.conf;
fastcgi_param SCRIPT_FILENAME /usr/local/nagios/share$fastcgi_script_name;
auth_basic "nagios admin";
auth_basic_user_file /usr/local/nagios/etc/nagiosAdmin.net;
}
location ~ .*\.cgi$ {
root /usr/local/nagios/sbin;
rewrite ^/nagios/cgi-bin/(.*)\.cgi /$1.cgi break;
fastcgi_pass unix:/tmp/nginx-fcgi.sock;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME /usr/local/nagios/sbin$fastcgi_script_name;
include fastcgi.conf; auth_basic "nagios admin";
auth_basic_user_file /usr/local/nagios/etc/nagiosAdmin.net;
}
location /nagios {
alias /usr/local/nagios/share;
auth_basic "nagios admin";
auth_basic_user_file /usr/local/nagios/etc/nagiosAdmin.net;
}
location ~ .*\.pl$ {
fastcgi_pass unix:/tmp/nginx-fcgi.sock;
fastcgi_index index.pl;
fastcgi_param SCRIPT_FILENAME /usr/local/nagios/sbin$fastcgi_script_name;
include fastcgi.conf;
}
}
其中 auth_basic和auth_basic_user_file用于指定该种URI的访问权限,对应的 /usr/local/nagios/etc/nagiosAdmin.net 需要事先用htpasswd命令生成后缀为.php的URI用
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
来指定给spawn-cgi处理后缀为.cgi的URI用
root /usr/local/nagios/sbin;
rewrite ^/nagios/cgi-bin/(.*)\.cgi /$1.cgi break;
fastcgi_pass unix:/tmp/nginx-fcgi.sock;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME /usr/local/nagios/sbin$fastcgi_script_name;
include fastcgi.conf;
指定给刚才启动的nginx-fcgi进程处理,注意nagios的php程序都在/usr/local/nagios/share 下,而cgi程序都在/usr/local/nagios/sbin下,别搞错路径之后就是启动nagios,nginx,在你当前机器设置host后访问 查看web内容.
nagios的配置
nagios的配置文件都在/usr/local/nagios/etc下,其中
nagios.cfg 是主配置文件
cgi.cfg 用于配置权限之类
详细配置文件在/usr/local/nagios/etc/object之内,如何配置详见
配置文件修改完毕后,执行命令
/usr/local/nagios/bin/nagios -pv /usr/local/nagios/etc/nagios.cfg
更新缓存,
详见
下面是nginx-fcgi的源码
-
#!/usr/bin/perl
-
#
-
# author Daniel Dominik Rudnicki
-
# thanks to: Piotr Romanczuk
-
# email daniel@sardzent.org
-
# version 0.4.3
-
# webpage http://www.nginx.eu/
-
#
-
# BASED @ http://wiki.codemongers.com/NginxSimpleCGI
-
#
-
#
-
# use strict;
-
use FCGI;
-
use Getopt::Long;
-
use IO::All;
-
use Socket;
-
-
sub init {
-
GetOptions( "h" => \$help,
-
"verbose!"=>\$verbose,
-
"pid=s" => \$filepid,
-
"l=s" => \$logfile,
-
"S:s" => \$unixsocket,
-
"P:i" => \$unixport) or usage();
-
usage() if $help;
-
-
print " Starting Nginx-fcgi\n" if $verbose;
-
print " Running with $> UID" if $verbose;
-
print " Perl $]" if $verbose;
-
-
# if ( $> == "0" ) {
-
# print "\n\tERROR\tRunning as a root!\n";
-
# print "\tSuggested not to do so !!!\n\n";
-
# exit 1;
-
# }
-
-
if ( ! $logfile ) {
-
print "\n\tERROR\t log file must declared\n"
-
. "\tuse $0 with option -l filename\n\n";
-
exit 1;
-
}
-
print " Using log file $logfile\n" if $verbose;
-
"\n\n" >> io($logfile);
-
addlog($logfile, "Starting Nginx-cfgi");
-
addlog($logfile, "Running with $> UID");
-
addlog($logfile, "Perl $]");
-
addlog($logfile, "Testing socket options");
-
-
if ( ($unixsocket && $unixport) || (!($unixsocket) && !($unixport)) ) {
-
print "\n\tERROR\tOnly one option can be used!\n";
-
print "\tSuggested (beacuse of speed) is usage UNIX socket -S \n\n";
-
exit 1;
-
}
-
-
if ($unixsocket) {
-
print " Daemon listening at UNIX socket $unixsocket\n" if $versbose;
-
addlog($logfile, "Deamon listening at UNIX socket $unixsocket");
-
} else {
-
print " Daemon listening at TCP/IP socket *:$unixport\n" if $verbose;
-
#
-
addlog($logfile, "Daemon listening at TCP/IP socket *:$unixport");
-
}
-
-
if ( -e $filepid ) {
-
print "\n\tERROR\t PID file $filepid already exists\n\n";
-
addlog($logfile, "Can not use PID file $filepid, already exists.");
-
exit 1;
-
}
-
-
if ( $unixsocket ) {
-
print " Creating UNIX socket\n" if $verbose;
-
$socket = FCGI::OpenSocket( $unixsocket, 10 );
-
if ( !$socket) {
-
print " Couldn't create socket\n";
-
addlog($logfile, "Couldn't create socket");
-
exit 1;
-
}
-
print " Using UNIX socket $unixsocket\n" if $verbose;
-
} else {
-
print " Creating TCP/IP socket\n" if $verbose;
-
$portnumber = ":".$unixport;
-
$socket = FCGI::OpenSocket( $unixport, 10 );
-
if ( !$socket ) {
-
print " Couldn't create socket\n";
-
addlog($logfile, "Couldn't create socket");
-
exit 1;
-
}
-
print " Using port $unixport\n" if $verbose;
-
}
-
addlog($logfile, "Socket created");
-
-
if ( ! $filepid ) {
-
print "\n\tERROR\t PID file must declared\n"
-
. "\tuse $0 with option -pid filename\n\n";
-
exit 1;
-
}
-
print " Using PID file $filepid\n" if $verbose;
-
addlog($logfile, "Using PID file $filepid");
-
-
my $pidnumber = $$;
-
$pidnumber > io($filepid);
-
print " PID number $$\n" if $verbose;
-
addlog($logfile, "PID number $pidnumber");
-
-
}
-
-
sub addzero {
-
my ($date) = shift;
-
if ($date < 10) {
-
return "0$date";
-
}
-
return $date;
-
}
-
-
sub logformat {
-
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$iddst) = localtime(time);
-
my $datestring;
-
$year += 1900;
-
$mon++;
-
$mon = addzero($mon);
-
$mday = addzero($mday);
-
$min = addzero($min);
-
$datestring = "$year-$mon-$mday $hour:$min";
-
return($datestring);
-
}
-
-
sub addlog {
-
my ($log_file, $log_message) = @_;
-
my $curr_time = logformat();
-
my $write_message = "[$curr_time] $log_message";
-
$write_message >> io($log_file);
-
"\n" >> io($log_file);
-
}
-
-
sub printerror {
-
my $message = @_;
-
print "\n Nginx FastCGI\tERROR\n"
-
. "\t $message\n\n";
-
exit 1;
-
}
-
-
sub usage {
-
print "\n Nginx FastCGI \n"
-
. "\n\tusage: $0 [-h] -S string -P int\n"
-
. "\n\t-h\t\t: this (help) message"
-
. "\n\t-S path\t\t: path for UNIX socket"
-
. "\n\t-P port\t\t: port number"
-
. "\n\t-p file\t\t: path for pid file"
-
. "\n\t-l file\t\t: path for logfile"
-
. "\n\n\texample: $0 -S /var/run/nginx-perl_cgi.sock -l /var/log/nginx/nginx-cfgi.log -pid /var/run/nginx-fcgi.pid\n\n";
-
exit 1;
-
}
-
-
-
init;
-
#
-
END() { } BEGIN() { }
-
*CORE::GLOBAL::exit = sub { die "fakeexit\nrc=".shift()."\n"; }; eval q{exit};
-
if ($@) {
-
exit unless $@ =~ /^fakeexit/;
-
} ;
-
-
# fork part
-
my $pid = fork();
-
-
if( $pid == 0 ) {
-
&main;
-
exit 0;
-
}
-
-
print " Forking worker process with PID $pid\n" if $verbose;
-
addlog($logfile, "Forking worker process with PID $pid");
-
print " Update PID file $filepid\n" if $verbose;
-
addlog($logfile, "Update PID file $filepid");
-
$pid > io($filepid);
-
print " Worker process running.\n" if $verbose;
-
addlog ($logfile, "Parent process $$ is exiting");
-
exit 0;
-
-
sub main {
-
$request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket );
-
if ($request) { request_loop()};
-
FCGI::CloseSocket( $socket );
-
}
-
-
sub request_loop {
-
while( $request->Accept() >= 0 ) {
-
# processing any STDIN input from WebServer (for CGI-POST actions)
-
$stdin_passthrough = '';
-
$req_len = 0 + $req_params{'CONTENT_LENGTH'};
-
if (($req_params{'REQUEST_METHOD'} eq 'POST') && ($req_len != 0) ){
-
while ($req_len) {
-
$stdin_passthrough .= getc(STDIN);
-
$req_len--;
-
}
-
}
-
# running the cgi app
-
if ( (-x $req_params{SCRIPT_FILENAME}) &&
-
(-s $req_params{SCRIPT_FILENAME}) &&
-
(-r $req_params{SCRIPT_FILENAME})
-
){
-
foreach $key ( keys %req_params){
-
$ENV{$key} = $req_params{$key};
-
}
-
if ( $verbose ) {
-
addlog($logfile, "running $req_params{SCRIPT_FILENAME}");
-
}
-
# http://perldoc.perl.org/perlipc.html#Safe-Pipe-Opens
-
#
-
open $cgi_app, '-|', $req_params{SCRIPT_FILENAME}, $stdin_passthrough or print("Content-type: text/plain\r\n\r\n"); print "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n"; # addlog($logfile, "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !");
-
-
if ($cgi_app) {
-
print <$cgi_app>;
-
close $cgi_app;
-
}
-
} else {
-
print("Content-type: text/plain\r\n\r\n");
-
print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";
-
addlog($logfile, "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.");
-
}
-
}
-
}