8 months

Interacting with Remote Systems

• Accessing SSH terminals with paramiko                         
• Transferring files through SFTP                                      
• Transferring files with the help of FTP                             
• Reading the SNMP packets                                            
• Reading the LDAP packets                                             
• Sharing the files with the help of SAMBA                        



Secure shell – access using Python


SSH has become a very popular network protocol for performing secure data communication between two computers. It provides an excellent cryptographic support, so that unrelated third-parties cannot see the content of the data during the transmission process.

Python's paramiko library provides a very good support for the SSH-based network communication. You can use Python scripts to benefit from the advantages of SSH-based remote administration, such as the remote command-line login, command execution, and the other secure network services between two networked computers. You may also be interested in using the pysftp module, which is based on paramiko.

The SSH is a client/server protocol. Both of the parties use the SSH key pairs to encrypt the communication. Each key pair has one private and one public key.

We can use the paramiko module to create an SSH client and then connect it to the SSH server. This module will supply the SSHClient() class.

ssh_client = paramiko.SSHClient()

import getpass
import paramiko
HOSTNAME = 'localhost'
PORT = 22
def run_ssh_cmd(username, password, cmd, hostname=HOSTNAME, 
 ssh_client = paramiko.SSHClient()
 ssh_client.connect(hostname, port, username, password)
 stdin, stdout, stderr = ssh_client.exec_command(cmd)
if __name__ == '__main__':
 username = input("Enter username: ")
 password = getpass.getpass(prompt="Enter password: ")
 cmd = 'ls -l /dev'
 run_ssh_cmd(username, password, cmd)

Inspecting the SSH packets
It would be very interesting to see the network packet exchange between the client and the server. We can use either the native tcpdump command or the third-party Wireshark tool to capture network packets. With tcpdump, you can specify the target network interface ( -i lo) and the port number (port 22) options.

[email protected]:~# tcpdump -i lo port 22

The client first initiates the SSH packet exchange and then indicates that it would like to talk over the SSHv2 protocol. Then, the server agrees on that and continues the packet exchange.

Transferring files through SFTP

The protocol used in this case is the secure file transfer protocol (SFTP). The Python paramiko module will supply the classes required for creating the SFTP session. This session can then perform a regular SSH login. 
import getpass
import paramiko
HOSTNAME = 'localhost'
PORT = 22
FILE_PATH = '/tmp/test.txt'
def sftp_download(username, password, hostname=HOSTNAME,  port=PORT):
   ssh_transport = paramiko.Transport(hostname, port)
   ssh_transport.connect(username=username, password=password)
   sftp_session =  paramiko.SFTPClient.from_transport(ssh_transport)
   file_path = input("Enter filepath: ") or FILE_PATH
   target_file = file_path.split('/')[-1]
   sftp_session.get(file_path, target_file)
   print("Downloaded file from: %s" %file_path)
if __name__ == '__main__':
   hostname = input("Enter the target hostname: ")
   port = input("Enter the target port: ")
   username = input("Enter yur username: ")
   password = getpass.getpass(prompt="Enter your password: ")
   sftp_download(username, password, hostname, int(port))

Transferring files with FTP

FTP uses the plain-text file transfer method. This means any username or password transferred through the wire can be detected by an unrelated third-party. 
In Python, ftplib is a built-in module used for transferring the files to and from the remote machines. You can create an anonymous FTP client connection with the FTP() class.

import ftplib
FTP_SERVER_URL = 'ftp.kernel.org'
DOWNLOAD_DIR_PATH = '/pub/software/network/tftp'
DOWNLOAD_FILE_NAME = 'tftp-hpa-0.11.tar.gz'
def ftp_file_download(path, username, email):
   # open ftp connection
   ftp_client = ftplib.FTP(path, username, email)
   # list the files in the download directory
   print("File list at %s:" %path)
   files = ftp_client.dir()
   # downlaod a file
   file_handler = open(DOWNLOAD_FILE_NAME, 'wb')
   #ftp_cmd = 'RETR %s ' %DOWNLOAD_FILE_NAME
   ftp_client.retrbinary('RETR tftp-hpa-0.11.tar.gz', 
if __name__ == '__main__':
 ftp_file_download(path=FTP_SERVER_URL, username='anonymous',  email='[email protected]')

Fetching Simple Network Management Protocol data

SNMP is a ubiquitous network protocol that is used by the network routers, such as switches, servers, and so on, for communicating the device's configuration, performance data, and the commands that are meant for the control devices. Although SNMP starts with the word simple, it's not a simple protocol. Internally, each device's information is stored in a sort of a database of information called the management information base (MIB). The SNMP protocol offers varying levels of security depending on the protocol version number. In SNMP v1 and v2c, the data is protected by a pass phrase known as the community string. In SNMP v3, a username and a password are required for storing the data. And, the data can be encrypted with the help of SSL. 
SNMP is a client/server-based network protocol. The server daemon provides the requested information to the clients. In your machine, if SNMP has been installed and configured properly, then you can use the snmpwalk utility command to query the basic system information by using the following syntax:
# snmpwalk -v2c -c public localhost.

In Python, you can use a third-party library called pysnmp for interfacing with the snmp daemon. You can install the pysnmp module by using pip.

$ pip install pysnmp

from pysnmp.entity.rfc3413.oneliner import cmdgen
SNMP_HOST = 'localhost'
if __name__ == '__manin__':
 cmd_generator = cmdgen.CommandGenerator()
 error_notify, error_status, error_index, var_binds = cmd_generator.getCmd(
 cmdgen.UdpTransportTarget((SNMP_HOST, SNMP_PORT)),
 cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0),
 lookupNames=True, lookupValues=True
 # Check for errors and print out results
 if error_notify:
 elif error_status:
 for name, val in var_binds:
 print('%s = %s' % (name.prettyPrint(), 

t cmdgen takes the following parameters:
• CommunityData(): Set the community string as public.
• UdpTransportTarget(): This is the host target, where the snmp agent is running. This is specified in a pair of the hostname and the UDP port.
• MibVariable: This is a tuple of values that includes the MIB version number and the MIB target string (which in this case is sysDescr; this refers to the 
description of the system).

Reading Light-weight Directory Access Protocol data

LDAP has been used for a long time for accessing and managing distributed directory information. This is an application level protocol that works over the 
IP network. Directory service is heavily used in organizations for managing the information about the users, the computer systems, the networks, the applications, and so on. The LDAP protocol contains plenty of technical jargon. It is a client/server-based protocol. So, the LDAP client will make a request to a properly configured LDAP server. After initializing the LDAP connection, the connection will need to be authenticated by using a few parameters. A simple BIND operation will establish an LDAP session. In a simple case, you can set up a simple anonymous BIND that would not need no password or any other credentials.

The Python's third-party python-ldap package provides the necessary functionality for interacting with an LDAP server. You can install this package with the help of pip.
$ pip install python-ldap

Sharing files with SAMBA

The protocol used for sharing the files and the printers among these machines is either the Server Message Block (SMB) protocol or its enhanced version called the Common Internet File System (CIFS) protocol. CIFS runs over TCP/IP and it is used by the SMB clients and servers. 

$ pip install pysmb
from smb.SMBConnection import SMBConnection
smb_connection = SMBConnection(username, password,  client_machine_name, server_name, use_ntlm_v2 = True,  domain='WORKGROUP', is_direct_tcp=True)

import tempfile
from smb.SMBConnection import SMBConnection
SAMBA_USER_ID = 'athaenas'
CLIENT_MACHINE_NAME = 'debian6box'

SHARED_FILE_PATH = '/test.rtf'
if __name__ == '__main__':
 smb_connection = SMBConnection(SAMBA_USER_ID, PASSWORD, 
 domain='WORKGROUP', is_direct_tcp=True)
 assert smb_connection.smb_connectionect(SERVER_IP, SERVER_PORT 
 = 445)
 shares = smb_connection.listShares()
 for share in shares:
 print share.name
 files = smb_connection.listPath(share.name, '/')
 for file in files:
 print file.filename
 file_obj = tempfile.NamedTemporaryFile()
 file_attributes, filesize = 
 SHARED_FILE_PATH, file_obj)
 # Retrieved file contents are inside file_obj