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.

$ 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

edit

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.
sftp-server(8) - SFTP server subsystem, started automatically by sshd(8) when needed.
ssh-keysign(8) - Helper program for hostbased authentication.
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.

$ /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

edit

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

edit

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)

Subsystem sftp internal-sftp -d /var/www

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

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.

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.

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.

$ /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.

Subsystem sftp internal-sftp -u 0002

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

Environment Variables

edit

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

edit
  1. "Service Name and Transport Protocol Port Number Registry". IETF. 2012.
  2. "OpenSSH 2.3.0p1 release notes". OpenSSH.com.