SSH Fingerprint and Hostkey with Paramiko in Python

November 24th, 2014

Following on from SSH and SFTP with Paramiko & Python, I recently had the need to gain a remote SSH server’s fingerprint and hostkey for verification purposes. This is achievable through setting up a socket, and then applying paramiko.Transport over our established socket. First, we include the various bits and pieces we’ll need:

import socket
import paramiko
import hashlib
import base64

Next, we establish a socket connection ‘mySocket’ to “localhost” on port 22 – our dummy SSH server. We then use paramiko.Transport to gain access to paramiko’s core SSH protocol options on the socket.

mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mySocket.connect(("localhost", 22))
myTransport = paramiko.Transport(mySocket)
myTransport.start_client()

To get the remote hostkey, we call myTransport.get_remote_server_key():
Read the rest of this entry »

SSH and SFTP with Paramiko & Python

November 23rd, 2014

Paramiko is a Python implementation of SSH with a whole range of supported features. To start, let’s look at the most simple example – connecting to a remote SSH server and gathering the output of ls /tmp/

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
        ssh.connect('localhost', username='testuser', password='t3st@#test123')
except paramiko.SSHException:
        print "Connection Failed"
        quit()

stdin,stdout,stderr = ssh.exec_command("ls /etc/")

for line in stdout.readlines():
        print line.strip()
ssh.close()

After importing paramiko, we create a new variable ‘ssh’ to hold our SSHClient. ssh.set_missing_host_key_policy automatically adds our server’s host key without prompting. For security, this is not a good idea in production, and host keys should be added manually. Should a host key change unexpectedly, it could indicate that the connection has been compromised and is being diverted elsewhere.

Next, we create 3 variables, stdin, stdout and stderr allowing us to access the respective streams when calling ls /etc/

Finally, for each “\n” terminated line on stdout, we print the line, stripping the trailing “\n” (as print adds one). Finally we close the SSH connection.

Let’s look at another example, where we communicate with stdin.
Read the rest of this entry »

Simple Ready to Roll Linux Backup Script

September 12th, 2014

I’d built a Linux backup BASH shell script a while ago that I’ve been using, and wanted to share it today. This is a simple and easy to configure script, useful for backing up and scheduling multiple hosts, as well as handling file and MySQL backups, and flexibly allowing multiple days or copies to be retained.

The full source is available here

The global configuration is performed at the top of the script:

#config
MAIN_DIR="/home/sysbackups"
BACKUP_DIR="${MAIN_DIR}/backups"
LOG_DIR="${MAIN_DIR}/logs"

RSYNC="time nice -19 rsync"
SSH=ssh
MYSQLDUMP="time nice -19 mysqldump"
GZIP=gzip
SCP=scp
CAT=cat
RM=rm
CP=cp
RSYNC_ARGS="-arplogu --delete --stats"
TODAY=`date +%Y%m%d`
LOG="${LOG_DIR}/log_error_${TODAY}.log"

The utilities that you see listed are all required to be installed: rsync gzip scp time nice cat mysqldump.

The directory structure for backups is a master directory, which in this case is /home/sysbackups, a directory for the actual backups to be placed, in this case /home/sysbackups/backups and a directory for log files, in this case /home/sysbackups/logs. These directories should exist prior to running the script.

The usage of ‘nice’ is to ensure the backups are as resource friendly as possible, and ‘time’ allows for timing data to be provided within the log files created.

Each backup set is defined lower down in the ‘startEntry’ function. Taking the first as an example:

10 )
 STARTED=1
 START="Local: vm1"
 HOST="192.168.1.50"
 B_RSYNC_USER=root
 B_RSYNC=1
 B_RSYNC_LIMIT=4096
 B_RSYNC_DIR=( "/var/www" "/var/spool/cron" "/etc" "/home" )
 B_MYSQLDUMP=1
 B_MULTIPLEDAYS_DB=3
 B_MYSQLDUMP_USER="root"
 B_MYSQLDUMP_MYSQLUSER="root"
 B_MYSQLDUMP_PASS="password"
 B_MYSQLDUMP_HOST="127.0.0.1"
 B_MYSQLDUMP_TMP="/tmp/mysqldump-backup.sql"
 B_MYSQLDUMP_GZIPAFTER=1
 B_MYSQLDUMP_DATABASES=( "all-databases" )
 ;;

The ‘START’ variable defines the “friendly name” of the machine for log purposes, and the ‘HOST’ variable defines it’s IP or hostname.

Setting ‘B_RSYNC’ to 1 instructs the script to execute the rsync routines for file backup. Setting ‘B_MYSQLDUMP’ to 1 allows us to back up MySQL databases from on the host.

Rsync options

B_RSYNC_USER defines the SSH user to connect to the host as
B_RSYNC_LIMIT defines the limit in kbps for the transferB_RSYNC_DIR is an array of directories to back up

Mysqldump options

B_MYSQLDUMP_USER defines the SSH user to connect to the host as
B_MYSQLDUMP_MYSQLUSER and B_MYSQLDUMP_PASS define the MySQL username and password to connect with
B_MYSQLDUMP_HOST defines the MySQL host to connect to, relative to the HOST variable.
B_MYSQLDUMP_TMP defines a temporary location for the mysql backup on the host
B_MYSQLDUMP_GZIPAFTER defines whether the MySQL backups should be GZipped before being transferred
B_MYSQLDUMP_DATABASES is an array of database names to be backed up, with “all-databases” being hopefully self explanatory

B_MULTIPLEDAYS_DB defines the number of database copies to keep and B_MULTIPLEDAYS defines the number of file sets to keep.

As we have defined this backup set as case ’10’ in the script, to execute it, we simply run: /path/to/backup.script.sh 10

This can be cronned to run on a daily basis.

Lastly, as connections to hosts are made via SSH, either a password will need to be entered on each run manually, or SSH keys can be set up.

Feel free to reply with changes or comments.

Hardening your server

July 7th, 2010

Hardening your server is perhaps the best way to prevent, or at least reduce, attacks on your server. What follows is a basic overview of what you should do to harden your server. If you are not completely comfortable doing this, you should retain the services of someone who is, to avoid data loss.

The key service you want to secure is SSH, as that is perhaps the most vulnerable. If someone should have access through this protocol, they would have complete power over your server, and all the sites on it.
Read the rest of this entry »

SSHing from a compromised machine

December 25th, 2009

Often, when working with compromised machines, as a security consultant, I find a malicious SSH binary. The malicious SSH binary generally logs all usernames, passwords and hosts connected to from the compromised machine, and usually in /tmp/. The attacker can then log back into the machine and collect this file at a later date.
Read the rest of this entry »

Copy files securely from host to host with SCP

March 17th, 2009

SCP is a really handy utility for copying files to or from your machine to another host over SSH.

Usage:

scp /tmp/myfile user@otherhost:/tmp/
Will send /tmp/myfile over to /tmp/ on otherhost

scp user@otherhost:/etc/passwd ~/
Will copy /etc/passwd from otherhost to my home directory (~/)

Like everything in Linux, it’s that easy 🙂

As SCP uses SSH as it’s transport, key authentication will allow a passwordless login.

rsync over SSH, SSH key login, public keys, automated backups

October 24th, 2008

This tutorial will cover how to set up a simple backup job between two machines using rsync and ssh. You will need HOST A and HOST B, whereby HOST B is your target backup service.

On HOST B:

ssh-keygen -t rsa  # Press enter to accept the default options.
mv ~/.ssh/id_rsa ~/.ssh/identity
cat ~/.ssh/id_rsa.pub

Read the rest of this entry »

Split access SSH problems

May 26th, 2008

So far everything works flawlessly, all applications, protocols and service with the split access setup, but I have a strange bug with SSH, and it only affects SSH clients built on openssl, such as dropbear and openssh. After authentication, it just hangs, and running in verbose mode shows that it seems to fail upon attempting to resize the tcp window. Only fails occasionally, when it receives no acknowledgement from the server.

After much digging, I only had minimal success getting to the bottom of the issue, but the following hack fixed the issue:
Read the rest of this entry »