NTP Monitor
Problem this snippet solves:
Version 9 (tested on v9.2.4)
Based on F5's example monitor, with the NTP check added. We make sure that the node gives us an NTP response and that the node hasn't become stratum 16 (ie, it's lost it's source). We use the CPAN Net::NTP module to make things easy.
Just use it like a normal external monitor, it only uses the default IP and port.
Code :
#!/usr/bin/perl -w ############################################################################### # # # F5 Networks and BIG/ip(c) Copyright # # # # No part of the software may be reproduced or transmitted in any form or by # # any means, electronic or mechanical, for any purpose, without express # # written permission of F5 Networks, Inc. It is against the law to copy the # # software. No part of this program may be reproduced or transmitted in any # # form or by any means, electronic or mechanical, including photocopying, # # recording, or information storage and retrieval systems, for any purpose # # other than the purchasers personal use, without the express written # # permission of F5 Networks, Inc. Copyright (c) 1996-2005 BIG/ip Software. All # # rights reserved. Our services are only available for legal users of the # # program for instance in case we extend our services by offering updating of # # files through Internet. # # # ############################################################################### # # # As for any external monitor program, the first two command # line arguments are the node ip address and the node port. # After that its whatever is supplied via the monitor template. # # Caveat: This does assume that you're using IPv4. # use lib "/shared/lib/perl5"; use strict; use Net::NTP; require 5.005; # Derive and untaint programname. my $programname = '/' . $0; $programname =~ m/^.*\/([^\/]+)$/; $programname = $1; if ($programname eq '') { die "Bad data in program name\n" } # Process ID and file where it's to be stored. The format # is significant. my $node = $ARGV[0]; $node =~ s/^::ffff://; my $port = $ARGV[1]; my $pidfile = "/var/run/$programname.$node..$port.pid"; my $pid = "$$"; # Maintenence. Clean up any existing EAV. if (-f $pidfile ) { open(PID, "<$pidfile"); my $pid =; close(PID); if ( $pid ) { chomp $pid; $pid =~ m/^(\d+)$/; $pid = $1; if ( $pid ) { kill 9, $pid; } } unlink($pidfile); } # Create a new maintenence file. open(PID, ">$pidfile"); print PID $pid, "\n"; close(PID); ########################################3 ## if (try_ntp_test($node,$port)) { print "OK\n"; } unlink($pidfile); exit(0); ######## sub try_ntp_test { # we just make sure we get a response # and that the server isn't a stratum # 16 server (ie, it's lost it's time source). my ($node,$port) = @_; my %response; eval { %response = get_ntp_response($node,$port); }; if ($@) { return 0; } else { if ($response{'Stratum'} =~ /\d+/) { # if the stratum is a number if ($response{'Stratum'} == 16) { return 0; } else { # and it isn't 16 return 1; } } else { return 0; } } }
Tested this on version:
11.0- WeaverJKNimbostratus
The script above uses arguments instead of environment variables.
Script hasn't worked with or without the invalid characters mentioned above.
Thanks for any additional input.
- Mark_57945Nimbostratus
External monitor input handling changed between version 10 and version 11. In version 10 and earlier, they used environment variables to pass the IP and port. Starting in version 11, the IP and port are passed as argv[0] and argv[1].
I don't know what to tell you about the script not working for you. The script above is what I currently have in service.
- WeaverJKNimbostratus
Thanks, Mark, for the background info.
If you don't mind, let's just walk through the steps again...
Should this work: ?
SSH or Console to the F5. Navigate to /shared/lib. Create a directory called "perl5" with 755 permissions. (Note: I created the directory and allowed it to inherit permissions). TFTP the NTP.pm file (from the ntp.zip file from the other post) to /shared/lib/perl5/Net/NTP.pm and set the permissions to 755. Copy the text above and paste it into a notepad.exe text file on a Windows computer. Use that Windows computer to connect to the Configuration Utility (CU). Use CU. Go to System > File Management > External Monitor File List (or something close). Import the contents of the text file while providing the external monitor a name.
Edit the external monitor to verify that it does not contain invalid characters (such as the question mark inside the diamond). Create a Monitor. Define the type as External. Select the External Monitor. Assign the monitor to a Pool. Pool Members are Nodes that are NTP servers.
Did I miss something or should this work?
Thanks!
John
- Mark_57945Nimbostratus
That should work.
- WeaverJKNimbostratus
Thanks, Mark, for your time and patience. I appreciate the explanations.
If/When the monitor works on our systems, I'll follow-up here.
- WeaverJKNimbostratus
Is there anything that needs to be done to ensure perl is working? Can the script (external monitor and NTP.pm) be tested from the command line to directly test functionality of the script between the F5 and the NTP server? If so, how?
At a quick glance (being new to perl), it looks like I'd have to copy the external monitor file over to the F5 as a perl script (such as TFTPing mon_ntp to /var/tmp/test/mon_ntp.pl), perhaps modify the script so that the arguments (IP and Port) are hard-coded, and call the script (/usr/bin/perl /var/tmp/test/mon_ntp.pl). Sound about right? Is there an easier way to test this and see the results/errors?
Thanks in advance!
John
- WeaverJKNimbostratus
I tried what I just suggested... F5_Prompt perl mon_ntp.pl Unrecognized character \xC2 in column 1 at mon_ntp.pl line 27.
I removed the offending characters.
F5_Prompt perl mon_ntp.pl syntax error at mon_ntp.pl line 59, near "= ;" Execution of mon_ntp.pl aborted due to compilation errors.
Perl appears to have a problem with something around this line:
Going through again to see what may have changed.
- WeaverJKNimbostratus
Comparing the code in this thread to the code in the original post (https://devcentral.f5.com/s/articles/ntp-monitor-for-11x-with-complete-instructions-999), I found this difference: Above, line 56: my $pid = ; Original: my $pid = ;
 
When I changed the code back to the original, perl processed further (past line 56).
 
Yeah! This resolved the issue!!!
 
pats self on back
 
I also determined WHY this issue with the code appears above. The code that these F5 web pages is using to parse and display the text treated the "" as something special and this text did not display in the code lines above. I had to preface the less-than symbol with a backslash. Another 10 points!
 
- Mark_57945Nimbostratus
I just checked, and the is there if I try to edit the code on this page. DevCentral is probably blocking things that look like HTML tags to prevent HTML injection. I wonder how I fix that. I can't very well leave it broken.
Ah, that's how. By replacing the < and > with HTML entity strings in the code. sigh
- WeaverJKNimbostratus
Mark - the rest of my post may help. Preface the less-than symbol with a backslash.
No worries. I figured the code was there, just not visible.