Просмотр исходного кода

Add option to delay check_ntp, check_ntp_time between packets (default 2s). I wasn't able to cherry-pick the commits from monitoring-plugins#1605, but these changes are equivalent to that PR for this project.

madlohe 6 лет назад
Родитель
Сommit
d4f659efd1
3 измененных файлов с 45 добавлено и 17 удалено
  1. 2 0
      NEWS
  2. 21 8
      plugins/check_ntp.c
  3. 22 9
      plugins/check_ntp_time.c

+ 2 - 0
NEWS

@@ -21,6 +21,8 @@ This file documents the major additions and syntax changes between releases.
 	check_mailq: Add option for opensmtpd (brigriffin)
 	check_mailq: Add support for opensmtpd
 	check_mysql_query: Add --character-set flag
+	check_ntp: Add --delay flag to circumvent DOS detection
+	check_ntp_time: Add --delay flag to circumvent DOS detection
 	check_ntp_time: Add support for monitoring stratum of timesources
 	check_oracle: Add support for Oracle XE databases (Peter Athaks)
 	check_ping: plugin output will now include hostname and IP address

+ 21 - 8
plugins/check_ntp.c

@@ -46,6 +46,7 @@ static char *ocrit="120";
 static short do_jitter=0;
 static char *jwarn="5000";
 static char *jcrit="10000";
+static int delay=2;
 
 int process_arguments (int, char **);
 thresholds *offset_thresholds = NULL;
@@ -79,6 +80,7 @@ typedef struct {
 /* this structure holds data about results from querying offset from a peer */
 typedef struct {
 	time_t waiting;         /* ts set when we started waiting for a response */
+	int num_requests;
 	int num_responses;      /* number of successfully received responses */
 	uint8_t stratum;        /* copied verbatim from the ntp_message */
 	double rtdelay;         /* converted from the ntp_message */
@@ -418,19 +420,21 @@ double offset_request(const char *host, int *status){
 	now_time=start_ts=time(NULL);
 	while(servers_completed<num_hosts && now_time-start_ts <= timeout_interval/2){
 		/* loop through each server and find each one which hasn't
-		 * been touched in the past second or so and is still lacking
-		 * some responses.  for each of these servers, send a new request,
-		 * and update the "waiting" timestamp with the current time. */
+		 * timed out yet and is still lacking some responses. For each
+		 * of these servers, send a new request, and update the
+		 * "waiting" timestamp with the current time. */
 		now_time=time(NULL);
 
 		for(i=0; i<num_hosts; i++){
 			if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){
-				if(verbose && servers[i].waiting != 0) printf("re-");
+				if(verbose && servers[i].num_requests != servers[i].num_responses) printf("re-");
 				if(verbose) printf("sending request to peer %d\n", i);
 				setup_request(&req[i]);
 				write(socklist[i], &req[i], sizeof(ntp_message));
-				if(servers[i].waiting == 0) now_time++;
-				servers[i].waiting=now_time;
+				servers[i].waiting=now_time+delay;
+				if(servers[i].num_requests == servers[i].num_responses) {
+					servers[i].num_requests++;
+				}
 				break;
 			}
 		}
@@ -460,6 +464,7 @@ double offset_request(const char *host, int *status){
 				servers[i].stratum=req[i].stratum;
 				servers[i].rtdisp=NTP32asDOUBLE(req[i].rtdisp);
 				servers[i].rtdelay=NTP32asDOUBLE(req[i].rtdelay);
+				servers[i].waiting--;
 				servers[i].flags=req[i].flags;
 				servers_readable--;
 				one_read = 1;
@@ -668,6 +673,7 @@ int process_arguments(int argc, char **argv){
 		{"verbose", no_argument, 0, 'v'},
 		{"use-ipv4", no_argument, 0, '4'},
 		{"use-ipv6", no_argument, 0, '6'},
+		{"delay", optional_argument, 0, 'd'},
 		{"warning", required_argument, 0, 'w'},
 		{"critical", required_argument, 0, 'c'},
 		{"jwarn", required_argument, 0, 'j'},
@@ -682,7 +688,7 @@ int process_arguments(int argc, char **argv){
 		usage ("\n");
 
 	while (1) {
-		c = getopt_long (argc, argv, "Vhv46w:c:j:k:t:H:", longopts, &option);
+		c = getopt_long (argc, argv, "Vhv46w:c:j:k:t:H:d:", longopts, &option);
 		if (c == -1 || c == EOF || c == 1)
 			break;
 
@@ -714,6 +720,9 @@ int process_arguments(int argc, char **argv){
 			do_jitter=1;
 			jcrit = optarg;
 			break;
+		case 'd':
+			delay=atoi(optarg);
+			break;
 		case 'H':
 			if(is_host(optarg) == FALSE)
 				usage2(_("Invalid hostname/address"), optarg);
@@ -868,11 +877,15 @@ void print_help(void){
 	printf ("    %s\n", _("Warning threshold for jitter"));
 	printf (" %s\n", "-k, --jcrit=THRESHOLD");
 	printf ("    %s\n", _("Critical threshold for jitter"));
+	printf (" %s\n", "-d, --delay=INTEGER");
+	printf ("    %s\n", _("Delay between each packet (seconds)"));
 	printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
 	printf (UT_VERBOSE);
 
 	printf("\n");
 	printf("%s\n", _("Notes:"));
+	printf(" %s\n", _("--delay is useful if you are triggering the anti-DOS for the"));
+	printf(" %s\n", _("NTP server and need to leave a bigger gap between queries"));
 	printf(UT_THRESHOLDS_NOTES);
 
 	printf("\n");
@@ -896,5 +909,5 @@ print_usage(void)
 	printf ("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or"));
 	printf ("%s\n\n", _("check_ntp_time instead."));
 	printf ("%s\n", _("Usage:"));
-	printf(" %s -H <host> [-w <warn>] [-c <crit>] [-j <warn>] [-k <crit>] [-4|-6] [-v verbose]\n", progname);
+	printf(" %s -H <host> [-w <warn>] [-c <crit>] [-j <warn>] [-k <crit>] [-4|-6] [-v verbose] [-d <delay>]\n", progname);
 }

+ 22 - 9
plugins/check_ntp_time.c

@@ -51,6 +51,7 @@ static char *ocrit="120";
 static char *swarn="16";
 static char *scrit="16";
 int time_offset=0;
+static int delay=2;
 
 int num_hosts;
 
@@ -85,6 +86,7 @@ typedef struct {
 typedef struct {
 	time_t waiting;         /* ts set when we started waiting for a response */
 	int connected;          /* don't try to "write()" if "connect()" fails */
+	int num_requests;
 	int num_responses;      /* number of successfully received responses */
 	uint8_t stratum;        /* copied verbatim from the ntp_message */
 	double rtdelay;         /* converted from the ntp_message */
@@ -374,20 +376,23 @@ double offset_request(const char *host, int *status){
 	now_time=start_ts=time(NULL);
 	while(servers_completed<num_hosts && now_time-start_ts <= timeout_interval - 1){
 		/* loop through each server and find each one which hasn't
-		 * been touched in the past second or so and is still lacking
-		 * some responses. For each of these servers, send a new request,
-		 * and update the "waiting" timestamp with the current time. */
+		 * timed out yet and is still lacking some responses. For each
+		 * of these servers, send a new request, and update the
+		 * "waiting" timestamp with the current time. */
 		now_time=time(NULL);
 
 		for(i=0; i<num_hosts; i++){
 			if(servers[i].connected == 0)
 				continue;
 			if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){
-				if(verbose && servers[i].waiting != 0) printf("re-");
+				if(verbose && servers[i].num_requests != servers[i].num_responses) printf("re-");
 				if(verbose) printf("sending request to peer %d\n", i);
 				setup_request(&req[i]);
 				write(socklist[i], &req[i], sizeof(ntp_message));
-				servers[i].waiting=now_time;
+				servers[i].waiting=now_time+delay;
+				if(servers[i].num_requests == servers[i].num_responses) {
+					servers[i].num_requests++;
+				}
 				break;
 			}
 		}
@@ -417,7 +422,7 @@ double offset_request(const char *host, int *status){
 				servers[i].stratum=req[i].stratum;
 				servers[i].rtdisp=NTP32asDOUBLE(req[i].rtdisp);
 				servers[i].rtdelay=NTP32asDOUBLE(req[i].rtdelay);
-				servers[i].waiting=0;
+				servers[i].waiting--;
 				servers[i].flags=req[i].flags;
 				servers_readable--;
 				one_read = 1;
@@ -469,6 +474,7 @@ int process_arguments(int argc, char **argv){
 		{"use-ipv6", no_argument, 0, '6'},
 		{"quiet", no_argument, 0, 'q'},
 		{"time-offset", optional_argument, 0, 'o'},
+		{"delay", optional_argument, 0, 'd'},
 		{"warning", required_argument, 0, 'w'},
 		{"critical", required_argument, 0, 'c'},
 		{"stratum-warn", required_argument, 0, 'W'},
@@ -484,7 +490,7 @@ int process_arguments(int argc, char **argv){
 		usage ("\n");
 
 	while (1) {
-		c = getopt_long (argc, argv, "Vhv46qw:c:t:H:p:o:W:C:", longopts, &option);
+		c = getopt_long (argc, argv, "Vhv46qw:c:t:H:p:o:d:", longopts, &option);
 		if (c == -1 || c == EOF || c == 1)
 			break;
 
@@ -528,7 +534,10 @@ int process_arguments(int argc, char **argv){
 			break;
 		case 'o':
 			time_offset=atoi(optarg);
-                        break;
+			break;
+		case 'd':
+			delay=atoi(optarg);
+			break;
 		case '4':
 			address_family = AF_INET;
 			break;
@@ -675,6 +684,8 @@ void print_help(void){
 	printf ("    %s\n", _("Offset to result in critical status (seconds)"));
 	printf (" %s\n", "-o, --time_offset=INTEGER");
 	printf ("    %s\n", _("Expected offset of the ntp server relative to local server (seconds)"));
+	printf (" %s\n", "-d, --delay=INTEGER");
+	printf ("    %s\n", _("Delay between each packet (seconds)"));
 	printf (" %s\n", "-W, --stratum-warn=INTEGER");
 	printf ("    %s\n", _("Alert warning if stratum is worse (less) than specfied value"));
 	printf (" %s\n", "-C, --stratum-crit=INTEGER");
@@ -694,6 +705,8 @@ void print_help(void){
 	printf(" %s\n", _("check_ntp_peer."));
 	printf(" %s\n", _("--time-offset is useful for compensating for servers with known"));
 	printf(" %s\n", _("and expected clock skew."));
+	printf(" %s\n", _("--delay is useful if you are triggering the anti-DOS for the"));
+	printf(" %s\n", _("NTP server and need to leave a bigger gap between queries"));
 	printf("\n");
 	printf(UT_THRESHOLDS_NOTES);
 
@@ -708,6 +721,6 @@ void
 print_usage(void)
 {
 	printf ("%s\n", _("Usage:"));
-	printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose] [-o <time offset>]\n", progname);
+	printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose] [-o <time offset>] [-d <delay>]\n", progname);
 }