SSH Cookbook v2

A SSH tools suite presentation

Enhanced version

Created by Jean-Marie Renouard / @jmrenouard
http://www.jmrenouard.fr/

What's SSH ?


  • SSH is a secure TCP communication protocol.
  • SSH v2 is base standard in all distributions.
  • SSH allows you to connect securely to server.
  • SSH avoid attack such man in the middle.

SSH basic usage


  • Connect to server REF01.mynetwork as osuser
  • $ ssh osuser@REF01.mynetwork
client ssh

What's next ?


  • Password is asked.
  • osuser@REF01.mynetwork's password : 
  • Password is checked based on system.
  • Input password is crypted.
  • Result is compared with /etc/shadow information.

  • Comparaison failed : command fails, simple !

And when it is OK ...


  • Comparaison successed 
  • SSH asks system for a new shell session.
  • Shell session is based on /etc/passwd info.
  • 7th and last field of /etc/passwd is shell path.
  • Default Welcome Message
Last login: Thu Mar 20 23:26:46 2014 from 192.168.X.X
  • Then, You've got a shell ( Bash for instance )
  • A shell as a local shell remotely / securely !

Shell is great


  • Ctrl-d : Kill the connection immediately.
  • Ctrl-l : Clean your screen
  • Ctrl-r : Search in bash history on the server
  • Readline powered
  • .bash_history : command history
  • .bash_profile and .bashrc for personal shell customisation (alias, functions, ...)

Boring aspect of SSH


One connection means one password check.

  • Password typing
  • No human error probe

  • Ctrl-d, exit, kill -9 0, killall bash, ...
  • Kill/terminate Shell session means :
    • All processes launched from Shell session are also killed.
    • You JUST have to REconnect and REtype your password.
    • REtype your command even if it's long time taking.

Avoiding password typing


  • Thanks God, it is possible to connect without passord typing.
  • It is as secure as password typing.
  • Maybe more secure:
    • No password Excel File on network
    • No Agile Access info Post-it on ScrumBoard :)

SSH Key Generation

2 keys

2 files MUST be generated

  1. Red key : .ssh/id_rsa is your Private SSH key
    • Keep it secret
  2. Blue key: .ssh/id_rsa.pub is your Public SSH key.

SSH Key Generation Command

  • Key Generation Command:
  • ssh-keygen -t rsa

  • Hey, it is asking me a F*** password !!!
  • Leave it empty :)
2 keys generation

SSH Key deployment


  • Public Key Deployment Command:
ssh-copy-id -i .ssh/id_rsa.pub ossuer@REF01.mynnetwork
  • It is asking a password for a last time ....
public keydeployment

And all is ok ?


  • On the server, .ssh/authorized_keys contains the content of your public key.
  • Try to connect one again.
  • ssh osuser@REF01.mynetwork
  • NO MORE PASSWORD ....
  • Magic Simple, Easy and secure ....

Is it all ?


  • How to automate this process ?

  • Library Expect :
    • library interacting with shell programmaticaly.
    • You can script an interactive scenario.
    • And you can execute it automatically.

Better than a shell

You can also remotely execute a command.


  • Shutdown the server
  • ssh root@REF01.mynetwork shutdown -h now
  • Execute a remote python script
  • ssh osuser@REF01.mynetwork \
      "python remoteScript.py"
  • Know load average on REF01 server
  • ssh osuser@REF01.mynetwork uptime  

Perl Expect

#!/usr/bin/perl
use strict;
use Expect;

my $timeout=1;
my $command="ssh ".$ARGV[0]." ".$ARGV[2];
my $exp = Expect->spawn($command) or die "Cannot spawn $command: $!\n";
$exp->raw_pty(1);
LOGIN:
$exp->expect($timeout,
        [ 'ogin: $' => sub {
                     $exp->send("luser\n");
                     exp_continue; }
        ],
    [ 'yes\/no\)\?\s*$' => sub {
              $exp->send("yes\n");
              goto LOGIN;
              }
    ],
        [ 'assword:\s*$' => sub {
                      $exp->send($ARGV[1]."\n");
                      exp_continue; }
        ],
        '-re', qr'[#>:] $'
);
$exp->soft_close();

Remote execute a local script

Python, bash, php, ryby, java, all interpreters

  • Interpreter must be present on the remote server

  • Simple Python Script: hello.py
  • #!/usr/bin/python
    print "Hello World !"
  • Remote execute script:ssh-exec
  • #!/bin/sh
    INTERPRETER=$(head -n 1 $2 | sed -e 's/#!//')
    cat $2 | grep -v "#" | ssh -t $1 $INTERPRETER
  • Usage
  • ssh-exec osuser@REF01.mynetwork hello.py

File transfert over SSH


  • Using the input/output redirection.
  • cat myLocalFile | \
     ssh osuser@REF01.mynetwork \
     "cat > myRemoteFile"
  • Compressing on fly.
  • cat myLocalFile | \
     gzip | \
     ssh osuser@REF01.mynetwork \
     "gzip > myRemoteFile"
  • Compression by SSH himself.
  • cat myLocalFile |\
      ssh -C osuser@REF01.mynetwork \
      "cat > myRemoteFile"

Directories over SSH


  • Commands using input/output for directory
  • tar UNIX archiver command works with stdin and stdout
  • tar -czf – myDir | \ 
     ssh -C osuser@ref01.mynetwork \ 
     "mkdir myDir;cd myDir ;tar -xzf -" 
  • Better solution
    • A kind of cp based on SSHv2 protocol
    scp -rp mydir osuser@ref01.mynetwork:myDir
  • Best solution
    • Incremental copy
  • rsync -avz myDir osuser@ref01.mynetwork:myDir

Multiple host commands

Simple Shell loop on 3 servers

for host in server1 server2 server3; do
 		echo "* Updating $host"
 		ssh -C root@${host}.mynetwork "yum -y update"
done

Simple Shell loop on server1 to server100

for i in `seq 1 100`; do
 		host=server${i}.mynetwork
 		echo "*Updating $host"
 		ssh -C root@${host} "yum -y update"
done

Multiple host commands in parallel

Forking Subshells in loop on server1 to server100

for i in `seq 1 100`; do
 		(
 		host=server${i}.mynetwork
 		echo "*Updating $host"
 		ssh -C root@${host} "yum -y update" 2>&1 >> ${host}.update.log
 		echo "* Updating $host ..DONE"
 		)&
done
  • Output and Errors are stored in individual log file per host

Multiple host commands in parallel

Forking Subshells in loop from a file

while read host; do
	(
	echo "*Updating $host"
	ssh -C root@${host} "yum -y update" 2>&1 >> ${host}.update.log
	echo "* Updating $host ..DONE"
	)&
done < "${1:-/proc/${$}/fd/0}"
  • Server are reading from a file or from stdin
  • A file with one server name by line
  • Output and Errors are stored in individual log file per host

Port Forwarding

Open a local port and redirect it throught SSH

ssh -L2000:localhost:80 user@host1
  • Open a local port 2000 and redirect I/O to server port 80 on host1
ssh -L8080:host2:80 user@host1
  • Open a local port 8080 and redirect I/O to server port 80 on host2
  • Using SSH to host1 to access host2 server

Reverse Port Forwarding

Open a remote port on server and redirect it throught SSH to client

ssh -R 2000:localhost:80 user@host1
  • Open a port 2000 on host1
  • Redirect I/O ond this port to local port80
ssh -R 8080:host2:80 user@host1
  • Open a remote port 8080 on host1
  • Redirect I/O to server host2 on port 80 from ssh client host
  • Using SSH to host1 to access host2 server

Useful scripts

Projects for massive remote execution

Projects for SSH management

Stellar Links

THE END

BY Jean-Marie Renouard / jmrenouard.fr