Skip to content

Commit

Permalink
Start PROTOCOLS.md, a detailed description of the SSH protocols
Browse files Browse the repository at this point in the history
So far we cover:
* the general layering,
* all (as far as I know) the details of the underlying SSH
  transport protocol, and
* some of the details of just `publickey` authentication in
  the user (client) authentication protocol
  • Loading branch information
0cjs committed Jan 12, 2017
1 parent c673a1a commit 1c3d2b1
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 0 deletions.
169 changes: 169 additions & 0 deletions PROTOCOLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
SSH Protocol Layers
===================

Overview
--------

SSH consists of multiple protocols in several layers, as described in
brief at [SSH Architecture] and in full detail in [RFC 4251][SSH-ARCH].
The layers are, from lowest to highest:

0. A connection-oriented _underlying transport_ protocol (usually TCP).
1. The SSH [_transport layer_][SSH-TRANS].
2. Other protocols that send messages via the SSH transport layer,
including the transport layer itself (for negotiating its own
parameters), the SSH [_user authentication layer_][SSH-USERAUTH]
and the SSH [_connection layer_][SSH-CONNECT].


[SSH Architecture]: https://en.wikipedia.org/wiki/Secure_Shell#Architecture
[SSH-NUMBERS]: https://tools.ietf.org/html/rfc4250
[SSH-ARCH]: https://tools.ietf.org/html/rfc4251
[SSH-USERAUTH]: https://tools.ietf.org/html/rfc4252
[SSH-TRANS]: https://tools.ietf.org/html/rfc4253
[SSH-CONNECT]: https://tools.ietf.org/html/rfc4253


Protocol Layer Details
----------------------

### Underlying Transport Protocol

As per [RFC 4253 §4], this is any 8-bit clean, binary-transparent
transport. (Usually this will be TCP.) Ideally it should protect
against errors, as SSH aborts the connection upon encountering a
transport error.

[RFC 4253 §4]: https://tools.ietf.org/html/rfc4253#section-4

### SSH Transport Protocol

#### Packet Format

This starts with the [connection banner][T§4.2] after which all
exchanges are in a fixed [packet format][T§6]:

field | type | contents
--------|-----------|-----------------------------------------------------
len | uint32 | length _l_ of all packet data following this word
padlen | byte | _p_, length of padding below
payload | byte[_d_] | length _d_ = _l_ - _p_ - 1
padding | byte[_p_] | random data
MAC | byte[_m_] | (unencrypted) Message Authentication Code; _m_ = MAC length

#### Messages

Though it's not terribly clear from the RFCs, the payload above always
consists of [fields][N§3.3], the first of which is always a message
type identifier. The address space of these identifiers is shared
amongst all the higher-level protocols that use the SSH transport
protocols. The message type identifiers fall in to the following
[ranges][N§4.1]:

Values | Protocol | Purpose
--------|-----------------|---------
1-19 | [SSH-TRANS] | Transport layer generic (disconnect, debug etc.)
20-29 | [SSH-TRANS] | Algorithm negotiation
30-49 | [SSH-TRANS] | Key exchange (varies w/auth method)
50-59 | [SSH-USERAUTH] | User authentication generic
60-79 | [SSH-USERAUTH] | User auth specific (varies w/auth method)
80-89 | [SSH-CONNECT] | Connection protocol generic
90-127 | [SSH-CONNECT] | Channel-related messages
128-191 | | Reserved
192-255 | | Local extensions

Note that the SSH transport protocol has its own set of messages run
over the basic packet format of that protocol. There is a list of the
[generic message numbers][N§4.1.2] for all protocols.

#### Connection Setup

As well as defining the base packet format, the SSH transport protocol
also defines the initial parts of the connection setup, which are:

a) Session key setup, typically using Diffie Hellman key exchange.
This creates an encrypted (but not authenticated) connection
between the client and the server that is protected from
eavesdropping by a third party.

b) Authentication of the server via verification by the client of a
host public key sent to the client by the server.

c) One or more ["service requests"][T§10] from the client to the
server. This will typically be a request for the `ssh-userauth`
service, part of which requests that the `ssh-connection` service
be started if the client authentication is successful.

After the first two steps all transport-layer packets are encrypted
and authenticated. (During the course of the connection, the
encryption parameters may be re-negotiated, e.g., to re-key the
connection.)

Note that this setup is the _only_ time the client ever checks the
identity of the server; from this point all future messages in the
transport protocol are known to come via the connection to that server
but no further checks are done. This implies, for example, that
higher-level messages could be generated by another host and just
relayed by the server, such as in the case where SSH agent forwarding
is used.

[T§4.2]: https://tools.ietf.org/html/rfc4253#section-4.2
[T§10]: https://tools.ietf.org/html/rfc4253#section-10
[T§6]: https://tools.ietf.org/html/rfc4253#section-6
[N§3.3]: https://tools.ietf.org/html/rfc4250#section-3.3
[N§4.1]: https://tools.ietf.org/html/rfc4250#section-4.1
[N§4.1.2]: https://tools.ietf.org/html/rfc4250#section-4.1.2


### SSH User Authentication Protocol

Once the transport level connection has been set up and the server has
accepted a request from the client for the `ssh-userauth` service, the
client may send [authentication requests][U§5] to the server.

All `SSH_MSG_USERAUTH_REQUEST` messages start with the following four
fields:

Field | Type | Description
---------|--------|---------------------------------------------
msg.type | byte | Always `SSH_MSG_USERAUTH_REQUEST`
username | string | (in UTF-8)
service | string | service to start if auth is successful (e.g., `ssh-connection`)
method | string | [method name][U§5], e.g., `publickey` or `password`

We discuss here only the [`publickey`][U§7] authentication method. In
this case the client constructs an `SSH_MSG_USERAUTH_REQUEST` message
which inlcudes the above and several further fields:

* The fifth field is a boolean. FALSE indicates that this is a check
to see if an authentication with a given public key would be
acceptable; TRUE indicates that this is an actual signed
authentication request.

* The sixth and seventh fields are the public key algorithm name
and the public key itself.

* The eighth field, present only if the fifth field is TRUE, is
a signature as described below.

The server response depends on the fifth field:

* If FALSE, the response is `SSH_MSG_USERAUTH_PK_OK` if the server
will accept an attempt to authenticate with the key or
`SSH_MSG_USERAUTH_FAILURE` if it will not accept such an attempt.

* If TRUE, the response is `SSH_MSG_USERAUTH_SUCCESS` if the server
could verify the signature and no further authentications are
needed, or `SSH_MSG_USERAUTH_FAILURE` if either it couldn't verify
the signature or if it could but further authentication is needed.

The signature is over the session identifier (from the lower-level
protocol, usually [SSH-TRANS]) prefixed to the `SSH_MSG_USERAUTH_REQUEST`
message. This is described in [U§1] as "the exchange hash H from the
first key exchange."


[U§5]: https://tools.ietf.org/html/rfc4252#section-5
[U§7]: https://tools.ietf.org/html/rfc4252#section-5

### SSH Connection Layer Protocol
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@ things progress both on my exploration of the 3.2 API and the release
process of 4.0.0, I may change to using 4.x sooner or later.


Other Information
-----------------

In the process of having to investigate some (to my mind rather silly)
questions about alternate methods of host authentication (my brief
answer: just do it the way the protocol is designed to do it) I did a
moderately deep dive into the details of the SSH protocol suite. The
RFCs are not terribly easy to read, so I made a summary with
references back to appropriate sections of the RFCS; this is in the
[PROTOCOLS.md] document.


License
-------

Expand Down

0 comments on commit 1c3d2b1

Please sign in to comment.