인포레터에서 최신 DevOps 트렌드를 격주로 만나보세요!
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
클라이언트 도구.tctl
및tsh
다운로드 방법에 대한 지침은 설치를 방문하십시오.
-
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.comtctl 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 ansiblecd 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
규칙을 포함합니다.
예상치 못하게 노드가 보이지 않는 경우, 사용자의 역할에 적절한 allow
및 deny
규칙이 포함되어 있는지 확인하십시오. 이는 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.yamlPLAY [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
다음 단계
- 구성 참조 를 읽고
사용 가능한 모든 구성 옵션을 탐색하세요.