Teleport – How to use it with Ansible?

In modern IT environments, managing secure remote access to servers is essential. Teleport provides a secure framework for accessing servers and databases, and when integrated with Ansible, it enhances both the security and efficiency of deploying and managing software. This article will guide you through integrating Teleport with Ansible, combining their strengths to improve security and streamline access control in automation processes.

Prerequisites

  • A running Teleport cluster version 15.4.0 or above.
  • The tsh client tool.
  • ssh openssh tool
  • ansible >= 2.9.6

Versions that I used:

  • Teleport cluster version 15.4.7
  • Ansible 2.15.10
  • Openssh 3.0.13

Setting up Teleport

For connecting to servers integrated within a Teleport cluster, it’s first necessary to generate Teleport certificates using the tsh command. We must verify that we have access to the servers we intend to configure with Ansible and with what user we can login in the server.

  1. Login into Teleport with the console, using tsh: tsh login --proxy={teleport_proxy} --user={teleport_user}
  2. Generate openssh configuration using tsh: tsh config > teleport.cfg

This command queries the Teleport cluster for the necessary configuration details and then outputs these settings directly into a file named teleport.cfg. This file effectively captures the specific setup of your Teleport environment, including the SSH configurations and authentication parameters required for secure connections.

Example of teleport.cfg:

# Begin generated Teleport configuration for {teleport_proxy} by tsh

# Common flags for all {teleport_proxy} hosts
Host *.{teleport_proxy} {teleport_proxy}
    UserKnownHostsFile "/home/{user}/.tsh/known_hosts"
    IdentityFile "/home/{user}/.tsh/keys/{teleport_proxy}/{teleport_user}"
    CertificateFile "/home/{user}/.tsh/keys/{teleport_proxy}/{teleport_user}/{teleport_proxy}-cert.pub"
    HostKeyAlgorithms [email protected],[email protected],[email protected]

# Flags for all {teleport_proxy} hosts except the proxy
Host *.{teleport_proxy} !{teleport_proxy}
    Port 3022
    ProxyCommand "/usr/local/bin/tsh" proxy ssh --cluster={teleport_proxy}--proxy={teleport_proxy}:443 %r@%h:%p
  1. Host matching: Applies settings for any host under the domain {teleport_proxy} and specifically for the {teleport_proxy} itself.
  2. UserKnownHostsFile: Specifies the location of the known hosts file, helping to verify the identity of the connected servers.
  3. Identity and Certificate Files: Points to the user’s private key and corresponding certificate for authentication, stored under the user’s home directory. These are specific to the {teleport_proxy} and {teleport_user}.
  4. HostKeyAlgorithms: Lists the secure host key algorithms that are accepted for connections, ensuring strong authentication standards.
  5. Excluding Direct Proxy Access: Configures settings for all hosts in the {teleport_proxy} domain, excluding direct connections to the proxy itself.
  6. Port and ProxyCommand: Uses port 3022 and sets a ProxyCommand that facilitates SSH connections through Teleport’s proxy. This command uses Teleport’s tsh proxy ssh to handle secure connections by resolving hostnames within the {teleport_proxy} cluster.

With this configuration, you can seamlessly connect to any server that is part of the cluster’s network. Once set up, these servers are accessible using a standardized naming convention: node-name.proxy-domain. For example, if a node is named jenkins and the Teleport domain is example.com, you can access this server using the standardized address jenkins.example.com.

Setting up Ansible

To leverage Teleport for managing server access in Ansible, it’s crucial to correctly set up the configuration files. The teleport.cfg file, generated earlier, should be placed at the same level as the ansible.cfg file in your project directory. This setup ensures that Ansible can easily reference the necessary Teleport configurations.

There are two primary ways to configure Ansible to use Teleport: setting it in the inventory or in the ansible.cfg file. And then the execution of playbooks and ad-hoc commands are treated in the same way.

The choice between these two methods can impact how flexible your Ansible deployments are, especially when connecting to a mix of servers, some of which may not be managed by Teleport.

Configuring Teleport settings in the ansible.cfg file applies these settings globally to all playbooks. This approach simplifies setup when all your servers are managed through Teleport but can become a complication if you need to connect to servers outside of the Teleport system. On the other hand, configuring Teleport in the Ansible inventory targets only a specific group of hosts. By defining Teleport settings for a designated group, you ensure that only those servers use the Teleport configuration.

Adding Host in the Inventory

Modify your Ansible inventory by creating a new group of hosts and define several variables to utilize the teleport.cfg file. Here’s how you can set it up:

  teleport:
    hosts:
      {node_name}.{teleport_proxy}:
    vars:
      ansible_user: {teleport_user}
      ansible_ssh_common_args: -F teleport.cfg
      ansible_scp_if_ssh: true

This configuration tells Ansible to use the specified Teleport configuration for SSH commands. With this setup, there is no need to adjust anything extra in your playbooks, making it straightforward and efficient.

Example:

We assume we have a cluster with the following name “example.com”, a node with the following name “test” and a teleport system user “teleport”.

inventory.yml

all:
  children:
    teleport_dp_dev:
      hosts:
        test.example.com:
      vars:
        ansible_user: devop
        ansible_ssh_common_args: -F teleport.cfg
        ansible_scp_if_ssh: true

Executing ad-hoc command: ansible all -i inventory.yml -m shell -a "sudo apt update && sudo apt upgrade -y" --become --limit test.example.com

Executing a playbook: ansible-playbook -i inventory.yml Ansible/playbooks/42m.example.yml --limit test.example.com

Adding Configuration in ansible.cfg

Directly incorporate the Teleport configuration into your ansible.cfg file to apply it globally across all playbooks:

[ssh_connection]
scp_if_ssh = True
ssh_args = -F ./teleport.cfg

This method ensures that all SSH connections made by Ansible will utilize the Teleport configuration, providing a consistent approach to access management. The server names in your inventory will follow the naming convention used in Teleport, such as "name in teleport"."cluster name".

Additionally, it’s common to specify the remote_user in your playbooks to dictate which user should execute the Ansible tasks. Take into account the users set on the servers and those to which your teleport user has permissions to enter the servers.

Example

We assume we have a cluster with the following name “example.com”, a node with the following name “test” and a teleport system user “teleport”.

inventory.yml

all:
  children:
    teleport_dp_dev:
      hosts:
        test.example.com:

ansible.cfg

[ssh_connection]
scp_if_ssh = True
ssh_args = -F ./teleport.cfg

Executing ad-hoc command: ansible all -i inventory.yml -m shell -a "sudo apt update && sudo apt upgrade -y" --become -u teleport --limit test.example.com

Executing a playbook: ansible-playbook -i inventory.yml Ansible/playbooks/42m.example.yml -u teleport --limit test.example.com

Conclusion

Setting up Teleport with Ansible is straightforward, requiring only minor configuration adjustments. By simply placing the teleport.cfg file correctly and tweaking a few settings in Ansible, you can enhance the security of your server management without significantly altering your existing processes. This setup ensures that you can maintain your routine operations while implementing an added layer of security with minimal effort.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.