# OpenSSH/Why Use Encryption

Encryption has been a hot topic in computing for a long time. It became
a high priority item in national and international politics in 1991 when
Dr. Phil Zimmermann at the Massachusetts Institute of Technology (MIT)
first published Pretty Good Privacy (PGP). With the arrival of the first
web shops, encryption went from a specialty to a requirement and
increasing volumes of money changed hands online. By 1996, encryption
became essential for e-business. By 2000, it became recognized as a
general, essential prerequisite in electronic communication. Currently,
in 2010, there is almost no chance of maintaining control over or
integrity of any networked machine for more than a few minutes without
the help of encryption.

Nowadays, much communication over computer networks is still done
without encryption. That would be most communication, if inadequate
encryption is also taken into account. This is despite years of
warnings, government recommendations, best practice guidelines and
incidents. As a result, any machine connected to the network can
intercept communication that passes over that network. The eavesdroppers
are many and varied. They include administrators, staff, employers,
criminals, corporate spies, and even governments. Corporate espionage
alone has become an enormous burden and barrier.

Businesses are well aware of dumpster diving and take precautions to
shred all paper documents. But what about electronic information?
Contracts and negotiations, trade secrets, patent applications,
decisions and minutes, customer data and invoicing, personnel data,
financial and tax records, calendars and schedules, product designs and
production notes, training materials, and even regular correspondence go
over the net daily. Archived materials, even if they are not accessed
directly, are usually on machines that are available and accessed for
other reasons.

Many company managers and executives are still unaware that their
communications and documents are so easily intercepted, in spite of
apparent and expensive access restrictions. In many cases these can be
shown to be ineffectual and at best purely cosmetic. Security Theater is
one obstacle and in the field of security it is more common to find
snake oil than authentic solutions. Still, there is little public
demonstration of awareness of the magnitude of corporate espionage
nowadays or the cost of failure. Even failure to act has its costs. Not
only is sensitive data available if left unencrypted, but also trends in
less sensitive data can be spotted with a large enough sampling. A very
large amount of information can be inferred even from lesser
communications. Data mining is now a well-known concept as is the
so-called wireless wiretap. With the increase in online material and
activity, encryption is more relevant than ever even if many years have
passed since the issues were first brought into the limelight.

## Excerpt of ssh-1.0.0 README from July 12, 1995

Tatu Ylönen, then at the Helsinki University of Technology, wrote the
README[^1] accompanying the early versions of his Open Source software,
SSH. The following is an excerpt about why encryption is important.

## Phil Zimmermann on encryption and privacy, from 1991, updated 1999

Phil Zimmermann wrote the encryption tool Pretty Good Privacy (PGP) in
1991 to promote privacy and to help keep encryption, and thus privacy,
legal around the world. Considerable difficulty occurred in the United
States until PGP was published outside and re-imported in a very
visible, public manner.

## Original Press Release for OpenSSH

Below is the original press release for OpenSSH sent back in 1999.[^2]

cvs.openbsd.org\>\
To: Liz Coolbaugh \<lwn{{@}}lwn.net\>\
Subject: OpenBSD Press Release: OpenSSH integrated into operating system

PRESS RELEASE

OpenSSH: Secure Shell integrated into OpenBSD operating system

Source: OpenBSD\
Contacts:

:   Louis Bertrand, OpenBSD media relations
:   Bertrand Technical Services
:   Tel: (905) 623-8925 Fax: (905) 623-3852
:   louis{{@}}openbsd.org

```{=html}
<!-- -->
```

:   Theo de Raadt, OpenBSD lead developer
:   deraadt{{@}}openbsd.org

Project Web site: <http://www.openbsd.org/>

OpenSSH: Secure Shell integrated into OpenBSD Secure communications
package no longer third-party add-on

\[October 25, 1999: Calgary, Canada\] \-- The OpenBSD developers are
pleased to announce the release of OpenSSH, a free implementation of the
popular Secure Shell encrypted communications package. OpenSSH, to be
released with OpenBSD 2.6, is compatible with both SSH 1.3 and 1.5
protocols and dodges most restrictions on the free distribution of
strong cryptography.

OpenSSH is based on a free release of SSH by Tatu Ylonen, with major
changes to remove proprietary code and bring it up to current security
and functionality standards. Secure Shell operates like the popular
TELNET remote terminal package but with an encrypted link between the
user and the remote server. SSH also allows \"tunnelling\" of network
services through the scrambled connection for added privacy. OpenSSH has
been tested to interoperate with ssh-1.2.27 from SSH Communications, and
the TTSSH and SecureCRT Windows clients.

\"Network sessions involving strong cryptographic security are a
requirement in the modern world,\" says lead developer Theo de Raadt.
\"Everyone needs this. People using the telnet or rlogin protocols are
not aware of the extreme danger posed by password sniffing and session
hijacking.\"

In previous releases of OpenBSD, users were urged to download SSH as
soon as possible after installing the OS. Without SSH, terminal sessions
transmitted in clear text allow eavesdroppers on the Internet to capture
user names and password combinations and thus bypass the security
measures in the operating system.

\"I asked everyone \`what is the first thing you do after installing
OpenBSD?\' Everyone gave me the same answer: they installed ssh,\" says
de Raadt. \"That\'s a pain, so we\'ve made it much easier.\"

All proprietary code in the original distribution was replaced, along
with some libraries burdened with the restrictive GNU Public License
(GPL). Much of of the actual cryptographic code was replaced by calls to
the crypto libraries built into OpenBSD. The source code is now
completely freely re-useable, and vendors are encouraged to re-use it if
they need ssh functionality.

OpenSSH relies on the Secure Sockets Layer library (libssl) which
incorporates the RSA public-key cryptography system. RSA is patented in
the US and OpenBSD developers must work around the patent restrictions.
Users outside the US may download a libssl file based on the patent-free
OpenSSL implementation. For US non-commercial users, OpenBSD is
preparing a libssl based on the patented RSAREF code. Unfortunately, the
US legal framework effectively bans US commercial users from using
OpenSSH, and curtails freedom of choice in that market.

OpenSSH was developed and integrated into OpenBSD by Niels Provos, Theo
de Raadt, Markus Friedl for cryptographic work; Dug Song, Aaron
Campbell, and others for various non-crypto contributions; and Bob Beck
for helping with the openssl library issues. The original SSH was
written by Tatu Ylonen. Bjoern Groenvall and Holger Trapp did the
initial work to free the distribution.

OpenBSD is an Internet-based volunteer effort to produce a secure
multi-platform operating system with built-in support for cryptography.
It has been described in the press as the world\'s most secure operating
system. For more information about OpenSSH and OpenBSD, see the project
Web pages at <http://www.OpenBSD.org/>.

Source: OpenBSD\
<http://lwn.net/1999/1028/a/openssh.html> }}

## The European Union (EU) on Encryption

During 2000, the European Commission investigated the state of
international and industrial electronic espionage. Counter-measures and
solutions were investigated as well as the risks. The result was a
resolution containing a summary of the findings and a series of
recommended actions for Member States to carry out and goals to meet.
Recommendations to EU Member States from the European Parliament
resolution ECHELON, A5-0264/2001 (emphasis added):

:   \"29. Urges the Commission and Member States to devise appropriate
    measures to promote, develop and manufacture European encryption
    technology and software and above all to support projects at
    developing user-friendly **open-source encryption** software;\"
:   . . .
:   \"33. Calls on the Community institutions and the public
    administrations of the Member States to provide training for their
    staff and make their staff familiar with new **encryption
    technologies and techniques** by means of the necessary practical
    training and courses;\"[^3]

It was found during the investigation that businesses were the most at
risk and the most vulnerable and that widespread use of open source
encryption technology is to be encouraged. The same can be said even
today.

## References

[^1]:

[^2]:

[^3]:


# OpenSSH/SSH Protocols

OpenSSH uses the SSH protocol which connects over TCP. Normally, one SSH
session per TCP connection is made, but multiple sessions can be
multiplexed over a single TCP connection if planned that way. The
current set of Secure Shell protocols is SSH2. It is a rewrite of the
old, deprecated SSH1 protocol. It contains significant improvements in
security, performance, and portability. The default is now SSH2 and SSH1
support has been removed from both the client and server.

!Sequence Diagram for SSH Password
Authentication

The Secure Shell protocol is an open standard. As such, it is
vendor-neutral and maintained by the Internet Engineering Task Force
(IETF). The current protocol is described in RFC 4250 through RFC 4256
and standardized by the IETF secsh working group. The overall structure
of SSH2 is described in RFC 4251, The Secure Shell (SSH) Protocol
Architecture.

The SSH protocol is composed of three layers: the transport layer, the
authentication layer, and the connection layer.

:   **SSH-CONNECT** -- The connection layer runs over the user
    authentication protocol. It multiplexes many different concurrent
    encrypted channels into logical channels over the authenticated
    connection. It allows for tunneling of login sessions and
    TCP-forwarding. It provides a flow control service for these
    channels. Additionally, various channel-specific options can be
    negotiated. This layer manages the SSH session, session
    multiplexing, X11 forwarding, TCP forwarding, shell, remote program
    execution, invoking SFTP subsystem.

```{=html}
<!-- -->
```

:   **SSH-USERAUTH** -- The user authentication layer authenticates the
    client-side to the server. It uses the established connection and
    runs on top of the transport layer. It provides several mechanisms
    for user authentication. These include password authentication,
    public-key or host-based authentication mechanisms,
    challenge-response, pluggable authentication modules (PAM), Generic
    Security Services API (GSSAPI) and even dongles.

```{=html}
<!-- -->
```

:   **SSH-TRANS** -- The transport layer provides server authentication,
    confidentiality and data integrity over TCP. It does this through
    algorithm negotiation and a key exchange. The key exchange includes
    server authentication and results in a cryptographically secured
    connection: it provides integrity, confidentiality and optional
    compression. [^1]

Among the differences between the current protocol, SSH2, and the
deprecated SSH1 protocol, is that SSH2 uses host keys for
authentication. Whereas SSH1 used both server and host keys to
authenticate. There\'s not much which can be added about the protocols
which is not already covered with more detail and authority in RFC 4251
[^2].

## SSH File Transfer Protocol (SFTP)

The SSH File Transfer Protocol (SFTP) is a binary protocol to provide
secure file transfer, access and management.

SFTP was added by Markus Friedl on the server side in time for the 2.3.0
release of OpenSSH in November 2000. Damien Miller added support for
SFTP to the client side in time for 2.5.0. Since then, many have added
to both the client and the server.

### SFTP is not FTPS

For basic file transfer, nothing more is needed than an account on the
machine with the OpenSSH server. SFTP support is built into the OpenSSH
server package. The SFTP protocol, in contrast to old FTP, has been
designed from the ground up to be as secure as possible for both login
and data transfer.

Unless the use-case calls for publicly available, read-only, downloads,
don\'t worry about trying to fiddle with FTP. It is the protocol FTP
itself that is inherently insecure. It\'s great for read-only, public
data transfer. The programs **vsftpd** and **proftpd**, for example, are
secure insofar as the server software itself goes, although the protocol
itself is still insecure. In other words the program itself is more or
less fine and if you need to provide read-only, publicly available
downloads then FTP maybe the right tool. Otherwise forget about FTP.
Nearly always when users ask for \"FTP\" they don\'t mean specifically
the old file transfer protocol from 1971 as described in RFC 114, but a
generic means of file transfer and there are many ways to solve that
problem. This is especially true since the next part of their request is
usually how to make it secure. The name \"FTP\" is frequently mis-used
generically to mean any file transfer utility, much the same way as the
term \"Coke\" is used in some of Southern United States to mean any
carbonated soft drink, not just Coca-Cola. Consider SFTP or, for larger
groups, even SSHFS, Samba "wikilink"), or
AFS. While old FTP succeeded very
well in achieving its main goal to promote use of networked computers by
allowing users at any host on the network to use the file system of any
cooperating host, it cannot be made secure. There\'s nothing to be done
about that, so it is past time to get over it.

Again, it is the protocol itself, FTP, which is the problem.[^3] With
FTP, the data, passwords and user name are all sent back and forth
unencrypted.[^4] Anyone on the client\'s subnet, the server\'s subnet or
any subnet in between can \'sniff\' the passwords and data when FTP is
used. With extra effort it is possible to wrap FTP inside SSL or TLS,
thus creating FTPS. However, tunneling FTP over SSL/TLS is complex to do
and far from an optimum solution.

Unfortunately because of name confusion combined with the large number
of posts and discussions created by complex, nit-picky tasks like
wrapping FTP in SSL to provide FTPS, the wrong way still turns up
commonly in web searches regarding file transfer. In contrast, easy,
relatively painless solutions vanish because it is rarely necessary to
post how to do those. Also, an easy solution can be summed up in very
few lines and maybe a single answer. Thus, there is still a lot of talk
online about \'securing\' FTP and very little mention of using SFTP.
It\'s a vicious cycle that this book hopes to help break: Difficult
tasks mean lots of discussion and noise, lots of discussion and noise
means strong web presence, strong web presence means high Google
ranking.

SFTP tools are very common, but might be taken for granted and thus
overlooked. SFTP tools are easy to use and more functional than old FTP
clients. In fact a lot of improvements have been made in usability.
There is no shortage of common, GUI-based SFTP clients to transfer
files: Filezilla, Konqueror, Dolphin, Nautilus, Cyberduck, Fugu, and
Fetch top the list but there are many more. Most are Free Software.
Again, these SFTP clients are very easy to use. For example, in
Konqueror, just type in the URL to the sftp server, where the server
name or address is xx.yy.zz.aa.

    sftp://xx.yy.zz.aa

If it is desirable to start with a particular directory, then that too
can be specified.

    sftp://xx.yy.zz.aa/var/www/pictures/

One special client worth knowing about is **sshfs**. With **sshfs** as
an SFTP client the other machine is accessible as an open folder on your
machine\'s local file system. In that way any program you normally have
to work with files, such as LibreOffice, Inkscape or Gimp can access the
remote machine via that folder.

### Background of FTP

FTP is from the 1970s. It\'s a well proven workhorse, but from an era
when if you were on the net you were supposed to be there and if there
was trouble it could usually be cleared up with a short phone call or an
e-mail or two. It sends the login name, password and all of the data
unencrypted for anyone to intercept. FTP clients can connect to the FTP
server in either passive or active modes. Both active and passive modes
for FTP[^5] use two ports, one for control and one for data. In FTP
Active mode, after the client makes a connection to the FTP server it
then allows an incoming connection to be initiated from the server to
for data transfer. In FTP Passive mode, after the client makes a
connection to the FTP server, the server then responds with information
about a second port for data transfer and the client initiates the
second connection. FTP is most relevant now as Anonymous FTP, which is
still excellent for read-only downloads without login. FTP is still one
way to go for transferring read-only data, as would be using the web
(HTTP or HTTPS), or a P2P protocol like Bittorrent. So there are other
options than FTP for offering read-only downloads. Preference is given
lately to HTTPS for small files and Bittorrent for large files or large
groups of files.

#### Using tcpdump to show FTP activity

An illustration of how the old protocol, FTP, is insecure can be had
from the utility **tcpdump**. It can show what is going over the network
during an Anonymous FTP session, or for that matter any FTP session.
Look at the manual page for **tcpdump** for an explanation of the
individual arguments, the usage example below displays the first FTP or
FTP-Data packets going from the client to the server and vice versa.

The output below shows an excerpt from the output of **tcpdump** which
captured packets between an FTP client and the FTP server, one line per
packet.

``` shell
$ sudo tcpdump -q -s 0 -c 10 -A -i eth0 \
"tcp and (port ftp or port ftp-data)"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
…
:18:36.010820 IP desk.55227 > server.ftp: tcp 16 E..D..@.@.....1..X.....G.r. ........l..... ."......USER anonymous
:18:36.073192 IP server.ftp > desk.55227: tcp 0 E..4jX@.7.3.[.X...1..... ...G.r#........... ....."..
:18:36.074019 IP server.ftp > desk.55227: tcp 34 E..VjY@.7.3.[.X...1..... ...G.r#....Y...... ....."..331 Please specify the password.
:18:36.074042 IP desk.55227 > server.ftp: tcp 0 E..4..@.@..+..1.[.X.....G.r# ..)........... ."......
:18:42.098941 IP desk.55227 > server.ftp: tcp 23 E..K..@.@.....1.[.X.....G.r# ..)....gv..... .".w....PASS user@example.net
:18:42.162692 IP server.ftp > desk.55227: tcp 23 E..KjZ@.7.3.[.X...1..... ..)G.r:........... .....".w230 Login successful.
…
:18:43.431827 IP server.ftp > desk.55227: tcp 14 E..Bj\@.7.3.[.X...1..... ..SG.rF.....j..... ....."..221 Goodbye.
…
```

As can be seen in lines 3 and 7, data such as text from the server is
visible. In lines 1 and 5, text entered by the user is visible and in
this case it includes the user name and password used to log in.
Fortunately the session is Anonymous FTP, which is read-only and used
for downloading. Anonymous FTP is a rather efficient way to publish
material for download. For Anonymous FTP, the user name is always
\"anonymous\" and the password is the user's e-mail address and the
server\'s data always read-only.

If you have the package for the OpenSSH server already installed, no
further configuration of the server is needed to start using SFTP for
file transfers. Though comparatively speaking, FTPS is significantly
more secure than FTP. If you want remote remote login access, then both
FTP and FTPS should be avoided. A very large reason to avoid both is to
save work.

### On FTPS

FTPS is FTP tunneled over SSL or TLS. A goal of FTP was to encourage the
use of remote computers which, along with the web, has succeeded. A goal
of FTPS was to secure logins and transfers, and it was a necessary step
in securing file transfers with the legacy protocol. However, since SFTP
is so much easier to deploy and most systems now include both graphical
and text-based SFTP clients, FTPS can really be considered deprecated
for most occasions.

Some good background material can be found in the Request for Comments
(RFCs) for FTP and FTPS. There, SFTP and even HTTPS are better matches
and largely supersede FTPS. See the section on [Client
Applications for an idea of the
SFTP clients available.

## Privilege Separation

!Sequence Diagram for OpenSSH Privilege
Separation
Privilege separation is when a process is divided into sub-processes,
each of which have just enough access to just the right services to do
their part of the job. An underlying principle is that of least
privilege, which is where each process has exactly enough privileges to
accomplish a task, neither more nor less. The goal of privilege
separation is to compartmentalize any corruption and prevent a corrupt
process from accessing other parts of the system. Privilege separation
is applied in OpenSSH by using several levels of access, some higher
some lower, to run sshd(8) and its
subsystems and components. The SSH server ➊ starts out with a privileged
process ➋ which then creates an unprivileged process ➌ to work with the
network traffic. Once the user has authenticated, another unprivileged
process is created ➍ with the privileges of that authenticated user. See
the \"Sequence Diagram for OpenSSH Privilege Separation\". As seen in
the diagram, a total of four processes get run to create an SSH session.
One process, the server, remains and listens for new connections and
spawn new child processes.

``` shell
$ ps -ax -o user,pid,ppid,state,start,command | awk '/sshd/ || NR==1'
USER       PID  PPID STAT   STARTED  COMMAND
root      1473     1 I     05:44:01  sshd: /usr/sbin/sshd [listener] 0 of 10-10
```

It is this privileged process that listens for the initial connection
from clients. Here it is seen waiting and listening on port 22.

``` shell
$ netstat -ntlp | awk '/sshd/ || NR<=2'
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1473/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      1473/sshd
```

After the initial connection while waiting for password authentication
from user \'fred\', a privileged monitor process supervises an
unprivileged process by user \'sshd\' which handles the contact with the
remote user\'s client.

``` shell
$ ps -ax -o user,pid,ppid,state,start,command | awk '/sshd/ || NR==1'
USER       PID  PPID S  STARTED COMMAND
root      1473     1 S 05:44:12 sshd: /usr/sbin/sshd [listener] 1 of 10-10
root      9481  1473 S 14:40:37 sshd: fred [priv]
sshd      9482  9481 S 14:40:37 sshd: fred [net]
```

Then after authentication is completed and a session established for
user \'fred\', a new privileged monitor process is created to supervise
the process running as user \'fred\'. At that point the other process
running as user \'sshd\' has gone away.

``` shell
$ ps -ax -o user,pid,ppid,state,start,command | awk '/sshd/ || NR==1'
USER       PID  PPID S  STARTED COMMAND
root      1473     1 S 05:44:12 sshd: /usr/sbin/sshd [listener] 0 of 10-10
root      9481  1473 S 14:40:37 sshd: fred [priv]
fred      9579  9481 S 14:42:02 sshd: fred@pts/30
```

Privilege separation has been the default in OpenSSH since version
3.3[^6] Since version 5.9, privilege separation further applies
mandatory restrictions on which system calls the privilege separated
child can perform. The intent is to prevent a compromised privilege
separated child from being used to attack other hosts either by opening
sockets and proxying or by probing local kernel attack surface. [^7]
Since version 6.1, this sandboxing has been the default.

## References

[^1]:

[^2]:

[^3]:

[^4]:

[^5]:

[^6]:

[^7]:


# OpenSSH/Other SSH Implementations

## Dropbear

Dropbear is a smaller,
modular, open source SSH2 client and server available for all regular
POSIX platforms. Dropbear is partially a derivative of OpenSSH and it is
often used in embedded systems because very small binaries can be
produced. Functions that are not needed can be left out of the binary,
leaving a lean executable. Thus a working SSH server can be boiled down
to 110KB by trimming away various functions.

Many distributions and products use Dropbear. This includes OpenWRT,
gumstix, Tomato Firmware, PSPSSH, DSLinux, Meego, OpenMoko, Ångström
(for Zaurus), ttylinux, Sisela, Trinux, SliTaz, Netcomm, US Robotics,
some Motorola phones, and many, many more.

-   <https://matt.ucc.asn.au/dropbear/dropbear.html>

## Tectia

Tectia is from SSH Communications
Security Corporation which is based in Finland. It is a closed-source
SSH client and server with FIPS support.

-   <http://www.ssh.com/?option=com_content&view=article&id=236&Itemid=364>

## Solaris Secure Shell (SunSSH)

Sun SSH is fork of
OpenSSH 2.3, with many subsequent changes.

-   <http://hub.opensolaris.org/bin/view/Community+Group+security/SSH>

## GlobalSCAPE EFT Server

EFT Server is a closed binary that
can include SSH and SFTP modules as extensions.

-   <http://www.globalscape.com/eft/>

## Gravitational Teleport

Teleport provides an
Apache-licensed SSH server and client written in Golang. It supports
only IPv4 and not IPv6 at this time.

-   <http://gravitational.com/teleport/>


# OpenSSH/Client Applications

On the client side, ssh(1),
scp(1), and
sftp(1) provide a wide range of
capabilities. Interactive logins and file transfers are just the tip of
the iceberg.

:   ssh(1) - The basic login shell-like
    client program.
:   sftp(1) - FTP-like program that
    works using the SSH protocol.
:   scp(1) - File copy program that acts
    like rcp(1).

```{=html}
<!-- -->
```

:   ssh_config(5) - The client
    configuration file.

## The SSH client

ssh(1) is a program which provides the
client side for secure, encrypted communications between hosts over an
insecure network. Its main use is for logging into and running programs
on a remote host. It can also be used to secure remote X11 connections
and forward arbitrary TCP ports to secure legacy protocols. ssh was
made, in part, to replace insecure tools like **rsh** and **telnet**. It
has largely succeeded at this goal. **rsh** and **telnet** are rarely
seen anymore for interactive sessions or anywhere else. ssh can
authenticate using regular passwords or with the help of a
public-private key pair. More options, such as use of Kerberos,
smartcards, or one-time passwords can be configured.

Remote login, authenticating via password:

``` shell
$ ssh fred@somehost.example.org
```

Another way of logging in to the same account:

``` shell
$ ssh -l fred somehost.example.org
```

Remote programs can be run interactively when the client is run via the
shell on the remote host. Or they can be run directly when passed as an
argument to the SSH client. They can even be pre-configured in the
authentication key or the server configuration.

Run uname(1) on the remote machine:

``` shell
$ ssh -l fred  somehost.example.org  "uname -a"
```

See what file systems are mounted and how much space is used there:

``` shell
$ ssh -l fred  somehost.example.org  "mount; df -h"
```

It is possible to configure in great detail which programs are allowed
by which accounts. There are many combinations of options that give
extra capabilities, such as re-using a single connection for multiple
sessions or passing through intermediary machines. The level of
granularity can be increased even more with the help of **sudo(8)**.

### SSH Client Environment Variables \-- Server Side

Of course the foundation of most SSH activity centers around use of the
shell. Upon a successful connection, OpenSSH sets several environment
variables.

    SSH_CLIENT='192.168.223.17 36673 22'
    SSH_CONNECTION='192.168.223.17 36673 192.168.223.229 22'
    SSH_TTY=/dev/pts/6

**SSH_CLIENT** shows the address of the client system, the outgoing port
number on the client system, and the incoming port on the server.
**SSH_CONNECTION** shows the address of the client, the outgoing port on
the client, the address of the server and the incoming port on the
server. **SSH_TTY** names the pseudo-terminal device, abbreviated PTY,
on the server used by the connection. For more information on
pseudo-terminals see ptm(4),
tty(1) and
tty(4).

The login session can be constrained to a single program with a
predetermined set of parameters using **ForceCommand** in the server
configuration or **Command=\"\...\"** in the authorized keys file. When
that happens an additional environment variable **SSH_ORIGINAL_COMMAND**
gets set.

    SSH_ORIGINAL_COMMAND=echo "hello, world"

If the server has **ExposeAuthInfo** set, then the **SSH_USER_AUTH**
environment variable points to a temporary file listing details about
the authentication methods used to start the current session.

    SSH_USER_AUTH=/tmp/sshauth.4JmbYfF0bhF6C17

The file is removed when the session ends.

Other variables are set depending on the user\'s shell settings and the
system\'s own settings.

### SSH Client Configuration Options

Configuration options can be passed to
ssh(1) as arguments, see the manual
pages for ssh(1) and
ssh_config(5) for the full list.

Connect very verbose output,
GSSAPI
authentication:

``` shell
$ ssh -vv -K -l account host.example.org
```

A subset of options can be defined on the server host in the user\'s own
authorized keys file, in conjunction with specific keys. See
sshd(8) for which subset exactly.

``` apache
command="/usr/local/sbin/backup.sh",no-pty ssh-rsa AAAAB3NzaC1yc2EAAAQEAsY6u71N...
command="/usr/games/wump",no-port-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1...
environment="gtm_dist=/usr/local/gtm/utf8",environment="gtm_principal_editing=NOINSERT:EDITING" ssh-rsa AAAA8a2s809poloh05yhh...
```

Note that some directives, like setting the environment variables, are
disabled by default and must be named in the server configuration before
available to the client. More configuration directives can be set by the
user in **\~/.ssh/config** or by the system administrator in
**/etc/ssh/ssh_config**. These same configuration directives can be
passed as arguments using **-o**. See
ssh_config(5) for the full list
with descriptions.

``` shell
$ ssh -o "ServerAliveInterval=60" -o "Compression=yes" -l fred server.example.org
```

The system administrators of the client host can set some global
defaults in **/etc/ssh/config**. Some of these global settings can be
targeted to a specific group or user by using a **Match** directive.

For example, if a particular SSH server is available via port 2022, it
may be convenient to have the client try that port automatically. Some
of OpenBSD's anonymous CVS servers accept SSH connections on this port.
However, compression should not be used in this case because CVS already
uses compression. So it should be turned off. So, one could specify
something like the following in the **\$HOME/.ssh/config** configuration
file so that the default port is 2022 and the connection is made without
compression:

``` {.apache .numberLines}
Host anoncvs anoncvs.example.org
        Compression no
        Port 2022
```

See ssh_config(5) for the client
side and sshd_config(5) for the
server side for the full lists with descriptions.

## The SFTP client

sftp(1) is an interactive file transfer
program which performs all its operations over an encrypted SSH
transport channel. It may also use many features of
ssh(1), such as public key
authentication and compression. It is also the name of the protocol
used.

The SFTP protocol is similar in some ways to the now venerable File
Transfer Protocol (FTP), except that the entire session, including the
login, is encrypted. However, SFTP is not FTPS. The latter old-fashioned
FTP tunneled over SSH/SSL. In contrast, SFTP is actually a whole new
protocol. sftp(1) can also be made to
start in a specific directory on the remote host.

``` shell
$ sftp fred@server.example.org:/var/www
```

Frequently, SFTP is used to connect and log into a specified host and
enter an interactive command mode. See the manual page for
sftp(1) for the available interactive
commands such as **get**, **put**, **rename**, and so on. Also, the same
configuration options that work for
ssh(1) also apply to
sftp(1).
sftp(1) accepts all
ssh_config(5) options and these
can be passed along as arguments at run time. Some have explicit
shortcuts.

``` shell
$ sftp -i ~/.ssh/some.key.ed25519 fred@server.example.org:/var/www
```

While others can be specified by naming them in full using the **-o**
option.

``` shell
$ sftp -o "ServerAliveInterval=60" -o "Compression=yes" fred@server.example.org
```

Another way to transfer is to send or receive files automatically. If a
non-interactive authentication method is used, the whole process can be
automatic using batch mode.

``` shell
$ sftp -b session.batch -i ~/.ssh/some_key_rsa fred@server.example.org
```

Batch processing only works with non-interactive authentication.

## The SCP client

scp(1) is used for encrypted transfers
of files between hosts and is used a lot like regular
cp(1). It is intended as a replacement
for **rcp** from the original Berkeley Software Distribution (BSD).
Since 9.0[^1] it is based on the SFTP protocol under the hood while the
old version is based on. Both the old and the new versions SSH to
encrypt the connection.

The scp(1) client, unlike the SFTP
client, is not based on any formal standard. It has aimed at doing more
or less what old **rcp** did and responded the same way. Since with it
the same program must be used at both ends of the connection and
interoperability is required with other implementations of SSH. Changes
in functionality would probably break that interoperability, so new
features are more likely to be added to
sftp(1) if at all. Thus, it is best to
lean towards using sftp(1) instead when
possible. However, recent versions are actually a front end for the SFTP
protocol instead.

Copy from remote to local:

``` shell
$ scp myaccount@sftp.example.org:*.txt .
```

Copy from local to remote, recursively:

``` shell
$ scp -r /etc/ myaccount@sftp.example.org:.
```

Being a front end for the SFTP protocol now, the new
scp(1) client can cover most but not all
of the behavior of the old client and is not quite bug-for-bug
compatible. One noticeable change which is fixed on the server side in
OpenSSH 8.7 or later was the absence of tilde (\~) expansion. So the
\"expand-path@openssh.com\" protocol extension has been added to support
this. Another area where there can potentially be trouble is when there
are shell meta-characters, such as \* or ?, in the file names.

See also the section for the SFTP client above.

## GUI Clients

There are a great many graphical utilities that support SFTP and SSH.
Many started out as transfer utilities with the outdated legacy protocol
FTP and grew with the times to include SSH and SFTP support. Sadly, many
retain the epithet FTP program despite modernization. Others are more
general file managers that include SFTP support as one means of network
transparency. Most if not all provide full SFTP support including
Kerberos authentication.

Below is a partial list to give an idea of the range of options
available.

**Bluefish** is a website management tool and web page editor with built
in support for SFTP. Closed source competitors XMetaL and Dreamweaver
are said to have at least partial support for SFTP. No support for SFTP
is available for Quanta+ or Kompozer as of this writing.
<http://bluefish.openoffice.nl/>

**Cyberduck** is a remote file browser for the Macintosh. It supports an
impressive range of protocols in addition to SFTP.
<http://cyberduck.ch/>

**Dolphin** is a highly functional file manager for the KDE desktop, but
can also be run in other desktop environments. It includes SFTP support

**Fetch**, by Fetch Softworks, is a reliable and well-known SFTP client
for the Macintosh. It has been around since 1989 and started life as
just an FTP client. It has many useful features combined with ease of
use. It is closed source, but academic institutions are eligible for a
free of charge site license. <http://fetchsoftworks.com/fetch/>

**Filezilla** is presented as a FTP utility, but it has built in support
for SFTP. It is available for multiple platforms under the Free Software
license, the GPL. <http://filezilla-project.org/>

**FireFTP** is a SFTP plugin for Mozilla Firefox. Though it is presented
as an FTP add-on, it supports SFTP. It is available under both the MIT
license and the GPL. <http://fireftp.mozdev.org/>

**Fugu**, developed by the University of Michigan research systems unix
group, is a graphical front-end for SFTP on the Macintosh.
<http://rsug.itd.umich.edu/software/fugu/>

**gFTP** is a multi-threaded file transfer client <http://www.gftp.org/>

**JuiceSSH** is an SSH Client for Android/Linux. It uses the
jsch Java implementation of SSH2.
<https://juicessh.com/>

**Konqueror** is a file manager and universal document viewer for the
KDE desktop, but can also be run in other environments. It includes SFTP
support. <http://www.konqueror.org/>

**lftp** is a file transfer program that supports multiple protocols.
<http://lftp.yar.ru/>

**Midnight Commander** is a visual file manager based on a text
interface and thus usable over a terminal or console. It includes SFTP
support. <https://midnight-commander.org/>

**Nautilus** is the default file manager for the GNOME desktop, but can
also be run in other environments. It includes SFTP support

**PCManFM** is an extremely fast, lightweight, yet feature-rich file
manager with tabbed browsing which is the default for LXDE. It includes
SFTP support. <http://wiki.lxde.org/en/PCManFM>

**PuTTY** is another FOSS implementation of Telnet and SSH for both
legacy and Unix platforms. It is released under the MIT license and
includes an SFTP client, PSFTP, in addition to an xterm terminal
emulator and other tools like a key agent, Paegent. It is written and
maintained primarily by Simon Tatham.
<http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html>

**Remmina** is a remote desktop client written in GTK+ which supports
multiple network protocols, including SSH. <http://www.remmina.org/>

**RemoteShell** is the default SSH client for MorphOS, written in C
using the GUI library Magic User Interface (MUI). The operating system
also contains the command-line tools
ssh(1),
scp(1) and
sftp(1). <http://www.morphos-team.net>

**SecPanel** is a GUI for managing and running SSH and scp connections.
It is not a new implementation of the protocol or software-suite, but
sits on top of either of the SSH software-suites
<http://themediahost.de/secpanel/>

**Thunar** is the default file manager for the XFCE desktop. It includes
SFTP support. <http://docs.xfce.org/xfce/thunar/start>

**Transfer** is the default SFTP client for MorphOS, written in C using
the GUI library Magic User Interface (MUI).
<http://www.morphos-team.net>

**Yafc** is Yet Another FTP Client and despite the name supports SFTP.
<http://yafc.sourceforge.net/>

[^1]:


# OpenSSH/Client Configuration Files

Client configuration files can be per user or system wide, with the
former taking precedence over the latter and run-time arguments in the
shell overriding both. In these configuration files, one parameter per
line is allowed. The syntax is the parameter name followed by its value
or values. Empty lines and lines starting with the hash (**\#**) are
ignored. An equal sign (**=**) can be used instead of whitespace between
the parameter name and the values. Values are case-sensitive, but
parameter names are not. The first value assigned is used. For key
files, the format is different.

With either type of file, there is no substitute for reading the
relevant manual pages on the actual systems involved, especially because
they match the specific versions which are in use.

## System-wide Client Configuration Files

System-wide client files set the default configuration for all users of
OpenSSH clients on that system. These defaults can be overridden in most
cases by the user\'s own default settings in a local configuration file.
Both can be overridden, in many cases, by specifying various options or
parameters at run time. The prioritization is as follows:

1.  run time arguments via the shell
2.  user\'s own configuration
3.  system-wide configuration

The first value obtained is used. The user\'s own configuration file and
the system-wide configuration file can also point to additional
configuration files to be included using the **Include** directive
starting with OpenSSH 7.3. The **Include** directive can be specified
anywhere in the configuration file even inside a **Match** or **Host**
block. Care should be used when nesting configurations.

### */etc/ssh/ssh_config*

This file defines all the default settings for the client utilities for
all users on that system. It must be readable by all users. The
configuration options are described in detail in
ssh_config(5).

Below a shortcut is made for connecting to *arc.example.org*.

``` {.apache .numberLines}
Host arc
        Port 2022
        HostName arc.example.org
        User fred
        IdentityFile ~/.ssh/id_rsa_arc
```

So with that configuration, it is enough to enter `ssh arc` and the rest
of the information gets filled in automatically.

### */etc/ssh/ssh_known_hosts*

This contains the system-wide list of known host keys used to verify the
identity of the remote host and thus hinder impersonation or
eavesdropping. This file should be prepared by the system administrator
to contain the public host keys of all necessary hosts. It should be
world-readable.

See **\~/.ssh/known_hosts** below for more explanation or see
sshd(8) for further details of the
format of this file.

### */etc/ssh/sshrc*

This file resides on the server and programs in this file are executed
there by ssh(1) when the user logs in,
just before the user\'s shell or designated program is started. It is
not run as root, but instead as the user who is logging in. See the
sshd(8) manual page in the section
\"SSHRC\" for more information. If it sends anything to **stdout** that
will interfere with SFTP sessions, among others. So if any output is
produced at all, it should be sent to **stderr** or else a log file.

## User-specific Client Configuration Files

Users can override the default system-wide client settings and choose
their own defaults. For situations where the same change is made
repeatedly it is recommended to add it to the user\'s local
configuration.

### Client-Side Files

These files reside on the client machine.

#### *\~/.ssh/config*

The user\'s own configuration file which, where applicable, overrides
the settings in the global client configuration file,
**/etc/ssh/ssh_config**. The configuration options are described in
detail in ssh_config(5).

This file must *not* be accessible to other users in any way. Set strict
permissions: read/write for the user, and not accessible by others. It
may group-writable if and only if that user is the only member of the
group in question.

##### Local Override of Client Defaults

The file is usually named **\~/.ssh/config**. However, a different
configuration file can be specified at runtime using the **-F** option.
General options intended to apply to all hosts can be set by matching
all hosts and should be done at the end of the configuration file. The
first match takes precedence, therefore more specific definitions must
come first and more general overrides at the end of the file.

``` {.apache .numberLines}
Host server1
        ServerAliveInterval 200
        HostName    203.0.113.76

Host *
        ExitOnForwardFailure    yes
        Protocol    2
        ServerAliveInterval 400
```

Options given as runtime arguments will override even those in the
configuration file. However, not all options can be set or overriden by
the user. Those options which may not be set or overridden will be
ignored.

#### *\~/.ssh/known_hosts*

This file is local to the user account and contains the known keys for
remote hosts. Often these are collected from the hosts when connecting
for the first time, but they can be added manually. As with those keys
stored in the global file, **/etc/ssh/ssh_known_hosts**, these keys are
used to verify the identity of the remote host, thus protecting against
impersonation or man-in-the-middle attacks. With each subsequent
connection the key will be compared to the key provided by the remote
server. If there is a match, the connection will proceed. If the match
fails, ssh(1) will fail with an error
message. If there is no key at all listed for that remote host, then the
key\'s fingerprint will be displayed and there will be the option to
automatically add the key to the file. This file can be created and
edited manually, but if it does not exist it will be created
automatically by ssh(1) when it first
connects to a remote host.

The **\~/.ssh/known_hosts** file can use either hashed or clear text
host names. Even with hashed names, it can still be searched using
ssh-keygen(1) using the **-F**
option.

``` shell
$ ssh-keygen -F server3.example.com
```

The default file to be searched will be **\~/.ssh/known_hosts** and the
key is printed if found. A different file can be searched using the
**-f** option. If a key must be removed from the file, the **-R** option
works similarly to search by host and then remove it if found even if
the host name is hashed.

``` shell
$ ssh-keygen -R server4.example.com -f ~/.ssh/known_hosts
```

When a key is removed, it will then be appended to the file
**\~/.ssh/known_hosts.old** in case it is needed later. Again, see the
manual page for sshd(8) for the format
of these **known_host** files.

If a non-default file is used with either **-F** or **-R** then the name
including the path must be specified using **-f**. But **-f** is
optional if the default file is intended.

If the global file **/etc/ssh/ssh_known_hosts** is used then it should
be prepared by the system administrator to contain the public host keys
of all necessary hosts and it should be world-readable.

##### Manually Adding Public Keys to \~/.ssh/known_hosts

Manually adding public host keys to **known_hosts** is a matter of
adding one unbroken line per key. How the key is obtained is not
important, as long as it is complete, valid, and **guaranteed to be the
real key and not a fake**. The utility
ssh-keyscan(1) can fetch a key
and ssh-keygen(1) can be used to
show the fingerprint for verification. See examples in the cookbook
chapter on  Public Key
Authentication
for methods of verification. Again, the corresponding system-wide file
is **/etc/ssh/ssh_known_hosts**

##### About the Contents of the known_hosts Files

The **known_hosts** file is for verifying the identity of other systems.
ssh(1) can automatically add keys to the
user\'s file, but they can be added manually as well. The file contains
a list of public keys for all the hosts which the user has connected to.
It can also include public keys for hosts that the user plans to log
into but are not already in the system-wide list of known host keys.
Usually when connecting to a host for the first time,
ssh(1) adds the remote host\'s public
key to the user\'s **known_hosts** file, but this behavior can be tuned.

The format is one public key or certificate per unbroken line. Each line
in contains a host name, number of bits, exponent, and modulus. At the
beginning of the line is either the host name or a hash representing the
host name. An optional comment can follow at the end of the line. These
can be preceded by an optional marker to indicate a certificate
authority, if an SSH certificate is used instead of a SSH key. These
fields are separated by spaces. It is possible to use a comma-separated
list of hosts in the host name field if a host has multiple names or if
the same key is used on multiple machines in a server pool. Here are two
examples for hosts with the basic host names:

    anoncvs.fr.openbsd.org,93.184.34.123 ssh-rsa AAAA...njvPw==
    anoncvs.eu.openbsd.org ssh-rsa AAAAB3Nz...cTqGvaDhgtAhw==

Non-standard ports can be indicated by enclosing the host name with
square brackets and following with a colon and the port number. Here are
three examples referring to hosts listening for SSH on non-standard
ports:

    [ssh.example.org]:2222 ssh-rsa AAAAB3Nz...AKy2R2OE=
    [127.0.0.2]:4922 ssh-rsa AAAAB4mV...1d6j=
    [anga.funkfeuer.at]:2022,[78.41.115.130]:2022 ssh-rsa AAAAB...fgTHaojQ==

Host name patterns can be created using \"**\***\" and \"**?**\" as
wildcards and \"**!**\" to indicate negation.

Up to one optional marker per line is allowed. If present it must be
either **\@cert-authority** or **\@revoked**. The former shows that the
key is a certificate authority key, the latter flags the key as revoked
and not acceptable for use.

See sshd(8) for further details on the
format of this file and
ssh-keygen(1) for managing the
keys.

### Server-Side Client Files

These client files reside on the server. By default they are kept in the
user\'s directory. However, the server can be configured to look for
them in other locations if needed.

#### *\~/.ssh/authorized_keys*

**authorized_keys** is a one-key-per-line register of public ECDSA, RSA,
and ED25519 keys that this account can use to log in with. The file\'s
contents are not highly sensitive, but the recommended permissions are
read/write for the user and not accessible by others. As always, the
whole key including options and comments must be on a single, unbroken
line.

    ssh-rsa AAAAB3NzaC1yc2EAAA...41Ev521Ei2hvz7S2QNr1zAiVaOFy5Lwc8Lo+Jk=

Lines starting with a hash (#) are ignored and can be used as comments.
Whitespace separates the key\'s fields, which are in sequence an
optional list of login options, the key type (usually ssh-rsa or better
like ecdsa-sha2-nistp256), the key itself encoded as base64, and an
optional comment.

If a key is followed by an annotation, the comment does not need to be
wrapped in quotes. It has no effect on what the key does or how it
works. Here is an annotated key, the comment having been generated with
the **-C** option ssh-keygen(1):

    ssh-rsa AAAAB3NzaC1yc2EAAA...zAiVaOFy5Lwc8Lo+Jk=  Fred @ Project FOOBAR

Keys can be preceded by a comma-separated list of options to affect what
happens upon successful login. The first key below forces the session to
launch **tinyfugue** automatically, the second forcibly sets the PATH
environment variable:

    command="/usr/bin/tinyfugue" ssh-rsa AAAAB3NzaC1yc2EAAA...OFy5Lwc8Lo+Jk=
    environment="PATH=/bin:/usr/bin/:/opt/gtm/bin" ssh-rsa AAAAB3N...4Y2t1j=

The format of **authorized_keys** is described in the
sshd(8) manual page. Old keys should be
deleted from the file when no longer needed. The server can specify
multiple locations for **authorized_keys**. See the next section,
Server-Side Client Key Login
Options, for details.

#### *\~/.ssh/authorized_principals*

By default this file does not exist. If it is specified in
sshd_config(5), it contains a
list of names which can be used in place of the username when
authorizing a certificate. This option is useful for role accounts,
disjoint account namespaces and \"user@realm\"-style naming policies in
certificates. Principals can also be specified in **authorized_keys**.

#### *\~/.ssh/environment*

If the server is configured to accept user-supplied, automatic changes
to environment variables as part of the login process, then these
changes can be set in this file.

If the server, the environment file and an authorization key all try to
change the same variable, the file **environment** takes precedence over
what a key might contain. Either one will override any environment
variables that might have been passed by
ssh(1) using **SendEnv**.

Authentication keys stored in **authorized_keys** can also be used to
set variables. See also the **AcceptEnv** and **PermitUserEnvironment**
directives in the manual page for
sshd_config(5).

#### *\~/.ssh/rc*

This is a script which is executed by
sh(1) just before the user\'s shell or
command is started. It is not run if **ForceCommand** is used. The
script is run after reading the environment variables. The corresponding
global file, **/etc/ssh/sshrc**, is not run if the user\'s **rc** script
exists.

### Local Account Public / Private Key Pairs

People might have a variety ECDSA, Ed25519, and RSA keys stored in the
file system. Since version 8.2, two new key types ECDSA-SK and
Ed25519-SK, along with corresponding certificate types are available for
keys tied to FIDO/U2F tokens. Though individual accounts can maintain
their own list of keys or certificates for authentication or to verify
the identity of remote hosts in any directory, the most common location
is in the **\~/.ssh/** directory. The naming convention for keys is only
a convention but recommended to follow anyway. Public keys usually have
the same name as the private key, but with **.pub** appended to the
name. Trouble can arise if the names of the public and private keys do
not match. If there is more than one key pair, then
ssh-keygen(1) can use the **-f**
option when generating keys to produce a useful name along with the
**-C** option which embeds a relevant comment inside the key pair.

People, programs, and scripts can authenticate using a private key
stored on the system, or even a private key fetched from a smartcard, if
the corresponding public key is stored in **authorized_keys** on the
remote system. The **authorized_keys** file is not highly sensitive, but
the recommended permissions are read/write for the user, and not
accessible by others. The private keys, however, are very sensitive and
should not be readable or even visible to other accounts. They should
never leave the client and should certainly never be put on the server.
See the chapter on  Public Key
Authentication
for more discussion and examples.

The keys can be preceded by a comma-separated list of options. The whole
key must be on a single, unbroken line. No spaces are permitted, except
within double quotes. Any text after the key itself is considered a
comment. The **authorized_keys** file is a one-key-per line register of
public RSA, Ed25519, ECDSA, Ed25519-SK, and ECDSA-SK keys that can be
used to log into a particular account. See the section above on the
**authorized_keys** file for more discussion.

DSA is considered deprecated. The time has passed for DSA keys and they
are no longer considered safe and should be replaced with better keys.

Per-account  Host-based Authentication
Configuration is
also possible using the **\~/.shosts**, **\~/.rhosts**,
**\~/.ssh/environment**, and **\~/.ssh/rc** files.

#### Public Keys: \~/.ssh/id_ecdsa.pub \~/.ssh/id_ed25519.pub \~/.ssh/id_rsa.pub \~/.ssh/id_ecdsa-sk.pub \~/.ssh/id_ed25519-sk.pub \~/.ssh/id_ecdsa-sk_rk.pub \~/.ssh/id_ed25519-sk_rk.pub

These are only the default names for the public keys. Again, it can be a
good idea to give more relevant names to keys. The **\*-sk.pub** keys
are those bound with a hardware security token and the **\*-sk_rk.pub**
keys are those generated from resident keys stored within hardware
security token.

Public keys are mainly used on the remote server for key-based
authentication. Public keys are not sensitive and are allowed to be
readable by anyone, unlike the private keys, but don\'t need to be. A
public key, minus comments and restriction options, can be regenerated
from a private key if lost. So while it can be useful to keep backups of
the public key, it is not essential unlike for private keys.

#### Private Keys: \~/.ssh/id_ecdsa \~/.ssh/id_ed25519 \~/.ssh/id_rsa \~/.ssh/id_ecdsa-sk \~/.ssh/id_ed25519-sk \~/.ssh/id_ecdsa-sk_rk \~/.ssh/id_ed25519-sk_rk

These are only the default names for private keys. Private keys are
always considered sensitive data and should be readable only by the user
and not accessible by others. In other words, they use mode 0600. The
directory they are in should also have mode 0700 or 0500. If a private
key file is accessible by others, ssh(1)
will ignore it.

It is possible to specify a passphrase when generating the key which
will be used to encrypt the sensitive part of this file using AES128.
Until version 5.3, the cipher 3DES was used to encrypt the passphrase.
Old keys using 3DES that are given new passphrases will use AES128 when
they are modified.

Private keys stored in hardware tokens as resident keys can be extracted
and automatically used to generate their corresponding public key using
ssh-keygen(1) with the **-K**
option. Such keys will default to being named **id_ecdsa-sk_rk** or
**id_ed25519-sk_rk**, depending on the key type, though the file names
can be changed after extraction. A passphrase can be assigned to the
private key upon extraction from the token to a file.

While public keys can be generated from private keys, new private keys
cannot be regenerated from public keys if the private keys are lost. Nor
can a new passphrase be set if the current one is forgotten. Gone is
gone, unlike the public keys, which can be regenerated from an existing
private key if the private key is lost or forgotten then a whole new key
pair must be generated and deployed.

### Legacy Files

These files might be encountered on very old or out of date systems but
not on up-to-date ones.

#### *\~/.shosts*

#### *\~/.rhosts*

**.rhosts** is a legacy from rsh containing a local list of trusted
host-user pairs that are allowed to log in. Login requests matching an
entry were granted access.

See also the global list of trusted host-user pairs,
**/etc/hosts.equiv**

**rhosts** can be used as part of host-based authentication. Otherwise
it is recommended not to use rhosts for authentication, there are a lot
of ways to misconfigure the **.rhosts** file.

#### Legacy DSA Keys \~/.ssh/id_dsa \~/.ssh/id_dsa.pub

Deprecated DSA keys might be found named as **id_dsa** and
**id_dsa.pub**, but regardless of the name any usage should be tracked
down. Support for DSA both on the server and client was discontinued in
OpenSSH 7.0. If DSA keys are found, the pair should be removed and
replaced with a better type of key.

#### Legacy SSH1 Protocol Keys \~/.ssh/identity \~/.ssh/identity.pub

The files **identity** and **identity.pub** were for SSH protocol
version 1, and thus deprecated. If found they should be investigated as
to what, if anything, uses them and why. Then once any remaining usage
is resolved they should be removed and replaced with newer key types.

## Mapping Client Options And Configuration Directives

Many run-time options for the SSH client have corresponding
configuration directives and vice versa. The following is a quick
overview. It is not a substitute for getting familiar with the relevant
manual pages, ssh(1) and
ssh_config(5) which are the
relevant, authoritative, up-to-date resources on the matter.

  Directive                 Option    Description
  ------------------------- --------- ----------------------------------------------------------------------------------------------------
  AddressFamily             -4 / -6   Limit connections to IPv4 or IPv6 only.
  ForwardAgent              -A / -a   Forward or block forwarding from the authentication agent.
  BindInterface             -B        Bind the outgoing connection to this network interface.
  BindAddress               -b        Bind the outgoing connection to this network address.
  Compression               -C        Specify whether to compress the data using gzip(1).
  Ciphers                   -c        Specify which cipher to use.
  DynamicForward            -D        Designate a local port to be forwarded, say for SOCKS5.
  EscapeChar                -e        Specify an escape character for PTY sessions.
  ForkAfterAuthentication   -f        Drop client to background right before command execution.
  GatewayPorts              -g        Whether other hosts are allowed to connect to local forwarded ports.
  PKCS11Provider            -I        Specify the path to the shared PKCS#11 library.
  IdentityFile              -i        Specify a particular certificate or private key to use for authentication.
  ProxyJump                 -J        Connect to the destination via this host or hosts first.
  GSSAPIAuthentication      -K / -k   Enable or disable Generic Security Services Application Program Interface (GSSAPI) authentication.
  LocalForward              -L        Specify which local port or socket to forward to the specified remote system.
  User                      -l        Designate which account on the remote system to try.
  ControlMaster             -M        Allow multiplexing of SSH sessions over a single TCP connection.
  MACs                      -m        Designate which message authentication code (MAC) algorithms to try.
  SessionType               -N / -s   Invoke a designated subsystem or even prevent any command execution at all.
  StdinNull                 -n        Prevent reading from **stdin**.
  Tag                       -P        Tag for use within **Match**.
  Port                      -p        Connect to this port on the remote system.
  LogLevel                  -q / -v   Adjust the verbosity of logging messages from the client.
  RemoteForward             -R        Specify which remote port or socket to forward to the specified local system.
  ControlPath               -S        Designate the control socket for multiplexing over this connection.
  RequestTTY                -T / -t   Prohibit or request a pseudo-TTY for the session.
  ForwardX11                -X / -x   Enable or prohibit X11 forwarding.

  : Lookup Table of OpenSSH Client Options Versus Configuration
  Directives

As of version 8.7 the **-f**, **-N**, and **-n** options also have
corresponding client configuration directives in
ssh_config(5).

## Server-Side Client Key Login Options

The login options available for use in the local user authorized keys
file might be overridden or blocked by the server\'s own settings.
However, within that constraint, the following options can be used.

**cert-authority**

Specifies that the listed key is a certification authority (CA) trusted
to validate signed certificates for user authentication. Certificates
may encode access restrictions similar to key options. If both
certificate restrictions and key restrictions are present, then the most
restrictive union of the two is applied.

**command=\"*program*\"**

Specifies a program and its options to be executed when the key is used
for authentication. This is a good way of forcing a program to restrict
a key to a single, specific operation such as a remote backup. However,
TCP and X11 forwarding are still allowed unless explicitly disabled
elsewhere.

The program is run on a PTY if the client requests it, otherwise the
default is to run without a TTY. The default, running without a TTY,
provides an 8-bit clean channel. If the default has been changed,
specify **no-pty** to get an 8-bit clean channel. If no programs are
allowed, then use an empty string \"\" to prevent anything from running.

    no-pty,command="" ssh-rsa AAAAB3NzaC1yc2EAAA...OFy5Lwc8Lo+Jk=

If only one program is allowed, with specific options, then it can be
spelled out explicitly.

    restrict,command="/usr/bin/svnserve -t --tunnel-user=fred" ssh-ed25519 AAAAC3NzaC1lZDI1NT...skSUlrRPoLyUq

Quotes provided in the program\'s options must be escaped using a
backslash. (\'\\\')

    command="sh -c \"mysqldump db1 -u fred1 -p\"" ssh-rsa AAAAB3NzaC1yc...Lwc8OFy5Lo+kU=

This option applies to execution of the shell, another program, or a
subsystem. Thus any other programs specified by the user are ignored
when **command** is present. However, the program originally specified
by the client remains available as the environment variable
**SSH_ORIGINAL_COMMAND**. That can be used by a script in a
multiple-choice case statement, for example, to allow the account to
select from a limited range of actions.

**environment=\"*NAME*=*value*\"**

Sets the value of an environment variable when this key is used to log
in. It overrides default values of the variable, if they exist. This
option can be repeated to set multiple variables up to 1024 discrete
names. First match wins in the case of repetition. This option is only
allowed if the **PermitUserEnvironment** option is set in the SSH
server\'s configuration. The default is that it is disabled. This option
used to be disabled automatically when **UseLogin** was enabled, but
**UseLogin** has been deprecated.

**expiry-time=\"*timespec*\"**

Sets a date or date-time, either as a YYYYMMDD date or a
YYYYMMDDHHMM\[SS\], after which the key will not be allowed to
authenticate. Otherwise the key will be considered valid indefinitely.
The system time zone is used.

**from=\"*pattern-list*\"**

Either the canonical name of the remote host or its IP address required
in addition to the key. Addresses and host names can be listed using a
comma-separated list of patterns, see PATTERNS in
ssh_config(5) for more
information on patterns, or use the CIDR address/masklen notation.

**no-agent-forwarding / agent-forwarding**

This option forbids the authentication agent from forwarding the key
when it is used for authentication. Alternately, it allows agent
forwarding even if it was otherwise previously disabled by the
**restrict** option.

**no-port-forwarding / port-forwarding**

Forbids TCP forwarding and any port forward requests by the client will
return an error when this key is used for authentication. Alternately,
override the **restrict** option and allow port forwarding. See also
**permitopen**.

**no-pty / pty**

TTY allocation is prohibited and any request to allocate a PTY will
fail. Alternately, TTY allocation is permitted, even if previously
disabled by the **restrict** option.

**no-touch-required**

FIDO keys which have been created with the **-O no-touch-required** can
use this method which makes the client skip the check for user presence.

**no-user-rc / user-rc**

Use the **no-user-rc** option in **authorized_keys** to disable
execution of **\~/.ssh/rc**. Alternately, use **user-rc** to override
the **restrict** option.

**no-X11-forwarding / x11-forwarding**

Prevent X11 forwarding when this key is used for authentication and
requests to forward X11 will return an error. Alternately, override the
**restrict** option and allow X11 forwarding.

*\'permitlisten=\"\[*host*:\]*port\'\'\"

**permitopen=\"*host*:*port*\"**

The **permitlisten** setting limits remote port forwarding (`ssh -R`) to
only the specified port and, optionally, host. In contrast,
**permitopen** limits local port forwarding (`ssh -L`) to only the
specified host and port. IPv6 addresses can be specified with an
alternative syntax: host/port. Multiple **permitopen** or
**permitlisten** options may be used and must be separated by commas. No
pattern matching is performed on the specified host names, they must be
literal host names or IP addresses. Can be used in conjunction with
agent-forwarding.

**principals=\"*name1*\[,*name2*,\...\]\"**

Specify a list of names that may be used in place of the username when
authorizing a certificate trusted via the **TrustedCAKeys** option
described in sshd_config(5).

**restrict**

Disable all options, such as TTY allocation, port forwarding, agent
forwarding, user-rc, and X11 forwarding all at once. Specific options
can then be explicitly allowed on an individual basis.

**tunnel=\"*n*\"**

Select a specific tun(4) device on the
server. Otherwise when a tunnel device is requested without this option
the next available device will be used.

**verify-required**

Require user-verification, such as with a PIN, with FIDO keys.

## Managing Keys

When working with keys there are some basic, hopefully common sense,
actions that should take place to prevent problems. The two most
beneficial approaches are to use sensible names for the key files and to
embed comments. The **-f** option for
ssh-keygen(1) allows a custom
name to be set. The **-C** option allows a comment to be embedded in
both the public and private keys. With the comment inside the private
key, it can be regenerated automatically if a replacement public key is
ever made using the **-y** option.

Other than that, there are three main rules of thumb for managing keys:

-   Keys should use strong passphrases. If autonomous logins are
    required, then the keys should be first loaded into an agent and
    used from there. See ssh-add(1)
    to get started there. It uses
    ssh-agent(1) which many
    systems have installed and some have running by default.

```{=html}
<!-- -->
```
-   Keys should always be stored in protected locations, even on the
    client side. This is especially important for private keys. The
    private keys should not have read permissions for any user or group
    other than their owner. They should also be kept in a directory that
    is not accessible by anyone other than the owner in order to limit
    exposure.

```{=html}
<!-- -->
```
-   Old and unused keys should be removed from the server. In
    particular, keys without a known, valid purpose should be removed
    and not allowed to accumulate. Using the comment field in the public
    key for annotation can help eliminate some of the confusion as to
    the purpose and owner once some time has passed. Along those lines,
    keys should be rotated at intervals. Rotation means generating new
    key pairs and removing the old ones. This gives a chance to remove
    old and unused keys. It is also an opportunity to review access
    needs, whether access is required and if so at what level.

Following the principle of least privilege can limit the chance for
accidents or abuse. If a key is only needed to run a specific
application or script, then its login options should be limited to just
what is needed. See sshd(8) for the
\"AUTHORIZED_KEYS FILE FORMAT\" section on key login options. For root
level access, it is important to remember to configure **/etc/sudoers**
or **/etc/doas.conf** appropriately. Access there can be granted to a
specific application and even limit that application to specific
options.

One major drawback to keys is that they never expire and are valid
indefinitely in principle. In contrast, certificates can be assigned a
validity interval with an end date, after which they can no longer be
used.


# OpenSSH/Server

The OpenSSH Server, sshd(8), listens
for connections from clients and starts a new process or two for each
new incoming connection to handle key exchange, encryption,
authentication, program execution, and data exchange. In the case of
multiplexing, some processes are reused. It can run standalone and wait
in the background, be run in the foreground, or it can be loaded on
demand by any Internet services daemon.

Since version 8.2, the listening process title shown in
ps(1) also shows the number of
connections pending authentication.

``` shell-session
$ ps -p $(pgrep -u root sshd) -o pid,user,args
  PID USER     COMMAND
44476 root     sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups (sshd)
```

Note that this is the number pending authentication, not the number
which of those which have already been authenticated. Those each have
their own separate handler process owned by the account which has
authenticated.

## sshd

sshd(8) is the secure shell daemon and
it listens for incoming connections. The standard port for
ssh(1) as specified by IANA is 22 [^1].
If sshd(8) does not listen to a
privileged port, it does not have to be launched by root. However there
are few, if any occasions where a non-standard port should be
considered. sshd(8) can be bound to
multiple addresses or just certain ones. Multiple instances of
sshd(8), each with a different
configuration, can be run on the same machine, something which may be
useful on multi-homed machines. An absolute path must be given to launch
sshd(8), i.e. `/usr/sbin/sshd`

Configuration data is parsed first from the arguments and options passed
by the shell, the user-specific file, and lastly the system-wide
configuration file.

:   sshd(8) - The SSH daemon that
    permits you to log in.

```{=html}
<!-- -->
```

:   sftp-server(8) - SFTP server
    subsystem, started automatically by
    sshd(8) when needed.
:   ssh-keysign(8) - Helper
    program for hostbased authentication.

```{=html}
<!-- -->
```

:   sshd_config(5) - The server
    configuration file.

The sshd(8) daemon can be made to parse
the configuration file, test it for validity, and then report the
effective configuration settings. This is done by running the extended
test mode (**-T**). The extended test will print out the actual server
settings. It can also report modifications to the settings through use
of the **Match** directive when combined with the connection
specification (**-C**) parameter. The options for **-C** are **user**,
**host**, and **addr**. This is where **host** and **addr** refer to the
host running sshd(8) and the address
from which the connection is being made, respectively.

The following will print out the configurations that will be applied if
the user \'fred\' tries to log in to the host *server.example.org* from
the address *192.168.100.5*.

``` shell-session
$ /usr/sbin/sshd -TC user=fred,host=server.example.org,addr=192.168.100.5
```

The output is long, so it might be sensible to pipe it through
sort(1) and a pager like
less(1). See the section on  Debugging
a Server
Configuration
for more options.

By default, login is allowed for all groups. However, if either
**AllowGroups** or **AllowUsers** is specified, then all users or groups
not listed are prohibited from logging in. The allow/deny directives are
processed in the following order:

1.  **DenyUsers**,
2.  **AllowUsers**,
3.  **DenyGroups**, and finally,
4.  **AllowGroups**.

The first pattern matched takes effect, so if **AllowUsers** exists it
will completely override **AllowGroups** regardless of the order in
which they appear in the configuration file. So for the most
flexibility, it is recommended to use **AllowGroups**. In contrast,
**DenyUsers** and **DenyGroups** do not interfere with each other and
may be used together. List group names or patterns of group names,
separated by spaces. If specified, login is allowed or denied only for
users who are members of a group that matches a group or pattern on the
list. Only group or user names are valid; numerical group or user IDs
are not recognized.

## sshd under inetd / xinetd

An Internet services daemon is a server to launch other servers on
demand. xinetd(8) and
inetd(8) are two variants, either of
which can be used to specify additional parameters and constraints,
including running the launched service as a particular user and group.
By having a single daemon active, which invokes others as needed,
demands on the system can be reduced. Launching
sshd(8) this way means
inetd(8) waits for an incoming
request, launches sshd(8) and then when
the SSH session is over, closes
sshd(8).

                  Packet
     Internet --> Filter --> tcpwrappers --> (x)inetd --> sshd
                 (firewall)  (aka tcpd)

Either can be used for additional logging such as successful or
unsuccessful login, access restriction even including time of day, cpu
priority, and number of connections. There are many more possibilities.
See the manual pages for
xinetd.conf(5) or
inetd.conf(5) for a full overview
of configuration options.

inetd(8) was **tcpd**-aware and could
make use of **tcpd**\'s tcpwrappers to further control access or
logging. So was sshd(8) by itself, up
through 6.6. See the manual pages for \ht ormation about how to use the
configuration files **hosts.allow** and **hosts.deny**. Since 6.7,
OpenSSH itself no longer supports tcpwrappers because current packet
filters filters made it mostly redundant.

The two main disadvantages of using
[inetd(8) or xinetd(8) are that there
can be a slight increase in the delay during the start of the connection
and that sshd(8) must be configured to
allow launching from the services daemon. The delay only affects the
initial connection and thus does not get in the way of actual operation.
An Internet services daemon should not be used for stateless services
like HTTP and HTTPS, where every action is essentially a new connection.
Again, see the manual page for
xinetd.conf(5) or
inetd.conf(5) for more details.

Example from xinetd.conf(5)

    service ssh
    {
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = root
        server          = /usr/sbin/sshd
        server_args     = -i
        per_source      = UNLIMITED
        log_on_failure  = USERID HOST
        # log_on_success  = PID HOST DURATION TRAFFIC EXIT
        # instances       = 10
        # nice            = 10
        # bind            = 192.168.0.100
        # only_from       = 192.168.0.0
        # access_times    = 08:00-15:25
        # no_access       = 192.168.54.0
        # no_access       += 192.168.33.0
        # banner          = /etc/banner.inetd.connection.txt
        # banner_success  = /etc/banner.inetd.welcome.txt
        # banner_fail     = /etc/banner.inetd.takeahike.txt
    }

Example from inetd.conf(5)

    ssh    stream  tcp     nowait  root /usr/sbin/sshd -i
    ssh    stream  tcp6    nowait  root /usr/sbin/sshd -i

There are several advantages with
xinetd(8) over
inetd(8) in capabilities but use-cases
where either would be useful are rare.

## The SFTP Server Subsystem

The SFTP subsystem first appeared in OpenBSD 2.8 / OpenSSH 2.3[^2]. It
is called by sshd(8) as needed using
the **Subsystem** configuration directive and not intended to operate
standalone. There are two forms of the subsystem. One is the regular
sftp-server(8). The other is an
in-process SFTP server, which requires no support files when used with
the **ChrootDirectory** directive. The **Subsystem** configuration
directive can be used to pass options:

**-d** specifies an alternate starting directory for users, the default
is the user\'s home directory. (First in 6.2)

``` text
Subsystem sftp internal-sftp -d /var/www
```

**-e** causes logging information to be sent to **stderr** instead of
syslog(3).

``` text
Subsystem sftp internal-sftp -e
```

**-f** specifies the syslog(3)
facility code that is used when logging messages from
sftp-server(8). The possible
values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4,
LOCAL5, LOCAL6, LOCAL7.

``` text
Subsystem    sftp    /usr/libexec/sftp-server -f LOCAL0
```

**-l** Specifies which messages will be logged by
sftp-server(8). The default is
AUTH. The other possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE,
DEBUG, DEBUG1, DEBUG2, and DEBUG3. INFO and VERBOSE log transactions
that sftp-server performs on behalf of the client. DEBUG and DEBUG1 are
equivalent while DEBUG2 and DEBUG3 each specify higher levels of
debugging output. Log levels DEBUG through DEBUG3 will violate user
privacy and should not be used for regular operation. The default log
level is ERROR. The actual path will vary depending on distro or
operating system.

``` text
Subsystem    sftp    /usr/libexec/sftp-server -l VERBOSE
```

**-p** and **-P** specify whitelisted and blacklisted protocol requests,
respectively. The comma separated lists are permitted or prohibited
accordingly, the blacklist is applied first if both are used. **-Q**
provides a list of protocol features supported by the server. All three
are available as of version 6.5. The actual path will vary depending on
distro or operating system.

In version 6.5 *requests* are the only protocol features queriable.

``` shell-session
$ /usr/libexec/sftp-server -Q requests
```

**-R** places the SFTP subsystem in read-only mode. Attempts to change
the filesystem, including opening files for writing, will fail.

**-u** overrides the user\'s default umask and explicitly sets the
umask(2) to be used for creating files
and directories. See the manual page for
syslog.conf(5) for more
information about log level or log facility.
sshd(8) must be able to access
**/dev/log** for logging to work. Using the
sftp-server(8) subsystem in
conjunction with the main SSH server\'s **ChrootDirectory** option
therefore requires that syslogd(8)
establish a logging node inside the chrooted directory.

``` text
Subsystem sftp internal-sftp -u 0002
```

That sets the umask for the SFTP subsystem in OpenSSH 5.4 and later.

## Environment Variables

ssh(1) and
sshd(8) set some environment variables
automatically when logging in. Other variables can be explicitly defined
by users in the **\~/.ssh/environment** file if the file exists and if
the user is allowed to change the environment. Variables can also be set
on a key by key basis in the **authorized_keys** file, again only if the
user is allowed to change the environment.

In **\~/.ssh/environment**, the format **NAME=value** is used to set the
variable. In **\~/.ssh/authorized_keys** and
**/etc/ssh/authorized_keys** the format is
**environment=\"NAME=value\"** For more information, see the
**PermitUserEnvironment** and **AcceptEnv** configuration directives in
sshd_config(5) and the
**SendEnv** directive in
ssh_config(5).

The following variables can be set by
ssh(1), depending on the situation.

**DISPLAY** If X11 is tunneled, this is set so that the **DISPLAY**
variable indicates the location of the X11 server. When it is
automatically set by ssh(1) it points to
a value in the form *hostname*:*n*, where *hostname* indicates the host
where the shell runs, and *n* is an integer greater than or equal to
one. ssh(1) uses this special value to
forward X11 connections over the secure channel. The user should
normally not set **DISPLAY** explicitly, as that will render the X11
connection insecure and will require the user to manually copy any
required authorization cookies.

**HOME** The path of the user\'s home directory.

**LOGNAME** Synonym for USER. This is set for compatibility with systems
that use this variable.

**MAIL** The path of the user\'s mailbox.

**PATH** The default PATH, as specified when compiling
ssh(1).

**SSH_ASKPASS** If **DISPLAY** and **SSH_ASKPASS** are both set, and the
SSH session does not have an associated terminal or pseudo-terminal, the
program specified by **SSH_ASKPASS** will execute and open an X11 window
to read the passphrase when one is needed. This is particularly useful
when calling ssh(1) from an xsession or
related script. On some machines it may be necessary to redirect the
input from **/dev/null** to make this work.

**SSH_AUTH_SOCK** The path on the client machine to tell
ssh(1) the UNIX-domain socket used to
communicate with an SSH key agent.

**SSH_CLIENT** Identifies the client end of the connection. It contains
three space-separated values: the client IP address, client port number
and the server port number.

**SSH_CONNECTION** Identifies the client and server ends of the
connection. The variable contains four space-separated values: client IP
address, client port number, server IP address, and server port number.

**SSH_ORIGINAL_COMMAND** If the **ForceCommand** directive was used, or
**Command=\"\...\"** in a key, then this variable contains the original
command including the original options. It can be used to extract the
original arguments.

**SSH_TTY** This is set to the name of the TTY (path to the device)
associated with the current shell or command. If the current session has
no TTY, this variable is not set.

**SSH_USER_AUTH** This will contain the name of a temporary file
containing the authentication methods used for this particular session
if **ExposeAuthInfo** is set in
sshd_config(5).

**TZ** This variable is set to indicate the present time zone if it was
set when the daemon was started. The SSH daemon passes this value on to
new connections.

**USER** Set to the name of the user logging in.

## References

[^1]:

[^2]:


# OpenSSH/Pattern Matching in OpenSSH Configuration

A pattern consists of zero or more non-whitespace characters. An
asterisk (**\***) matches zero or more characters in a row, and a
question mark (**?**) matches exactly one character. For example, to
specify a set of declarations that apply to any host in the \".co.uk\"
set of domains in ssh_config(5),
the following pattern could be used:

    Host *.co.uk

The following pattern would match any host in the 192.168.0.1 -
192.168.0.9 range:

    Host 192.168.0.?

A pattern-list is a list of patterns separated by whitespace. The
following list of patterns match hosts in both the \".co.uk\" or
\".ac.uk\" domains.

    Host *.co.uk *.ac.uk

Individual patterns by themselves or as part of a pattern-lists may be
negated by preceding them with an exclamation mark (**!**). The
following will match any host from *example.org* except for *gamma*.

    Host *.example.org !gamma.example.org

Pattern lists in ssh_config(5) do
not use commas. Pattern lists in keys need commas.

For example, to allow a key to be used from anywhere within an
organisation except from the dialup pool, the following entry in
**authorized_keys** could be used:

    from="!*.dialup.example.com,*.example.com"

See also glob(7)


# OpenSSH/Utilities

:   ssh-agent(1) - An
    authentication agent that can store private keys.
:   ssh-add(1) - A tool which adds
    or removes keys to or from the above agent.
:   ssh-keygen(1) - A key
    generation tool.
:   ssh-keyscan(1) - A utility
    for gathering public host keys from a number of hosts.
:   ssh-copy-id(1) - Install a
    public key in a remote machine\'s **authorized_keys** register.
:   ssh-vulnkey(1) - Check a key against blacklist of compromised keys

## ssh-agent

ssh-agent(1) is a tool to hold
private keys in memory for re-use during a session. Usually it is
started at the beginning of a session and subsequent windows or programs
run as clients to the agent. The environment variable **SSH_AUTH_SOCK**
points applications to the socket used to communicate with the agent.

## ssh-add

ssh-add(1) is a tool to load key
identities into an agent for re-use. It can also be used to remove
identities from the agent. The agent holds the private keys used for
authentication.

## ssh-keyscan

ssh-keyscan(1) has been part of
the OpenSSH suite since OpenSSH version 2.5.1 and is used to retrieve
public keys. Keys retrieved using
ssh-keyscan(1), or any other
method, must be verified by checking the key fingerprint to ensure the
authenticity of the key and reduce the possibility of a
man-in-the-middle attack. The default is to request a ECDSA key using
SSH protocol 2. David Mazieres wrote the initial version of
ssh-keyscan(1) and Wayne Davison
added support for SSH protocol version 2.

## ssh-keygen

ssh-keygen(1) is for generating
key pairs or certificates for use in authentication, update and manage
keys, or to verify key fingerprints. It works with SSH keys and can do
the following activities:

-   generate new key pairs, either ECDSA, Ed25519, RSA, ECDSA-SK or
    Ed25519-SK.
-   remove keys from known hosts
-   regenerate a public key from a private key
-   change the passphrase of a private key
-   change the comment text of a private key
-   show the fingerprint of a specific public key
-   show ASCII art fingerprint of a specific public key
-   load or read a key to or from a smartcard, if the reader is
    available

If the legacy protocol, SSH1, is used, then
ssh-keygen(1) can only generate
RSA keys. However, SSH1 is long since deprecated and the systems should
be re-tooled if found in use. Also, although DSA keys can be generated,
they are deprecated and should be replaced if found.

One important use for key fingerprints is when connecting to a machine
for the first time. A fingerprint is a hash or digest of the public key.
Fingerprints can be transferred out of band and loaded into either the
**\~/.ssh/known_hosts** or **/etc/ssh/ssh_known_hosts** files in advance
of the first connection. The verification data for the key should be
sent out of band. It can be sent ahead of time by post, fax, SMS or a
phone call instead or otherwise communicated in some way such that you
can be sure it is authentic and unchanged.

``` shell-session
$ ssh -l fred zaxxon.example.org
The authenticity of host 'zaxxon.example.org (203.0.113.114)' can't be established.
RSA key fingerprint is SHA256:DnCHntWa4jeadiUWLUPGg9FDTAopFPR0c5TgjU/iXfw.
Are you sure you want to continue connecting (yes/no)?
```

If you see that message and the key\'s fingerprint matches the one you
were given in advance, then the connection is probably good. If you see
that and the key\'s fingerprint is different than what you were given in
advance, then stop and disconnect and get on the phone or VoIP to work
out the mistake. Once the SSH client has accepted the key from the
server, it is saved in **known_hosts**.

``` shell-session
$ ssh -l fred galaga.example.org
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:QIWi4La8svQSf5ZYow8wBHN4tF0jtRlkIaLCUQRlxRI.
Please contact your system administrator.
Add correct host key in /home/fred/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/fred/.ssh/known_hosts:1
ECDSA host key for galaga.example.org has changed and you have requested strict checking.
Host key verification failed.
```

If you start to connect to a known host and you get an error like the
one above, then either the first connection was to an impostor or the
current connection is to an impostor, or something very foolish was done
to the machine. Regardless, disconnect and don\'t try to log in. Contact
the system administrator out of band to find out what is going on.[^1]
It is possible that the server was reinstalled, either the whole
operating system or just the OpenSSH server, without saving the old
keys. That would result in new keys being generated and explain their
presence. Either way, check with the system administrator before
connecting to be sure.

Hashed host names and addresses can be looked up in **known_hosts**
using **-F**. Or else **-R** can be used to delete them.

``` shell-session
$ ssh-keygen -F sftp.example.org -f ~/.ssh/known_hosts
# Host sftp.example.org found: line 7 type RSA
|1|slYCk3msDPyGQ8l0lq82IbUTzBU=|KN7HPqVnJHOFX5LFmTXS6skjK4o= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA3cqqA6fZtgexZ7+4wxoLN1+YDvPfBtt4/m+N/RI8o95CXqvqZMIQjuVarVKjwRwt9pTJIVzf6bwjcNkrUx9dQqZNpNBkcvBRdmd775opWCAfkHEueKxkNx3Kb1yitz0dUaFkRwfTsXAjh+NleBq2ofAfjowu/zzCnnbAKy2R2OE=
```

## ssh-copy-id

**ssh-copy-id** is included in some distros to install a public key into
a remote machine\'s **authorized_keys** file. It is a simple shell
script and the **authorized_keys** file should still be checked manually
after first login to verify that everything went ok and that the key was
copied as it should be.

## ssh-vulnkey

**ssh-vulnkey** was included in some versions of some GNU/Linux distros
to check a key against a blacklist of compromised keys. The blacklist
was made necessary when a broken version of OpenSSL was distributed by
some distros[^2], resulting in bad keys that were easily predicted and
compromised. Keys made while that broken version was in use that are
found to have been compromised cannot be repaired and must be replaced.
The problem has since been fixed and new keys should be all right.

## References

[^1]:

[^2]:


# OpenSSH/Third Party Utilities

:   autossh - Automatically
    restart SSH sessions and tunnels
:   scanssh -
    a scanner for SSH hosts and some kinds of proxies
:   sshfs - a user-space file system
    client based on SFTP
:   sshfp - generates SSHFP DNS
    records from **known_hosts** files or ssh-keyscan(1)
:   keychain - re-use ssh-agent
    and/or gpg-agent between logins
:   rsync - synchronizes files and
    directories using delta encoding
:   gstm - a graphical front-end for
    managing SSH-tunneled port redirects
:   sslh - a protocol
    demultiplexer
:   sshguard - an intrusion detection system
    with packet filtering
:   ssh-audit - identifies the
    server\'s banner, key exchange, encryption, MAC, compression,
    compatibility, and other information.
:   webcat - can use
    websockets[^1] for tunneling, is otherwise very similar to
    netcat and
    curl.

## scanssh

**scanssh** scans hosts and networks for running services[^2]. It checks
the version number of the server and displays the results in a list. It
detects ssh, sftp and several kinds of SOCKS, HTTP, and telnet proxies.

Scan a small subnet for ssh servers:

``` shell-session
$ sudo scanssh -n 22 -s ssh 192.168.100.32/26
```

Scan the same small network for SOCKS proxies:

``` shell-session
$ sudo scanssh -s socks5,socks4 192.168.100.32/26
```

Variable scanning speeds can be set as well as random sampling. Open
proxy detection scans to detect open proxies on common ports.

Scan 1000 hosts randomly selected from 172.16.1.1 through
172.31.254.254, at a rate of 200 per second :

``` shell-session
$ sudo scanssh -r 200 -p random(1000)/172.16.0.0/12
```

The hosts and networks to be scanned can be either specified as an IPv4
address or an CIDR like IP prefix with ip address and network mask.
Ports can be appended by adding a colon at the end of address
specification. The sequence of hosts scanned is random, but that can be
modified by the following two parameters, **random** and **split**:

**random(n\[,seed\])/** selects a sample of *n* random addresses from
the range specified as targets for scanning. *n* is the number of
address to randomly create in the given network and *seed* is an
optional seed for the pseudo random number generator. For example, it is
possible to sample 10000 random IPv4 hosts from the Internet by
specifying \'random(10000)/0.0.0.0/0\' as the address.

**split(s,e)/** selects a specific segment of the address range for use.
*e* specifies the number of segments in parallel and *s* is the segment
number used by this particular scan. This can be used to scan from
several hosts in parallel by scanning a different segment from each
host.

**-n** Specifies the port numbers to scan. Ports are separated by
commas. Each specified scanner is run for each port in this list. The
default port is 22.

Scan for SSH servers on both port 22 and 2022:

``` shell-session
$ sudo scanssh -s ssh -n 22,2022 192.168.0.0/24
```

## sshfs

**sshfs** builds on the Filesystem in Userspace (FUSE) interface to
allow non-privileged users to create a secure, reliable file system
framework. It allows a remote file system to be mounted as a local
folder by taking advantage of the SFTP subsystem. It uses SFTP to mount
a directory from a remote server as a local directory. In that way, all
use applications can interact with that directory and its contents as if
it were local.As the name implies, this is done in user space and not
the kernel as is usually required for file systems. FUSE has a stable
API library and bindings to C, C++, and Java. In this case it is
specifically the SFTP client that is run over
ssh(1) and is then mounted as a file
system.

See the Cookbook section on SFTP for
more regarding **sshfs**.

## sshfp

**sshfp** generates SSHFP NS records using the public keys stored in a
**known_hosts** file or provided by
ssh-keyscan(1) as a means to use
DNS to publish SSH key fingerprints. That in turn allows DNSSEC lookups
to verify SSH keys before use. SSHFP resource records in DNS are used to
store fingerprint of SSH public host keys that are associated with the
host names. A record itself consists of an algorithm number, fingerprint
type, and the fingerprint of the public host key.

See RFC 4255 for details on SSHFP.

## keychain

**keychain** is another manager for
ssh-agent(1) to allow multiple
shells and processes, including cron(8)
jobs, to use the keys held by the agent. It is often integrated into
desktop-specific tools like Apple Keychain on OS X or kdewallet for KDE.
<http://www.funtoo.org/en/security/keychain/intro/>

## rsync

**rsync** is a file transfer utility to transfer files between computers
very efficiently. It can run on top of SSH or use its own protocol. SSH
is the default. <http://rsync.samba.org/>

See the Cookbook section on Automated
Backup for examples on
using **rsync** live or in scripts.

## gstm (Gnome SSH Tunnel Manager)

**gstm** is a graphical front-end for managing SSH connections and
especially port forwarding. <http://sourceforge.net/projects/gstm/>

## sslh

**sslh** is a protocol demultiplexer. It accepts connections on
specified ports and forwards them based on the first packet sent by the
client. It can be used to share a single port between SSH, SSL, HTTP,
OpenVPN, tinc, and XMPP. <http://www.rutschle.net/tech/sslh.shtml>

See also the section on
Multiplexing
for a discussion with examples.

## sshguard

**sshguard** is an intrusion prevention system. It monitors logs to
detect undesirable patterns of activities and triggers corresponding
packet filter rules for increasing periods of time. It can be used with
a few other services besides SSH. <http://www.sshguard.net/>

## ssh-audit

**ssh-audit** is a python script to gather information about SSH
servers. It can identify banners used, key exchange, encryption, Message
Authentication Code (MAC) algorithms, compression, compatibility
settings, and several other security-related aspects.
<https://github.com/arthepsy/ssh-audit>

## Additional Third Party Utilities

The following are useful in working with OpenSSH, but outside the scope
of this book to go into detail. They are nevertheless worth mentioning
enough to warrant a list:

:   **netstat** -- Show network connections, routing tables, interface
    statistics, masquerade connections, and multicast memberships
:   **nc** or **netcat** -- Netcat, the TCP/IP swiss army knife.
:   **socat** -- SOcket CAT, a multipurpose relay similar to netcat.
:   **nmap** -- Network exploration tool and security scanner.
:   **tcpdump** -- Display network traffic real time.
:   **telnet** -- Unencrypted interaction with another host.
:   **pagsh** -- Creates a new credential cache sandbox and process
    authentication group (PAG).
:   **nohup** -- Invoke a process that ignores HANGUP signals
:   **sudo** -- Execute programs as another user
:   **lftp** -- A handy interactive multi-protocol file transfer
    text-based client supporting SFTP.
:   **curl** -- A multi-protocol file transfer text-based client
    supporting SCP and SFTP.
:   **tmux** -- A terminal multiplexer.

## References

[^1]:

[^2]: