SSH Client Tips and Tricks

[Ref: SSH Mastery: OpenSSH, Putty, Tunnels and Keys]

Veterans know their way back, forward, up, down, sideways. The rest of us need serious assistance with effective utilisation of this basic infrastructure for managing our servers:

Remote Access with ssh

[Ref: ssh(1) | OpenBSD FAQ4]

When the itch arrives and you just have to get a 'console' connection to that server, telnet is asking for someone to sniff your password and OpenBSD's [OpenSSH](http://www.openbsd.org) is the preferred, secureable 'terminal' access system. Ssh is the preferred method of remote access with OpenBSD. There are many features of ssh including the ability to provide a tunnel for other services. The clear advantage of ssh is the full encryption of all communications between the localhost and the remote host.

For the MS Windows fans amongst us there are even ssh clients Windows can run as a terminal window or from the command-prompt.

Communicating with a remote host is usually in the form shown below:

$ ssh user-id@remotehost.example.com

If you don't specify the user-id you wish to login as, then ssh will send the current user-id in which you started ssh (ie. if you are currently logged into your host as johndoe, then ssh remotehost.example.com will attempt to make the connection using your user-id, johndoe)

Configuring ssh

[Ref: ssh(1)]

ssh checks for its configuration from the command-line, then the user's configuration file ($HOME/.ssh/config), then the system-wide configuration file (/etc/ssh/ssh_config) The files are text files.

Below is an excerpt of what I choose to include in the system wide /etc/ssh_config file

File: /etc/ssh/ssh_config

UseRsh no
FallBackToRsh no
ForwardX11 no
KeepAlive no
Protocol 2,1

More documentation can be found in the man pages (ssh(1).) I choose not to UseRsh or FallBackToRsh because I want secure communications or none. I don't want to be forwarding X11 because I don't run X11 on the servers I'm connecting to. I don't want keepalive 'cause if I'm not doing something with the connection I would prefer it to dump me.

sshd - your ssh server daemon

[Ref: sshd(8)]

sshd is the daemon that listens for connections from clients. It is normally started at boot from /etc/rc. It forks a new daemon for each incoming connection. The forked daemons handle key exchange, encryption, authentication, command execution, and data exchange. This implementation of sshd supports both SSH protocol version 1 and 2 simultaneously.

System configuration is normally controlled by the /etc/ssh/sshd_config. Below is an excerpt of the config file

File: /etc/ssh/sshd_config

Port 22
ListenAddress 0.0.0.0 
ListenAddress ::
HostKey /etc/ssh_host_key
ServerKeyBits 1664
PermitRootLogin yes
  • Port specifies to listen on the ssh port (22,) obviously this line implies that you can specify a different port to listen to (or add additional ports)
  • ListenAddress is specifying to listen on all active interfaces (both IPv4 and IPv6).
  • HostKey specifies the location where the hosts key is to be located. /etc/sshhostkey is the default location.
  • ServerKeyBits specifies the size of the key to be generated, the number above is larger than the 568 normally used (is this more secure ?)

Disable Root Login

The afterboot(8) man page recommends that you disable direct login to root through the ssh daemon.

For security reasons, it is bad practice to log in as root during 
regular use and maintenance of the system. Instead, administrators 
are encouraged to add a "regular" user, add said user to 
the "wheel" group, then use the su and sudo commands when root 
privieges are required.

Edit the /etc/sshd_config file:

PermitRootLogin No

Check through the /etc/ssh/sshd_config for what looks interesting, and look through the man page for further information.

DO NOT DISCONNECT an active ssh connection until AFTER testing has verified behaviour is as you expect.

  1. Config: verify what you think sshd is supposed to be doing
  2. Test Mode: verify the configuration is valid using "-t"
  3. Server Live Monitor: start a verbose 'test' version of the server you can live monitor
  4. Client Live Monitor: start a verbose 'test' client connection you can live monitor

1. Config

Review the sshd configuration file without all the commentary with something like the below (assuming sshd_config is the correct file and in /etc/ssh)

$ grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

This just clears things out so we verify what we think we're changing (not necessarily whether it is correct or not.)

2. Test Mode

From the man page of the sshd's I'm using,

-t Test mode. Only check the validity of the configuration file and sanity of the keys. This is useful for updating sshd reliably as configuration options may change.

Other changes can have more subtle circumstances. For example, do not disable password authentication until you are sure that the public key authentication is working correctly.

3. Server Live Monitor

$ sudo /usr/sbin/sshd -ddd -p 9999

This keeps your existing, working session active, but gives you another instance of sshd to verify your new configuration changes. SSHD is now running in the foreground to a user-defined port (9999 in our example.) and pushing a lot of noisy debug information you can track in /var/log/authlog (or possibly /var/log/auth.log depending on your OS.)

4. Client Live Monitor

Run the ssh client connection in verbose mode to display on your screen more information that might lead you to better debugging your error.

$ ssh -vvv -p 9999 server-name

You should now have enough information in either the server's log files, or the client's connection screen to isolate any problems.

Copying a file through SSH

[Ref: scp(1)]

scp is a utility that allows you to copy files between hosts using the ssh transport. With ssh2 there is also support for gzip style compression of files for transmission.

$ scp files user-id@remote-host.example.com:path

SSH Login without a Password

  • Generate SSH keys
  • Copy to Destination Host
  • Set up agent
  • Connect

Generate SSH keys

Use ssh-keygen to generate authentication keys.

From manpage ssh-keygen(1):

ssh-keygen generates, manages and converts authentication keys for
ssh(1).  ssh-keygen can create RSA keys for use by SSH protocol version 1
and RSA or DSA keys for use by SSH protocol version 2.  The type of key
to be generated is specified with the -t option.  If invoked without any
arguments, ssh-keygen will generate an RSA key for use in SSH protocol 2
connections.

To generate our authentication keys at:

  • ~/.ssh/id_rsa : private key
  • ~/.ssh/id_rsa.pub : public key
ssh-keygen -b 4096 -t rsa    
-b bits
    Specifies the number of bits in the key to create.
-t type
    Specifies the type of key to create.  The possible values are
    ``rsa1'' for protocol version 1 and ``rsa'' or ``dsa'' for proto-
    col version 2.

Copy to Destination Host

For ssh authentication keys to work, the SSH Daemon on the remote host needs to have access to the public key generated above. This file is usually located in ~/.ssh as authorized_keys.

ssh user@remotehost mkdir ~/.ssh
ssh user@remotehost chmod 0700 ~/.ssh
cat ~/.ssh/id_rsa.pub | ssh user@remotehost "cat - >> ~/.ssh/authorized_keys"
ssh user@remotehost chmod 0600 ~/.ssh/authorized_keys

Set up Agent

To set up login, such that you only have to enter your ssh authentication password (not your remotehost password) and for that authentication to persist whilst your desktop session is active, we use an 'agent' to securely hold your credentials.

  • agent to store credentials
  • add credentials to store
eval `ssh-agent`

From the manpage ssh-agent(1):

ssh-agent is a program to hold private keys used for public key authentication 
(RSA, DSA).  The idea is that ssh-agent is started in the beginning of an 
X-session or a login session, and all other windows or programs are started 
as clients to the ssh-agent program.

From the manpage ksh(8):

eval command ...
    The arguments are concatenated (with spaces between them) to form
    a single string which the shell then parses and executes in the
    current environment.

Add the credentials to the agent store using ssh-add

ssh-add

From manpage sshd-add(1):

ssh-add adds RSA or DSA identities to the authentication agent,
ssh-agent(1).  When run without arguments, it adds the files
~/.ssh/id_rsa, ~/.ssh/id_dsa and ~/.ssh/identity.  Alternative file names
can be given on the command line.

Connect

You should now be able to connect to the remote host without need to enter your HOST password

ssh user@remotehost

SSH Tunnel

[ O'Reilly SSH: The Secure Shell 9.2 Port Forwarding, SSH tunneling for secure web surfing]

SSH Tunnels are simpler to execute using authentication keys.

From manpage ssh(1):

 -4     Forces ssh to use IPv4 addresses only.

 -A     Enables forwarding of the authentication agent connection.  This
        can also be specified on a per-host basis in a configuration
        file.

 -f     Requests ssh to go to background just before command execution.
        This is useful if ssh is going to ask for passwords or passphras-
        es, but the user wants it in the background.  This implies -n.
        The recommended way to start X11 programs at a remote site is
        with something like ssh -f host xterm.

 -L [bind_address:]port:host:hostport

 -N     Do not execute a remote command.  This is useful for just for-
        warding ports (protocol version 2 only).

Port Forwarding

Something we use a lot is to lock down the POP3 (port 110) on our servers. POP3 is normally only available from localhost.

In the below example, used in our fetchmailrc files, we access POP3 by forwarding a localhost port address to the POP3 port on the remote host (from inside the host.)

Local Host to Remote Host

ssh -4 -f -L1125:127.0.0.1:110 $REMOTEHOST -N

We can now encrypt traffic to POP3 port on REMOTEHOST by talking to port 1125 on our current machine.

An interesting permutation of port forwarding, is accessing a REMOTEHOST through a proxy server (e.g. gateway box.)

ssh -4 -f -L6389:$RDPHOST:3389 $PROXY -N

The above example, links port 6389 on our local machine through $PROXY to port 3389 at $RDPHOST. Another valid permutation, is to not use "-N" by executing a "sleep" command (which will tell SSH to teardown the connection if not used within the sleep timeperiod.

ssh -4 -f -L6389:$RDPHOST:3389 $PROXY "sleep 10" && rdesktop -T '$WINDOW_TITLE' uUsername -g800x600 -a8 -rsound:off -5 localhost:6389

Remote Port Forwading

We often have the case where access to various machines, is through an intermediary host. We thus have to initiate a tunnel to that intermediary host, then from that host to our actual target host.

To simplify things, we use the same port address on our current host for the port address to be used on the intermediary host.

Local Host to Intermediate Host to Remote Host

ssh -4 -f -A $INTERMEDIATE  -L 1109:127.0.0.1:1109 "ssh -4 -L 1109:127.0.0.1:110 $REMOTEHOST -N"

Again, the above example is connecting to the POP3 port on REMOTEHOST, by using a local port 1109 which connects to the same port on an intermediary host.

SSH Tunnel SMB

Limit Bandwidth used

Limit the bandwidth used for file transfers

scp -l SIZE SRC DST

From manpage scp(1)

-l limit
    Limits the used bandwidth, specified in Kbit/s.

Miscellaneous