Blog Archives

Oracle Enterprise Linux 6.x networking

Lately I got many questions regarding the network configuration of Oracle Enterprise Linux 6 (Red Hat Enterprise Linux 6).
Enough to write a little article about it.

It seems that some of the network configuration was altered in OEL6. The reason as far as I know is the implementation of the NetworkManager daemon. I don’t know why they are using CamelCase for the daemon name, but mind that. Even though the NetworkManager should make the configuration as painless as possible (at least thats what the manual page said), it seems to actually make the configuration more of a pain for some.

Below I will cover some topics in an effort to get you going and remove the pain šŸ™‚

Configuring eth0 for manual operation

  • Step 1: disable the NetworkManager daemon
    service NetworkManager stop
  • Step 2: remove the NetworkManager from Init (start-up)
    chkconfig --level 2345 NetworkManager off
  • Step 3: open the ifcfg-eth0 config file (alter the suffix ‘eth0’ to match the adapter of your choice)
    vi /etc/sysconfig/network-scripts/ifcfg-eth0
  • Step 4: Alter the following to match your environment…
    DEVICE=eth0
    TYPE=Ethernet
    HWADDR={Your MAC address here}
    ONBOOT=yes
    NM_CONTROLLED=no
    BOOTPROTO=static
    IPADDR=192.168.1.10
    #PREFIX=24Ā Ā Ā  [can be used alternativly to NETMASK=]
    NETMASK=255.255.255.0
    NETWORK=192.168.1.0
    BROADCAST=192.168.1.255
    GATEWAY=192.168.1.1
    
  • Step 5: Write/close the configuration fileĀ (:wq in vi)
  • Step 6: Restart the network service
    service network restart
  • TIP 0: Obviously match the configuration above to match your home network.
  • TIP 1: NetworkManager is not always present in which case you can obviously skip step 1 – 2.
  • TIP 2: There are reports that NETMASK=xxx.xxx.xxx.xxx is actually more stable then PREFIX=xx notation.
    My advice, use NETMASK= which is also better understood by non networking guys.
  • TIP 3: Not sure about the correct NETWORK, NETMASK, BROADCAST or PREFIXĀ settings, give ipcalc a try:
    ipcalc --netmask {IPADDR}
    ipcalc --prefix {IPADDR} {NETMASK}
    ipcalc --broadcast {IPADDR} {NETMASK}
    ipcalc --network {IPADDR} {NETMASK}
    

Configuring DNS

DNS always seems to be a bugger and a hard one to understand. Do note that DNS is JUST A IP PHONEBOOK. Nothing fancy there. Also there are various ways of configuring DNS. One way is by adding the DNS configuration in the ifcfg-suffix configuration file with the DNS1=ip.ip.ip.ip DNS2=ip.ip.ip.ip keywords.Ā As anĀ effect, the networking service will update the appropriateĀ configuration files.Ā ToĀ be frank,Ā I find this to be confusing and do not like duplicate configurations everywhere in my -has to be clean- environment. My advice is to configure the DNS is the appropriate files directly like this…

  • Step 1: EditĀ theĀ resolve.conf where DNS is configured.
    vi /etc/resolv.conf
  • Step 2: Add or Alter the following to match your environment
    search mydomain.home
    nameserver 192.168.1.1
    nameserver 8.8.8.8
    
  • Step 3: Test to see if name resolution works
    nslookup
    set debug
    www.google.com
    
  • TIP 1: Linux actually tries to find the ip in the /etc/hosts file first. If you know the hostnamename and FQDN to an certain IP and it can be classified as static. Consider using the hostsfile instead of a centralized DNS. This will boost performance if the name is resolved often. If multiple systems use and depend on a machine reference, use centralized DNS in order to lighten the administrative tasks.
    vi /etc/hosts
  • TIP 2: Experiencing slow log on times or slow application performance? A faulty DNS configuration might just be theĀ cause. A quick way to test this is byĀ temp. disabling DNS all together. This can be done by editing the /etc/nsswitch.conf file.
    vi /etc/nsswitch.conf
    • alter the line
      hosts:Ā Ā Ā Ā  files dns
    • to the line
      hosts: files
    • write the file and test if the performance has improved.
  • The reason for this is that DNS is often used to register user logon or session information based on the visitors IP address. Examples are the ssh daemon, ftp servers, webservers, linux logon, etc.

STATIC ROUTES

In some case you want linux to use alternative routes to access certain Linux resources. The way to go in these cases are creating routes. In most cases you want these to be presistant in which case ‘route add –‘ wont suffice. In our example we will create two new routes. On describing a route to a specific host, the other describing the route to a specific network. Alter the example to match your needs.

  • STEP 1: Create a new file called static-routes in theĀ /etc/sysconfig/ directory
    vi /etc/sysconfig/static-routes
  • STEP 2: Add the following, obviously matching your specific needs
    any net 192.168.2.0/24 gw 192.168.1.254 metric 1
    any host 192.168.2.254 gw 192.168.1.254 metric 1
  • STEP 3: Restart the network service
    service network restart
  • TIP 1: SIOCADDRT: No such process means the designated gateway doesnt exsist on any known interface. (typo?)
  • TIP 2: view the route information usint the route command
  • TIP 3: use the ipcalc –prefix {IPADDR} {NETMASK} command to determin the right /prefix for your environment.
  • TIP 4: In older environments the ifup-routes is used, this shscript still exsists in the /etc/sysconfig/network-scripts/ifup-routes

Locate my mac address

The ifcfg-eth# config allows you to configure the specific mac address to guarantee the IP is bound to the right adapter. In virtualized environments this might save you a lot of trouble in the situation where the virtualized domain is altered. On the other hand it might cause trouble when the staticly configured MAC is migrated in virtual environments. Either case, you might want to know the MAC linux sees belonging to an certain adapter. You can find the MAC address in the following location:

 cat /sys/class/net/eth0/address

Obviously you need to alter eth0 in the path to match the adapter you are looking for. Not sure? The change directory to /sys/class/net and perform a list to see all discovered and registered adapters.

IPTables (Linux firewall)

By default IPtables (which is the linux firewall) is enabled. You can view the running configuration by checking the service status like this.

 service iptables status

You can simply turn the firewall off by modifying and applying steps 1-2 of the first configuring eth0 instruction. This will reduce the security of your linux platform significantly. My advice, add the ports you need for your services and let IPtables protect you. The easiest way is by simply editing the iptables configuration file.

 vi /etc/sysconfig/iptables 

Adding a port is as easy as copy/pasting the always present firewall rule that allowes port 22 (ssh). Copy past it and alter the -p (protocol) -dport (destination port) to match your needs. For example, allowing HTTP/HTTPS.

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

afterward restart iptables

service iptables restart

TIP: If you are experimenting with IPv6 (then your Instant COOL!), mind that the ipv6 firewall is called ip6tables and the configuration is called the same. The basic iptables doesnt handle ipv6 at all.

TIP: If you are using ipv6 code your IPv4 ip to ease administration. Example:

ipv4: 192.168.10.1/32
ipv6: 2001::0192:0168:0010:0001/64
Then route on the nibble of choice.

Additional questions?

Just post it below and maybe ill respond in due time šŸ™‚

Fix the inline images -bug- in glpi knowledgebase (htmLawed.php)

GLPI-0-84-8 FIX

GLPI uses the htmLawed filter to clean inserted HTML code. Documentation on this framework can be found here: http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/

Problem with this framework in GLPI is that it does not match image tags properly when they contain inline base64 information.

Here is a simple fix to overcome this problem. The htmLawed.php file can be located in %glpi_root%/lib/htmlawed/htmLawed.php. Open it with your favorite editor. Next locate line: 47. Somewhere arround that area you should find the following.

Web - sftp___nagios@glpi.amis.nl_var_www_glpi_prod_lib_htmlawed_htmLawed.php - A_2013-10-29_12-34-30

Add ‘data’ at the end of the marked line.

$x = (isset($C['schemes'][2]) && strpos($C['schemes'], ':')) ? strtolower($C['schemes']) : 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https, data';

The above will stop htmLawed from adding disabled: to the data: in the src=”” tag.

The next step is a bit trickier.

Now we need to actually change the hl_tag function. In the file locate the hl_tag($t) function somewhere around line:407. In this codeblock we are looking for the regular expression marked in the image below:

Web - sftp___nagios@glpi.amis.nl_var_www_glpi_prod_lib_htmlawed_htmLawed.php - A_2013-10-29_12-38-10

This is the expression that doenst match the valid <img> tags within the htmLawed. We dont want to create leaks here, so all we need to do is introduce an exception for our images. You can do so by replacing the text with the following:

Web - sftp___nagios@glpi.amis.nl_var_www_glpi_test_lib_htmlawed_htmLawed.php - A_2013-10-29_12-49-27

In code:


if(!preg_match('`^&lt;(/?)([a-zA-Z][a-zA-Z1-6]*)([^&gt;]*?)\s?&gt;$`m', $t, $m)){
if(strstr($t, 'data:image')){
return $t;
}else{
return str_replace(array('&lt;', '&gt;'), array('&amp;lt;', '&amp;gt;'), $t);
}
}elseif(!isset($C['elements'][($e = strtolower($m[2]))])){
return (($C['keep_bad']%2) ? str_replace(array('&lt;', '&gt;'), array('&amp;lt;', '&amp;gt;'), $t) : '');
}

After this, the images should show up just fine

GLPI - Knowledge base_2013-10-29_12-50-51

I hope this was helpfull šŸ™‚

peimg.exe missing? here is how to fix it :)

Facts.

peimg is not being used anymore in the WAIK for windows 7. Instead you need to use the dism command. because the help is hidden pretty well, here is the Help you prob. are looking for šŸ™‚

To get all the available options on the “offline” wim image provided by dism you need to run the following.


# Mount the image as usual (use the WAIK command line from the start menu

imagex /mountrw C:\path\to\image.wim {1/2}* C:\path\to\mount-dir\

*There can be multiple images in a wim image, for boot.wim these are 1 = Microsoft Windows PE, 2= Microsoft Windows Setup. The 1 or 2 in the given command selects the required image.

#To get all the dism options type the following;
dism /image:C:\path\to\mount-dir /?

Keep in mind that sub options have new help menus. For example, adding additional drivers has new help instructions that are accasible by calling;

dism /image:c:\path\to\mounted\image /add-driver /?

All the base options provided by dism

Image Version: 6.1.7600.16385

The following commands may be used to service the image:

UNATTEND SERVICING COMMANDS:
/Apply-Unattend - Applies an unattend file to an image.

DRIVER SERVICING COMMANDS:
/Remove-Driver - Removes driver packages from an offline image.
/Add-Driver - Adds driver packages to an offline image.
/Get-DriverInfo - Displays information about a specific driver
in an offline image or a running operating system.
/Get-Drivers - Displays information about all drivers in
an offline image or a running operating system.

WINDOWS PE COMMANDS:
/Apply-Profiles - Applies profiles to the Windows PE image.
/Disable-Profiling - Disables profiling.
/Enable-Profiling - Enables profiling.
/Get-PESettings - Displays Windows PE image information.
/Get-Profiling - Gets the enabled/disabled state of the Windows PE
profiler.
/Get-ScratchSpace - Gets the configured amount of Windows PE system
volume scratch space.
/Get-TargetPath - Gets the target path of the Windows PE image.
/Set-ScratchSpace - Sets the scratch space of the Windows PE image.
/Set-TargetPath - Sets the target path of the Windows PE image.

INTERNATIONAL SERVICING COMMANDS:
/Set-LayeredDriver - Sets keyboard layered driver.
/Set-UILang - Sets the default system UI language that is used
in the mounted offline image.
/Set-UILangFallback - Sets the fallback default language for the system
UI in the mounted offline image.
/Set-UserLocale - Sets the user locale in the mounted offline image.
/Set-SysLocale - Sets the language for non-Unicode programs (also
called system locale) and font settings in the
mounted offline image.
/Set-InputLocale - Sets the input locales and keyboard layouts to
use in the mounted offline image.
/Set-TimeZone - Sets the default time zone in the mounted offline
image.
/Set-AllIntl - Sets all international settings in the mounted
offline image.
/Set-SKUIntlDefaults - Sets all international settings to the default
values for the specified SKU language in the
mounted offline image.
/Gen-LangIni - Generates a new lang.ini file.
/Set-SetupUILang - Defines the default language that will be used
by setup.
/Get-Intl - Displays information about the international
settings and languages.

PACKAGE SERVICING COMMANDS:
/Add-Package - Adds packages to the image.
/Remove-Package - Removes packages from the image.
/Enable-Feature - Enables a specific feature in the image.
/Disable-Feature - Disables a specific feature in the image.
/Get-Packages - Displays information about all packages in
the image.
/Get-PackageInfo - Displays information about a specific package.
/Get-Features - Displays information about all features in
a package.
/Get-FeatureInfo - Displays information about a specific feature.
/Cleanup-Image - Performs cleanup and recovery operations on the
image.

For more information about these servicing commands and their arguments,
specify a command immediately before /?.

Examples:
DISM.exe /Image:C:\test\offline /Apply-Unattend /?
DISM.exe /Image:C:\test\offline /Get-Features /?
DISM.exe /Online /Get-Drivers /?

Check_iostat.pl version 0.9.7

Previous version and detaild information
https://sysengineers.wordpress.com/2010/02/05/check_iostat-for-nagios-version-0-9-5/

Application Goal:
Check disk IO using a simple perl script and possibly the counters allready available in the linux /proc/ directory. The program must be able to run under Nagios and should return a ‘Nagios’ correct syntax to the prompt. This way the plugin should be usable for Linux users to monitor their Disk IO within Nagios. The program should also report back performance information in the ‘Nagios’ compatible syntax so that graphing is available in the ‘Nagios’ / Cacti / Centreon add-ons.

Changes
Fixed lacking devision in validated summed results
Added sprintf functions rounding the validated numbers with 2 dimentions
Fixed some declaration problems
Added -debug switch to enable the debugging options
Coded arround the used math::Complex functions and removed the module
Improved the debugging output (readability)
Small fixes in de syntax

Installation
1. Copy the code below to your clipboard (ctr+c or the copy-button inside the code field)
2. Logon to the linuxbox with the nagios or nrpe client.
3. browse to the plugin-dir usually cd /usr/local/nagios/libexec/
4. Create a new file vi ./check_iostat.pl
5. Press insert and paste the code inside (when using putty paste is done with a rightmouse click)
6. save the file (esc > : > rq > enter, when using vi)
7. give the file execute rights using chmod +x ./check_iostat
8. make nagios the owner chown nagios:nagios ./check_iostat
9. Test it using updatedb& ./check_iostat -d sd -dbu -dbuw 70 -dbuc 88 -kbs -kbsw 10000 -kbsc 50000 -p

Next configure a nagios command or use nrpe and have fun šŸ™‚

#!/usr/bin/perl
# Written by Chris Gralike @ AMIS.
# Perl based check command to fetch and report the
# TPS (transactions per second) and IO wait times.
# Plugin uses iostat for opperation.
# Verion 0.9.7
#
# Changes post 0.9.7 >> 28-05-2010
# Line 298...303 Prevent devision by zerro else exit because no data was collected  - Bug reported by Epiq.
# Line 380       Correction of a type that prevented pref data of r/s w/s from being printed. - Bug reported by Epiq.
# Line 40        Added dm as possible device input used by the linux LVM. - Suggested by Epiq.
# Line 269       Extended the device if/pragmatch validation to match more devices - Added by Jean Ventura.
#
###########################
use Switch;
use warnings;

my($numArgs,
   $debug,	# Print debugging information.
   $DevType,	# Used to match a certain devicetype from the resulting IOstat rows.
   $IOBIN,	# Is used to store a path to the iostat binairy for execution.
   $Samples,	# Used to store the initial Samples returned by iostat.
   @SampleRows, # Used to store the rows generated by the splitted samples.
   $firstseen,  # Used to keep track of the found devices (IOstat might return a set of devices i.e sda, sdb, sdc etc.)
   $Items,      # Used in the foreach to store the row being parsed.
   @cols,       # Used to store the columns in a row after an split.
   $dev,	# Used to create a symbolic link to dynamicly create a var.
   $rqm,
   $val,
   $devtypes,
   $rws, $rws_warn, $rws_crit,
   $kbs, $kbs_warn, $kbs_crit,
   $awt, $awt_warn, $awt_crit,
   $svc, $svc_warn, $svc_crit,
   $devices, $itd,$v1,$v2,$v3,
   $v4,$v5,$v6,$v7,$v8,$v9,$v10,$v11,
   $dbu, $dbu_warn, $dbu_crit
   );

# Preparing to collect the dangerious user input.
# Here is a list of known device types. Please add any device you would like to monitor..
$devtypes=";sd;hd;dm;";
$numArgs = $#ARGV + 1;
$critical_global = 0;
$warning_global = 0;

if($numArgs gt '0'){
	for($i=0;$i<$numArgs;$i++){
	# Process our command line arguments and do some basic testing.
	# Could be make human save in the future.
	switch ($ARGV[$i]) {
		# Enable debugging.
		case '-debug'{
				$debug = 1;
			     }
		# Handle device type
		case '-d'    {
				$val=$ARGV[$i+1];
		 		if( (index($devtypes, $val)) gt '-1'){
					$DevType=$val;
					$i++;
		  		}else{
					print "Ivalid Disktype found. Typo?\n"; exit 1;
		  		}
			     }
		# Do we need to check rqm?
		case '-rqm'  { $rqm='1'; }
		# What is the warning treshold?
		case '-rqmw' {
				$val=$ARGV[$i+1];
				# Is the value nummeric?
				if($val=~m/[0-9]*/){
					$rqm_warn= int $val;
					$i++;
				}else{
				# Possible type?
					print "Non Numeric value used in rqmw, typo? \n"; exit 1;
				}
			     }
		case '-rqmc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rqm_crit= int $val;
					$i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rqmc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check rws?
		case '-rws'  { $rws='1'; }
		case '-rwsw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rws_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rwsw, typo? \n"; exit 1;
                                }
			     }
		case '-rwsc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rws_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rwsc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check kbs?
		case '-kbs'  { $kbs='1'; }
		case '-kbsw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $kbs_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in kbsw, typo? \n"; exit 1;
                                }
			     }
		case '-kbsc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $kbs_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in kbsc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check awt?
		case '-awt'  { $awt='1'; }
		case '-awtw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $awt_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in awtw, typo? \n"; exit 1;
                                }
			     }
		case '-awtc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $awt_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in awtc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check svc?
		case '-svc'  { $svc='1'; }
		case '-svcw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $svc_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in svcw, typo? \n"; exit 1;
                                }
			     }
		case '-svcc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $svc_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in svcc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check dbu?
		case '-dbu'  { $dbu='1'; }
		case '-dbuw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $dbu_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in dbuw, typo? \n"; exit 1;
                                }
			     }
		case '-dbuc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $dbu_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in dbuc, typo? \n"; exit 1;
                                }
			     }
		# performance data. Might make the string human unreadable.. ow well, no loss there <img src="https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
		case '-p'    { $prf='1'; }
		# Print full messages per device overview.
		#case '-m'    { $fms='1'; }
		# Most used help switches.
		case '--help'{ USAGE(); }
		case '-h'    { USAGE(); }
	}
	}
	# Check if the basic requirements are met.
	if(!($DevType) ||  !(($rqm || $rws || $kbs || $awt || $svc || $dbu))){
		print "Minimal requiremens, device and checktype are not met\n";
		USAGE();
	}
}else{
	# No input was given. Show the Usage();
	USAGE();
}

# Locate the IOBin binairy needed to fetch the stats.
chomp($IOBIN=`which iostat`);

if( !(-f $IOBIN) || !(-x $IOBIN)){
	print "A working iostat command is needed for this script to work \n";
	print "Also make sure the sysstat service is running! /etc/init.d/sysstat \n";
	exit 1;
}

if($DevType){
	# IF IOStat is found, lets collect some data.
	chomp($Samples=`$IOBIN -d -x -k 1 5 | grep $DevType`);
}else{
	print "Please select a valid devicetype \n";
	exit 1;
}

# Break the samples up in lines so we can evaluate them.
# The first set of samples are avg. values counted from boot.
# We need to discard them and collect the remaining samples.
@SampleRows=split(/\n/, $Samples);

# Firstseen is used to track de device names and to skip the first itteration of iostat that contains
# avg stats counted from system boot time, stats we cant use here sadly <img src="https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
$firstseen='';
$CT=0;
$Devices=0;

# Print Debugging information
if($debug){
	    print "### Data collected ###\n";
	    print "dev|rrqm|wrqm|r/s|w/s|rKB/s|wKB/s|rq-sz|qu-sz|await|svctm|util%|\n";
}

foreach $Items (@SampleRows){
	 # Break the latter up in usable columns.
        @cols=split(/\s+/,$Items);
	 # We only want a certain device type. So lets match what we know.
	 # Disks usualy have a prefix for example (scsi = sd) its set using
	 # the DevType var.
         if($cols[0]=~m/$DevType-[0-9]$/ || $cols[0]=~m/$DevType[a-z]$/ || $cols[0]=~m/$DevType[a-z][0-9]$/){

		$dev=$cols[0];
		if((rindex $firstseen, $dev) gt '-1'){
			#Declare new $$
			#my @$dev;
			# Store the collected data in the correct (dynamic) vars.
			$$dev[1]+=$cols[1];	# rrqm/s   Read Requests Merged per Second.
			$$dev[2]+=$cols[2];	# wrqm/s   Write Requests Merged per Second.
			$$dev[3]+=$cols[3];	# r/s      Number of read requests issued per Second
			$$dev[4]+=$cols[4];	# w/s      Number of write requests issued per Second
			$$dev[5]+=$cols[5];	# rKB/s    Number of Kilobytes read per Second.
			$$dev[6]+=$cols[6];	# wKB/s    Number of Kilobytes written per Second.
			$$dev[7]+=$cols[7];	# Avgrq-sz Avarage size (in sectors) of the issued requests.
			$$dev[8]+=$cols[8];	# Avgqu-sz Avarage Queue length of the requests issued.
			$$dev[9]+=$cols[9];	# Await	  Avarage wait time in ms for IO requests to be served.
			$$dev[10]+=$cols[10];	# svctm    Avarage service time in ms for IO requests that where issued.
			$$dev[11]+=$cols[11];   # %util    Precentage of CPU time during IO requests (bandwidth util), saturation at 90~100%
			$CT++; # Add a new itteration to the count
			# Print some debugging vars if requested. to show the data is collected.
			if($debug){
				    print "$dev|$cols[1]|$cols[2]|$cols[3]|$cols[4]|$cols[5]|$cols[6]|$cols[7]|$cols[8]|$cols[9]|$cols[10]|$cols[11]|\n";
			}
		}else{
			$Devices++;
			$firstseen.="$dev;";
		}
	}
}

# Prevent $itd (itterations / disk) from becomming zerro and exit when no devices are found.
# on line 299.
if($Devices > 0){
	$itd = ($CT / $Devices);
}else{
	print "No performance data was captured. Please check if the device name is correct\n"; exit 1;
}

# Print debugging information
if($debug){
	print "###Devices Counted###\n";
	print "Number of devices : $Devices\n";
	print "Number of itterations per device : $itd\n";
	print "Total Number of Itterations : $CT\n";
}
# Lets collect the device information from the firstseen var
# and start processing it for some perf check/data
# Lets also recycle some previously used vars for this.
@cols=split(/;/,$firstseen);
foreach $Items (@cols){
	# Items now contains the devicenames needed to access the data again.
	# We now need to check them against some basic tresholds
	# Print a nice table with the calculated values when we are in debug.

  	# Print debugging information
	if($debug){
		   print "### Counted Values ###\n";
		   print "$Items|$$Items[1]|$$Items[2]|$$Items[3]|$$Items[4]|$$Items[5]|$$Items[6]|$$Items[7]|$$Items[8]|$$Items[9]|$$Items[10]|$$Items[11]|\n";
        }

	#What do we want to check against a treshold?
	#First check the selection if any.
	if($rqm || $rws || $kbs || $awt || $svc || $dbu){

		#Set the counts to zerro
		$critical_state='0';
		$warning_state='0';
		$ok_state='0';
		# Devide
		$round="%.2f";
		$v1 = sprintf($round, ($$Items[1] / $itd));
        $v2 = sprintf($round, ($$Items[2] / $itd));
		$v3 = sprintf($round, ($$Items[3] / $itd));
        $v4 = sprintf($round, ($$Items[4] / $itd));
		$v5 = sprintf($round, ($$Items[5] / $itd));
        $v6 = sprintf($round, ($$Items[6] / $itd));
		$v7 = sprintf($round, ($$Items[7] / $itd));
        $v8 = sprintf($round, ($$Items[8] / $itd));
		$v9 = sprintf($round, ($$Items[9] / $itd));
        $v10 = sprintf($round, ($$Items[10] / $itd));
        $v11 = sprintf($round, ($$Items[11] / $itd));

		# Requests Merged per second.
		if($rqm){
			# Critical
			if(($v1 >= $rqm_crit) || ($v2 >= $rqm_crit)){
				$critical_state+='1';
			# Warning?
			}elsif(($v1 >= $rqm_warn) || ($v2 >= $rqm_warn)){
				$warning_state+='1';
			# Ok
			}else{
				$ok_state+='1';
			}
			# Add the counters to the performance vars
			$perf.="$Items-rrqm/s=$v1; $Items-wrqm/s=$v2;";
		}
		# Reads / Writes per second.
		if($rws){
			if(($v3 >= $rws_crit) || ($v4 >= $rws_crit)){
	                    	$critical_state+='1';
             		# Warning?
               	 	}elsif(($v3 >= $rws_warn) || ($v4 >= $rws_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			# Add the counters to the performance var.
			$perf.="$Items-r/s=$v3; $Items-w/s=$v4; ";
		}
		# KB Read/Writes per second.
		if($kbs){
			if(($v5 >= $kbs_crit) || ($v6 >= $kbs_crit)){
	                        $critical_state+='1';
	                # Warning?
       	         	}elsif(($v5 >= $kbs_warn) || ($v6 >= $kbs_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                       	 	$ok_state+='1';
                	}
			$perf.="$Items-rKB/s=$v5; $Items-wKB/s=$v6; ";
		}
		# Avarage wait time
		if($awt){
			if(($v9 >= $awt_crit)){
                        	$critical_state+='1';
                	# Warning?
                	}elsif(($v9 >= $awt_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-await=$v9; ";
		}
		# Avarage service time issuing time
		if($svc){
			if($v10 >= $svc_crit){
       	                	$critical_state+='1';
                	# Warning?
                	}elsif($v10 >= $svc_warn){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-svctm=$v10; "
		}
		# Disk bandwidth Utilization
		if($dbu){
			if($v11 >= $dbu_crit){
                	        $critical_state+='1';
              	  	# Warning?
               	 	}elsif($v11 >= $dbu_warn){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-util=$v11%; ";
		}
	}else{
		print "At least select a value to measure..\n";
		exit 1;
	}
	# Print Debugging information about the validated values.
	if($debug){ print "### validated Devisions ###\n";
                    print "$Items|$v1|$v2|$v3|$v4|$v5|$v6|$v7|$v8|$v9|$v10|$v11|\n";
	}

	# Create a messages var.
	$mgs.="$Items=O:$ok_state,W:$warning_state,C:$critical_state; ";

	# Track the global state (1 crit 1 warn)
	if(($critical_state gt '0') || ( $critical_global gt '0')){
		$critical_global+='1';
	}
	if(($warning_state gt '0') || ( $warning_global gt '0')){
		$warning_global+='1';
	}
}

# Compose a nice nagios output.
if($critical_global >= '1'){
	print "CRITICAL:";
	$exit=2;
}elsif($warning_global >= '1'){
	print "WARNING:";
	$exit=1;
}else{
	print "OK:";
	$exit=0;
}
# Print the remainder, the most important data was processed.
print $mgs; if($prf){ print "|$perf"; } print "\n";
exit $exit;

###Subroutines
sub USAGE{
	print "
                Usage : $0 -d [Dev] [options]

		-p Print performance data about the measured samples.

		-d {grep string used on IOstat}
		examples;
                 sd     #All scsi devices.
                 hd     #All Cdrom devices.
		 sda	#Only device sda

                [Available Measurement Options]
                -rqm -rqmw val -rqmc val        # read/write merged             [#]
                -rws -rwsw val -rwsc val        # read/write per second.        [s]
                -kbs -kbsw val -kbsc val        # KBs read/written per second.  [s]
                -awt -awtw val -awtc val        # Avarage IO wait time.         [ms]
                -svc -svcw val -svcc val        # Avarage service IO wait time. [s]
                -dbu -dbuw val -dbuc val        # Disk utilization              [%]\n";
        exit 1;
}

Elevation and altering hosts / system files in windows7

In the past days we started to roll out the first of many windows 7 clients we noticed that some of my collegues where having trouble altering system configuration files. One of the files that was most discussed was the local hosts file that allows you to configure name to ip mappings on the local machine.

The reason this file can`t be edited on the fly is because you need to ‘elevate’ the editor or command prompt to gain write permissions inside the windows folder. Even though you ‘might’ be part of the local administrators groep doesnt mean these priviledges are available on the fly as was the case in XP. Disabling the UAC in this matter will only remove the ‘warnings’ from your screen but still doesnt mean the ‘elevation’ can be skipped for administrative tasks.

In some cases windows 7 will run an program as administrator (elevated) by default, in these cases a ‘small bleu/yellow shield’ will be displayed near the link. In all other cases elevation should be done by ‘you’ or progamatically by the program itself.

But how to elevate in windows 7?

Run single command as administrator
1. open the start menu and locate the ‘search programs and files’ field.
2. In the field type the following command:
notepad c:\%systemroot%\system32\drivers\etc\hosts
3. Next execute this command using the following key combination:
press-hold ‘control + shift’ and hit enter.
4. confirm the UAC message warning you for the elevation.

Step 4 can be used with alternative executables as well but only works (could be a bug) in the ‘search programs and files’ field. Using the ‘windows-key + r’ to open the ‘run dialog’ wont allow you to elevate using the ‘control + shift’ combination.

Shortcut manually as administrator
In XP there was a somewhat ‘hidden’ feature called the ‘run as’ option that appeared when a shortcut was rightclicked while holding the left shift key. In windows 7 microsoft now shows a ‘run as administrator’ option by default (thanks for that šŸ™‚ ). This means that ‘any’ shortcut can be ran as administrator (elevated) by simply right-clicking it and selecting the ‘run as administrator’ option.

Set shortcut to allways run as administrator
If you like to run programs as administrator by default you will need to create a shortcut on your desktop. Next edit the properties of the shortcut and locate the ‘compatibility’ tab. In the bottom there should be an option called ‘privilege level’ that allows you to set the ‘magic switch’ called ‘run this program ad an administrator’.

Scripts as administrator?
Scripts are always a fun part when it comes to elevation. One thing to take notice about is that non-functioning login scripts are usualy caused by default policies that are in place inside the windows7 host. In other words ‘Configuration errors’. Please refference the microsoft documentation about this.

For all other ‘scripting’ tasks if elevation is required from within your script, have a look at the powertoys ‘elevation’ found here,
http://technet.microsoft.com/en-us/magazine/2008.06.elevation.aspx

Other ‘tricks’ that i have seen used where executing ‘other’ vb scripts from the initial script using a ‘runas wscript’ shell command. Downside is that you might need to hardcode passwords in there wich i think is a ‘worst’ practise in any situation and shouldnt be used. I leave the choice to you on this subject.

Hope this helps.
Rgrds,

Adding perfmon counters using nrpe and centreon

In this little tutorial a detailed description on how to succesfully monitor and addĀ various windows counters using the check_nrpe command and the NSClient++ agent for windows using the Centreon configuration and MonitoringĀ GUI for Nagios. Yup, its all open source, and free for usage…
Read the rest of this entry

Altering the Nagios daemon startup script to include NDO.

previously I wrote an article on how to create a deamon script for ndo. But when you are using Centreon the only “nice” way to do this is by altering the Nagios startupscript to include the ndo part.

Here is what i have done to make this possible.

First i wrote a function to find the PIDs for the ndo deamon process based on a specific config. In this one the config is hardcoded,
but you might also replace the $NagiosNdoConfig with $1 instead and call the function like;

getNdoPid “/usr/local/nagios/etc/yourconfig.cfg”

getNdoPid ()
{
 #Declare a var containing the correct ndo PID, there are processes being forked from ndo so we need to
 #do some awk filtering also to fetch the correct one.
 #Not that the parent process always has a parent pid "1" so we use that to filter the parent from the childs.
 ndoPID=`ps -ef | grep $NagiosNdoConf | grep "?" | awk -F ' '  '{if($3 == '1') print $2}'`
        #next we validate if we got an pid returned to us, and fill a wrapper that we will use like $? that ill convieniently call "ls" LastState.
        if [[ "$ndoPID" == '' ]]; then
            ls=1;
        else
            ls=0;
        fi
}

Next using the getNdoPid function u wrote another two functions to start and to stop the ndo daemon. I choose this method so i can include these function inside the existing start stop scripting used by nagios. In effect when you start nagios, th start case select is used which will call our ndo start script.

The ndo kill function

kill_ndo ()
{
        #Find the actual PID
        if [[ "$ndoPID" == '' ]]; then
             #No process running to kill...
             ls=0;
        else
             kill $ndoPID;
             sleep 2 #parent needs some time to kill the child processes if any
             getNdoPid
             if [[ "$ls" == '1' ]]; then
                   ls=0;
             else
                   ls=1;
             fi
        fi
}

and the start portion…
The ndo start function

start_ndo ()
{
        #always make sure ndo isnt running!
        $NagiosNdo -c $NagiosNdoConf;
        if [[ "$?" == '0' ]]; then
                ls=0;
        else
                ls=1;
        fi
}

Again i am using the ls (laststate) var to save the last state of the executed command. This is important because the state of a command can only be tested right after execution of that command. by using the ls var i make sure i am always testing the correct result. this is because the $? is also overwritten when performing an var assignment, if test etc.

Next I added a few vars for configuration, stuff like where the ndo2db bin is located, and the config file.

NagiosNdo=/usr/sbin/ndo2db;
NagiosNdoConf=/usr/local/nagios/etc/ndo2db.cfg;

naturally the NDO bin could also be found like;
NagiosNdo=`which ndo2db`;
Bu this will require the ndo2db bin to be somewhere in the path var. We are not sure this is always the case because there is no consensus on where these nagios bins should be placed. This may vary from distro to distro and from user to user. In my case, it being placed inside /user/bin this whould also work.

I also extended the functionality of the startupscript by adding new options to start, stop and restart the ndo deamon by using the nagios startupscript. This is what i did.

inside the “case” statement where the “/etc/init.d/nagios args” are tested i added some new options namely “startndo, stopndo, restartndo” and this is what it looks like.

For the option “/etc/init.d/nagios startndo”

 startndo)
                getNdoPid
                if [[ "$ls" == '1' ]]; then
                    start_ndo
                    if [[ "$ls" == '0' ]]; then
                        echo 'NDO deamon started succesfully';
                        exit 0;
                    else
                        echo 'Failed to start NDO, check your logging for more info';
                        exit 1;
                    fi
                else
                    echo "Ndo deamon allready running with PID : $ndoPID";
                    exit 1;
                fi
                ;;

for the “/etc/init.d/nagios stopndo” option

stopndo)
                getNdoPid
                if [[ "$ls" == '1' ]]; then
                     echo "$ls";
                     exit 1;
                else
                     kill_ndo
                     sleep 2 #it needs some time to kill the childs (that get ppid 1 when the parent quits)
                     getNdoPid
                     if [[ "$ls" == '1' ]]; then
                         echo "Ndo stopped succesfully";
                         exit 0;
                     else
                         echo "Unable to kill ndo, please review you logging";
                         exit 1;
                     fi
                fi
                ;;

And a restart option “/etc/init.d/nagios restartndo”

restartndo)
                $0 stopndo
                $0 startndo
                ;;

To include the start and stop options in the nagios start and stop process all you need to do is add the start and or stop options in there.
Here is an example

 start)
                echo -n "Starting nagios:"
                $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1;
                if [ $? -eq 0 ]; then
                        su - $NagiosUser -c "touch $NagiosVarDir/nagios.log $NagiosRetentionFile"
                        rm -f $NagiosCommandFile
                        touch $NagiosRunFile
                        chown $NagiosUser:$NagiosGroup $NagiosRunFile
                        $NagiosBin -d $NagiosCfgFile
                        if [ -d $NagiosLockDir ]; then touch $NagiosLockDir/$NagiosLockFile; fi
                        #chmod 777 $NagiosCommandFile
                        start_ndo
                        echo " done."
                        exit 0
                else
                        echo "CONFIG ERROR!  Start aborted.  Check your Nagios configuration."
                        exit 1
                fi
                ;;
#Stop portion
stop)
                echo -n "Stopping nagios: "

                pid_nagios
                killproc_nagios nagios
                kill_ndo
                # now we have to wait for nagios to exit and remove its
                # own NagiosRunFile, otherwise a following "start" could
                # happen, and then the exiting nagios will remove the
                # new NagiosRunFile, allowing multiple nagios daemons
                # to (sooner or later) run - John Sellens
                #echo -n 'Waiting for nagios to exit .'
                for i in 1 2 3 4 5 6 7 8 9 10 ; do
                    if status_nagios > /dev/null; then
                        echo -n '.'
                        sleep 1
                    else
                        break
                    fi
                done
                if status_nagios > /dev/null; then
                    echo ''
                    echo 'Warning - nagios did not exit in a timely manner'
                else
                    echo 'done.'
                fi

                rm -f $NagiosStatusFile $NagiosRunFile $NagiosLockDir/$NagiosLockFile $NagiosCommandFile
                ;;

        status)
                pid_nagios
                printstatus_nagios nagios
                ;;

Now when i start and stop nagios using the centreon “start / stop / reload” options my ndo daemon is also started / stopped. Ps. This manual uses Nagios 3.0 and Centreon 2.2

This is what a restart looks like šŸ˜‰

[root@UX127 var]# service nagios restartndo
Ndo stopped succesfully
NDO deamon started succesfully

Rgrds,