Forum Discussion

Purnadi_K's avatar
Purnadi_K
Former Employee
7 years ago

SSH key for remote session in LogicMonitor

Info: Groovy script is the base for the environment and certainly the target/end device must be a linux-based, be it a distro of Linux server/desktop or an appliance with linux-kernel firmware (err...it's basically almost every device then: firewalls, switches, IDS/IPS, LB, Apple devices, Android devices, etc....it seems all gadgets on the planet using linux kernel)

It is a request some years ago (seems so long though, which actually is +2 years) by a LogicMonitor's Customer:

/topic/524-ssh-key-based-auth-for-groovy-scripts-datasources/

 

Obviously, this is not an official datasource crafted by the amazing Monitoring Engineering team of LogicMonitor, but patting my own back, it suffices to say that it serves the purpose for a better security connecting remotely which has been a common best-practice by anyone who enjoys text-based command line remote session.

SSH Key is used over the option of sending password due to the apparent reason of information security, although one might argue that the ssh password will be only between a LogicMonitor collector and the endpoint, within a supposed-to-be internal network. Yet a security best practice may dictate such usage regardless of the network.

Before progressing further, however, there is a catch in using ssh key, which is the necessity for a deployment of public key to each target device. Simply put, every time SSH Keys are used for remote session between two devices, there will be private key and public key used for authentication process, hence no password needed. These keys are to be put in the devices, private key in the source device where the remote session is originated and public key in the endpoint. Private key is not for a share whilst public key is for any device that the source will need to connect, should the ssh key be used. The only hassle, even if it is considered to be one, is to load that public key on each target device (if there are many). From the security standpoint, that is totally not an issue and rather a compulsory instead. (As a comparison, by using ssh user and password, the process would be similar too, that is to create user and password in each target device). This practice is really not an ancient stuff and almost every cloud provider, AWS being the one, has that feature recommended (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html).

In LogicMonitor case where I did the test, it is between a collector server/device and a monitored device (both happen to be Ubuntu 16 although Windows can be used for the collector as well and on the other hand, definitely it can not be used for Windows target device, for the obvious reason). For my simple test, it is just to monitor a log file size which is a syslog. One thing worth noting is, remote session type of monitoring will certainly consume more resource of collector, as a matter of fact, every datasource using script will do. Besides, using this method, the processing time seems to increase by a little bit, compared with user/password, but I have not done any thorough observations though (not only that I do not intend to, since this is just a test, nor have I the environment huge enough to do a high load-test). Security and processing speed, they do not go in parallel for sure, especially considering the recent havoc by a processor company caused a nightmare for information security worldwide, bypassing security measure for the sake of increasing a speed of data processing.

So here is the script which is basically running a command to throw output of a data from a file named 'dusyslog' in the remote device and a datapoint will capture it (datapoint name: size):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
        try{
            String command = "cat dusyslog";
            String host = hostProps.get("system.hostname");
            String user = hostProps.get("ssh.user");
            String key = hostProps.get("ssh.key");             
            JSch jsch = new JSch();
			jsch.addIdentity(key);
			jsch.setConfig("StrictHostKeyChecking", "no");			
			Session session=jsch.getSession(user, host, 22);
			session.connect();			
			Channel channel = session.openChannel("exec");
			channel.setCommand(command);
			channel.setErrStream(System.err);
			channel.connect();
            InputStream input = channel.getInputStream();
            channel.connect();
               
            try{
                InputStreamReader inputReader = new InputStreamReader(input);
                BufferedReader bufferedReader = new BufferedReader(inputReader);
                String line = null;          
               while((line = bufferedReader.readLine()) != null){
                    println(line);
                }
                bufferedReader.close();
                inputReader.close();
            }catch(IOException err){
                err.printStackTrace();
            }
             
            channel.disconnect();
            session.disconnect();
        }catch(Exception err){
            err.printStackTrace();
        }

The first thing you can notice is I am using : 

jsch.addIdentity(key)

for adding the key file into the session for authentication.

So what is this file? it is the private key file residing in a secure place in collector server. You need to make sure the file 'dwelleth in the secret place of the most High and shall abide under the shadow of the Almighty'.I really mean it that the private key should not be exposed to the world. But of course, I make it sound like a very serious security matter :)/emoticons/smile@2x.png 2x" title=":)" width="20"> So just to make sure that file is given limited permission for collector service to access is sufficient. Undoubtedly the script is not built by myself from scratch but I have made some modification so it is safe to be copyrighted by me and you have the 'the right to copy' & enhance it if you need to and providing me a treat of coffee would be highly appreciated.

Further to that, this part:

key = hostProps.get("ssh.key");

as per normal, is defined at the device property and following is the sample from my test:

Linux device:
/security/key

Windows device:
C:\\security\\key

Note: you can add an additional security to disguise the location of the file too and that folder "security" is not the original folder where the private key resides. This is for paranoid security practitioners. (But as I usually joke with friends in the IT field, the best data security was during WordStar era, before Windows 3.11 came and before tcp/ip was introduced to home users :)/emoticons/smile@2x.png 2x" title=":)" width="20"> ).

 

Below are some screenshots from the implementation:

 

  • On 1/14/2018 at 9:24 PM, Purnadi K said:

    Info: Groovy script is the base for the environment and certainly the target/end device must be a linux-based, be it a distro of Linux server/desktop or an appliance with linux-kernel firmware (err...it's basically almost every device then: firewalls, switches, IDS/IPS, LB, Apple devices, Android devices, etc....it seems all gadgets on the planet using linux kernel)

    It is a request some years ago (seems so long though, which actually is +2 years) by a LogicMonitor's Customer:

    /topic/524-ssh-key-based-auth-for-groovy-scripts-datasources/

     

    Obviously, this is not an official datasource crafted by the amazing Monitoring Engineering team of LogicMonitor, but patting my own back, it suffices to say that it serves the purpose for a better security connecting remotely which has been a common best-practice by anyone who enjoys text-based command line remote session.

    SSH Key is used over the option of sending password due to the apparent reason of information security, although one might argue that the ssh password will be only between a LogicMonitor collector and the endpoint, within a supposed-to-be internal network. Yet a security best practice may dictate such usage regardless of the network.

    Before progressing further, however, there is a catch in using ssh key, which is the necessity for a deployment of public key to each target device. Simply put, every time SSH Keys are used for remote session between two devices, there will be private key and public key used for authentication process, hence no password needed. These keys are to be put in the devices, private key in the source device where the remote session is originated and public key in the endpoint. Private key is not for a share whilst public key is for any device that the source will need to connect, should the ssh key be used. The only hassle, even if it is considered to be one, is to load that public key on each target device (if there are many). From the security standpoint, that is totally not an issue and rather a compulsory instead. (As a comparison, by using ssh user and password, the process would be similar too, that is to create user and password in each target device). This practice is really not an ancient stuff and almost every cloud provider, AWS being the one, has that feature recommended (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html).

    In LogicMonitor case where I did the test, it is between a collector server/device and a monitored device (both happen to be Ubuntu 16 although Windows can be used for the collector as well and on the other hand, definitely it can not be used for Windows target device, for the obvious reason). For my simple test, it is just to monitor a log file size which is a syslog. One thing worth noting is, remote session type of monitoring will certainly consume more resource of collector, as a matter of fact, every datasource using script will do. Besides, using this method, the processing time seems to increase by a little bit, compared with user/password, but I have not done any thorough observations though (not only that I do not intend to, since this is just a test, nor have I the environment huge enough to do a high load-test). Security and processing speed, they do not go in parallel for sure, especially considering the recent havoc by a processor company caused a nightmare for information security worldwide, bypassing security measure for the sake of increasing a speed of data processing.

    So here is the script which is basically running a command to throw output of a data from a file named 'dusyslog' in the remote device and a datapoint will capture it (datapoint name: size):

    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.Properties;
    import com.jcraft.jsch.Channel;
    import com.jcraft.jsch.ChannelExec;
    import com.jcraft.jsch.JSch;
    import com.jcraft.jsch.Session;
            try{
                String command = "cat dusyslog";
                String host = hostProps.get("system.hostname");
                String user = hostProps.get("ssh.user");
                String key = hostProps.get("ssh.key");             
                JSch jsch = new JSch();
    			jsch.addIdentity(key);
    			jsch.setConfig("StrictHostKeyChecking", "no");			
    			Session session=jsch.getSession(user, host, 22);
    			session.connect();			
    			Channel channel = session.openChannel("exec");
    			channel.setCommand(command);
    			channel.setErrStream(System.err);
    			channel.connect();
                InputStream input = channel.getInputStream();
                channel.connect();
                   
                try{
                    InputStreamReader inputReader = new InputStreamReader(input);
                    BufferedReader bufferedReader = new BufferedReader(inputReader);
                    String line = null;          
                   while((line = bufferedReader.readLine()) != null){
                        println(line);
                    }
                    bufferedReader.close();
                    inputReader.close();
                }catch(IOException err){
                    err.printStackTrace();
                }
                 
                channel.disconnect();
                session.disconnect();
            }catch(Exception err){
                err.printStackTrace();
            }

    The first thing you can notice is I am using : 

    
    jsch.addIdentity(key)

    for adding the key file into the session for authentication.

    So what is this file? it is the private key file residing in a secure place in collector server. You need to make sure the file 'dwelleth in the secret place of the most High and shall abide under the shadow of the Almighty'.I really mean it that the private key should not be exposed to the world. But of course, I make it sound like a very serious security matter :)/emoticons/smile@2x.png 2x" title=":)" width="20" /> So just to make sure that file is given limited permission for collector service to access is sufficient. Undoubtedly the script is not built by myself from scratch but I have made some modification so it is safe to be copyrighted by me and you have the 'the right to copy' & enhance it if you need to and providing me a treat of coffee would be highly appreciated.

    Further to that, this part:

    
    key = hostProps.get("ssh.key");

    as per normal, is defined at the device property and following is the sample from my test:

    
    Linux device:
    /security/key
    
    Windows device:
    C:\\security\\key

    Note: you can add an additional security to disguise the location of the file too and that folder "security" is not the original folder where the private key resides. This is for paranoid security practitioners. (But as I usually joke with friends in the IT field, the best data security was during WordStar era, before Windows 3.11 came and before tcp/ip was introduced to home users :)/emoticons/smile@2x.png 2x" title=":)" width="20" /> ).

     

    Below are some screenshots from the implementation:

     

     

    Currently i am working with Juniper_JUNOS configsources with SSH key login, i was thinking to use your script above and merge with the existing configsources, but still not working, could you please guide me how to achieve it?