Understanding a bit about the SSH connection protocol

July 23, 2017

The SSH connection protocol is the final SSH protocol; depending on your perspective, it sits either on top of or after the SSH transport protocol and SSH user authentication protocol. It's the level of SSH where all of the useful things happen, like remote logins, command execution, and port forwarding.

An important thing to know about the connection protocol is that it's a multiplexed protocol. There is not one logical connection that everything happens over but instead multiple channels, all operating more or less independently. SSH has its own internal flow control mechanism for channels to make sure that data from a single channel won't saturate the overall stream and prevent other channels from being responsive. There are different types of channels (and subtypes of some of them as well); one type of channel is used for 'sessions', another for X11 forwarding, another for port forwarding, and so on. However, the connection protocol and SSH as a whole doesn't really interpret the actual data flowing over a particular channel; once a channel is set up, data is just data and is shuttled back and forth blindly. Like many things in the SSH protocol, channel types and subtypes are specified as strings.

(SSH opted to make a lot of things be strings to make them easily extensible, especially for experiments and implementation specific extensions. With strings, you just need a naming convention to avoid collisions instead of any sort of central authority to register your new number. This is why you will see some SSH ciphers with names like 'aes128-gcm@openssh.com'.)

The major channel type is a 'session', which are basically containers that are used to ask for login shells, command execution, X11 forwarding, and 'subsystems', which is a general concept for other sorts of sessions that can be used to extend SSH (with the right magic on both the server and the client). Subsystems probably aren't used much, although they are used to implement SFTP. A single session can ask for and contain multiple things; if you ssh in to a server interactively with X11 forwarding enabled, your session will ask for both a shell and X11 forwarding.

(However, the RFC requires a session to only have one of a shell, a command execution, or a subsystem. This is probably partly because of data flow issues; if you asked for more than one, the connection protocol provides no way to sort out which input and output is attached to which thing within a single channel. X11 forwarding is different, because a new channel gets opened for each client.)

Channels can be opened by either end. Normally the client opens most channels, but the server can wind up opening channels for X11 clients and for ports being forwarded from the server to the client (with eg OpenSSH ssh's -R set of options).

OpenSSH's connection sharing works through channel multiplexing, since a client can open multiple 'session' channels over a single connection. The client side is going to be a little complicated, but from the server side everything is generic and general.

Written on 23 July 2017.
« When the SSH protocol does and doesn't do user authentication
Trying to understand the ZFS l2arc_noprefetch tunable »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Jul 23 01:18:13 2017
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.