Getting started with SSH security and configuration

A hands-on guide


What is SSH? A basic description

Secure Shell (SSH) was intended and designed to afford the greatest protection when remotely accessing another host over the network. It encrypts the network exchange by providing better authentication facilities as well as features such as Secure Copy (SCP), Secure File Transfer Protocol (SFTP), X session forwarding, and port forwarding to increase the security of other insecure protocols. Various types of encryption are available, ranging from 512-bit encryption to as high as 32768 bits, inclusive of ciphers, like Blowfish, Triple DES, CAST-128, Advanced Encryption Scheme (AES), and ARCFOUR. Higher-bit encryption configurations come at a cost of greater network bandwidth use. Figure 1 and Figure 2 show how easily a telnet session can be casually viewed by anyone on the network using a network-sniffing application such as Wireshark.

Figure 1. Telnet protocol sessions are unencrypted.
Illustration displaying how telnet protocol sessions are unencrypted
Illustration displaying how telnet protocol sessions are unencrypted

When using an unsecured, "clear text" protocol such as telnet, anyone on the network can pilfer your passwords and other sensitive information. Figure 1 shows user fsmythe logging in to a remote host through a telnet connection. He enters his user name fsmythe and password r@m$20!0, which are both then viewable by any other user on the same network as our hapless and unsuspecting telnet user.

Figure 2. SSH protocol sessions are encrypted.
Illustration showing how SSH protocol sessions are encrypted
Illustration showing how SSH protocol sessions are encrypted

Figure 2 provides an overview of a typical SSH session and shows how the encrypted protocol cannot be viewed by any other user on the same network segment. Every major Linux® and UNIX® distribution now comes with a version of the SSH packages installed by default—typically, the open source OpenSSH packages—so there is little need to download and compile from source. If you're not on a Linux or UNIX platform, a plethora of open source and freeware SSH-based tools are available that enjoy a large following for support and practice, such as WinSCP, Putty, FileZilla, TTSSH, and Cygwin (POSIX software installed on top the Windows® operating system). These tools offer a UNIX- or Linux-like shell interface on a Windows platform.

Whatever your operating system, SSH touts many positive benefits for commonplace, everyday computing. Not only is it dependable, secure, and flexible, but it is also simple to install, use, and configure—not to mention feature laden.

SSH architecture

IETF RFCs 4251 through 4256 define SSH as the "Secure Shell Protocol for remote login and other secure network services over an insecure network." The shell consists of three main elements (see Figure 3):

  • Transport Layer Protocol: This protocol accommodates server authentication, privacy, and integrity with perfect forward privacy. This layer can provide optional compression and is run over a TCP/IP connection but can also be used on top of any other dependable data stream.
  • User Authentication Protocol: This protocol authenticates the client to the server and runs over the transport layer.
  • Connection Protocol: This protocol multiplexes the encrypted tunnel to numerous logical channels, running over the User Authentication Protocol.
Figure 3. SSH protocol logical layers
SSH protocol logical layers

The transport layer is responsible for key exchange and server authentication. It sets up encryption, integrity verification, and (optionally) compression and exposes to the upper layer an API for sending and receiving plain text packets. A user authentication layer provides authentication for clients as well as several authentication methods. Common authentication methods include password, public key, keyboard-interactive, GSSAPI, SecureID, and PAM.

The connection layer defines channels, global requests, and the channel requests through which SSH services are provided. A single SSH connection can host multiple channels concurrently, each transferring data in both directions. Channel requests relay information such as the exit code of a server-side process. The SSH client initiates a request to forward a server-side port.

This open architecture design provides extensive flexibility. The transport layer is comparable to Transport Layer Security (TLS), and you can employ custom authentication methods to extend the user authentication layer. Through the connection layer, you can multiplex secondary sessions into a single SSH connection (see Figure 4).

Figure 4. SSH within the Seven-layer OSI Model
SSH within the Seven-layer OSI Model
SSH within the Seven-layer OSI Model

Common use of SSH for UNIX and Linux systems

You typically use SSH to allow users to log in to a remote host and execute commands. However, SSH also supports tunneling and X11 connections. It can even transfer files using SFTP or SCP. SSH is applicable for numerous applications within most common platforms, including Linux, UNIX, Windows, and Apple® OS X, although some applications may require features that are only available or compatible with specific SSH clients or servers.

Here are a few common SSH syntax examples:

  • Remote host shell access (supersedes telnet and rlogin clear text, insecure protocols):
    # ssh
    [] ~
  • Executing a single command on a remote host (replacing rsh):
    # ssh reboot's password: ******
  • Copying files from a local server to a remote host by way of the SCP command:'s password: ******
    file1.txt      100%    0     0.0KB/s   00:00
    file2.txt      100%    0     0.0KB/s   00:00
  • In combination with SFTP, as a secure substitute to FTP file transfer:
    Connecting to's password: *******
  • In combination with rsync to back up, copy, and mirror files efficiently and securely to a local or remote host:
    # rsync -avul --rsh=ssh /opt/edbdata/'s password: ******
    building file list ... done
    sent 982813 bytes  received 2116 bytes  1374860.38 bytes/sec
    total size is 982138  speedup is 1.00
  • Port forwarding or tunneling a port (not to be confused with a VPN):
    ssh -L 8000:mailserver:110's password: ********
  • Forwarding X sessions from a remote host (possible through multiple intermediate hosts):
    Edit /etc/ssh/sshd_config and change 2 keywords : 
    AllowTcpForwarding yes
    X11Forwarding yes
    # service sshd restart 
    $ export DISPLAY 
    $ ssh -X
  • With the X11 forwarding configuration in conjunction with an X Windows client with SSH X11 tunneling to allow for the implementation of a UNIX or Linux GUI subsystem run over SSH securely on the same Windows machine host that is the source for the SSH session to the Linux or UNIX remote host:
    ssh -ND 8000
    Browser Settings, goto 'Manual Proxy Configuration' set "SOCKS Host" to,
    the 'Port to 8000' , Enable SOCKS v5, and lastly set 'No Proxy for' field
    to 'localhost,'
  • Securely mounting a directory on a remote server as a file system on a local computer using sshfs:
    # yum install sshfs fuse-utils (Install sshfs and fuse-utils)
    $sshfs /mnt/local_dir
  • Automated remote host monitoring and management of servers through one or more mechanism:
    (Report number of apache processes running on the remote server
    $ ssh ps -ef | grep httpd | wc -l's password: *****

SSH security and configuration best practices

With some of the previously illustrated code examples, many good systems administrators are nervous about some of the security implementations for SSH usage and functions. Although much has been said and written about the various approaches to SSH security and remote host security in general, here is a list of processes and configurations that you can use to tighten and enhance SSH security with regard to remote host access:

  • Restrict the root account to console access only:
    # vi /etc/ssh/sshd_config
    PermitRootLogin no
  • Create private-public key pairs using a strong passphrase and password protection for the private key (never generate a password-less key pair or a password-less passphrase key-less login):
    (Use a higher bit rate for the encryption for more security)
    ssh-keygen -t rsa -b 4096
  • Configure TCP wrappers to allow only selective remote hosts and deny undesirable hosts:
    # vi /etc/hosts.deny
    ALL:		# IP Address of badguy
  • On workstations or laptops, disable the SSH server by turning off the SSH service, and then removing the ssh server package:
    # chkconfig sshd off 
    # yum erase openssh-server
  • Restrict SSH access by controlling user access:
    # vi /etc/ssh/sshd_config 
    AllowUsers fsmythe bnice swilson
    DenyUsers jhacker joebadguy jripper
  • Only use SSH Protocol 2:
    # vi /etc/ssh/sshd_config
    Protocol 2
  • Don't allow Idle sessions, and configure the Idle Log Out Timeout interval:
    # vi /etc/ssh/sshd_config
    ClientAliveInterval 600		# (Set to 600 seconds = 10 minutes)
    ClientAliveCountMax 0
  • Disable host-based authentication:
    # vi /etc/ssh/sshd_config
    HostbasedAuthentication no
  • Disable users' .rhosts files:
    # vi /etc/ssh/sshd_config
    IgnoreRhosts yes
  • Configure firewalls to accept SSH connections only from know network segments:
    Update /etc/sysconfig/iptables (Redhat specific file) to accept connection only 
    from and, enter:
    -A RH-FW-1-INPUT -s -m state --state NEW -p tcp --dport 22 -j ACCEPT
    -A RH-FW-1-INPUT -s -m state --state NEW -p tcp --dport 22 -j ACCEPT
  • Restrict the available interfaces that SSH will listen on and bind to:
    # vi /etc/ssh/sshd_config
  • Set user policy to enforce strong passwords to protect against brute force, social engineering attempts, and dictionary attacks:
    # < /dev/urandom tr -dc A-Za-z0-9_ | head -c8
  • Confine SFTP users to their own home directories by using Chroot SSHD:
    # vi /etc/ssh/sshd_config 
    ChrootDirectory /data01/home/%u
    X11Forwarding no
    AllowTcpForwarding no
  • Disable empty passwords:
    # vi /etc/ssh/sshd_config
    PermitEmptyPasswords no
  • Rate-limit the number of incoming port 2022 connections within a specified time:
    Redhat iptables example (Update /etc/sysconfig/iptables): 
    -A INPUT  -i eth0 -p tcp --dport 2022 -m state --state NEW -m limit --limit 3/min
    --limit-burst 3 -j ACCEPT
    -A INPUT  -i eth0 -p tcp --dport 2022 -m state --state ESTABLISHED -j ACCEPT
    -A OUTPUT -o eth0 -p tcp --sport 2022 -m state --state ESTABLISHED -j ACCEPT
  • Configure iptables to allow only three connection attempts on port 2022 within 30 seconds:
    Redhat iptables example (Update /etc/sysconfig/iptables): 
    -I INPUT -p tcp --dport 2022 -i eth0 -m state --state NEW -m recent --set
    -I INPUT -p tcp --dport 2022 -i eth0 -m state --state NEW -m recent --update 
    --seconds 30 --hitcount 3 -j DR
  • Use a log analyzer such as logcheck, loggrep, splunk, or logwatch to better understand the logs and create logging reports. Also, increase logging verbosity within the SSH application itself:
    Installation of the logwatch package on Redhat Linux 
    # yum install logwatch
  • Configure an increase in SSH logging verbosity:
    # vi /etc/ssh/sshd_config
    LogLevel DEBUG
  • Always keep the SSH packages and required libraries up to date on patches:
    # yum update openssh-server openssh openssh-clients -y
  • Conceal the OpenSSH version, require SSH source code, and re-compile. Then, make the following updates:
    # vi /etc/ssh/sshd_config
    VerifyReverseMapping yes	# Turn on  reverse name checking
    UsePrivilegeSeparation yes	# Turn on privilege separation
    StrictModes yes			# Prevent the use of insecure home directory    
    				# and key file permissions
    AllowTcpForwarding no		# Turn off , if at all possible 
    X11Forwarding no		# Turn off , if at all possible
    PasswordAuthentication no	# Specifies whether password authentication is 
    				# allowed.  The default is yes. Users must have 
    				# another authentication method available .
  • Delete the rlogin and rsh binaries from the system, and replace them with a symlink to SSH:
    # find /usr -name rsh
    # rm -f /usr/bin/rsh
    # ln -s /usr/bin/ssh /usr/bin/rsh

SSH supports numerous, diverse methods and techniques for authentication that you can enable or disable. Within the /etc/ssh/sshd_config file, you make these configurations changes by entering the keyword listed for the authentication method followed by yes or no. Here are some of the common configuration changes:

# RSAAuthentication yes		
# PubkeyAuthentication yes		
# RhostsRSAAuthentication no
# HostbasedAuthentication no
# RhostsRSAAuthentication and HostbasedAuthentication
PasswordAuthentication yes
ChallengeResponseAuthentication no
# KerberosAuthentication no
GSSAPIAuthentication yes

The keywords AllowedAuthentications and RequiredAuthentications within the sshd_config file dictate which authentication methods and configurations are used with SSH Protocol 2 only, and the syntax for them to allow password and public key authentication is as follows:

# vi /etc/ssh/sshd_config
AllowedAuthentications publickey, password
RequiredAuthentications publickey, password

Private and public key pairs for SSH

To help validate identities, SSH has a key management capacity and related agents. When configured with public key authentication, your key proves your identity to remote SSH hosts. An SSH-based identity consists of two parts: a public key and a private key. The private SSH key is the user's identity for outbound SSH connections and should be kept confidential. When a user initiates an SSH or SCP session to a remote host or server, he or she is said to be the SSH client. Through a mathematical algorithm, a private key is like your electronic identification card; the public key is like the lock or gate mechanism that you present your ID card to. Your private key says, "This really is Fred Smythe"; the public key says, "Yes, you are indeed the real Fred Smythe; you are now authenticated: Please enter."

Your public key represents who you will allow inbound access to through your gate or lock. Public keys need not be kept secret; they cannot be used to compromise a system or for unwarranted access into a system. On a Linux or UNIX system, these private and public key pairs are stored in ASCII text files; on Windows systems, some programs store the key pairs as text files, some in the Windows registry.

Multiple identifications using multiple private keys can be created with an SSH Protocol 2 configuration. Let's look at how to generate, set up, and configure an SSH private and public key pair on typical Linux hosts (see Figure 5).

Figure 5. Diagram of the SSH private-public key pair transactions, as defined within the SSH defined architecture model
SSH private-public key pair transactions
SSH private-public key pair transactions

Steps for configuring public and private SSH key pairs

The example shown in step 1 (see Listing 1) uses the ssh-keygen utility for user fsmythe to create the SSH private-public key pair with the type of dsa.

Listing 1. Generate the SSH key pair
[ ~]$ /usr/bin/ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/fsmythe/.ssh/id_dsa):
Enter passphrase (empty for no passphrase): ******    (Enter 'mypassword')
Enter same passphrase again: ******	(Enter 'mypassword')
Your identification has been saved in /home/fsmythe/.ssh/id_dsa.
Your public key has been saved in /home/fsmythe/.ssh/
The key fingerprint is:
[ ~]$

The example shown in step 2 (Listing 2) illustrates copying the public key of the key pair from the source to the destination host's authorized_keys file within the .ssh subdirectory under the home directory of the desired user account on the destination host.

Listing 2. Copy the public key from the source host to the authorized_keys file on the destination host
[ ~]$ scp -p /home/fsmythe/.ssh/
fsmythe@'s password:       100%  	624   	0.6KB/s    	00:00

The example shown for step 3 (see Listing 3) makes the first-time remote SSH call (ls -d /tmp) to the destination server, thereby caching the key within your server's .ssh/known_hosts file. You enter the same passphrase with which you created the SSH private-public key pair, and the output of the command run on the remote destination server is seen locally back on your source server.

Listing 3. Verify the SSH access by running a remote command on the target remote host
[ ~]$ ssh ls -d /tmp
The authenticity of host ' (' can't be established.
RSA key fingerprint is 84:4f:e5:99:0b:7d:54:d0:1b:3e:2b:96:02:34:41:25.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ',' (RSA) to the list of known hosts.
Enter passphrase for key '/root/.ssh/id_dsa': ******  (Enter 'mypassword') 

Note: For the examples above, you didn't have to enter the user fsmythe's password. Rather, you enter the passphrase that you set in the first step. If you would rather not have to enter a passphrase when accessing the remote destination, create an empty passphrase by typing enter in step 1 when prompted for the passphrase. Now, you won't have to type anything to access the remote target machine as the user fsmythe.

Configuring and using the ssh-agent

For the truly paranoid who refuse to create a password-less SSH public-private key pair, there's the ssh-agent utility. In a nutshell, you use the ssh-agent utility to temporarily grant password-less SSH access on a public-private key pair configuration that does have a passphrase set, but only for the current shell session. Before employing the ssh-agent utility, enter the passphrase as normal:

[ ~]# ssh
Enter passphrase for key '/root/.ssh/id_dsa':******	(User must type password)
Last login: Sat May  8 06:37:26 2010 from

Next, query ssh-agent to generate Bourne shell commands on stdout:

[ ~]# ssh-agent -s
SSH_AUTH_SOCK=/tmp/ssh-vxZIxF1845/agent.1845; export SSH_AUTH_SOCK;
echo Agent pid 1849;

In step 3, you set the aforementioned environmental variables in the current shell session:

[root@example01 ~]# SSH_AUTH_SOCK=/tmp/ssh-vxZIxF1845/agent.1845;export SSH_AUTH_SOCK
SSH_AGENT_PID=1849; export SSH_AGENT_PID;echo Agent pid 1849
Agent pid 1849

Then, verify that the ssh-agent is running:

[ ~]# ps -fp $SSH_AGENT_PID
root      1849     1  0 06:14 ?        00:00:00 ssh-agent -s

Now, list the currently loaded identities within the running ssh-agent:

[ ~]# ssh-add -l
The agent has no identities.

In step 6, add the desired SSH identities (preauthenticating them with the correct passphrase for that SSH key):

[ ~]# ssh-add
Enter passphrase for /root/.ssh/id_dsa:
Identity added: /root/.ssh/id_dsa (/root/.ssh/id_dsa)	****** (Entered 'mypassword')

Now, you can verify that those identities are loaded into the running ssh-agent:

[ ~]# ssh-add -l
1024 33:af:35:cd:58:9c:11:91:0f:4a:0c:3a:d8:1f:0e:e6 /root/.ssh/id_dsa (DSA)

Finally, test the ssh-agent with SSH command syntax. Note that now there's no passphrase prompt:

# Assuming target remote host has correct authorized key for private key from example01
[ ~]# ssh -A	
Last login: Sat May  8 06:36:27 2010 from
[root@example02 ~]#

# Assuming target remote host has correct authorized key for private key from example03
[ ~]# ssh -A		
Last login: Sat May  8 07:04:05 2010 from
[root@example03 ~]#

When you enter the passphrase using the ssh-add command, you are actually decrypting the private key and then placing it in memory through the agent for any future SSH connections with that particular passphrase. Note that you can enter multiple private keys and pre-authenticate them with the ssh-add command.

The SSH tool ssh-keyscan, shown in Listing 4, allows you to gather the public SSH host keys from multiple remote SSH hosts. The tool is helpful in building of the /etc/ssh_known_hosts files and is exceptionally fast and efficient. It is primarily suited to shell scripts for automation purposes.

Listing 4. Example using ssh-keyscan
[root@example01 ~]# /usr/bin/ssh-keyscan -t rsa,dsa
# example02.comSSH-2.0-OpenSSH_4.3
example02.comssh-dss AAAAB3NzaC1kc3MAAACBALd5/TGn7jCL1DWWzYMw96jw3QOZGBXJgP4m9LACViyM0QHs
# example03.comSSH-2.0-OpenSSH_4.3
example03.comssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq5So5VBeH4gPX1A1VEeQkGsb/miiWsWnNTW8ZWYj
# example04.comSSH-2.0-OpenSSH_4.3
example04.comssh-dss AAAAB3NzaC1kc3MAAACBALd5/TGn7jCL1DWWzYMw96jw3QOZGBXJgP4m9LACViyM0QHs
# example05.comSSH-2.0-OpenSSH_4.3
example05.comssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq5So5VBeH4gPX1A1VEeQkGsb/miiWsWnNTW8ZWYj

Configuring SSH with UNIX applications or scripts

Configuration of SSH access for use by remote shell scripts and remote tools for maintenance, remote backup, and archival systems has great usefulness, but it has always been at the very least a subject of high controversy when it comes to server security. Many shell scripts that a user might want to run, such as:

$ ssh /usr/local/bin/

cannot handle a required SSH passphrase prompting him or her to authenticate but in fact will break unless a password-less private-public SSH key pair, an ssh-agent configuration, or possibly a trusted host network mechanism—something that does not prompt for an SSH password—has been configured ahead of time. This is because SSH expects the passphrase from the current terminal associated with that shell session. A user can get around this issue by using an expect script or possibly a Perl (see CPAN Module Net::SSH::Perl) script (or your shell script could alternatively call one of the aforementioned types of scripts):

spawn sftp $argv
expect "password:"
send "mysshpassowrd\r"

Granting a password-less SSH mechanism for remote host access to typical users is justification enough for a lynching in the eyes of some systems administrators. However, alternative security measures to justify the password-less SSH mechanism for remote host access, such as a user on the remote host machine only given a restricted korn shell (rksh) account or restricted shell (rssh) instead of a full bash or Bourne shell account. It is also possible on an authorized key to restrict a user to a subset of commands in a list so that in effect, the user can only use the exact commands required to run remotely without the possibility for further access or an accidental command run that could damage the system. The SSH restriction example provided in Listing 5 provides such a restriction type.

Listing 5. Example of configuration restricting the authorized_keys file on remote host
[fsmythe@example02 .ssh]$ more authorized_keys
rwarding,no-pty ssh-dss AAAAB3NzaC1kc3MAAACBAOFsC6C7cJUGOZG4Ur9W0J6mxTTk5+MYTu5XfRESPLVwQ
F78BTk2Ess0SZu8dwpOtasTNEp+xPcsOvQx2Kdr17gTp+28SfpREuLudOr6R3KeTb+hw== fsmythe@example01

User fsmythe at host example01 is only allowed to execute the command ="/usr/local/bin/ in this example.

Creating a trusted host environment using SSH

Finally, I mention the trusted host environment as an alternative to setting up public-private SSH key pairs. For automation or in a scripted environment in which these types of calls are necessary, the trusted host network, though still bearing some security risks, has advantages over the public-private key pair scenario. A trusted host network or trusted host authentication relies primarily on preconfigured files that list a combination of users and hosts that are allowed access. There are two types of trusted-host authentication. The older (such as for OpenSSH and SSH1) and weaker uses the clear-text protocol commands (rsh, rcp, and rlogin); checks the two files; and sets one keyword in the sshd_config file:


SSH Protocol 2 does not support this method. Instead, for a more secure trusted host network, make the following changes in the /etc/ssh/sshd_config file (which accepts host names or IP Addresses), and configure the shosts.equiv and/or the .shosts files:


To enable a trusted-host environment in the /etc/ssh/sshd_config file for SSH Protocol 2, use:

PermitEmptyPasswords yes

For example, if you were on the server and had configured your /etc/shosts.equiv file as follows: fsmythe sallyh
+ fsmythe james

you would allow user fsmythe trusted host authentication from the remote sources,, and and user sallyh access from, denying access from user james at the remote source

The trusted-host authentication and public-private SSH key pair authentication methods are similar and to a greater end achieve the same results. Table 1 provides a side-by-side comparison of the two authentication methods.

Table 1. Comparison of private-public SSH key pairs with trusted-host configuration
SSH aspectTrusted hostPrivate-public key pair
Authenticate by IP addressYesYes
Authenticate by host nameYesYes
Use other public key featuresNoYes
Authenticate by remote user nameYesNo
Allow wildcards in host names and IP addressesNoYes
Passphrase is necessary for login accessNoNo
Breaks on IP address or host name changeSometimesYes
Configuration required on the server and clientNoYes
Useful for automated tasks or scripting needsYesYes

To those admins who are scoffing right now at the thought of allowing a trusted host authentication system using password-less remote SSH access on their network, consider the downside of public-private key pairs when using a script for remote SSH functionality:

  • If a server host name or IP address changes, the public-private key pair configuration will break because of the cached known hosts. The old entry will need to be removed in the .ssh/known_hosts file and the SSH remote host name and/or IP address re-cached again. This will break scripts dependant on the private-public key pair.
  • Private-public key pair authentication requires both client and server configuration. If an SSH public key changes or the pair is regenerated, all of the remote hosts will need the new public key in their authorized_keys file.
  • If the permissions of the .ssh/ folder or private or public key files themselves change, it could prevent the SSH password-less access from occurring. To disable strict file and directory permissions checking, set the keyword StrictModes to no within /etc/ssh/sshd_config file.
  • There is no centralized way to revoke a key once a key pair has been generated or to know exactly to whom the key has been distributed.


SSH is a powerful and secure network utility that countless users worldwide use for numerous tasks. Offered as a safe and secure alternative to the clear-text protocols such as telnet and the r* series command and with multiple offerings of freely distributable SSH clients and servers, SSH is difficult to beat. Used widely in many networks for mass remote monitoring, system maintenance, remote system auditing, reporting, and automation within scripting technologies, it appears that SSH is here to stay and will continue to evolve.

Downloadable resources

Related topics


Sign in or register to add and subscribe to comments.

Zone=AIX and UNIX
ArticleTitle=Getting started with SSH security and configuration