cp over all the bundles from kunsis bw repo
This commit is contained in:
parent
65b117b819
commit
1f73b04351
89 changed files with 3991 additions and 0 deletions
9
bundles/nginx/files/arch-override.conf
Normal file
9
bundles/nginx/files/arch-override.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
|
||||
|
||||
ExecReload=
|
||||
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)"
|
||||
|
||||
ExecStop=
|
||||
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)"
|
475
bundles/nginx/files/check_nginx_status
Normal file
475
bundles/nginx/files/check_nginx_status
Normal file
|
@ -0,0 +1,475 @@
|
|||
#!/usr/bin/env perl
|
||||
# editorconfig-checker-disable-file
|
||||
# check_nginx_status.pl
|
||||
# Author : regis.leroy at makina-corpus.com
|
||||
# Licence : GPL - http://www.fsf.org/licenses/gpl.txt
|
||||
#
|
||||
# help : ./check_nginx_status.pl -h
|
||||
#
|
||||
# issues & updates: http://github.com/regilero/check_nginx_status
|
||||
use warnings;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use LWP::UserAgent;
|
||||
use Time::HiRes qw(gettimeofday tv_interval);
|
||||
use Digest::MD5 qw(md5 md5_hex);
|
||||
use FindBin;
|
||||
|
||||
# ensure all outputs are in UTF-8
|
||||
binmode(STDOUT, ":utf8");
|
||||
|
||||
# Nagios specific
|
||||
use lib "/usr/lib/nagios/plugins";
|
||||
use utils qw($TIMEOUT);
|
||||
|
||||
# Globals
|
||||
my $Version='0.20';
|
||||
my $Name=$0;
|
||||
|
||||
my $o_host = undef; # hostname
|
||||
my $o_help= undef; # want some help ?
|
||||
my $o_port= undef; # port
|
||||
my $o_url = undef; # url to use, if not the default
|
||||
my $o_user= undef; # user for auth
|
||||
my $o_pass= ''; # password for auth
|
||||
my $o_realm= ''; # password for auth
|
||||
my $o_version= undef; # print version
|
||||
my $o_warn_a_level= -1; # Number of active connections that will cause a warning
|
||||
my $o_crit_a_level= -1; # Number of active connections that will cause an error
|
||||
my $o_warn_rps_level= -1; # Number of Request per second that will cause a warning
|
||||
my $o_crit_rps_level= -1; # Number of request Per second that will cause an error
|
||||
my $o_warn_cps_level= -1; # Number of Connections per second that will cause a warning
|
||||
my $o_crit_cps_level= -1; # Number of Connections per second that will cause an error
|
||||
my $o_timeout= 15; # Default 15s Timeout
|
||||
my $o_warn_thresold= undef; # warning thresolds entry
|
||||
my $o_crit_thresold= undef; # critical thresolds entry
|
||||
my $o_debug= undef; # debug mode
|
||||
my $o_servername= undef; # ServerName (host header in http request)
|
||||
my $o_https= undef; # SSL (HTTPS) mode
|
||||
my $o_disable_sslverifyhostname = 0;
|
||||
|
||||
my $TempPath = '/tmp/'; # temp path
|
||||
my $MaxTimeDif = 60*30; # Maximum uptime difference (seconds), default 30 minutes
|
||||
|
||||
my $nginx = 'NGINX'; # Could be used to store version also
|
||||
|
||||
# functions
|
||||
sub show_versioninfo { print "$Name version : $Version\n"; }
|
||||
|
||||
sub print_usage {
|
||||
print "Usage: $Name -H <host ip> [-p <port>] [-s servername] [-t <timeout>] [-w <WARN_THRESOLD> -c <CRIT_THRESOLD>] [-V] [-d] [-u <url>] [-U user -P pass -r realm]\n";
|
||||
}
|
||||
sub nagios_exit {
|
||||
my ( $nickname, $status, $message, $perfdata , $silent) = @_;
|
||||
my %STATUSCODE = (
|
||||
'OK' => 0
|
||||
, 'WARNING' => 1
|
||||
, 'CRITICAL' => 2
|
||||
, 'UNKNOWN' => 3
|
||||
, 'PENDING' => 4
|
||||
);
|
||||
if(!defined($silent)) {
|
||||
my $output = undef;
|
||||
$output .= sprintf('%1$s %2$s - %3$s', $nickname, $status, $message);
|
||||
if ($perfdata) {
|
||||
$output .= sprintf('|%1$s', $perfdata);
|
||||
}
|
||||
$output .= chr(10);
|
||||
print $output;
|
||||
}
|
||||
exit $STATUSCODE{$status};
|
||||
}
|
||||
|
||||
# Get the alarm signal
|
||||
$SIG{'ALRM'} = sub {
|
||||
nagios_exit($nginx,"CRITICAL","ERROR: Alarm signal (Nagios timeout)");
|
||||
};
|
||||
|
||||
sub help {
|
||||
print "Nginx Monitor for Nagios version ",$Version,"\n";
|
||||
print "GPL licence, (c)2012 Leroy Regis\n\n";
|
||||
print_usage();
|
||||
print <<EOT;
|
||||
-h, --help
|
||||
print this help message
|
||||
-H, --hostname=HOST
|
||||
name or IP address of host to check
|
||||
-p, --port=PORT
|
||||
Http port
|
||||
-u, --url=URL
|
||||
Specific URL to use, instead of the default "http://<hostname or IP>/nginx_status"
|
||||
-s, --servername=SERVERNAME
|
||||
ServerName, (host header of HTTP request) use it if you specified an IP in -H to match the good Virtualhost in your target
|
||||
-S, --ssl
|
||||
Wether we should use HTTPS instead of HTTP
|
||||
--disable-sslverifyhostname
|
||||
Disable SSL hostname verification
|
||||
-U, --user=user
|
||||
Username for basic auth
|
||||
-P, --pass=PASS
|
||||
Password for basic auth
|
||||
-r, --realm=REALM
|
||||
Realm for basic auth
|
||||
-d, --debug
|
||||
Debug mode (show http request response)
|
||||
-m, --maxreach=MAX
|
||||
Number of max processes reached (since last check) that should trigger an alert
|
||||
-t, --timeout=INTEGER
|
||||
timeout in seconds (Default: $o_timeout)
|
||||
-w, --warn=ACTIVE_CONN,REQ_PER_SEC,CONN_PER_SEC
|
||||
number of active connections, ReqPerSec or ConnPerSec that will cause a WARNING
|
||||
-1 for no warning
|
||||
-c, --critical=ACTIVE_CONN,REQ_PER_SEC,CONN_PER_SEC
|
||||
number of active connections, ReqPerSec or ConnPerSec that will cause a CRITICAL
|
||||
-1 for no CRITICAL
|
||||
-V, --version
|
||||
prints version number
|
||||
|
||||
Note :
|
||||
3 items can be managed on this check, this is why -w and -c parameters are using 3 values thresolds
|
||||
- ACTIVE_CONN: Number of all opened connections, including connections to backends
|
||||
- REQ_PER_SEC: Average number of request per second between this check and the previous one
|
||||
- CONN_PER_SEC: Average number of connections per second between this check and the previous one
|
||||
|
||||
Examples:
|
||||
|
||||
This one will generate WARNING and CRITICIAL alerts if you reach 10 000 or 20 000 active connection; or
|
||||
100 or 200 request per second; or 200 or 300 connections per second
|
||||
check_nginx_status.pl -H 10.0.0.10 -u /foo/nginx_status -s mydomain.example.com -t 8 -w 10000,100,200 -c 20000,200,300
|
||||
|
||||
this will generate WARNING and CRITICAL alerts only on the number of active connections (with low numbers for nginx)
|
||||
check_nginx_status.pl -H 10.0.0.10 -s mydomain.example.com -t 8 -w 10,-1,-1 -c 20,-1,-1
|
||||
|
||||
theses two equivalents will not generate any alert (if the nginx_status page is reachable) but could be used for graphics
|
||||
check_nginx_status.pl -H 10.0.0.10 -s mydomain.example.com -w -1,-1,-1 -c -1,-1,-1
|
||||
check_nginx_status.pl -H 10.0.0.10 -s mydomain.example.com
|
||||
|
||||
EOT
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
Getopt::Long::Configure ("bundling");
|
||||
GetOptions(
|
||||
'h' => \$o_help, 'help' => \$o_help,
|
||||
'd' => \$o_debug, 'debug' => \$o_debug,
|
||||
'H:s' => \$o_host, 'hostname:s' => \$o_host,
|
||||
's:s' => \$o_servername, 'servername:s' => \$o_servername,
|
||||
'S:s' => \$o_https, 'ssl:s' => \$o_https,
|
||||
'u:s' => \$o_url, 'url:s' => \$o_url,
|
||||
'U:s' => \$o_user, 'user:s' => \$o_user,
|
||||
'P:s' => \$o_pass, 'pass:s' => \$o_pass,
|
||||
'r:s' => \$o_realm, 'realm:s' => \$o_realm,
|
||||
'p:i' => \$o_port, 'port:i' => \$o_port,
|
||||
'V' => \$o_version, 'version' => \$o_version,
|
||||
'w:s' => \$o_warn_thresold,'warn:s' => \$o_warn_thresold,
|
||||
'c:s' => \$o_crit_thresold,'critical:s' => \$o_crit_thresold,
|
||||
't:i' => \$o_timeout, 'timeout:i' => \$o_timeout,
|
||||
'disable-sslverifyhostname' => \$o_disable_sslverifyhostname,
|
||||
);
|
||||
|
||||
if (defined ($o_help)) {
|
||||
help();
|
||||
nagios_exit($nginx,"UNKNOWN","leaving","",1);
|
||||
}
|
||||
if (defined($o_version)) {
|
||||
show_versioninfo();
|
||||
nagios_exit($nginx,"UNKNOWN","leaving","",1);
|
||||
};
|
||||
|
||||
if (defined($o_warn_thresold)) {
|
||||
($o_warn_a_level,$o_warn_rps_level,$o_warn_cps_level) = split(',', $o_warn_thresold);
|
||||
}
|
||||
if (defined($o_crit_thresold)) {
|
||||
($o_crit_a_level,$o_crit_rps_level,$o_crit_cps_level) = split(',', $o_crit_thresold);
|
||||
}
|
||||
if (defined($o_debug)) {
|
||||
print("\nDebug thresolds: \nWarning: ($o_warn_thresold) => Active: $o_warn_a_level ReqPerSec :$o_warn_rps_level ConnPerSec: $o_warn_cps_level");
|
||||
print("\nCritical ($o_crit_thresold) => : Active: $o_crit_a_level ReqPerSec: $o_crit_rps_level ConnPerSec : $o_crit_cps_level\n");
|
||||
}
|
||||
if ((defined($o_warn_a_level) && defined($o_crit_a_level)) &&
|
||||
(($o_warn_a_level != -1) && ($o_crit_a_level != -1) && ($o_warn_a_level >= $o_crit_a_level)) ) {
|
||||
nagios_exit($nginx,"UNKNOWN","Check warning and critical values for Active Process (1st part of thresold), warning level must be < crit level!");
|
||||
}
|
||||
if ((defined($o_warn_rps_level) && defined($o_crit_rps_level)) &&
|
||||
(($o_warn_rps_level != -1) && ($o_crit_rps_level != -1) && ($o_warn_rps_level >= $o_crit_rps_level)) ) {
|
||||
nagios_exit($nginx,"UNKNOWN","Check warning and critical values for ReqPerSec (2nd part of thresold), warning level must be < crit level!");
|
||||
}
|
||||
if ((defined($o_warn_cps_level) && defined($o_crit_cps_level)) &&
|
||||
(($o_warn_cps_level != -1) && ($o_crit_cps_level != -1) && ($o_warn_cps_level >= $o_crit_cps_level)) ) {
|
||||
nagios_exit($nginx,"UNKNOWN","Check warning and critical values for ConnPerSec (3rd part of thresold), warning level must be < crit level!");
|
||||
}
|
||||
# Check compulsory attributes
|
||||
if (!defined($o_host)) {
|
||||
print_usage();
|
||||
nagios_exit($nginx,"UNKNOWN","-H host argument required");
|
||||
}
|
||||
}
|
||||
|
||||
########## MAIN ##########
|
||||
|
||||
check_options();
|
||||
|
||||
my $override_ip = $o_host;
|
||||
my $ua = LWP::UserAgent->new(
|
||||
protocols_allowed => ['http', 'https'],
|
||||
timeout => $o_timeout
|
||||
);
|
||||
|
||||
if ( $o_disable_sslverifyhostname ) {
|
||||
$ua->ssl_opts( 'verify_hostname' => 0 );
|
||||
}
|
||||
|
||||
# we need to enforce the HTTP request is made on the Nagios Host IP and
|
||||
# not on the DNS related IP for that domain
|
||||
@LWP::Protocol::http::EXTRA_SOCK_OPTS = ( PeerAddr => $override_ip );
|
||||
# this prevent used only once warning in -w mode
|
||||
my $ua_settings = @LWP::Protocol::http::EXTRA_SOCK_OPTS;
|
||||
|
||||
my $timing0 = [gettimeofday];
|
||||
my $response = undef;
|
||||
my $url = undef;
|
||||
|
||||
if (!defined($o_url)) {
|
||||
$o_url='/nginx_status';
|
||||
} else {
|
||||
# ensure we have a '/' as first char
|
||||
$o_url = '/'.$o_url unless $o_url =~ m(^/)
|
||||
}
|
||||
my $proto='http://';
|
||||
if(defined($o_https)) {
|
||||
$proto='https://';
|
||||
if (defined($o_port) && $o_port!=443) {
|
||||
if (defined ($o_debug)) {
|
||||
print "\nDEBUG: Notice: port is defined at $o_port and not 443, check you really want that in SSL mode! \n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defined($o_servername)) {
|
||||
if (!defined($o_port)) {
|
||||
$url = $proto . $o_servername . $o_url;
|
||||
} else {
|
||||
$url = $proto . $o_servername . ':' . $o_port . $o_url;
|
||||
}
|
||||
} else {
|
||||
if (!defined($o_port)) {
|
||||
$url = $proto . $o_host . $o_url;
|
||||
} else {
|
||||
$url = $proto . $o_host . ':' . $o_port . $o_url;
|
||||
}
|
||||
}
|
||||
if (defined ($o_debug)) {
|
||||
print "\nDEBUG: HTTP url: \n";
|
||||
print $url;
|
||||
}
|
||||
|
||||
my $req = HTTP::Request->new( GET => $url );
|
||||
|
||||
if (defined($o_servername)) {
|
||||
$req->header('Host' => $o_servername);
|
||||
}
|
||||
if (defined($o_user)) {
|
||||
$req->authorization_basic($o_user, $o_pass);
|
||||
}
|
||||
|
||||
if (defined ($o_debug)) {
|
||||
print "\nDEBUG: HTTP request: \n";
|
||||
print "IP used (better if it's an IP):" . $override_ip . "\n";
|
||||
print $req->as_string;
|
||||
}
|
||||
$response = $ua->request($req);
|
||||
my $timeelapsed = tv_interval ($timing0, [gettimeofday]);
|
||||
|
||||
my $InfoData = '';
|
||||
my $PerfData = '';
|
||||
#my @Time = (localtime); # list context and not scalar as we want the brutal timestamp
|
||||
my $Time = time;
|
||||
|
||||
my $webcontent = undef;
|
||||
if ($response->is_success) {
|
||||
$webcontent=$response->decoded_content;
|
||||
if (defined ($o_debug)) {
|
||||
print "\nDEBUG: HTTP response:";
|
||||
print $response->status_line;
|
||||
print "\n".$response->header('Content-Type');
|
||||
print "\n";
|
||||
print $webcontent;
|
||||
}
|
||||
if ($response->header('Content-Type') =~ m/text\/html/) {
|
||||
nagios_exit($nginx,"CRITICAL", "We have a response page for our request, but it's an HTML page, quite certainly not the status report of nginx");
|
||||
}
|
||||
# example of response content expected:
|
||||
#Active connections: 10
|
||||
#server accepts handled requests
|
||||
#38500 38500 50690
|
||||
#Reading: 5 Writing: 5 Waiting: 0
|
||||
|
||||
# number of all open connections including connections to backends
|
||||
my $ActiveConn = 0;
|
||||
if($webcontent =~ m/Active connections: (.*?)\n/) {
|
||||
$ActiveConn = $1;
|
||||
# triming
|
||||
$ActiveConn =~ s/^\s+|\s+$//g;
|
||||
}
|
||||
|
||||
|
||||
# 3 counters with a space: accepted conn, handled conn and number of requests
|
||||
my $counters = '';
|
||||
my $AcceptedConn = 0;
|
||||
my $HandledConn = 0;
|
||||
my $NbRequests = 0;
|
||||
if($webcontent =~ m/\nserver accepts handled requests\n(.*?)\n/) {
|
||||
$counters = $1;
|
||||
# triming
|
||||
$counters =~ s/^\s+|\s+$//g;
|
||||
#splitting
|
||||
($AcceptedConn,$HandledConn,$NbRequests) = split(' ', $counters);
|
||||
# triming
|
||||
$AcceptedConn =~ s/^\s+|\s+$//g;
|
||||
$HandledConn =~ s/^\s+|\s+$//g;
|
||||
$NbRequests =~ s/^\s+|\s+$//g;
|
||||
}
|
||||
|
||||
# nginx reads request header
|
||||
my $Reading = 0;
|
||||
# nginx reads request body, processes request, or writes response to a client
|
||||
my $Writing = 0;
|
||||
# keep-alive connections, actually it is active - (reading + writing)
|
||||
my $Waiting = 0;
|
||||
if($webcontent =~ m/Reading: (.*?)Writing: (.*?)Waiting: (.*?)$/) {
|
||||
$Reading = $1;
|
||||
$Writing = $2;
|
||||
$Waiting = $3;
|
||||
# triming
|
||||
$Reading =~ s/^\s+|\s+$//g;
|
||||
$Writing =~ s/^\s+|\s+$//g;
|
||||
$Waiting =~ s/^\s+|\s+$//g;
|
||||
}
|
||||
|
||||
# Debug
|
||||
if (defined ($o_debug)) {
|
||||
print ("\nDEBUG Parse results => Active :" . $ActiveConn . "\nAcceptedConn :" . $AcceptedConn . "\nHandledConn :" . $HandledConn . "\nNbRequests :".$NbRequests . "\nReading :" .$Reading . "\nWriting :" . $Writing . "\nWaiting :" . $Waiting . "\n");
|
||||
}
|
||||
|
||||
my $TempFile = $TempPath.$o_host.'_check_nginx_status'.md5_hex($url);
|
||||
my $FH;
|
||||
|
||||
my $LastTime = 0;
|
||||
my $LastAcceptedConn = 0;
|
||||
my $LastHandledConn = 0;
|
||||
my $LastNbRequests = 0;
|
||||
if ((-e $TempFile) && (-r $TempFile) && (-w $TempFile)) {
|
||||
open ($FH, '<',$TempFile) or nagios_exit($nginx,"UNKNOWN","unable to read temporary data from :".$TempFile);
|
||||
$LastTime = <$FH>;
|
||||
$LastAcceptedConn = <$FH>;
|
||||
$LastHandledConn = <$FH>;
|
||||
$LastNbRequests = <$FH>;
|
||||
close ($FH);
|
||||
if (defined ($o_debug)) {
|
||||
print ("\nDebug: data from temporary file: $TempFile\n");
|
||||
print (" LastTime: $LastTime LastAcceptedConn: $LastAcceptedConn LastHandledConn: $LastHandledConn LastNbRequests: $LastNbRequests \n");
|
||||
}
|
||||
}
|
||||
|
||||
open ($FH, '>'.$TempFile) or nagios_exit($nginx,"UNKNOWN","unable to write temporary data in :".$TempFile);
|
||||
#print $FH (@Time),"\n";
|
||||
print $FH "$Time\n";
|
||||
print $FH "$AcceptedConn\n";
|
||||
print $FH "$HandledConn\n";
|
||||
print $FH "$NbRequests\n";
|
||||
close ($FH);
|
||||
|
||||
my $ConnPerSec = 0;
|
||||
my $ReqPerSec = 0;
|
||||
my $RequestsNew = 0;
|
||||
# by default the average
|
||||
my $ReqPerConn = 0;
|
||||
if ($AcceptedConn > 0) {
|
||||
$ReqPerConn = $NbRequests/$AcceptedConn;
|
||||
}
|
||||
my $elapsed = $Time - $LastTime ;
|
||||
if (defined ($o_debug)) {
|
||||
print ("\nDebug: pre-computation\n");
|
||||
print ("Average ReqPerconn: $ReqPerConn, Seconds elapsed Since last check: $elapsed\n");
|
||||
}
|
||||
# check only if the counters may have been incremented
|
||||
# but not if it may have been too much incremented
|
||||
# if nginx was restarted ($NbRequests is now lower than previous value), just skip
|
||||
if ( ($elapsed < $MaxTimeDif) && ($elapsed != 0) && ($NbRequests >= $LastNbRequests) ) {
|
||||
$ConnPerSec = ($AcceptedConn-$LastAcceptedConn)/$elapsed;
|
||||
$RequestsNew = $NbRequests-$LastNbRequests;
|
||||
$ReqPerSec = $RequestsNew/$elapsed;
|
||||
# get finer value
|
||||
if ( $ConnPerSec!=0 ) {
|
||||
my $ReqPerConn = $ReqPerSec/$ConnPerSec;
|
||||
} else {
|
||||
my $ReqPerConn = 0;
|
||||
}
|
||||
}
|
||||
if (defined ($o_debug)) {
|
||||
print ("\nDebug: data computed\n");
|
||||
print ("ConnPerSec: $ConnPerSec ReqPerSec: $ReqPerSec ReqPerConn: $ReqPerConn\n");
|
||||
}
|
||||
$InfoData = sprintf (" %.3f sec. response time, Active: %d (Writing: %d Reading: %d Waiting: %d)"
|
||||
. " ReqPerSec: %.3f ConnPerSec: %.3f ReqPerConn: %.3f"
|
||||
,$timeelapsed,$ActiveConn,$Writing,$Reading,$Waiting,$ReqPerSec,$ConnPerSec,$ReqPerConn);
|
||||
|
||||
# Manage warn and crit values for the perfdata
|
||||
my $p_warn_a_level = "$o_warn_a_level";
|
||||
my $p_crit_a_level = "$o_crit_a_level";
|
||||
my $p_warn_rps_level = "$o_warn_rps_level";
|
||||
my $p_crit_rps_level = "$o_crit_rps_level";
|
||||
my $p_warn_cps_level = "$o_warn_cps_level";
|
||||
my $p_crit_cps_level = "$o_crit_cps_level";
|
||||
|
||||
if ($p_warn_a_level == "-1") {
|
||||
$p_warn_a_level = "";
|
||||
}
|
||||
if ($p_crit_a_level == "-1") {
|
||||
$p_crit_a_level = "";
|
||||
}
|
||||
if ($p_warn_rps_level == "-1") {
|
||||
$p_warn_rps_level = "";
|
||||
}
|
||||
if ($p_crit_rps_level == "-1") {
|
||||
$p_crit_rps_level = "";
|
||||
}
|
||||
if ($p_warn_cps_level == "-1") {
|
||||
$p_warn_cps_level = "";
|
||||
}
|
||||
if ($p_crit_cps_level == "-1") {
|
||||
$p_crit_cps_level = "";
|
||||
}
|
||||
|
||||
$PerfData = sprintf ("Writing=%d;;;; Reading=%d;;;; Waiting=%d;;;; Active=%d;%s;%s;; "
|
||||
. "ReqPerSec=%f;%s;%s;; ConnPerSec=%f;%s;%s;; ReqPerConn=%f;;;;"
|
||||
,($Writing),($Reading),($Waiting),($ActiveConn)
|
||||
,($p_warn_a_level),($p_crit_a_level)
|
||||
,($ReqPerSec),($p_warn_rps_level),($p_crit_rps_level)
|
||||
,($ConnPerSec),($p_warn_cps_level),($p_crit_cps_level)
|
||||
,($ReqPerConn));
|
||||
# first all critical exists by priority
|
||||
if (defined($o_crit_a_level) && (-1!=$o_crit_a_level) && ($ActiveConn >= $o_crit_a_level)) {
|
||||
nagios_exit($nginx,"CRITICAL", "Active Connections are critically high " . $InfoData,$PerfData);
|
||||
}
|
||||
if (defined($o_crit_rps_level) && (-1!=$o_crit_rps_level) && ($ReqPerSec >= $o_crit_rps_level)) {
|
||||
nagios_exit($nginx,"CRITICAL", "Request per second ratios is critically high " . $InfoData,$PerfData);
|
||||
}
|
||||
if (defined($o_crit_cps_level) && (-1!=$o_crit_cps_level) && ($ConnPerSec >= $o_crit_cps_level)) {
|
||||
nagios_exit($nginx,"CRITICAL", "Connection per second ratio is critically high " . $InfoData,$PerfData);
|
||||
}
|
||||
# Then WARNING exits by priority
|
||||
if (defined($o_warn_a_level) && (-1!=$o_warn_a_level) && ($ActiveConn >= $o_warn_a_level)) {
|
||||
nagios_exit($nginx,"WARNING", "Active Connections are high " . $InfoData,$PerfData);
|
||||
}
|
||||
if (defined($o_warn_rps_level) && (-1!=$o_warn_rps_level) && ($ReqPerSec >= $o_warn_rps_level)) {
|
||||
nagios_exit($nginx,"WARNING", "Requests per second ratio is high " . $InfoData,$PerfData);
|
||||
}
|
||||
if (defined($o_warn_cps_level) && (-1!=$o_warn_cps_level) && ($ConnPerSec >= $o_warn_cps_level)) {
|
||||
nagios_exit($nginx,"WARNING", "Connection per second ratio is high " . $InfoData,$PerfData);
|
||||
}
|
||||
|
||||
nagios_exit($nginx,"OK",$InfoData,$PerfData);
|
||||
|
||||
} else {
|
||||
nagios_exit($nginx,"CRITICAL", $response->status_line);
|
||||
}
|
26
bundles/nginx/files/fastcgi.conf
Normal file
26
bundles/nginx/files/fastcgi.conf
Normal file
|
@ -0,0 +1,26 @@
|
|||
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;
|
||||
|
||||
fastcgi_param REDIRECT_STATUS 200;
|
||||
|
||||
# This is the only thing that's different to the debian default.
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
28
bundles/nginx/files/logrotate.conf
Normal file
28
bundles/nginx/files/logrotate.conf
Normal file
|
@ -0,0 +1,28 @@
|
|||
/var/log/nginx/*.log {
|
||||
compress
|
||||
copytruncate
|
||||
create 0640 www-data adm
|
||||
daily
|
||||
dateext
|
||||
missingok
|
||||
notifempty
|
||||
rotate ${node.metadata.get('nginx/log_retention_days', 7)}
|
||||
sharedscripts
|
||||
prerotate
|
||||
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
|
||||
run-parts /etc/logrotate.d/httpd-prerotate; \
|
||||
fi
|
||||
endscript
|
||||
}
|
||||
|
||||
/var/log/nginx-timing/*.log {
|
||||
compress
|
||||
copytruncate
|
||||
create 0644 www-data adm
|
||||
dateext
|
||||
missingok
|
||||
notifempty
|
||||
rotate 3
|
||||
sharedscripts
|
||||
size 1M
|
||||
}
|
61
bundles/nginx/files/nginx.conf
Normal file
61
bundles/nginx/files/nginx.conf
Normal file
|
@ -0,0 +1,61 @@
|
|||
user ${username};
|
||||
worker_processes ${worker_processes};
|
||||
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections ${worker_connections};
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
charset UTF-8;
|
||||
override_charset on;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 15;
|
||||
client_body_timeout 12;
|
||||
client_header_timeout 12;
|
||||
send_timeout 10;
|
||||
|
||||
access_log off;
|
||||
error_log off;
|
||||
|
||||
client_body_buffer_size 16K;
|
||||
client_header_buffer_size 4k;
|
||||
client_max_body_size 1M;
|
||||
large_client_header_buffers 4 8k;
|
||||
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
# GDPR compatible IP smashinator 5000000
|
||||
map $remote_addr $ip_anonym1 {
|
||||
default 0.0.0;
|
||||
"~(?P<ip>(\d+)\.(\d+))\.(\d+)\.\d+" $ip;
|
||||
"~(?P<ip>[^:]+:[^:]+):" $ip;
|
||||
}
|
||||
map $remote_addr $ip_anonym2 {
|
||||
default .0.0;
|
||||
"~(?P<ip>(\d+)\.(\d+)\.(\d+))\.\d+" .0.0;
|
||||
"~(?P<ip>[^:]+:[^:]+):" ::;
|
||||
}
|
||||
map $ip_anonym1$ip_anonym2 $ip_anonymized {
|
||||
default 0.0.0.0;
|
||||
"~(?P<ip>.*)" $ip;
|
||||
}
|
||||
|
||||
log_format gdpr '$ip_anonymized - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"<stripped>" "$http_user_agent"';
|
||||
|
||||
log_format anon_timing '[$time_local] $request_time $upstream_response_time "$request" $status';
|
||||
|
||||
include /etc/nginx/sites/*;
|
||||
}
|
13
bundles/nginx/files/port80.conf
Normal file
13
bundles/nginx/files/port80.conf
Normal file
|
@ -0,0 +1,13 @@
|
|||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
server_name _;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
alias /var/lib/dehydrated/acme-challenges/;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 404;
|
||||
}
|
||||
}
|
9
bundles/nginx/files/security.txt
Normal file
9
bundles/nginx/files/security.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
Contact: ${vhost.get('contact', repo.libs.defaults.security_email)}
|
||||
Expires: ${vhost.get('expires', expiry)}
|
||||
Preferred-Languages: ${','.join(sorted(vhost.get('lang', repo.libs.defaults.security_lang)))}
|
||||
Canonical: ${proto}://${domain}/.well-known/security.txt
|
||||
% for key, value in sorted(vhost.items()):
|
||||
% if key[0].isupper():
|
||||
${key}: ${value}
|
||||
% endif
|
||||
% endfor
|
156
bundles/nginx/files/site_template
Normal file
156
bundles/nginx/files/site_template
Normal file
|
@ -0,0 +1,156 @@
|
|||
server {
|
||||
% if domain_aliases:
|
||||
server_name ${domain} ${' '.join(sorted(domain_aliases))};
|
||||
% else:
|
||||
server_name ${domain};
|
||||
% endif
|
||||
root ${webroot if webroot else '/var/www/{}/'.format(vhost)};
|
||||
index ${' '.join(index)};
|
||||
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
% if ssl:
|
||||
location / {
|
||||
return 308 https://$host$request_uri;
|
||||
}
|
||||
|
||||
% if ssl == 'letsencrypt':
|
||||
location /.well-known/acme-challenge/ {
|
||||
alias /var/lib/dehydrated/acme-challenges/;
|
||||
}
|
||||
% endif
|
||||
}
|
||||
|
||||
server {
|
||||
% if domain_aliases:
|
||||
server_name ${domain} ${' '.join(sorted(domain_aliases))};
|
||||
% else:
|
||||
server_name ${domain};
|
||||
% endif
|
||||
root ${webroot if webroot else '/var/www/{}/'.format(vhost)};
|
||||
index ${' '.join(index)};
|
||||
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
% if ssl == 'letsencrypt':
|
||||
ssl_certificate /var/lib/dehydrated/certs/${domain}/fullchain.pem;
|
||||
ssl_certificate_key /var/lib/dehydrated/certs/${domain}/privkey.pem;
|
||||
% else:
|
||||
ssl_certificate /etc/nginx/ssl/${vhost}.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/${vhost}.key;
|
||||
% endif
|
||||
ssl_dhparam /etc/ssl/certs/dhparam.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
|
||||
% endif
|
||||
|
||||
resolver 8.8.8.8 8.8.4.4 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
|
||||
% if create_access_log:
|
||||
access_log /var/log/nginx/access-${vhost}.log gdpr;
|
||||
% endif
|
||||
access_log /var/log/nginx-timing/${vhost}.log anon_timing;
|
||||
# error_log is disabled globally
|
||||
|
||||
% if max_body_size:
|
||||
client_max_body_size ${max_body_size};
|
||||
% endif
|
||||
|
||||
% if not do_not_set_content_security_headers:
|
||||
add_header Referrer-Policy same-origin;
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
% endif
|
||||
add_header Permissions-Policy interest-cohort=();
|
||||
|
||||
error_page 404 /not_found.html;
|
||||
location = /not_found.html {
|
||||
root /var/www/;
|
||||
internal;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /error.html;
|
||||
location = /error.html {
|
||||
root /var/www/;
|
||||
internal;
|
||||
}
|
||||
|
||||
% if ssl == 'letsencrypt':
|
||||
location /.well-known/acme-challenge/ {
|
||||
alias /var/lib/dehydrated/acme-challenges/;
|
||||
}
|
||||
% endif
|
||||
|
||||
% if security_txt:
|
||||
location = /.well-known/security.txt {
|
||||
alias /etc/nginx/security.txt.d/${vhost};
|
||||
}
|
||||
% endif
|
||||
|
||||
% if locations:
|
||||
% for location, options in sorted(locations.items()):
|
||||
location ${location} {
|
||||
% if 'target' in options:
|
||||
proxy_pass ${options['target']};
|
||||
proxy_http_version ${options.get('http_version', '1.1')};
|
||||
proxy_set_header Host ${domain};
|
||||
% if options.get('websockets', False):
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
% endif
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host ${options.get('x_forwarded_host', domain)};
|
||||
% for option, value in options.get('proxy_set_header', {}).items():
|
||||
proxy_set_header ${option} ${value};
|
||||
% endfor
|
||||
% if location != '/':
|
||||
proxy_set_header X-Script-Name ${location};
|
||||
% endif
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout ${options.get('proxy_read_timeout', 60)};
|
||||
client_max_body_size ${options.get('max_body_size', '5M')};
|
||||
% elif 'redirect' in options:
|
||||
return ${options.get('mode', 308)} ${options['redirect']};
|
||||
% elif 'return' in options:
|
||||
return ${options.get('mode', 200)} '${options['return']}';
|
||||
% elif 'root' in options:
|
||||
root ${options['root']};
|
||||
% elif 'alias' in options:
|
||||
alias ${options['alias']};
|
||||
% endif
|
||||
% if 'auth' in options:
|
||||
auth_basic "${options['auth'].get('realm', vhost)}";
|
||||
auth_basic_user_file ${options['auth']['file']};
|
||||
% endif
|
||||
% for opt in sorted(options.get('additional_config', set())):
|
||||
${opt};
|
||||
% endfor
|
||||
}
|
||||
|
||||
% endfor
|
||||
% endif
|
||||
% if php:
|
||||
location ~ \.php$ {
|
||||
include fastcgi.conf;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/run/php/php${php_version}-fpm.sock;
|
||||
}
|
||||
% if not max_body_size:
|
||||
client_max_body_size 5M;
|
||||
% endif
|
||||
|
||||
% endif
|
||||
% if extras:
|
||||
<%include file="extras/${node.name}/${vhost}" />
|
||||
% endif
|
||||
}
|
6
bundles/nginx/files/ssl_template
Normal file
6
bundles/nginx/files/ssl_template
Normal file
|
@ -0,0 +1,6 @@
|
|||
<%
|
||||
from os.path import isfile, join
|
||||
%><%include file="ssl/${domain}.crt.pem"/>
|
||||
% if isfile(join(repo.path, 'data', 'ssl', f'{domain}.crt_intermediate.pem')):
|
||||
<%include file="ssl/${domain}.crt_intermediate.pem"/>
|
||||
% endif
|
6
bundles/nginx/files/stub_status
Normal file
6
bundles/nginx/files/stub_status
Normal file
|
@ -0,0 +1,6 @@
|
|||
server {
|
||||
listen 127.0.0.1:22999 default_server;
|
||||
server_name _;
|
||||
|
||||
stub_status;
|
||||
}
|
178
bundles/nginx/items.py
Normal file
178
bundles/nginx/items.py
Normal file
|
@ -0,0 +1,178 @@
|
|||
from datetime import datetime, timedelta
|
||||
|
||||
if node.has_bundle('pacman'):
|
||||
package = 'pkg_pacman:nginx'
|
||||
username = 'http'
|
||||
else:
|
||||
package = 'pkg_apt:nginx'
|
||||
username = 'www-data'
|
||||
|
||||
directories = {
|
||||
'/etc/nginx/sites': {
|
||||
'purge': True,
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
},
|
||||
'/etc/nginx/security.txt.d': {
|
||||
'purge': True,
|
||||
},
|
||||
'/etc/nginx/ssl': {
|
||||
'purge': True,
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
},
|
||||
'/var/log/nginx-timing': {
|
||||
'owner': username,
|
||||
'needs': {
|
||||
package,
|
||||
},
|
||||
},
|
||||
'/var/www': {},
|
||||
}
|
||||
|
||||
files = {
|
||||
'/etc/logrotate.d/nginx': {
|
||||
'source': 'logrotate.conf',
|
||||
},
|
||||
'/etc/nginx/nginx.conf': {
|
||||
'content_type': 'mako',
|
||||
'context': {
|
||||
'username': username,
|
||||
**node.metadata['nginx'],
|
||||
},
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
},
|
||||
'/etc/nginx/fastcgi.conf': {
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
},
|
||||
'/etc/nginx/sites/stub_status': {
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
},
|
||||
'/etc/nginx/sites/000-port80.conf': {
|
||||
'source': 'port80.conf',
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
},
|
||||
'/usr/local/share/icinga/plugins/check_nginx_status': {
|
||||
'mode': '0755',
|
||||
},
|
||||
'/var/www/error.html': {},
|
||||
'/var/www/not_found.html': {},
|
||||
}
|
||||
if node.has_bundle('pacman'):
|
||||
files['/etc/systemd/system/nginx.service.d/bundlewrap.conf'] = {
|
||||
'source': 'arch-override.conf',
|
||||
'triggers': {
|
||||
'action:systemd-reload',
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
}
|
||||
|
||||
actions = {
|
||||
'nginx-generate-dhparam': {
|
||||
'command': 'openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048',
|
||||
'unless': 'test -f /etc/ssl/certs/dhparam.pem',
|
||||
},
|
||||
}
|
||||
|
||||
svc_systemd = {
|
||||
'nginx': {
|
||||
'needs': {
|
||||
'action:nginx-generate-dhparam',
|
||||
'directory:/var/log/nginx-timing',
|
||||
package,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
now = datetime.now()
|
||||
in_three_months = now + timedelta(days=90)
|
||||
default_security_expiry = in_three_months.strftime('%Y-%m') + '-01T00:00:00.000Z'
|
||||
|
||||
for vhost, config in node.metadata.get('nginx/vhosts', {}).items():
|
||||
if not 'domain' in config:
|
||||
config['domain'] = vhost
|
||||
|
||||
security_txt_enabled = False
|
||||
if (
|
||||
node.metadata.get('nginx/security.txt/enabled', True) and
|
||||
config.get('security.txt', {}).get('enabled', True)
|
||||
):
|
||||
security_txt_enabled = True
|
||||
|
||||
files[f'/etc/nginx/security.txt.d/{vhost}'] = {
|
||||
'source': 'security.txt',
|
||||
'content_type': 'mako',
|
||||
'context': {
|
||||
'domain': config['domain'],
|
||||
'expiry': default_security_expiry,
|
||||
'proto': 'https' if config.get('ssl', 'letsencrypt') else 'http',
|
||||
'vhost': config.get('security.txt', node.metadata.get('nginx/security.txt', {})),
|
||||
},
|
||||
}
|
||||
|
||||
files[f'/etc/nginx/sites/{vhost}'] = {
|
||||
'source': 'site_template',
|
||||
'content_type': 'mako',
|
||||
'context': {
|
||||
'create_access_log': config.get('access_log', node.metadata.get('nginx/access_log', False)),
|
||||
'php_version': node.metadata.get('php/version', ''),
|
||||
'security_txt': security_txt_enabled,
|
||||
'vhost': vhost,
|
||||
**config,
|
||||
},
|
||||
'needs': set(),
|
||||
'needed_by': {
|
||||
'svc_systemd:nginx',
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
}
|
||||
|
||||
if not 'webroot' in config:
|
||||
directories[f'/var/www/{vhost}'] = config.get('webroot_config', {})
|
||||
|
||||
if config.get('ssl', 'letsencrypt') == 'letsencrypt':
|
||||
files[f'/etc/nginx/sites/{vhost}']['needs'].add('action:letsencrypt_ensure-some-certificate_{}'.format(config['domain']))
|
||||
files[f'/etc/nginx/sites/{vhost}']['needed_by'].add('action:letsencrypt_update_certificates')
|
||||
|
||||
elif config.get('ssl', 'letsencrypt'):
|
||||
files[f'/etc/nginx/ssl/{vhost}.crt'] = {
|
||||
'content_type': 'mako',
|
||||
'source': 'ssl_template',
|
||||
'context': {
|
||||
'domain': config['ssl'],
|
||||
},
|
||||
'needed_by': {
|
||||
'svc_systemd:nginx',
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:reload',
|
||||
},
|
||||
}
|
||||
files[f'/etc/nginx/ssl/{vhost}.key'] = {
|
||||
'content': repo.vault.decrypt_file('ssl/{}.key.pem.vault'.format(config['ssl'])),
|
||||
'mode': '0600',
|
||||
'needed_by': {
|
||||
'svc_systemd:nginx',
|
||||
'svc_systemd:nginx:restart',
|
||||
},
|
||||
'triggers': {
|
||||
'svc_systemd:nginx:reload',
|
||||
},
|
||||
}
|
||||
|
||||
files[f'/etc/nginx/sites/{vhost}']['needs'].add(f'file:/etc/nginx/ssl/{vhost}.crt')
|
||||
files[f'/etc/nginx/sites/{vhost}']['needs'].add(f'file:/etc/nginx/ssl/{vhost}.key')
|
209
bundles/nginx/metadata.py
Normal file
209
bundles/nginx/metadata.py
Normal file
|
@ -0,0 +1,209 @@
|
|||
from bundlewrap.metadata import atomic
|
||||
|
||||
defaults = {
|
||||
'apt': {
|
||||
'repos': {
|
||||
'nginx': {
|
||||
'items': {
|
||||
'deb http://nginx.org/packages/{os} {os_release} nginx',
|
||||
},
|
||||
},
|
||||
},
|
||||
'packages': {
|
||||
'nginx': {},
|
||||
},
|
||||
},
|
||||
'backups': {
|
||||
'paths': {
|
||||
'/var/www',
|
||||
},
|
||||
},
|
||||
'icinga2_api': {
|
||||
'nginx': {
|
||||
'services': {
|
||||
'NGINX PROCESS': {
|
||||
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_systemd_unit nginx',
|
||||
},
|
||||
'NGINX STATUS': {
|
||||
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_nginx_status',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'nginx': {
|
||||
'worker_connections': 768,
|
||||
},
|
||||
'pacman': {
|
||||
'packages': {
|
||||
'nginx': {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if node.has_bundle('telegraf'):
|
||||
defaults['telegraf'] = {
|
||||
'input_plugins': {
|
||||
'builtin': {
|
||||
'nginx': [{
|
||||
'urls': ['http://localhost:22999/server_status'],
|
||||
}],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'nginx/worker_processes',
|
||||
)
|
||||
def worker_processes(metadata):
|
||||
return {
|
||||
'nginx': {
|
||||
'worker_processes': metadata.get('vm/cpu', 2),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'letsencrypt/domains',
|
||||
'letsencrypt/reload_after',
|
||||
'nginx/vhosts',
|
||||
)
|
||||
def letsencrypt(metadata):
|
||||
if not node.has_bundle('letsencrypt'):
|
||||
raise DoNotRunAgain
|
||||
|
||||
domains = {}
|
||||
vhosts = {}
|
||||
|
||||
for vhost, config in metadata.get('nginx/vhosts', {}).items():
|
||||
if config.get('ssl', 'letsencrypt') == 'letsencrypt':
|
||||
domain = config.get('domain', vhost)
|
||||
domains[domain] = config.get('domain_aliases', set())
|
||||
vhosts[vhost] = {
|
||||
'ssl': 'letsencrypt',
|
||||
}
|
||||
|
||||
return {
|
||||
'letsencrypt': {
|
||||
'domains': domains,
|
||||
'reload_after': {
|
||||
'nginx',
|
||||
},
|
||||
},
|
||||
'nginx': {
|
||||
'vhosts': vhosts,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'nginx/vhosts',
|
||||
)
|
||||
def index_files(metadata):
|
||||
vhosts = {}
|
||||
|
||||
for vhost, config in metadata.get('nginx/vhosts', {}).items():
|
||||
vhosts[vhost] = {
|
||||
'index': [
|
||||
'index.html',
|
||||
'index.htm',
|
||||
],
|
||||
}
|
||||
|
||||
if config.get('php', False):
|
||||
# If we're using PHP, make sure index.php is tried first
|
||||
vhosts[vhost]['index'].insert(0, 'index.php')
|
||||
|
||||
|
||||
return {
|
||||
'nginx': {
|
||||
'vhosts': vhosts,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'icinga2_api/nginx/services',
|
||||
)
|
||||
def monitoring(metadata):
|
||||
services = {}
|
||||
|
||||
for vname, vconfig in metadata.get('nginx/vhosts', {}).items():
|
||||
domain = vconfig.get('domain', vname)
|
||||
|
||||
if vconfig['ssl']:
|
||||
scheme = 'https'
|
||||
else:
|
||||
scheme = 'http'
|
||||
|
||||
if 'website_check_path' in vconfig and 'website_check_string' in vconfig:
|
||||
services['NGINX VHOST {} CONTENT'.format(vname)] = {
|
||||
'check_command': 'check_http_wget',
|
||||
'vars.http_wget_contains': vconfig['website_check_string'],
|
||||
'vars.http_wget_url': '{}://{}{}'.format(scheme, domain, vconfig['website_check_path']),
|
||||
'vars.notification.sms': True,
|
||||
}
|
||||
|
||||
if vconfig.get('check_ssl', vconfig['ssl']):
|
||||
services['NGINX VHOST {} CERTIFICATE'.format(vname)] = {
|
||||
'check_command': 'check_https_cert_at_url',
|
||||
'vars.domain': domain,
|
||||
'vars.notification.mail': True,
|
||||
}
|
||||
|
||||
max_connections = metadata.get('nginx/worker_connections') * metadata.get('nginx/worker_processes')
|
||||
connections_warn = int(max_connections * 0.8)
|
||||
connections_crit = int(max_connections * 0.9)
|
||||
|
||||
services['NGINX STATUS'] = {
|
||||
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_nginx_status --warn={},-1,-1 --critical={},-1,-1 -H 127.0.0.1:22999'.format(connections_warn, connections_crit),
|
||||
}
|
||||
|
||||
return {
|
||||
'icinga2_api': {
|
||||
'nginx': {
|
||||
'services': services,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'firewall/port_rules/80',
|
||||
'firewall/port_rules/443',
|
||||
)
|
||||
def firewall(metadata):
|
||||
return {
|
||||
'firewall': {
|
||||
'port_rules': {
|
||||
'80': atomic(metadata.get('nginx/restrict-to', {'*'})),
|
||||
'443': atomic(metadata.get('nginx/restrict-to', {'*'})),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'telegraf/input_plugins/tail',
|
||||
)
|
||||
def telegraf_anon_timing(metadata):
|
||||
result = {}
|
||||
|
||||
for vhost in metadata.get('nginx/vhosts', {}):
|
||||
result[f'nginx-{vhost}'] = {
|
||||
'files': [f'/var/log/nginx-timing/{vhost}.log'],
|
||||
'from_beginning': False,
|
||||
'grok_patterns': ['%{LOGPATTERN}'],
|
||||
'grok_custom_patterns': 'LOGPATTERN \[%{HTTPDATE:ts:ts-httpd}\] %{NUMBER:request_time:float} (?:%{NUMBER:upstream_response_time:float}|-) "%{WORD:verb:tag} %{NOTSPACE:request} HTTP/%{NUMBER:http_version:float}" %{NUMBER:resp_code:tag}',
|
||||
'data_format': 'grok',
|
||||
'name_override': 'nginx_timing',
|
||||
}
|
||||
|
||||
return {
|
||||
'telegraf': {
|
||||
'input_plugins': {
|
||||
'tail': result,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue