인포레터에서 최신 DevOps 트렌드를 격주로 만나보세요!
Ansible와 함께하는 머신 ID
Ansible은 SSH를 통해 리눅스 호스트 집합을 관리하기 위한 일반적인 도구입니다. 호스트에 연결하기 위해서는 인증 방법이 필요합니다. 머신 ID는 Ansible에 제공하여 SSH 노드에 연결할 수 있는 단기 인증서를 안전하고 감사 가능한 방식으로 제공할 수 있습니다.
이 가이드에서는 머신 ID 에이전트인 tbot
을 구성하여 자격 증명 및 OpenSSH 구성을 생성하고, 그런 다음 Ansible을 구성하여 이러한 자료를 사용하여 Teleport 프록시 서비스를 통해 SSH 노드에 연결하는 방법을 안내합니다.
전제 조건
Ansible과 함께 Teleport를 사용하려면 다음 도구가 필요합니다.
-
실행 중인 Teleport 클러스터 버전 이상. Teleport를 시작하려면, 가입하기 위해 무료 평가판에 등록하거나 데모 환경 설정하기를 참조하세요.
-
tctl
관리 도구와tsh
클라이언트 도구.tctl
과tsh
다운로드에 대한 지침은 설치를 방문하세요.
-
ssh
OpenSSH 도구 -
ansible
>= 2.9.6 -
선택 사항:
JSON
출력을 처리하기 위한jq
-
tbot
은 Ansible을 실행할 머신에 이미 설치되고 구성되어 있어야 합니다. 자세한 정보는 배포 가이드를 참조하십시오. -
위 가이드를 따라 했다면, SSH 인증서 및 Ansible에서 사용할 OpenSSH 구성의 디렉토리를 정의하는
--destination-dir=/opt/machine-id
플래그를 주목하십시오.특히, Ansible 구성에서 Teleport 노드에 연결하는 방법을 정의하는 데 사용되는
/opt/machine-id/ssh_config
파일을 사용하게 됩니다. -
당신의 Teleport 클러스터에 연결할 수 있는지 확인하려면,
tsh login
으로 로그인한 다음 현재 자격 증명을 사용하여tctl
명령어를 실행할 수 있는지 확인하십시오.예를 들어:
tsh login --proxy=teleport.example.com --user=email@example.comtctl status클러스터 teleport.example.com
버전 16.2.0
CA 핀 sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
클러스터에 연결하고
tctl status
명령어를 실행할 수 있다면, 현재 자격 증명을 사용하여 작업대에서 후속tctl
명령어를 실행할 수 있습니다.자신의 Teleport 클러스터를 호스팅하는 경우, Teleport 인증 서비스를 호스팅하는 컴퓨터에서 전체 권한으로
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이 필요로 하는 호스트로 제한하기 위해 레이블을 사용해야 합니다. 이는 최소 권한 원칙(Principle of Least Privilege)으로 알려져 있으며, 유출된 자격 증명으로 인한 피해를 줄입니다.
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이 머신 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
When Teleport의 인증 서비스가 Teleport 노드를 나열하라는 요청을 받으면 (예: 웹 UI에서 노드를 표시하거나 tsh ls
를 통해), 현재 사용자가 볼 수 있는 권한이 있는 노드만 반환합니다.
사용자의 Teleport 클러스터에 있는 각 노드에 대해 인증 서비스는 다음 검사를 순서대로 적용하며, 하나의 검사가 실패하면 해당 노드를 사용자에게 숨깁니다:
- 사용자의 역할 중 어느 것도 노드의 레이블과 일치하는
deny
규칙을 포함하지 않아야 합니다. - 사용자의 역할 중 적어도 하나는 노드의 레이블과 일치하는
allow
규칙을 포함해야 합니다.
예상할 때 노드를 볼 수 없다면, 사용자의 역할에 Teleport 접근 제어 참조에 문서화된 적절한 allow
및 deny
규칙이 포함되어 있는지 확인하세요.
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에 연결된 단기 인증서를 제공합니다.
문제 해결
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
다음 단계
- 사용 가능한 모든 구성 옵션을 탐색하기 위해 구성 참조를 읽으십시오.