Fork me on GitHub

Teleport

SSH Authentication with Azure Active Directory (AD)

Improve

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 the "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 Azure AD groups with security roles. You can choose to configure other options.

Prerequisites

Before you get started you’ll need:

  • 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 Azure AD and assign one or more users to each group
  • Teleport role with access to maintaining saml resources. This is available in the default editor role.
  • A running Teleport cluster. For details on how to set this up, see our Enterprise Getting Started guide.

  • The tctl admin tool and tsh client tool version >= 10.1.2, which you can download by visiting the customer portal.

    tctl version

    Teleport v10.1.2 go1.18

    tsh version

    Teleport v10.1.2 go1.18

  • A Teleport Cloud account. If you do not have one, visit the sign up page to begin your free trial.

  • The tctl admin tool and tsh client tool version >= 9.3.10. To download these tools, visit the Downloads page.

    tctl version

    Teleport v9.3.10 go1.18

    tsh version

    Teleport v9.3.10 go1.18

To connect to Teleport, log in to your cluster using tsh, then use tctl remotely:

tsh login --proxy=teleport.example.com [email protected]
tctl status

Cluster teleport.example.com

Version 10.1.2

CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

You can run subsequent tctl commands in this guide on your local machine.

For full privileges, you can also run tctl commands on your Auth Service host.

To connect to Teleport, log in to your cluster using tsh, then use tctl remotely:

tsh login --proxy=myinstance.teleport.sh [email protected]
tctl status

Cluster myinstance.teleport.sh

Version 9.3.10

CA pin sha256:sha-hash-here

You must run subsequent tctl commands in this guide on your local machine.

Enable default SAML authentication

Configure Teleport to use SAML authentication as the default instead of the local user database.

You can either edit your Teleport configuration file or create a dynamic resource.

Update /etc/teleport.yaml in the auth_service section and restart the teleport daemon.

auth_service:
  authentication:
    type: saml

Create a file called cap.yaml:

kind: cluster_auth_preference
metadata:
  name: cluster-auth-preference
spec:
  authentication:
    type: saml
version: v2

Create a resource:

tctl create -f cap.yaml

Configure Azure AD

  1. Select Azure AD -> Enterprise Applications

    Select Enterprise Applications From Manage

  2. Select New application

    Select New Applications From Manage

  3. Select a Non-gallery application

    Select Non-gallery application

  4. Enter the display name (e.g, Teleport)

    Enter application name

  5. Select Properties under Manage and set User assignment required? to No

Turn off user assignment

  1. Select Single sign-on under Manage and choose SAML

    Select SAML

  2. Edit the Basic SAML Configuration

    Edit Basic SAML Configuration

  3. For Entity ID and Reply URL, enter the same proxy URL.

    For self-hosted deployments, the URL will be similar to https://teleport.example.com:3080/v1/webapi/saml/acs.

    For Teleport Cloud users, the URL will be similar to https://mytenant.teleport.sh.

    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 make user security groups available to the connector

    Put in Security group claim

    • Add a claim that transforms an Azure AD username in order to pass it to Teleport.

    Add a transformed username

  5. In SAML Signing Certificate, click the link to download the Federation Metadata XML.

    Download Federation Metadata XML

Important

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

Create a SAML Connector

Now, create a SAML connector resource. Write the following to 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>

Replace the acs field with your Teleport address, update the group IDs in the attributes_to_roles field with the actual Azure AD group ID values, and insert the downloaded Federation Metadata XML into the entity_descriptor field.

Create the connector using tctl:

tctl create azure-connector.yaml
Automatic signing key pair

Teleport will generate a signing key pair and update the SAML connector with the 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

Create a Teleport role resource that will use external username data from the Azure AD connector to determine which Linux logins to allow on a host.

Users with the following dev role are only allowed to log in to nodes with the access: relaxed Teleport label. They can log in as either ubuntu or a username that arrives via the Azure AD connector. Users with this role cannot obtain admin access to Teleport.

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

Replace ubuntu with the Linux login available on your servers.

tctl create dev.yaml

Testing

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

Azure AD'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.

Set up Teleport token encryption

Start with generating a public/private key and a certificate. You will set up the public certificate with Azure AD and the private key with Teleport.

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

If you are modifying the existing connector, write the YAML to a file first:

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

You will notice 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

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

Troubleshooting SSO configuration can be challenging. Usually a Teleport administrator must be able to:

  • Ensure that HTTP/TLS certificates are configured properly for both Teleport proxy and the SSO provider.
  • Be able to see what SAML/OIDC claims and values are getting exported and passed by the SSO provider to Teleport.
  • Be able to see how Teleport maps the received claims to role mappings as defined in the connector.

If something is not working, we recommend to:

  • Double-check the host names, tokens and TCP ports in a connector definition.

Using the Web UI

If you get "access denied" or other login errors, the number one place to check is the Audit Log. You can access it in the Activity tab of the Teleport Web UI.

Audit Log Entry for SSO Login error

Example of a user being denied because the role clusteradmin wasn't set up:

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

Teleport does not show the expected Nodes

When Teleport's Auth Service receives a request to list Teleport Nodes (e.g., to display Nodes in the Web UI or via tsh ls), it only returns the Nodes that the current user is authorized to view.

For each Node in the user's Teleport cluster, the Auth Service applies the following checks in order and, if one check fails, hides the Node from the user:

  • None of the user's roles contain a deny rule that matches the Node's labels.
  • None of the user's roles contain a deny rule that matches the user's login.
  • At least one of the user's roles contains an allow rule that matches the Node's labels.
  • At least one of the user's roles contains an allow rule that matches the user's login.

If you are not seeing Nodes when expected, make sure that your user's roles include the appropriate allow and deny rules as documented in the Teleport Access Controls Reference.

When configuring SSO, ensure that the identity provider is populating each user's traits correctly. For a user to see a Node in Teleport, the result of populating a template variable in a role's allow.logins must match at least one of a user's traits.logins.

In this example a user will have usernames ubuntu, debian and usernames from the SSO trait logins for Nodes that have a env: dev label. If the SSO trait username is bob then the usernames would include ubuntu, debian, and bob.

kind: role
metadata:
  name: example-role
spec:
  allow:
    logins: ['{{external.logins}}', ubuntu, debian]
    node_labels:
      'env': 'dev'
version: v5

Failed to process SAML callback

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

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 a Name ID format that is not compatible with Teleport's naming conventions.

Change the Name ID format to use email instead:

Change NameID format to use email

Further reading