# 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]:
    