Fork me on GitHub
Teleport

SSH Authentication with Azure Active Directory (AD)

This guide will cover how to configure Microsoft Azure Active Directory to issue SSH credentials to specific groups of users with a SAML Authentication Connector. When used in combination with role based access control (RBAC) it allows SSH administrators to define policies like:

  • Only members of "DBA" Azure AD group can SSH into machines running PostgreSQL.
  • Developers must never SSH into production servers.

The following steps configure an example SAML authentication connector matching AzureAD groups with security roles. You can choose to configure other options.

Version Warning
This guide requires an Enterprise version of Teleport.

Prerequisites

Before you get started you’ll need:

  • An Enterprise version of Teleport 7.1.3 or greater, downloaded from https://dashboard.gravitational.com/.
  • An Azure AD admin account with access to creating non-gallery applications (P2 License)
  • To register one or more users in the directory
  • To create at least two security groups in AzureAD and assign one or more users to each group

Configure Azure AD

  1. Select AzureAD -> Enterprise Applications

    Select Enterprise Applications From Manage
  2. Select New application

    Select New Applications From Manage
  3. Select a "Create your own application"

    Select Non-gallery application
  4. Enter the display name (Ex: Teleport)

    Enter application name

5.Select properties under Manage and turn off User assignment required

Turn off user assignment
  1. Select Single Sign-on under Manage and choose SAML

    Select SAML
  2. Select to edit Basic SAML Configuration

    Edit Basic SAML Configuration
  3. Put in the Entity ID and Reply URL the same proxy URL https://teleport.example.com:3080/v1/webapi/saml/acs

    Put in Entity ID and Reply URL
  4. Edit User Attributes & Claims

    • Edit the Claim Name. Change the name identifier format to Default. Make sure the source attribute is user.userprincipalname.
    Confirm Name Identifier
    • Add a group Claim to have user security groups available to the connector
    Put in Security group claim
    • Add a Claim to pass the username from transforming the AzureAD User name.
    Add a transformed username
  5. On the SAML Signing Certificate select to download SAML Download the Federation Metadata XML.

    Download Federation Metadata XML
Important
This is a important document. Treat the Federation Metadata XML file as you would a password.

Create a SAML Connector

Now, create a SAML connector resource. Replace the acs element with your Teleport address, update the group IDs with the actual AzureAD group ID values, and insert the downloaded Federation Metadata XML into the entity_descriptor resource. Write down this template as azure-connector.yaml:

kind: saml
version: v2
metadata:
  # the name of the connector
  name: azure-saml
spec:
  display: "Microsoft"
  # acs is the Assertion Consumer Service URL. This should be the address of
  # the Teleport proxy that your identity provider will communicate with.
  acs: https://teleport.example.com:3080/v1/webapi/saml/acs
  attributes_to_roles:
    - {name: "http://schemas.microsoft.com/ws/2008/06/identity/claims/groups", value: "<group id 930210...>", roles: ["editor"]}
    - {name: "http://schemas.microsoft.com/ws/2008/06/identity/claims/groups", value: "<group id 93b110...>", roles: ["dev"]}
  entity_descriptor: |
    <federationmedata.xml contents>

Create the connector using tctl tool:

tctl create azure-connector.yaml
Automatic signing keypair

Teleport will generate a signing key pair and update SAML connector with signing_key_pair property.

Sample Connector Transform

Alternatively, you can generate your own keypair when creating a connector using openssl:

openssl req -nodes -new -x509 -keyout server.key -out server.cer

Create a new Teleport Role

We are going to create a new that'll use external username data from Azure to map to a host linux login.

In the below role, Devs are only allowed to login to nodes labelled with access: relaxed Teleport label. Developers can log in as either ubuntu to a username that arrives in their assertions. Developers also do not have any rules needed to obtain admin access to Teleport.

kind: role
version: v4
metadata:
  name: dev
spec:
  options:
    max_session_ttl: 24h
  allow:
    logins: [ "{{external.username}}", ubuntu ]
    node_labels:
      access: relaxed

Notice: Replace ubuntu with linux login available on your servers!

tctl create dev.yaml

Testing

Update the Teleport settings to use the SAML settings to make this the default.

auth_service:
  authentication:
    type: saml
Login with Microsoft

The Web UI will now contain a new button: "Login with Microsoft". The CLI is the same as before:

tsh --proxy=proxy.example.com login

This command will print the SSO login URL (and will try to open it automatically in a browser).

Tip
Teleport can use multiple SAML connectors. In this case a connector name can be passed via tsh login --auth=connector_name

Token Encryption

AzureAD's SAML token encryption encrypts the SAML assertions sent to Teleport during SSO redirect.

Tip
This is Azure Active Directory Premium feature and requires a separate license. You can read more about it here

Setup Teleport Token Encryption

Start with generating a public/private key and a certificate. You will setup the public certificate with AzureAD and the private key with Teleport.

openssl req -nodes -new -x509 -keyout server.key -out server.cer

If you are modifying the existing connector, first, save it to YAML:

tctl get saml --with-secrets > azure-out.yaml

You will spot that Teleport has generated a signing_key_pair. This key pair is used to sign responses.

kind: saml
metadata:
  name: azure-saml
spec:
  acs: https://teleport.example.com/v1/webapi/saml/acs
  attributes_to_roles:
  - name: http://schemas.microsoft.com/ws/2008/06/identity/claims/groups
    roles:
    - editor
    - access
    - auditor
    value: '*'
  audience: https://teleport.example.com/v1/webapi/saml/acs
  cert: ""
  display: Microsoft
  entity_descriptor: |
    <?xml ...
  entity_descriptor_url: ""
  issuer: https://sts.windows.net/your-id-here/
  service_provider_issuer: https://teleport.example.com/v1/webapi/saml/acs
  signing_key_pair:
    cert: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    private_key: |
      -----BEGIN RSA PRIVATE KEY-----
      ...
      -----END RSA PRIVATE KEY-----
  sso: https://login.microsoftonline.com/your-id-here/saml2
version: v2

Add assertion_key_pair using the data from server.key and server.cer.

kind: saml
metadata:
  name: azure-saml
spec:
  acs: https://teleport.example.com/v1/webapi/saml/acs
  attributes_to_roles:
  - name: http://schemas.microsoft.com/ws/2008/06/identity/claims/groups
    roles:
    - editor
    - access
    - auditor
    value: '*'
  audience: https://teleport.example.com/v1/webapi/saml/acs
  cert: ""
  display: Microsoft
  entity_descriptor: |
    <?xml ...
  entity_descriptor_url: ""
  issuer: https://sts.windows.net/your-id-here/
  service_provider_issuer: https://teleport.example.com/v1/webapi/saml/acs
  signing_key_pair:
    cert: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    private_key: |
      -----BEGIN RSA PRIVATE KEY-----
      ...
      -----END RSA PRIVATE KEY-----
  sso: https://login.microsoftonline.com/your-id-here/saml2
version: v2
Warning
Make sure to have the same indentation for all lines of the certificate and key, otherwise Teleport will not parse the YAML file.

After your edits, the file will look like this:

kind: saml
metadata:
  name: azure-saml
spec:
  acs: https://teleport.example.com/v1/webapi/saml/acs
  attributes_to_roles:
  - name: http://schemas.microsoft.com/ws/2008/06/identity/claims/groups
    roles:
    - editor
    - access
    - auditor
    value: '*'
  audience: https://teleport.example.com/v1/webapi/saml/acs
  cert: ""
  display: Microsoft
  entity_descriptor: |
    <?xml ...
  entity_descriptor_url: ""
  issuer: https://sts.windows.net/your-id-here/
  service_provider_issuer: https://teleport.example.com/v1/webapi/saml/acs
  assertion_key_pair:
    cert: |
      -----BEGIN CERTIFICATE-----
      New CERT
      -----END CERTIFICATE-----
    private_key: |
      -----BEGIN RSA PRIVATE KEY-----
      New private key
      -----END RSA PRIVATE KEY-----  
  signing_key_pair:
    cert: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    private_key: |
      -----BEGIN RSA PRIVATE KEY-----
      ...
      -----END RSA PRIVATE KEY-----
  sso: https://login.microsoftonline.com/your-id-here/saml2
version: v2

Update the connector:

tctl create -f azure-out.yaml

Activate token encryption

  • Navigate to Token Encryption section
Navigate to token encryption
  • Import certificate
Import certificate
  • Activate it
Activate certificate

If the SSO login with this connector is successful, the encryption works.

Troubleshooting

Access denied

If you get "access denied" errors the number one place to check is the audit log on the Teleport auth server. It is located in /var/lib/teleport/log by default and it will contain the detailed reason why a user's login was denied.

Example of a user being denied due as the role clusteradmin wasn't setup.

{"code":"T1001W","error":"role clusteradmin is not found","event":"user.login","method":"saml","success":false,"time":"2019-06-15T19:38:07Z","uid":"cd9e45d0-b68c-43c3-87cf-73c4e0ec37e9"}

Some errors (like file-system permissions or misconfigured network) can be diagnosed using Teleport's stderr log, which is usually available via:

sudo journalctl -fu teleport

If you wish to increase the verbosity of Teleport's syslog, you can pass the --debug flag to teleport start command.

Failed to process SAML callback

If you encounter "Failed to process SAML callback", take a look at the logs.

Special characters are not allowed in resource names, please use name composed only from characters,
hyphens and dots: /web/users/ops_example.com#EXT#@opsexample.onmicrosoft.com/params

The error above is caused by nameid format that is not compatible with Teleport's naming conventions.

Change nameid format to use email instead:

Change NameID format to use email
Have a suggestion or can’t find something?
IMPROVE THE DOCS