Friday, December 6, 2013

Virus Scanner using ClamAv

Virus Scanner Component

Introduction

As part of any project, we will allow users to upload some documents. We must scan these files for viruses and malware. To that end, we will use ClamAV as our virus scanner. ClamAV has a daemon process that can run on the OS in the background waiting for requests to scan data. We will submit files that we receive from the user to this daemon to scan. Based on the result, we will either reject the file or persist it on our system.

ClamAV

ClamAV is an open-source virus scanner. It provides a daemon process that can be used to scan data. For our purposes, we will set up the ClamAV daemon to listen for requests on a TCP socket. Using our Java API, we will send request to scan data to that socket and inspect the results returned by ClamAV.

Setting up ClamAV on Ubuntu

We will use the default ClamAV that is packaged with Ubuntu. The advantage of this is that it will be easier to update the scanner, than if we built it from source code.

Setting Up ClamAV

To install ClamAV
sudo apt-get install clamav
This will install ClamAV, create a ClamAV user etc. This does not install the daemon process.

Setting Up ClamAV Daemon

 To install the ClamAV Daemon
sudo apt-get install clamav-daemon
This will create the ClamAV Daemon process and start it up.

Updating virus definitions

By default freshclam is installed as a daemon and the default update frequency is 24 times a day. You can update this by modifying the file /etc/clamav/freshclam.conf

Configuring ClamAV Daemon

The default ClamAV Daemon configuration does not create the TCP socket that we need. To set it up, we will need to add the following lines to /etc/clamav/clamd.conf at the end

clamd.conf
# TCP port address.
# Default: no
TCPSocket 3310
 
 
# TCP address.
# By default we bind to INADDR_ANY, probably not wise.
# Enable the following to provide some degree of protection
# from the outside world.
# Default: no
TCPAddr 127.0.0.1
 
 
# Close the connection when the data size limit is exceeded.
# The value should match your MTA's limit for a maximum attachment size.
# Default: 25M
StreamMaxLength 100M

Once this is done, you should restart the clamd service using the following line
sudo service clamav-daemon restart

Java Application Setup

To communicate with the ClamAV daemon, ClamAV defines a protocol. We could write Java code to use that protocol to make our request. Luckily there is a Jenkins plugin that we can leverage that already has a Java API for ClamAV.

Maven Import

Add the following maven import to your project pom file.
Maven Dependency
<dependency>
    <groupId>org.jenkins-ci.plugins</groupId>
    <artifactId>clamav</artifactId>
    <version>0.2.1</version>
</dependency>

Usage

To actually perform a scan on a given set of data, you can use the following snippet of code   

// Create a ClamAvScanned with a given hostname/IPAddress and the port.
// This should match what is put in the /etc/clamav/clamd.conf file.
//
// The third value is the timeout in milliseconds before we give up
// on talking to the ClamAV daemon
// If the Daemon is running on the same machine, you can specify "localhost" as the IP address.
ClamAvScanner scanner = new ClamAvScanner("192.168.23.129", 3310, 5000);
 
// To check whether the scanner is listening at the port, you can "Ping" it
// isAvailable will return true if the server responds to the "Ping"
boolean isAvailable = scanner.ping();
 
 
// In the example, we are passing a ByteArrayInputStream of a String.
//
// You can pass any InputStream that you want. It could be a File,
// a Socket, anything.
// The string passed in this example will return as a virus.
ScanResult result = scanner.scan(new ByteArrayInputStream("X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*".getBytes()));
 
 
// ScanResult.Status is an enum with 3 values:
// PASSED, INFECTED, WARNING
//
// WARNING indicates that an error occurred while trying to scan the file. ScanResult.getMessage() will give you the exception message.
// INFECTED indicates that the file does contain a virus. ScanResult.getMessage() returns the virus' signature.
//
// If the result is PASSED, we sould consider the file safe
if (result.getStatus() == ScanResult.Status.PASSED) {
    System.out.println("No Virus");
} else {
    System.out.println("Possible Virus detected");
}


Setting up ClamAV Daemon on Windows machines for testing

To install the ClamAV daemon follow the instructions on this page:
http://www.andornot.com/blog/post/How-to-set-up-ClamAV-as-a-Windows-Service-to-scan-file-streams-on-demand.aspx




Tuesday, May 7, 2013

Apache module development to protect digital good.

Apache module development by extending existing mod_basic_auth

This below mentioned step by step procedure help you to create apache module to protected your digital good.


Step 1: Prerequisite



    1.1 Install apache2 webserver 
               sudo apt-get install apache2 
    1.2 Install apache compiler using the below mentioned command.
               sudo apt-get install apache2-threaded-dev 
    1.3 Install latest libcurl package using the below mentioned command.
               sudo apt-get install libcurl4-openssl-dev



 


Step 2: Create a simple apache module c file and compile it using the below mentioned command.

    apxs2 -c mod_paypal_ec.c (for debian OS)
    apxs -c mod_paypal_ec.c (for mac OS)

Step 3: Apache load config file

Create test_ec.load config file under /etc/apache2/mods-available



LoadFile /usr/lib/x86_64-linux-gnu/libcurl.so

LoadModule mod_test_ec /Users/csivakolundu/mod_test_ec/src/.libs/mod_test_ec.so

<Location /books>

    AuthType EC

    AuthName "Test EC"

    Require valid-user

</Location>





Step 4: Apache config file

Create test_ec.conf config file under /etc/apache2/mods-available with all your application properties which are going to referred in your c file.



ApiUserName aaaaaa_1350334651_biz_api1.paypal.com
ApiPassword 1350334729




Step 5: Enabling mod_test_ec module 

 Create symbolic link for test_ec.load and test_ec.conf files under /etc/apache2/mods-enable/ folder.



Step 6: Apache virtual host 

Update apache virtual host file from /etc/apache2/sites-enabled/  with the following changes.



<IfModule mod_paypal_ec>

    <Location /books>
       AuthType ExpressCheckout
       AuthName "PayPal ExpressCheckout"
       Require valid-user       

    </Location>

</IfModule>




Step 7: Simple mod_test_ec.c file. 


Simple apache c file to protected your digital good available under /var/www/books folder. Auth check is not done in the below example.



#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_main.h"
#include "http_protocol.h"
#include "http_request.h"
#include "util_script.h"
#include "mod_auth.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
#include <curl/curl.h>
#include <curl/easy.h>

typedef struct {
   const char* endPoint;
   const char* userName;
   const char* password;  
   const char* ecType;
}app_config;

static app_config config;


int ec_handler(request_rec *r);
void register_hooks(apr_pool_t *p);
int sendFile(request_rec *r, apr_table_t *data);
static int authenticate_user(request_rec *r);

const char *api_endpoint_handler(cmd_parms *cmd, void *cfg, const char *arg)
{
    config.endPoint= arg;
    return NULL;
}
const char *api_username_handler(cmd_parms *cmd, void *cfg, const char *arg)
{
    config.userName= arg;
    return NULL;
}

const char *apr_password_handler(cmd_parms *cmd, void *cfg, const char *arg)
{
    config.password= arg;
    return NULL;
}

const char *ec_type_handler(cmd_parms *cmd, void *cfg, const char *arg)
{
    config.ecType = arg;
    return NULL;
}

static const command_rec ec_directives[] = {
   AP_INIT_TAKE1("ApiEndPoint", api_endpoint_handler, NULL, RSRC_CONF, "The mod_paypal_ec application configuration file"),
   AP_INIT_TAKE1("ApiUserName", api_username_handler, NULL, RSRC_CONF, "The mod_paypal_ec application configuration file"),
   AP_INIT_TAKE1("ApiPassword", apr_password_handler, NULL, RSRC_CONF, "The mod_paypal_ec application configuration file"),
   AP_INIT_TAKE1("ECType", ec_type_handler, NULL, RSRC_CONF, "The mod_paypal_ec application configuration file"),
   
   {NULL}
};

module AP_MODULE_DECLARE_DATA   mod_test_ec =
{
    STANDARD20_MODULE_STUFF,
    NULL,
    NULL,
    NULL, 
    NULL,
    ec_directives,
    register_hooks
};


void register_hooks(apr_pool_t *p) {
        ap_hook_check_user_id(authenticate_user,NULL,NULL,APR_HOOK_MIDDLE);
}

static int authenticate_user(request_rec *r)
{
    const char *sent_user, *sent_pw, *current_auth;
    int res;
    authn_status auth_result;
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Authenticate_user starting....");
    current_auth = ap_auth_type(r);
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Current auth %s", current_auth);
    if (!current_auth || strcasecmp(current_auth, "EC")) {
        return DECLINED;
    }
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "After auth check");
    /* We need an authentication realm. */
    if (!ap_auth_name(r)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR,
                      0, r, "need AuthName: %s", r->uri);
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "After auth name check");
    r->ap_auth_type = "EC";
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Calling ec handler");
    return ec_handler(r);
}

int ec_handler(request_rec *r)
{
    char *next = r->uri;
    char *uri = r->unparsed_uri;     
    if ( r->method_number != M_GET ) {
        return HTTP_METHOD_NOT_ALLOWED ;  
    }   
       status = sendFile(r, data);
       if(status > 0) {
          return HTTP_INTERNAL_SERVER_ERROR;
       }
       return OK;
   
}

int sendFile(request_rec *r, apr_table_t *data) {
   int status = 0;
   apr_file_t *fd;
   apr_size_t sz;
   apr_status_t rv;
   if (r->filename == NULL) {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,"Incomplete request_rec!");
      status = 1;
      return status;
   }
   char* ext = strrchr(r->filename, '.') ;
   if(strcmp(ext, ".pdf") ==0) {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Downloading pdf file");
      ap_set_content_type(r, "application/pdf");
   } else {
      ap_set_content_type(r, "application/pdf");
   }
   ap_set_content_length(r, r->finfo.size);
   //ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "File size : %zu", r-> finfo.size);
   if (r->finfo.mtime) {
               char *datestring = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
               apr_rfc822_date(datestring, r->finfo.mtime);
               apr_table_setn(r->headers_out, "Last-Modified", datestring);
   }
   rv = apr_file_open(&fd, r->filename,
                        APR_READ|APR_SHARELOCK|APR_SENDFILE_ENABLED,
                        APR_OS_DEFAULT, r->pool);
   if (rv != APR_SUCCESS) {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,"can't open %s", r->filename);
      return HTTP_NOT_FOUND ;
   }
   ap_send_fd(fd, r, 0, r->finfo.size, &sz);
   apr_file_close(fd);
   return status;
}







Step 8: For Mac only.


    4.1 Update the libcurl.so path from paypal_ec.load to  "LoadFile /usr/lib/libcurl.4.dylib"
    4.2 Create Simbolic link like below.
           $> cd /Applications/Xcode.app/Contents/Developer/Toolchains/
           $> sudo ln -s XcodeDefault.xctoolchain/ OSX10.8.xctoolchain








Dynamic JMX MBean at Runtime

Simple DynamicMBean to monitor 

JMX API Includes possibility to create "Dynamic MBean", whose management interface is determined at runtime. It means management interface can not be determined by looking at the source code. 

Here is a simple example using Spring.

JMX Bean Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

 <description>KPI Agent Context</description>
 
 <context:annotation-config />
 <context:component-scan base-package="com.test.dm.kpi.agent" />
 <!-- JMX Beans -->
 <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
        <property name="autodetect" value="true" />
        <property name="namingStrategy" ref="namingStrategy" />
        <property name="assembler" ref="assembler" />
 </bean>
 <bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
 <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
         <property name="attributeSource" ref="jmxAttributeSource" />
 </bean>
 <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
         <property name="attributeSource" ref="jmxAttributeSource" />
 </bean>
</beans>



Create DynamicMBean :

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.ReflectionException;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Component;

@Component
@ManagedResource(objectName = "performancedyna:name=ProfilingDataDyna", description = "Profiling Data for dynamic profiled methods.")
public class ProfilingDataDynamicMBean implements DynamicMBean {


 protected Map<String, String> methodExecutionData  = new ConcurrentHashMap<String, String>();
 private MBeanAttributeInfo[] mbeanAttributesInfo = new MBeanAttributeInfo[2];
 private MBeanInfo mbeanInfo = null;
 
 public ProfilingDataDynamicMBean() {
  this.buildDynamicMBeanInfo();
 }
 
 @Override
 public Object getAttribute(String attribute) throws AttributeNotFoundException,
   MBeanException, ReflectionException {
  return methodExecutionData.get(attribute);
 }

 @Override
 public AttributeList getAttributes(String[] attributes) {
  if (attributes == null) {
   return new AttributeList();
  }
  final List<Attribute> result = new ArrayList<Attribute>(attributes.length);
   for (String attr : attributes) {
    result.add(new Attribute(attr, methodExecutionData.get(attr)));
   }
  return new AttributeList(result);
 }

 @Override
 public MBeanInfo getMBeanInfo() {
  return mbeanInfo;
 }

 @Override
 public Object invoke(String arg0, Object[] arg1, String[] arg2)
   throws MBeanException, ReflectionException {  
  return null;
 }

 @Override
 public void setAttribute(Attribute arg0) throws AttributeNotFoundException,
   InvalidAttributeValueException, MBeanException, ReflectionException {
 }

 @Override
 public AttributeList setAttributes(AttributeList arg0) {
  return null;
 }
 
 private void buildDynamicMBeanInfo() {
  mbeanAttributesInfo[0] = new MBeanAttributeInfo("TestAttribute1", "java.lang.String", "Its a test attribute 1", false, false, false);                   // writable
  mbeanAttributesInfo[1] = new MBeanAttributeInfo("TestAttribute2", "java.lang.String", "Its a test attribute 2", false, false, false);
  mbeanInfo = new MBeanInfo("com.test.dm.kpi.agent.application.ProfilingDataDynamicMBean", "ProfilingDataDynamicMBean", mbeanAttributesInfo, null, null, null);
  methodExecutionData.put("TestAttribute1", "Test Values 1");
  methodExecutionData.put("TestAttribute2", "Test Values 2");
 }
 
 
 private Map<String, String> getMethodExecutionData() {
  return methodExecutionData;
 }
 
 public void setMethodExecutionData(Map<String, String> methodExecutionData) {
  this.methodExecutionData = methodExecutionData;
 }
 
 public void addMethodExcutionData(String key, String value) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
  this.getMethodExecutionData().put(key, value);
 }
}


Adding Dynamic Attribute at Runtime:

User the ProfilingDataDynamicMBean to add execution data like below.

dataDynamicBean.addMethodExcutionData("TestAttribute1", (System.currentTimeMillis() + "1111"));



Wednesday, April 10, 2013

How to install and configure Nagios 3 and NRPE in Ubuntu

Nagios Server and NRPE Installation

Nagios is an open source host, service and network monitoring tool. This page talks about how to install and configure Nagios Server and Nagios Remote Plugin Executor Server (NRPE).

This guide works just fine for Ubuntu 12.04 64 bit.

Nagios 3 Server Setup

Step 1:

Install Nagios 3 from the Ubuntu main repository. 

sudo apt-get install  nagios3
sudo apt-get install openssl



This command will install and configure Nagios 3 along with the following required dependencies (Apache2, PHP, Postfix.....). You can ignore the email configuration during the installation process, then you will be prompted for the password to enter and confirm for user "nagiosadmin".
Remember this password, because you will be using this to login nagios web ui.


Use the below mentioned command to start, stop and restart nagios 3 server.

  sudo service nagios3 restart  


Step 2:

Install  nrpe plugin from the Ubuntu main repository.

sudo apt-get install nagios-nrpe-plugin
This command will install NRPE plugin on the server.

Remote Host Setup

Step 3:

Install NRPE server on the remote host from the Ubuntu main repository.
sudo apt-get install nagios-nrpe-server
sudo apt-get install openssl

Use the netstat command to check if the nrpe server is running.
bash$ :/etc/nagios$ netstat -an | grep 5666

tcp        0      0 0.0.0.0:5666            0.0.0.0:*               LISTEN 


Step 4:

Install  nrpe plugin from the Ubuntu main repository.

sudo apt-get install --no-install-recommends  nagios-nrpe-plugin
This command will install NRPE plugin on the remote host. The argument --no-install-recommends is required to avoid installing the entire dependent libraries.


Use the below mentioned command to start, stop and restart NRPE.

  sudo service nagios-nrpe-server restart  

Nagios Server Configuration

Step 5:

You need to register the nagios server IP address on the Nagios remote host by editing the following file.
sudo vi /etc/nagios/nrpe.cfg
and update allowed_hosts=127.0.0.1,<Nagios Server IP Address>

Don't forget to restart Nagios NRP server after making the changes.
sudo service nagios-nrpe-server restart

Execute the below mentioned command from Nagios Server to confirm the remote host is being configured properly.
bash$ /usr/lib/nagios/plugins/check_nrpe -H <Remote Host IP Address>
NRPE v2.12

You now have a very basic working installation of Nagios on your system (login at http://<Nagios Server IP Address>/nagios3 with those nagiosadmin credentials). It has been configured to monitor your local machine. 



Remote Service Configuration

Step 6:

Define all the required custom commands in the /etc/nagios/nrpe.cfg from remote host like below.

command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10
command[check_load]=/usr/lib/nagios/plugins/check_load -w 15,10,5 -c 30,25,20
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 10% -c 5% -A -I /boot -I /dev/shm
command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z
command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 150 -c 200
command[check_cpu_stats]=/usr/lib/nagios/plugins/check_cpu_stats.sh -w 50 -c 75
command[check_if_traffic]=/usr/lib/nagios/plugins/check_ifutil.pl -i eth0 -w 70 -c 80 -p -b 1000M
command[check_ssh]=/usr/lib/nagios/plugins/check_ssh localhost
command[check_swap]=/usr/lib/nagios/plugins/check_swap -w 20 -c 10

Ensure no duplicate commands defined in this nrpe.cfg file. There may be already few commands exists in the nrpe.cfg. 

Don't forget to restart NRPE after making the changes.
 sudo service nagios-nrpe-server restart


Step 7:

Create a new file /etc/nagios3/conf.d/remote-host_nagios2.cfg on Nagios server like below. As per the below example, the host name is "remoe-host"
define host{
        name                            remote-host    ; The name of this host template
        notifications_enabled           1       ; Host notifications are enabled
        event_handler_enabled           1       ; Host event handler is enabled
        flap_detection_enabled          1       ; Flap detection is enabled
        failure_prediction_enabled      1       ; Failure prediction is enabled
        process_perf_data               1       ; Process performance data
        retain_status_information       1       ; Retain status information across program restarts
        retain_nonstatus_information    1       ; Retain non-status information across program restarts
        check_command                   check-host-alive
        max_check_attempts              10
        notification_interval           0
        notification_period             24x7
        notification_options            d,u,r
        contact_groups                  admins
        register                        0       ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE!
        }


Create a new file /etc/nagios3/conf.d/remote-host_nagios2.cfg on Nagios server like below. As per the below example, the service name is "remote-service"

define service{
        name                            remote-service ; The 'name' of this service template
        active_checks_enabled           1       ; Active service checks are enabled
        passive_checks_enabled          1       ; Passive service checks are enabled/accepted
        parallelize_check               1       ; Active service checks should be parallelized (disabling this can lead to major performance problems)
        obsess_over_service             1       ; We should obsess over this service (if necessary)
        check_freshness                 0       ; Default is to NOT check service 'freshness'
        notifications_enabled           1       ; Service notifications are enabled
        event_handler_enabled           1       ; Service event handler is enabled
        flap_detection_enabled          1       ; Flap detection is enabled
        failure_prediction_enabled      1       ; Failure prediction is enabled
        process_perf_data               1       ; Process performance data
        retain_status_information       1       ; Retain status information across program restarts
        retain_nonstatus_information    1       ; Retain non-status information across program restarts
        notification_interval           0       ; Only send notifications on status change by default.
        is_volatile                     0
        check_period                    24x7
        normal_check_interval           5       ; Update this value to change check interval 
        retry_check_interval            1
        max_check_attempts              4
        notification_period             24x7
        notification_options            w,u,c,r
        contact_groups                  admins
        register                        0   ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE!
        }




Create a new file /etc/nagios3/conf.d/rh_services_nagios2.cfg on Nagios server like below.

define host{
        use                     <Host name created above>            ; Name of the host template to use
        host_name               <Name of the remote host>
        alias                   <Name of the remote host alias>
        address                 <IP address of the remote host>
        }

define service{
        use                             <Service name created above>    ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             Disk Space
        check_command                   check_nrpe_1arg!check_disks
        }
define service{
        use                             <Service name created above>    ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             Current Users
        check_command                   check_nrpe_1arg!check_users
        }
define service{
        use                             <Service name created above>    ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             Total Processes
        check_command                   check_nrpe_1arg!check_procs
        }
define service{
        use                             <Service name created above>    ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             Current Load
        check_command                   check_nrpe_1arg!check_load
        }
define service{
        use                             <Service name created above>    ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             Zombie_procs
        check_command                   check_nrpe_1arg!check_zombie_procs
        }

define service{
        use                             <Service name created above>    ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             CPU Stats
        check_command                   check_nrpe_1arg!check_cpu_stats
        }

define service{
        use                             <Service name created above>    ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             If Traffic
        check_command                   check_nrpe_1arg!check_if_traffic
        }

define service{
        use                             <Service name created above>  ; Name of service template to use
        host_name                       ubuntu
        service_description             SSH
        check_command                   check_nrpe_1arg!check_ssh
        }
define service{
        use                             <Service name created above>   ; Name of service template to use
        host_name                       <Name of the remote host>
        service_description             Swap
        check_command                   check_nrpe_1arg!check_swap
        }

Note that the arguments are hardcoded in the remote host itself, there is no need of passing arguments.

Restart the Nagios server after making the above changes.

Open a webbrowser and launch the below URL


   http://<Nagios Server IP Address>/nagios3


Miscellaneous


Install iostat if there is any error "UNKNOWN: iostat not found or is not executable by the nagios user." when you run the check_cpu_stats command

bash$ /usr/lib/nagios/plugins/check_cpu_stats.sh -w 50 -c 75
/usr/lib/nagios/plugins/check_cpu_stats.sh: line 1: PU: command not found
UNKNOWN: iostat not found or is not executable by the nagios user.
bash$ sudo apt-get install sysstat

You may find /check_ifutil.pl and check_cpu_stats.sh from google.





Monday, April 8, 2013

AspectJ Load Time Weaving in Spring web application

What is LTW?

Load-time weaving (LTW) is simply binary weaving defered until the point that a class loader loads a class file and defines the class to the JVM. To support this, one or more "weaving class loaders", either provided explicitly by the run-time environment or enabled through a "weaving agent" are required.

Following the below mentioned steps to enabled AspectJ LTW in any web based application.

Step 1: Create Aspect class

Create ProfilingAspect like below

package com.test.peek.agent;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class ProfilingAspect {
private static Logger logger = LoggerFactory.getLogger(ProfilingAspect.class);
@Around("methodsToBeProfiled()")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {        
        try {        
           
            logger.info("****************************************************Going to call the method.**************************************");
            return pjp.proceed();
        } finally {
            logger.info("****************************************************Method Execution completed.**************************************");
        }
       
    }

    @Pointcut("execution(public * com.test.peek..*.*(..))")
    public void methodsToBeProfiled(){}
   
}


Step 2:  Creat aop.xml in META-INF folder

Create aop.xml in META-INF folder with the following content.


<!DOCTYPE aspectj PUBLIC
        "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>

    <weaver>
       <exclude within="*..*CGLIB*" />
        <!-- only weave classes in our application-specific packages -->
        <include within="com.test.peek.web.service.SearchService"/>
         <!-- Package name of Aspect class -->
        <include within="com.test.peek.agent.*"/>
        <include within="com.test.peek.agent.ProfilingAspect"/>
    </weaver>

    <aspects>
        <!-- weave in just this aspect -->        
        <aspect name="com.test.peek.agent.ProfilingAspect"/>
    </aspects>

  </aspectj>


Step 3: Passing spring-instrument jar path as a VM -javaagent argument

The below mentioned argument should be passed as an VM argument while starting tomcat server.

-javaagent:/Users/test.m2/repository/org/aspectj/aspectjweaver/1.7.2/aspectjweaver-1.7.2.jar

Step 4: Maven Dependency

  <dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.7.0</version>
  </dependency>



Just follow the above mentioned step to enable LTW in any web based application.