Pages

Friday, August 29, 2014

Monitor your SSL certificates through Nagios with shell scripts

Recently I had a requirement to monitor few SSL certificate expiry dates through Nagios. The easiest method was to define a service with check_http. –S for SSL and –C for warning dates.

define service{
        use             generic-service         ; Inherit default values from a template
        host_name               XXXweb
        service_description     XXX.lk Certificate Expire
        check_command   check_http! -S -H XX.XX.XX.XX -C 90
        }

That worked for some hosts but unfortunately there were some SSL issues in some hosts.
But I could get the certificate details through openssl command.
echo | openssl s_client -connect XXX.lk:443 2>/dev/null | openssl x509 -noout -dates

So what my option was to write a shell script with relevant EXIT codes to Nagios and configure Nagios to run it periodically.  
Step 1
Created a separate command definition in /etc/nagios/objects/commands.cfg
define command{
        command_name    check_cus_command
        command_line    $ARG1$
        }

So I need only to call check_cus_command with my full command.

Step 2

Create a custom script at /usr/lib64/nagios/plugins/ with right permission 755 and I call it expscript.sh
 Thank to http://superuser.com/questions/618370/check-expiry-date-of-ssl-certificate-for-multiple-remote-servers, I found a script only had to do some minor modifications to support Nagios EXIT codes.

#!/bin/bash

DEBUG=false
#DEBUG=true
warning_days=90 # Number of days to warn about soon-to-expire certs
#certs_to_check='XXX.YYY.lk:443'
certs_to_check=$1

for CERT in $certs_to_check
do
  $DEBUG && echo "Checking cert: [$CERT]"

  output=$(echo | openssl s_client -connect ${CERT} 2>/dev/null |\
  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' |\
  openssl x509 -noout -subject -dates 2>/dev/null)
  if [ "$?" -ne 0 ]; then
    $DEBUG && echo "Error connecting to host for cert [$CERT]"
    logger -p local6.warn "Error connecting to host for cert [$CERT]"
    continue
  fi

  start_date=$(echo $output | sed 's/.*notBefore=\(.*\).*not.*/\1/g')
  end_date=$(echo $output | sed 's/.*notAfter=\(.*\)$/\1/g')

  start_epoch=$(date +%s -d "$start_date")
  end_epoch=$(date +%s -d "$end_date")

  epoch_now=$(date +%s)

  if [ "$start_epoch" -gt "$epoch_now" ]; then
    $DEBUG && echo "Certificate for [$CERT] is not yet valid"
    logger -p local6.warn "Certificate for $CERT is not yet valid"
  fi

  seconds_to_expire=$(($end_epoch - $epoch_now))
  days_to_expire=$(($seconds_to_expire / 86400))
  #$DEBUG && echo "Days to expiry: ($days_to_expire)"
  echo "Days to expiry: ($days_to_expire) - $end_date"

  warning_seconds=$((86400 * $warning_days))

  if [ "$seconds_to_expire" -lt "$warning_seconds" ]; then
    #$DEBUG && echo "Cert [$CERT] is soon to expire ($seconds_to_expire seconds)"
    echo "Cert [$CERT] is soon to expire ($seconds_to_expire seconds)"
    logger -p local6.warn "cert [$CERT] is soon to expire ($seconds_to_expire seconds)"
    exit 1

  elif [ "$seconds_to_expire" -gt "$warning_seconds" ]; then
    exit 0
  fi
done


Step 3

My service definition at my relevant host;

define service{
        use             generic-service         ; Inherit default values from a template
        host_name               XXX.YYYWeb
        service_description     XXX.YYY Cert
        check_command   check_cus_command!sh /usr/lib64/nagios/plugins/expscript.sh XXX.YYY.lk:443
        servicegroups   URL_Checks
        }

That’s it…..

Tuesday, October 8, 2013

Linux Running out of Memory for buffers/cache


Recently our systems guys got some Nagios warnings on one of our servers that it is running out of RAM. When we were logged in to the system yes it is... it was something like this,

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1504       1491         13          0         91        764
(not actual data)

But what are these buffers and cached, They over consumes my RAM. But what are the details below that...!!

-/+ buffers/cache:        635        869
Swap:         2047          6       2041
Swap of course about your disk swap space.. Buffers/cache ..?? After I google it i just found this post that talks everything about this matter...


Disk caching makes the system much faster! There are no downsides, except for confusing newbies. It does not take memory away from applications in any way, ever! If your applications want more memory, they just take back a chunk that the disk cache borrowed. Disk cache can always be given back to applications immediately! You are not low on ram! “

So it says it is not a problem at all... But for the purpose of removing warnings on Nagios I wanted to clear this cache memory. So this is the command for that;

sync; echo 3 > /proc/sys/vm/drop_caches

explanation of this command as follows; Ref: http://www.linuxinsight.com/proc_sys_vm_drop_caches.html

drop_caches

Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.
To free pagecache:
  • echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
  • echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
  • echo 3 > /proc/sys/vm/drop_caches
As this is a non-destructive operation, and dirty objects are not freeable, the user should run "sync" first in order to make sure all cached objects are freed.

Note: All the credits goes to the actual owners of the references... 

Friday, August 30, 2013

Common SAMBA Errors

Recently my SAMBA server started crashing giving bellow errors in logs;

standard input is not a socket, assuming -D option
[2013/08/30 09:06:22.619250,  0] ../source3/smbd/server.c:1280(main)

Google didn't help me as well as my previous SAMBA experiences couldn't come up with a solution. Luckily I found this forum post and yes... he maid my day....

http://www.hkepc.com/forum/viewthread.php?tid=1923469

All the credits goes to the writer...


vim /etc/sysfconfig/samba
and edit;
SMBDOPTIONS="-D"

So according to the man page of smbd -D causes the server to operate as a daemon.

Friday, October 28, 2011

Show Hide HTML Contents inside Nested Loops

Show hide contents with Javascript is not a big issue in php, HTML development. But when it comes to dynamically changing environment, contents inside a loop which the number of rows not known, it gets little difficult. Because Javascripts are running on client side and it will do the job through content IDs. Below code will show you how to show/hide contents inside a loop where the number of rows not predefined and also the number of rows inside a single row also not predefined. Basically a nested loop.

This is the Javascript code inside the <head>

<script type="text/javascript">
function toggle(div_id, count)
{
    for (i=0;i<=count;i++)
    {
        var a=div_id+"-"+i;
        var divval = document.getElementById(a);
        if (divval != null)
        {
            if ( divval.style.display == 'none' )
            {   
                divval.style.display = 'block';
            }
            else
            {
                divval.style.display = 'none';
            }
        }
    }

</script>

And here is the php,

$count = 0;
while(condition for loop1)
    {
            $count2 = 0;
            while(condition for loop2)
            {
                       ?>
                       
                        <tr  id='<? echo $count."-".$count2 ?>' style="display:none"><td></td></tr>                       
                        <?
                         $count2 = $count2+1;
              }
              $count = $count+1;
              ?>
             <tr id='<? echo $count."-more" ?>' style="display:block"; align="right"><td><img src="./images/more.png" align="right" onmouseover="this.src='./images/moremo.png';" onmouseout="this.src='./images/more.png';" onclick="toggle('<? echo $count ?>', '<? echo $count2 ?>')" height="17" width="40"  /></td><td>&nbsp;</td></tr>
             <?
     }

The basic idea of this code is a 'show more records' button inside the first loop. (one button per record) According to the button click event it will show/hide the result of the second loop.
What I have done here is sending the div_id (count of the first loop) and the number of records in the second loop to the JScript. The JScript will run another loop for the count of the second mentioned loop and do the necessary. See how I have created dynamic div ids.

Simple but powerful JavaScripts
Regards,
  

Tuesday, September 20, 2011

Server side (web) clock on your client's browser

There you can find many number or Javascript clocks available on the Internet, graphical as well as numerical. But all they do is showing the clock in the client's machine. What if the client machine's time is not correct? or the viewer is from another region or timezone but you need to display the clock according to your regional or server time. Here is the solution.

I'm calling this in my page onload event;
<BODY onLoad="startTimee(<? echo $a ?>, <? echo $b ?>, <? echo $c ?>)">

Here is my piece of PHP code, this should be located before the <body> tag;
<?
$a = date('H');
$b = date('i');
$c = date('s');
?>

Finally my simple Javascript, displays the server ticking clock;
<script type="text/javascript">
var a;
var b;
var c;
<! --This should be defined before all JS functions so it will work as global values for JS. -->


function startTimee(x, y, z)
{


var today=new Date();
var h=today.getHours();
var m=today.getMinutes();
var s=today.getSeconds();
 a=x-h;
 b=y-m;
 c=z-s;
startTime();
}


function startTime()
{
var today=new Date();
var h=today.getHours();
var m=today.getMinutes();
var s=today.getSeconds();


h=h+(a);
m=m+(b);
s=s+(c);


if (s>59)
{
s=(s)-60;
m=m+1;
}


if (s<0)
{
s=60+(s);
m=m-1;
}


if (m>59)
{
m=(m)-60;
h=h+1;
}


if (m<0)
{
m=60+(m);
h=h-1;
}


if (h>12)
{
h=h-12;
}


// add a zero in front of numbers<10
m=checkTime(m);
s=checkTime(s);
document.getElementById('txt').innerHTML=h+":"+m+":"+s;
t=setTimeout('startTime()',500);
}


function checkTime(i)
{
if (i<10)
  {
  i="0" + i;
  }
return i;
}
</script>

What I all do is taking the time difference with my server and clients machine on page load and assignees them to JS global values. Finally add (or subtract) it to the normal JS clock. Simple as that, (but powerful :) ) So you can embed this with any JS clock on the web as your requirement.

Note: the actual time may be differ + or - 5 to 10 seconds depending on the page load time.

Regards,

Monday, September 12, 2011

Remove and/or prevent inserting invalid characters on client side

This simple Javascript will prevent inserting ' < ' ' > ' and ' " ' characters from your HTML form,

<SCRIPT language=Javascript>
<!--
      function reminvalid(evt)
      {
         var charCode = (evt.which) ? evt.which : event.keyCode
         if ((charCode < 60 || charCode > 62) && charCode != 34)
            return true;

         return false;
      }

//-->
</SCRIPT>


The primary requirement of this code is to prevent cross site scripting on the web form. You can modify the char code(s) as the requirement. 

Unfortunately this won't prevent copy and paste insertion. So I had to embed this code too..

function delinvalid(string)
    {   
        output =  string.replace(/[<>"]+/g,' ');
        return output;
    }

This will remove the unwanted characters and replace by a space (or any other character you specify after the comma, in this case ' ')

You can use it this way too,


string.replace(/[^a-zA-Z 0-9]+/g,' ');

Then it will remove everything other than a-z A-Z 0-9 and space.

Remember to use the below notation if you want to replace the '^' sign.

string.replace(/\^/g, '\r\n');

Here is my input element,

<input name="***" type="text" size="**" id="**" onkeypress="return reminvalid(event)" onChange="this.value=delinvalid(this.value)">

Simple and powerful Javascripts....

Regards.

Tuesday, June 28, 2011

Install Squid on your home directory

Squid is a open source proxy server mostly running on linux environment  (also there is a version for windows too). The default path that the squid will install is /usr/local/squid/. You can change the path by using ./configure --prefix=/some/other/directory/squid at the compilation of squid. (Please refer http://wiki.squid-cache.org/SquidFaq/CompilingSquid)

Occasionally some may want to install squid on the home directory. As usual you need to set the permission squid/var/logs  & cache_dir directories to the cache_effective_user you have configured at squid.conf. the default is squid:squid. The problem arise here is it still gives an error saying permission denied.

The solution is easy. Change your cache_effective_user to your home directory name. And set permission of above mentioned directories to the same. Ya.. It works....