Ansible 권한 상승 오류 해결: Become과 Sudo 사용하기
올바른 플레이북 설정, 인벤토리 변수, sudoers 규칙 및 진단을 통해 Ansible의 become 및 sudo 오류를 수정합니다.
Ansible 권한 상승 오류 해결: Become과 Sudo 사용하기
Ansible 권한 상승 오류는 일반적으로 작업에 루트 액세스가 필요하지만 연결 사용자가 sudo를 올바르게 사용할 수 없을 때 발생합니다. "permission denied", "missing sudo password" 또는 SSH에서는 작동하지만 플레이북 내에서는 실패하는 작업을 볼 수 있습니다.
해결 방법은 일반적으로 Ansible become 설정과 대상 호스트 sudoers 구성의 조합입니다. 이 가이드에서는 양쪽 측면을 모두 설명합니다.
Ansible의 become 메커니즘 이해
핵심적으로 Ansible은 일반적으로 SSH를 통해 대상 호스트에 연결하고 원격 사용자로 명령을 실행하여 작동합니다. 그러나 많은 관리 작업에는 상승된 권한(예: Linux 시스템의 root 액세스)이 필요합니다. 이때 Ansible의 become 기능이 사용됩니다. become 메커니즘을 사용하면 Ansible이 특정 작업이나 전체 플레이를 상승된 권한으로 실행하기 위해 다른 사용자(일반적으로 root)로 "전환"할 수 있습니다.
become이 필요한 이유
모든 Ansible 작업을 root 사용자로 직접 실행하는 것은 일반적으로 나쁜 보안 관행입니다. 대신 일반적으로 권한이 없는 일반 사용자(종종 ansible_user라고 함)로 원격 호스트에 연결한 다음 become을 사용하여 필요한 작업에 대해 일시적으로 권한을 상승시킵니다. 이는 최소 권한 원칙을 준수하여 보안 침해의 잠재적 영향을 최소화합니다.
become 방법
Ansible은 각각 다른 시스템 유틸리티에 해당하는 여러 권한 상승 방법을 지원합니다. 특히 Linux/Unix 시스템에서 가장 일반적이고 널리 사용되는 방법은 sudo(Substitute User Do)입니다. 다른 방법으로는 su, pbrun, doas 등이 있지만, 이 가이드는 sudo의 보편성으로 인해 주로 sudo에 초점을 맞춥니다.
Ansible에서 become 설정 구성
Ansible은 전역 구성에서 작업별 재정의에 이르기까지 become 설정을 구성하는 여러 방법을 제공합니다. 이러한 범위를 이해하는 것은 효과적인 권한 관리에 중요합니다.
1. ansible.cfg의 전역 구성
여러 플레이북에서 일반적인 사용 사례의 경우 ansible.cfg 파일에 기본 become 매개변수를 설정할 수 있습니다. 이 파일은 일반적으로 Ansible을 실행하는 디렉토리, ~/.ansible.cfg 또는 /etc/ansible/ansible.cfg에 있습니다.
# ansible.cfg
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False ; Ansible이 비밀번호를 묻도록 하려면 True로 설정
become=True: 모든 플레이에 대해 기본적으로 권한 상승을 활성화합니다.become_method=sudo: 권한 상승 방법으로sudo를 지정합니다.become_user=root: 전환할 대상 사용자로root를 지정합니다.become_ask_pass=False: Ansible이become비밀번호를 묻는지 여부를 제어합니다. 다른 방법으로 비밀번호를 제공하지 않는 경우True로 설정합니다.
2. 플레이북의 플레이별 또는 작업별 설정
보다 세분화된 제어를 위해 become 설정은 플레이북 내에서 직접 정의할 수 있으며, 플레이 수준(해당 플레이의 모든 작업에 영향을 미침) 또는 개별 작업 수준에서 정의할 수 있습니다.
플레이 수준 구성:
---
- name: 상승된 권한으로 Nginx 설치
hosts: webservers
become: yes # 이 플레이의 모든 작업에 대해 become 활성화
become_user: root
become_method: sudo
tasks:
- name: Nginx가 설치되었는지 확인
ansible.builtin.apt:
name: nginx
state: present
# 이 작업은 sudo를 통해 root로 실행됩니다.
- name: Nginx 구성 복사
ansible.builtin.copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
# 이 작업도 sudo를 통해 root로 실행됩니다.
작업 수준 구성:
---
- name: 다른 사용자로 파일 관리
hosts: all
tasks:
- name: ansible_user(기본값)로 파일 생성
ansible.builtin.file:
path: /tmp/unprivileged_file.txt
state: touch
mode: '0644'
- name: become을 사용하여 root 소유 파일 생성
ansible.builtin.file:
path: /root/privileged_file.txt
state: touch
mode: '0600'
become: yes # 이 작업만 become을 사용합니다.
become_user: root
become_method: sudo
3. 인벤토리 변수 사용
become 설정은 Ansible 인벤토리에서도 정의할 수 있으므로 호스트 또는 그룹에 따라 다른 권한 상승 전략을 지정할 수 있습니다.
hosts.ini 예:
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
[all:vars]
ansible_user=devops_user
ansible_become=true
ansible_become_method=sudo
ansible_become_user=root
여기서 ansible_become, ansible_become_method 및 ansible_become_user는 become 설정에 해당하는 인벤토리 변수입니다. all:vars 수준, 그룹 수준 또는 호스트 수준에서 설정할 수 있습니다.
4. ansible-playbook CLI 인수 사용
빠른 재정의 또는 대화식 실행의 경우 명령줄에서 직접 become 매개변수를 전달할 수 있습니다.
--become또는-b:become을 활성화합니다.--become-method <METHOD>: become 방법을 지정합니다(예:sudo).--become-user <USER>: 대상 사용자를 지정합니다(예:root).--ask-become-pass또는-K: 실행 중에become비밀번호를 묻습니다. 테스트에는 유용하지만 일반적으로 자동화에는 사용되지 않습니다.
예:
ansible-playbook my_playbook.yml --become --become-user root --ask-become-pass
become 사용자에 대한 sudo 권한 보장
Ansible에서 become을 올바르게 구성하는 것은 전투의 절반에 불과합니다. Ansible이 연결하는 사용자(ansible_user)는 become_user가 되기 위해 대상 호스트에서 필요한 sudo 권한을 반드시 가지고 있어야 합니다. 이는 대상 호스트의 /etc/sudoers 파일 또는 /etc/sudoers.d/ 아래 파일에서 구성됩니다.
sudoers 구성
sudoers 파일은 누가 어떤 명령을, 누구로 실행할 수 있는지 정의합니다. Ansible 연결 사용자(이 예에서는 devops_user)가 비밀번호 프롬프트 없이 모든 명령을 모든 사용자로 실행할 수 있도록 하는 일반적인 항목은 다음과 같습니다.
# /etc/sudoers.d/devops
devops_user ALL=(ALL) NOPASSWD: ALL
설명:
devops_user: Ansible이 연결하는 사용자 이름(ansible_user).ALL: 이 사용자는 모든 터미널에서 명령을 실행할 수 있습니다.(ALL): 이 사용자는 모든 사용자로 명령을 실행할 수 있습니다.NOPASSWD::sudo작업에 비밀번호가 필요하지 않음을 지정합니다.ALL: 이 사용자는 모든 명령을 실행할 수 있습니다.
경고: NOPASSWD: ALL을 부여하면 ansible_user에게 비밀번호 없이 제한 없는 루트 액세스 권한이 부여되므로 상당한 보안 위험이 될 수 있습니다. 정말로 필요한 경우에만 사용하고 ansible_user의 자격 증명이 매우 안전한지 확인하십시오. 더 엄격한 보안을 위해 사용자가 실행할 수 있는 정확한 명령 또는 명령 집합을 지정할 수 있습니다.
sudo 액세스 확인
플레이북을 실행하기 전에 대상 호스트에서 ansible_user에게 sudo 액세스 권한이 있는지 수동으로 확인할 수 있습니다. ansible_user로 호스트에 SSH로 접속하여 다음을 실행합니다.
# 비밀번호 없이 sudo로 root가 될 수 있는지 확인
sudo -n whoami
# 비밀번호가 필요한 경우 프롬프트가 표시됩니다. 간단한 명령으로 테스트:
sudo whoami
# 현재 사용자의 sudo 권한 나열:
sudo -l
# 특정 사용자(예: devops_user)의 sudo 권한 나열:
sudo -l -U devops_user
sudo -n whoami가 비밀번호 프롬프트 없이 root를 반환하면 NOPASSWD 구성이 올바른 것입니다. 비밀번호를 묻는 메시지가 표시되면 sudoers 항목에 NOPASSWD가 없거나 잘못 구성된 것입니다.
권한 상승 오류 진단
Ansible은 일반적으로 정보를 제공하는 오류 메시지를 제공하지만 권한 관련 문제는 때때로 이해하기 어려울 수 있습니다. 다음은 일반적인 오류와 해결 방법입니다.
1. "permission denied"
이는 일반적으로 작업이 root 대신 권한이 없는 연결 사용자로 실행되었음을 의미합니다.
플레이 또는 작업을 확인합니다.
- name: root가 필요한 패키지 설치
ansible.builtin.package:
name: nginx
state: present
become: true
그런 다음 Ansible이 사용하는 사용자를 확인합니다.
ansible webservers -m ansible.builtin.command -a 'whoami'
ansible webservers -b -m ansible.builtin.command -a 'whoami'
sudo가 작동하는 경우 두 번째 명령은 root를 반환해야 합니다.
2. "Missing sudo password"
이는 대상 호스트에 sudo 비밀번호가 필요하지만 Ansible에 비밀번호가 제공되지 않은 경우 발생합니다.
대화식 실행의 경우 다음을 사용합니다.
ansible-playbook site.yml --ask-become-pass
자동화의 경우 인벤토리에 일반 텍스트 비밀번호를 저장하지 마십시오. 환경에서 비밀번호 없는 sudo가 허용되지 않는 경우 Ansible Vault를 ansible_become_password에 사용합니다.
ansible-vault encrypt group_vars/webservers/vault.yml
암호화 전 암호화되지 않은 변수 이름 예:
ansible_become_password: "replace-with-real-password"
3. "user is not in the sudoers file"
이는 대상 호스트 구성 문제입니다. Ansible이 이미 충분한 권한이 있는 사용자로 연결할 수 없는 경우 이 문제를 해결할 수 없습니다.
대상 호스트에서 visudo 또는 /etc/sudoers.d/ 아래 파일을 사용합니다.
devops_user ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/apt, /usr/bin/yum
이는 NOPASSWD: ALL보다 좁지만 플레이북에 해당 명령이 정확히 필요한 경우에만 작동합니다. 패키지 모듈은 OS에 따라 다른 바이너리를 호출할 수 있으므로 신중하게 테스트하십시오.
4. 잘못된 become_user
대부분의 Linux 관리 작업은 become_user: root를 사용합니다. become_user를 애플리케이션 계정으로 설정하면 해당 사용자에게 시스템 파일을 수정하거나 서비스를 관리할 수 있는 권한이 여전히 없을 수 있습니다.
빠른 확인을 사용합니다.
- name: 유효 사용자 확인
ansible.builtin.command: whoami
become: true
changed_when: false
출력이 예상한 사용자가 아닌 경우 충돌하는 become_user 값에 대해 플레이북 변수, 인벤토리 변수 및 ansible.cfg를 확인합니다.
안전한 문제 해결 체크리스트
대상 호스트에서 플레이북으로 작업합니다.
ansible_user로 호스트에 SSH로 접속합니다.sudo -l을 실행하고 사용자에게 필요한 권한이 있는지 확인합니다.- 비밀번호 없는 sudo를 예상하는 경우
sudo -n whoami를 실행합니다. - 하나의 테스트 호스트에 대해
ansible all -b -m command -a 'whoami'를 실행합니다. - 오류가 여전히 명확하지 않은 경우 실패하는 플레이북 실행에
-vvv를 추가합니다.
핵심 요점
Ansible become은 Ansible에게 권한을 상승시키라고만 지시합니다. 대상 호스트는 여전히 sudo 또는 다른 become 방법을 통해 연결 사용자가 그렇게 할 수 있도록 허용해야 합니다. 양쪽을 모두 수정하십시오. 작업에 필요한 곳에 become을 설정한 다음 호스트에서 직접 sudo 권한을 확인하십시오.