Skip to content

tufteddeer/openssh-tdx-remote-attestation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Integrating Intel TDX remote attestation into SSH

This project adds Intel TDX remote attestation to OpenSSH using Microsoft Azure Attestation.

Intel TDX is a Confidential Computing technology that provides hardware-based memory protection for virtual machines, so called Trusted Domains. By performing remote attestation, the existence and integrity of the Trusted Domain can be proven to a remote party.

Using a custom SSH extension, the client and server perform a challenge-response protocol where the server proves it is running in a Trusted Domain. The client will verify the claims and only connect if the attestation is successful. This ensures that the SSH client only connects to servers running in a trusted environment, verified by remote attestation.

SSH is widely used in existing software for securely connecting machines via network. Practical applications especially profiting from remote attestation before establishing an SSH connection include:

  • limiting the deployment of software to trusted environments

  • transfering of backups containing sensitive data via software that uses SSH (e.g. rsync or borg backup)

  • connecting microservices or accessing a database via SSH tunnels

  • transfering source code containing intellectual property via git over SSH

This is the readme for remote attestation in SSH. You can find the original Portable OpenSSH readme in Readme_openssh.md.

Licensing

The additions to the original OpenSSH source code fall under the BSD-2-Clause license.

How it works

The implementation is based on a challenge-response protocol.

The client starts the connection as usual. After the keys are exchanged and the user is authenticated, it sends a message to the server, requesting the attestation information together with a nonce (challenge). The server create an Intel TDX report that contains the nonce and information about the Trusted Domain and uses an Azure Service to generate a JWT token from it. The token is send to the client (response).

As relying party, the client validates the signature on the JWT and veryfies the claims and the nonce. If the attestation is successful, the SSH connection continues, otherwise the client terminates the connection.

A visual explanation can be found under Sequence diagram.

Demo

This is a recording of the SSH server accepting a client connection and performing remote attestation.

asciicast

Some parts are slowed down for more readability.

Development

The following new dependencies are required to build the project:

  • libcurl for HTTP requests

  • jansson for JSON parsing

  • libjwt for JWT parsing and validation

Build instructions and original dependencies for OpenSSH can be found in the original Readme_openssh.md file. The Dockerfile contains instructions specific to Ubuntu 22.04.

autoreconf
./configure
make

Running

This part focuses on the development. If you are interested in testing the project, see Testing.

See Testing without a confidential VM for some workarounds to run on non-TDX hardware. Further modifications to the source code are required to bypass some checks (using a hardcoded nonce or disabling verification).

ssh needs an absolute path to the sshd-session binary (an artifact of this project). Use the SSHD_SESSION environment variable or the SshdSessionPath config item to set the path (see the sshd_config_dev file)

You also need a ssh hostkey (see Testing) named hostkey

Note: Due to privilege separation, running on Linux needs some additional setup (see Dockerfile)

sudo $(pwd)/sshd -f sshd_config_dev -ddd
./ssh test@localhost -vvv

Note: In my experience, password based authentication does not work when the server runs on MacOS, public key does.

Testing

To test the project, you need a confidential VM using Intel TDX on Microsoft Azure. The following configuration was used during development:

  • Security Type: Confidential virtual machines

  • Image: Ubuntu Server 22.04 LTS (Confidential VM) x64 Gen2

  • Size: Standard_DC2es_v5[1]

To simplify testing, there is a Docker image available containing

  • Ubuntu 22.04, which is required for the Intel trustauthority-cli

  • dependencies needed to build OpenSSH

  • new dependencies needed for remote attestation (libcurl, jansson, libjwt)

  • required build artifacts (ssh, sshd, ssh-session)

  • Intel trustauthority-cli (pinned to version 1.4.0) and dependencies

  • a demo user account ("user" with password "user")

Running the image will start the ssh server.

The following requirements must be provided for the container to run:

  • /dev/tpmrm0 device from the host (the confidential VM)

  • sshd_config and ssh_config files

  • ssh_host_rsa_key and ssh_host_rsa_key.pub files

Step by step guide

The following steps assume you are inside the confidential VM.

  • Install Docker

  • clone this repository or copy the config files manually

  • cd into the repository

  • Create a hostkey for the ssh server. When prompted for a password, press enter to create a key without a password.

ssh-keygen -f ssh_host_rsa_key
  • Start the container with the following command:

sudo docker run --rm --device /dev/tpmrm0 -v ./:/config -it --name ra-ssh ghcr.io/tufteddeer/openssh-tdx-remote-attestation:ra-ssh

This will mount the tpm device and the configuration files into the container and start the ssh server.

In another shell session, on the same VM:

  • Start the ssh client:

sudo docker exec -it ra-ssh ./ssh -F /config/ssh_config user@localhost -v

When asked, type "yes" to accept the host fingerprint. Use "user" as the password for the "user" account.

After attestation is performed (which my take a few seconds), the connection will be established and you should be in a shell session as "user".

Note that sh prompt is just a single $ and the shell session may be interlaced with the debug logs of the ssh client.

Type exit to quit the session.

Since sshd is running in debug mode to be able to see the logs in the terminal, it will exit when the connection is terminated.

To get more context or investigate failures, use ssh with -vvv and sshd with -ddd (in the Dockerfile) flags to increase logging verbosity. All logging for remote attestation uses debug level 1.

Testing without a confidential VM

To test the project without a VM capable of Azure TDX attestation, you can modify the sshd_config file to use the trustauthority-cli-mock.sh script which will just echo a hardcoded quote. Note that this quote may be outdated or use keys that are not valid or available anymore and that the nonce verification will fail, so this method is mainly useful during development or to simulate a failed attestation attempt.

# in docker
TrustauthorityCliPath /config/trustauthority-cli-mock.sh
# general
TrustauthorityCliPath /path/to/trustauthority-cli-mock.sh

Sequence diagram

Seuence diagram

About

OpenSSH fork with support for Intel TDX remote attestation

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages