Skip to content

aakso/ssh-inscribe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

b0d25e1 · Oct 30, 2023
Sep 4, 2023
Oct 29, 2023
Sep 4, 2023
Oct 29, 2023
May 7, 2018
Oct 30, 2023
Jun 8, 2023
Sep 28, 2023
Oct 29, 2023
Mar 28, 2017
Oct 29, 2023
Jun 8, 2023
May 7, 2018
Apr 6, 2017
Oct 30, 2023
Oct 30, 2023

Repository files navigation

ssh-inscribe - SSH CA Client/Server

Note: this software is in alpha phase. Commands and API can change. Feedback would be appreciated.

Overview

ssh-inscribe can help you to manage your secure access to your organizations SSH hosts. It achieves this by leveraging SSH User Certificates.

Client/Server model allows us to store the CA key on a secure host while users request certificates with the client. In addition the CA key signing can also be offloaded to a HSM.

Users authenticate against the server using some credentials. After the user is known we can generate a certificate with very specific options and principals.

Requirements

For server you need:

  • ssh-agent binary in PATH
  • Some execution environment such as Systemd or Docker as the server does not support daemonization

For client you need:

  • ssh binary in path to use the ssh subcommand
  • ssh-agent running for convenient use

Installation

Released version

Prebuilt binaries and packages are available at project releases.

apt and dnf/yum package repositories are available at Packagecloud.

Development version

go install github.com/aakso/ssh-inscribe/...@latest

Quick start (flat file authentication)

Install and configure the server

  1. Install the software, single binary ssh-inscribe
  2. Generate default configuration file: mkdir ~/.ssh_inscribe && ssh-inscribe defaults > ~/.ssh_inscribe/config.yaml
  3. Edit ~/.ssh_inscribe/auth_users.yaml example:
users:
- name: testuser
  # password hash. use "ssh-inscribe crypt" to generate
  password: $2a$10$75.sk/zr/Rg3SUVpkg2wy.6D6Y1PvBs73OUHJWVqoW5KsSeSxN0Be # test
  principals: 
  - testPrincipal
  criticalOptions: {}
  extensions:
    permit-pty: ""
    permit-user-rc: ""
    permit-agent-forwarding: ""
    permit-X11-forwarding: ""
  1. Edit other options in ~/.ssh_inscribe/config.yaml (you should set TLSCertFile and TLSKeyFile at least)
  2. Start the server ssh-inscribe server
  3. Use the client to add a CA signing key:
sshi --url <server url> ca add <keyfile>

alternatively you can use OpenSSH ssh-add command locally on the server:

SSH_AUTH_SOCK=<path to auth sock> ssh-add <keyfile>

Configure your hosts to trust the CA public key

There are many guides to this available in the web but the easiest way is to use the authorized_keys file. Just put following in it:

cert-authority,principals="testPrincipal" <your CA Public Key>

It is also possible to configure global trust in your sshd_config. Refer to sshd_options man page and look for TrustedUserCAKeys and AuthorizedPrincipalsFile options.

Use the client

Recommended way to use the client is to have ssh-agent running. However keyfiles are also supported. Most options are also settable as environment variables. Check sshi --help and sshi req --help for up to date list.

You should at least set SSH_INSCRIBE_URL in your profile so you can omit the --url flag.

Quick start

The most simple way to use the client is to use the ssh subcommand. This generates a temporary key and requests a certificate for it. After this invokes the ssh command. All the flags and arguments are passed thru. If ssh-agent is unavailable, an internal agent is started for the duration of the session. Example:

# Assumes SSH_INSCRIBE_URL is set
sshi ssh <hostname> -l <username>

Certificate request commands

Generate temporary key, request certificate for it and place it on the ssh-agent

sshi req --url <url to server> --generate

Request certificate for an existing key and place it on the ssh-agent

sshi req --url <url to server> --identity /path/to/identity/file

Request certificate for an existing key and write it to <identity file>-cert.pub

sshi req --url <url to server> --identity /path/to/identity/file --write

Generate temporary key, request certificate for it and write keys and cert to <identity file>

sshi req --url <url to server> --identity /path/to/identity/file --write --generate

You should now have three files:

  • /path/to/identity/file
  • /path/to/identity/file.pub
  • /path/to/identity/file-cert.pub

Clear certificates and keys managed by sshi on the ssh-agent

sshi req --url <url to server> --clear

Advanced topics

LDAP

Here is an example configuration of a Directory Server Integration

mycompanyldapconfig:
  name: my.company.example.com
  realm: My Company Ltd
  serverUrl: ldaps://ad.my.company.example.com:636          # Using LDAP over SSL
  timeout: 5                                                # Connect and search timeout
  insecure: false                                           # Disables certificate validation on LDAP bind
  userBindDN: '{{.UserName}}@my.company.example.com'        # Template for binding. This example is for Microsoft AD
  userSearchBase: dc=my,dc=company,dc=example,dc=com
  userSearchFilter: (&(objectClass=user)(sAMAccountName={{.UserName}})) # For Microsoft AD
  addPrincipalsFromGroups: true                             # Add matching groups as SSH Cert Principals
  groupSearchBase: dc=my,dc=company,dc=example,dc=com
  groupSearchFilter: (&(objectClass=group)(member:1.2.840.113556.1.4.1941:={{.User.DN}})) # Recursive group search
  subjectNameTemplate: '{{.User.displayName}}'              # How to display user name in KeyId in the SSH Cert
  principalTemplate: 'my.company.example.com-{{.Group.cn}}' # How to display group based Principals in the SSH Cert
  # Add these Cert options to every successful authentication
  principals: []
  criticalOptions: {}
  extensions:
    permit-pty: ""
    permit-user-rc: ""
    permit-agent-forwarding: ""
    permit-X11-forwarding: ""
server:
  listen: :8540
  TLSCertFile: server_cert.pem # x509 certificate for HTTPS
  TLSKeyFile: server_key.pem
  authBackends:
  - type: authldap
    config: mycompanyldapconfig # Refer authldap config section
  maxCertLifetime: 24h
  defaultCertLifetime: 1h

Now here is an example session using the above configuration (ssh-agent is running):

mylaptop:~ aakso$ export SSH_INSCRIBE_URL=https://localhost:8540
mylaptop:~ aakso$ sshi ssh devbox.my.company.example.com
Enter Username for "my.company.example.com" (My Company Ltd): aakso
Enter Password for "my.company.example.com" (My Company Ltd):
CERT DETAILS:
         Fingerprint: SHA256:KUJHQ00IzkEmhH10HO3E7rddgARypH1pJgRH0ODbOHs (49:76:13:e4:08:ba:69:96:78:7a:99:9f:96:8d:90:86)
      CA Fingerprint: SHA256:VNyotPgHDkgsjEH7MhaTQrYTGe9mgIeMZxm5pS6uap0 (94:47:ae:2e:95:87:23:e1:45:fb:af:f8:26:43:91:ee)
               KeyId: subject="Anton Aksola" audit_id="WzaCsfQtrW8gEVEqTODJMqQ6jHnbmIya" via="my.company.example.com"
          Valid from: 1970-01-01 02:00:00 +0200 EET
            Valid to: 2017-04-06 09:35:12 +0300 EEST (expires in 59m59.25427059s)
          Principals:
                      my.company.example.com-SEC_DEVELOPER
                      my.company.example.com-SEC_PRODUCTION_SYSTEM_X
    Critical Options:
          Extensions:
                      permit-X11-forwarding
                      permit-agent-forwarding
                      permit-pty
                      permit-user-rc
Last login: Thu Apr  5 04:55:10 2017 from somewhere.at.my.company.example.com
[aakso@devbox ~]$

By using ssh-agent subsequent login happens without user/pass prompt until the cert is expired:

mylaptop:~ aakso$ sshi ssh devbox.my.company.example.com
Last login: Thu Apr  6 05:35:15 2017 from somewhere.at.my.company.example.com
[aakso@devbox ~]$

HSM

TODO