Infograb logo
Ansible와 함께하는 머신 ID

Ansible은 SSH를 통해 Linux 호스트의 플릿을 관리하는 데 일반적으로 사용되는 도구입니다. 호스트에 연결하기 위해 인증의 한 형태가 필요합니다. 머신 ID는 Ansible에 단기 인증서를 제공하는 데 사용되어 Teleport에 등록된 SSH 노드에 안전하고 감사 가능한 방식으로 연결할 수 있습니다.

이 가이드에서는 머신 ID 에이전트인 tbot 을 구성하여 자격 증명과 OpenSSH 구성을 생성하고, 그런 다음 Ansible이 이를 사용하여 Teleport 프록시 서비스를 통해 SSH 노드에 연결하도록 설정합니다.

전제 조건

Ansible과 함께 Teleport를 사용하려면 다음 도구가 필요합니다.

  • 실행 중인 Teleport 클러스터 버전 17.0.0-dev 이상. Teleport를 시작하려면 가입하여 무료 평가판을 이용하거나 데모 환경 설정 방법을 확인하십시오.

  • tctl 관리자 도구와 tsh 클라이언트 도구.

    tctltsh 다운로드 방법에 대한 지침은 설치를 방문하십시오.

  • ssh OpenSSH 도구

  • ansible >= 2.9.6

  • 선택 사항: JSON 출력을 처리하기 위한 jq

  • tbot 은 이미 Ansible을 실행할 기계에 설치 및 구성되어 있어야 합니다. 자세한 내용은 배포 가이드를 참조하십시오.

  • 위의 가이드를 따랐다면, Ansible에서 사용될 SSH 인증서 및 OpenSSH 구성의 디렉토리를 정의하는 --destination-dir=/opt/machine-id 플래그를 주목하십시오.

    특히, Ansible 구성에서 Teleport 노드에 연결하기 위한 방법을 정의하기 위해 /opt/machine-id/ssh_config 파일을 사용하게 됩니다.

  • 연결이 가능한지 확인하기 위해 tsh login 으로 로그인한 다음, 현재 자격 증명을 사용하여 tctl 명령어를 실행할 수 있는지 확인하십시오.

    예를 들어:

    tsh login --proxy=teleport.example.com --user=email@example.com
    tctl status

    클러스터 teleport.example.com

    버전 17.0.0-dev

    CA 핀 sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    클러스터에 연결할 수 있고 tctl status 명령어를 실행할 수 있다면, 현재 자격 증명을 사용하여 워크스테이션에서 후속 tctl 명령어를 실행할 수 있습니다.
    자신의 Teleport 클러스터를 호스팅하는 경우, Teleport Auth Service를 호스팅하는 컴퓨터에서 전체 권한으로 tctl 명령어를 실행할 수도 있습니다.

1/4단계. RBAC 구성하기

Ansible은 SSH 노드에 연결하기 위해 tbot 에서 생성된 자격 증명을 사용할 것이므로, 먼저 Teleport를 구성하여 봇에 접근 권한을 부여해야 합니다. 이는 필요한 권한을 부여하는 역할을 생성한 다음 이 역할을 봇에 할당하여 수행됩니다.

이 예시에서는 사용자 이름 root에 대해 모든 SSH 노드에 대한 접근을 허용합니다. 이 사용자 이름이 SSH 노드 전반에서 사용 가능하고, 노드를 관리할 적절한 권한이 있는지 확인하십시오.

다음 내용을 포함하는 role.yaml 파일을 만드세요:

kind: role
version: v6
metadata:
  name: example-role
spec:
  allow:
    # 사용자 'root'에게 로그인 허용.
    logins: ['root']
    # 모든 노드에 연결 허용. 이러한 레이블을 조정하여 Ansible이 접근해야 하는 노드만 일치하도록 하세요.
    node_labels:
      "*": "*"

example-role 를 사용 사례와 관련된 설명적인 이름으로 바꾸십시오.

운영 환경에서는 레이블을 사용하여 이 접근을 Ansible이 접근해야 할 호스트로만 제한해야 합니다. 이는 최소 권한 원칙으로 알려져 있으며, 유출된 자격 증명이 미칠 수 있는 피해를 줄입니다.

tctl create -f ./role.yaml 을 사용하여 역할을 생성하십시오.

이제 tctl bots update 를 사용하여 역할을 봇에 추가합니다. example 을 배포 가이드에서 생성한 봇의 이름으로, example-role 을 방금 생성한 역할의 이름으로 바꾸십시오:

tctl bots update example --add-roles example-role

2/4단계. tbot 출력 구성하기

이제 tbot 을 Ansible에서 필요한 자격 증명과 SSH 구성을 생성할 수 있는 출력을 설정해야 합니다. SSH의 경우, identity 출력 유형을 사용합니다.

출력은 목적지를 설정해야 합니다. 이 예제에서는 directory 목적지를 사용합니다. 이는 이러한 자격 증명을 디스크의 지정된 디렉토리에 기록합니다. 해당 디렉토리가 tbot 이 실행되는 리눅스 사용자가 쓸 수 있고, Ansible이 실행될 리눅스 사용자가 읽을 수 있도록 해야 합니다.

tbot 구성을 수정하여 identity 출력을 추가하십시오:

outputs:
  - type: identity
    destination:
      type: directory
      # 이 가이드에서는 /opt/machine-id를 목적지 디렉토리로 사용합니다.
      # 이를 사용자 정의하려고 할 수 있습니다. 여러 출력이 동일한
      # 목적지를 공유할 수 없습니다.
      path: /opt/machine-id

tbot 을 백그라운드 서비스로 운영하는 경우, 이를 재시작하십시오. tbot 를 원숭이 모드에서 실행하는 경우 Ansible 플레이북을 실행하기 전에 실행해야 합니다.

이제 /opt/machine-id 아래에 여러 파일이 있는 것을 볼 수 있어야 합니다:

  • ssh_config : 이는 Ansible 또는 OpenSSH와 함께 사용되어 연결할 때 올바른 자격 증명으로 Teleport 프록시 서비스를 사용할 수 있도록 구성합니다.
  • known_hosts : 이는 Teleport SSH 호스트 CA를 포함하고 있으며, SSH 클라이언트가 호스트의 인증서를 검증하는 것을 가능하게 합니다.
  • key-cert.pub : 이는 Teleport SSH 사용자 CA에 의해 서명된 SSH 인증서입니다.
  • key : 이는 SSH 인증서를 사용하기 위해 필요한 개인 키입니다.

다음으로 Ansible은 이러한 파일을 사용하여 연결을 구성할 것입니다.

3/4단계. Ansible 구성하기

모든 Ansible 파일을 수집할 ansible 라는 폴더를 생성합니다.

mkdir -p ansible
cd ansible

ansible.cfg 라는 이름의 파일을 생성합니다. Ansible을 구성하여 Machine ID로 생성된 구성 파일 /opt/machine-id/ssh_config 를 사용하여 OpenSSH 클라이언트를 실행하도록 설정합니다. 여기서 example.com 은 여러분의 Teleport 클러스터 이름입니다.

[defaults]host_key_checking = Trueinventory=./hostsremote_tmp=/tmp
[ssh_connection]scp_if_ssh = Truessh_args = -F /opt/machine-id/ssh_config

hosts 라는 인벤토리 파일을 생성할 수 있습니다. 이 파일은 Teleport에 등록된 호스트 이름을 사용하여 호스트를 참조해야 하며, 여러분의 Teleport 클러스터 이름이 이 뒤에 추가되어야 합니다. 예를 들어, 클러스터 이름이 teleport.example.com 이고 호스트 이름이 node1 이면, hosts 파일의 항목은 node1.teleport.example.com 이 됩니다.

다음과 같은 스크립트를 사용하여 이 요구 사항을 충족하는 모든 노드에 대한 인벤토리 파일을 생성할 수 있습니다:

현재 Teleport 클러스터 이름을 얻기 위해 tsh env 소스 실행.

eval "$( tsh env )"

레이블에 따라 노드를 필터링하기 위해 `tsh ls` 명령을 수정할 수 있습니다.

tsh ls --format=json | jq --arg cluster $TELEPORT_CLUSTER -r '.[].spec.hostname + "." + $cluster' > hosts

Teleport의 Auth 서비스가 Teleport 노드를 목록화하라는 요청을 받을 때(예: 웹 UI에서 노드를 표시하거나 tsh ls 를 통해), 현재 사용자가 볼 수 있는 노드만 반환합니다.

사용자의 Teleport 클러스터의 각 노드에 대해 Auth 서비스는 다음과 같은 검사를 순서대로 적용하며, 하나의 검사가 실패할 경우 해당 노드를 사용자에게 숨깁니다:

  • 사용자의 역할 중 어느 것도 노드의 레이블과 일치하는 deny 규칙을 포함하지 않습니다.
  • 사용자의 역할 중 최소 하나가 노드의 레이블과 일치하는 allow 규칙을 포함합니다.

예상치 못하게 노드가 보이지 않는 경우, 사용자의 역할에 적절한 allowdeny 규칙이 포함되어 있는지 확인하십시오. 이는 Teleport Access Controls Reference에서 문서화되어 있습니다.

4/4단계. 플레이북 실행하기

마지막으로, 간단한 Ansible 플레이북 playbook.yaml 을 생성해 보겠습니다. 아래의 예시 플레이북은 모든 호스트에서 hostname 을 실행합니다.

- hosts: all
  remote_user: root
  tasks:
    - name: "hostname"
      command: "hostname"

ansible 폴더에서 Ansible 플레이북을 실행합니다:

ansible-playbook playbook.yaml

PLAY [all] *****************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************

ok: [terminal]

TASK [hostname] ************************************************************************************************************************************

changed: [terminal]

PLAY RECAP *****************************************************************************************************************************************

terminal : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

모든 설정이 완료되었습니다. 여러분은 기계 ID에 연결된 단기 인증서를 머신에 제공했으며, 이러한 인증서는 회전, 감사 및 모든 친숙한 Teleport 액세스 제어로 관리할 수 있습니다.

문제 해결

Ansible이 연결할 수 없는 경우 다음과 같은 오류를 볼 수 있습니다:

example.host | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname node-name: Name or service not known",
    "unreachable": true
}

ssh_config 에서 인벤토리 호스트와 일치하는 패턴을 검사하고 조정할 수 있습니다.

오류를 검사하기 위해 상세 모드에서 ssh_config 를 사용하여 SSH 연결을 시도해 보십시오:

ssh -vvv -F /opt/machine-id/ssh_config root@node-name.example.com

ssh 가 작동하면 상세 모드에서 플레이북을 실행해 보십시오:

ansible-playbook -vvv playbook.yaml

호스트 이름에 대문자가 포함되어 있는 경우(예: MYHOSTNAME ), Teleport의 내부 호스트 이름 일치는 기본적으로 대소문자를 구분하므로 이 오류가 발생할 수 있습니다.

이 경우, 클러스터 수준에서 대소문자를 구분하지 않는 라우팅을 활성화하여 해결할 수 있습니다.

모든 Teleport auth_service 를 실행 중인 서버의 /etc/teleport.yaml 구성 파일을 편집한 다음, 각 서버에서 Teleport를 재시작하십시오.

auth_service:
  case_insensitive_routing: true

다음 사양을 추가하기 위해 tctl edit cluster_networking_config 를 실행한 후 저장하고 종료합니다.

spec:
  case_insensitive_routing: true

다음 단계

  • 구성 참조 를 읽고
    사용 가능한 모든 구성 옵션을 탐색하세요.
Teleport 원문 보기