Corrigindo Erros de Escalação de Privilégios no Ansible Usando Become e Sudo
Corrija erros de become e sudo no Ansible com configurações corretas de playbook, variáveis de inventário, regras sudoers e diagnósticos.
Corrigindo Erros de Escalação de Privilégios no Ansible Usando Become e Sudo
Erros de escalação de privilégios no Ansible geralmente aparecem quando uma tarefa precisa de acesso root, mas seu usuário de conexão não consegue usar sudo corretamente. Você pode ver "permissão negada", "senha sudo ausente" ou uma tarefa que funciona via SSH, mas falha dentro de um playbook.
A correção geralmente é uma combinação das configurações de become do Ansible e da configuração sudoers no host de destino. Este guia mostra ambos os lados.
Entendendo o Mecanismo become do Ansible
Em sua essência, o Ansible opera conectando-se a hosts de destino, tipicamente via SSH, e executando comandos como o usuário remoto. Muitas tarefas administrativas, no entanto, requerem privilégios elevados (por exemplo, acesso root em sistemas Linux). É aqui que o recurso become do Ansible entra em ação. O mecanismo become permite que o Ansible "se torne" outro usuário, geralmente root, para executar tarefas específicas ou plays inteiros com permissões elevadas.
Por que become é Necessário
Executar todas as tarefas do Ansible diretamente como usuário root é geralmente uma má prática de segurança. Em vez disso, você normalmente se conecta aos seus hosts remotos como um usuário regular e sem privilégios (frequentemente chamado de ansible_user) e então usa become para escalar privilégios temporariamente para tarefas que exigem isso. Isso segue o princípio do menor privilégio, minimizando o impacto potencial de uma violação de segurança.
Métodos become
O Ansible suporta vários métodos para escalação de privilégios, cada um correspondendo a diferentes utilitários do sistema. O método mais comum e amplamente usado, especialmente em sistemas Linux/Unix, é sudo (Substitute User Do). Outros métodos incluem su, pbrun, doas e mais, mas este guia focará principalmente no sudo devido à sua prevalência.
Configurando as Opções become no Ansible
O Ansible oferece várias maneiras de configurar as opções become, desde configurações globais até substituições específicas de tarefas. Entender esses escopos é crucial para um gerenciamento eficaz de privilégios.
1. Configuração Global em ansible.cfg
Para casos de uso gerais em muitos playbooks, você pode definir parâmetros become padrão no seu arquivo ansible.cfg. Isso geralmente é encontrado no diretório onde você executa o Ansible, ~/.ansible.cfg ou /etc/ansible/ansible.cfg.
# ansible.cfg
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False ; Defina como True se quiser que o Ansible solicite a senha
become=True: Habilita a escalação de privilégios por padrão para todos os plays.become_method=sudo: Especificasudocomo o método para escalação de privilégios.become_user=root: Especificarootcomo o usuário de destino a se tornar.become_ask_pass=False: Controla se o Ansible deve solicitar a senhabecome. Defina comoTruese você não fornecer a senha por outros meios.
2. Por Play ou Por Tarefa em Playbooks
Para um controle mais granular, as opções become podem ser definidas diretamente dentro dos seus playbooks, seja no nível do play (afetando todas as tarefas naquele play) ou no nível da tarefa individual.
Configuração no nível do play:
---
- name: Instalar Nginx com privilégios elevados
hosts: webservers
become: yes # Habilita become para todas as tarefas neste play
become_user: root
become_method: sudo
tasks:
- name: Garantir que o Nginx esteja instalado
ansible.builtin.apt:
name: nginx
state: present
# Esta tarefa será executada como root via sudo
- name: Copiar configuração do Nginx
ansible.builtin.copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
# Esta tarefa também será executada como root via sudo
Configuração no nível da tarefa:
---
- name: Gerenciar arquivos como diferentes usuários
hosts: all
tasks:
- name: Criar um arquivo como ansible_user (padrão)
ansible.builtin.file:
path: /tmp/unprivileged_file.txt
state: touch
mode: '0644'
- name: Criar um arquivo de propriedade do root usando become
ansible.builtin.file:
path: /root/privileged_file.txt
state: touch
mode: '0600'
become: yes # Apenas esta tarefa usará become
become_user: root
become_method: sudo
3. Via Variáveis de Inventário
As opções become também podem ser definidas no seu inventário do Ansible, permitindo que você especifique diferentes estratégias de escalação de privilégios para diferentes hosts ou grupos.
Exemplo de 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
Aqui, ansible_become, ansible_become_method e ansible_become_user são variáveis de inventário que correspondem às opções become. Elas podem ser definidas no nível all:vars, no nível do grupo ou no nível do host.
4. Usando Argumentos de CLI do ansible-playbook
Para substituições rápidas ou execução interativa, você pode passar parâmetros become diretamente via linha de comando:
--becomeou-b: Ativabecome.--become-method <MÉTODO>: Especifica o método become (por exemplo,sudo).--become-user <USUÁRIO>: Especifica o usuário de destino (por exemplo,root).--ask-become-passou-K: Solicita a senhabecomedurante a execução. Isso é útil para testes, mas geralmente não para automação.
Exemplo:
ansible-playbook my_playbook.yml --become --become-user root --ask-become-pass
Garantindo Direitos sudo para o Usuário become
Configurar corretamente o become no Ansible é apenas metade da batalha. O usuário ao qual o Ansible se conecta (o ansible_user) deve ter os privilégios sudo necessários no host de destino para se tornar o become_user. Isso é configurado no host de destino dentro do arquivo /etc/sudoers ou em um arquivo sob /etc/sudoers.d/.
Configurando sudoers
O arquivo sudoers define quem pode executar quais comandos e como quem. Uma entrada comum para permitir que um usuário de conexão do Ansible (devops_user neste exemplo) execute qualquer comando como qualquer usuário sem solicitação de senha é:
# /etc/sudoers.d/devops
devops_user ALL=(ALL) NOPASSWD: ALL
Explicação:
devops_user: O nome de usuário ao qual o Ansible se conecta (ansible_user).ALL: Este usuário pode executar comandos de qualquer terminal.(ALL): Este usuário pode executar comandos como qualquer usuário.NOPASSWD:: Especifica que nenhuma senha é necessária para operaçõessudo.ALL: Este usuário pode executar todos os comandos.
Aviso: Conceder NOPASSWD: ALL dá ao ansible_user acesso root irrestrito sem senha, o que pode ser um risco de segurança significativo. Use isso apenas se realmente necessário e garanta que as credenciais do seu ansible_user sejam altamente seguras. Para uma segurança mais rigorosa, você pode especificar comandos exatos ou conjuntos de comandos que o usuário pode executar.
Verificando o Acesso sudo
Antes de executar seu playbook, você pode verificar manualmente se seu ansible_user tem acesso sudo em um host de destino. Faça SSH no host como ansible_user e execute:
# Verifique se você pode usar sudo para root sem senha
sudo -n whoami
# Se uma senha for necessária, você será solicitado. Teste com um comando simples:
sudo whoami
# Liste os privilégios sudo para o usuário atual:
sudo -l
# Liste os privilégios sudo para um usuário específico (por exemplo, devops_user):
sudo -l -U devops_user
Se sudo -n whoami retornar root sem solicitação de senha, sua configuração NOPASSWD provavelmente está correta. Se solicitar uma senha, sua entrada sudoers pode estar faltando NOPASSWD ou estar configurada incorretamente.
Diagnosticando Erros de Escalação de Privilégios
O Ansible geralmente fornece mensagens de erro informativas, mas problemas relacionados a privilégios podem às vezes ser enigmáticos. Aqui estão erros comuns e suas soluções:
1. "permissão negada"
Isso geralmente significa que a tarefa foi executada como o usuário de conexão sem privilégios em vez de root.
Verifique o play ou a tarefa:
- name: Instalar pacote que requer root
ansible.builtin.package:
name: nginx
state: present
become: true
Em seguida, confirme qual usuário o Ansible está usando:
ansible webservers -m ansible.builtin.command -a 'whoami'
ansible webservers -b -m ansible.builtin.command -a 'whoami'
O segundo comando deve retornar root quando o sudo estiver funcionando.
2. "Senha sudo ausente"
Isso acontece quando o host de destino requer uma senha sudo, mas o Ansible não recebeu uma.
Para uma execução interativa, use:
ansible-playbook site.yml --ask-become-pass
Para automação, evite armazenar senhas em texto simples no inventário. Use o Ansible Vault para ansible_become_password se o sudo sem senha não for permitido em seu ambiente.
ansible-vault encrypt group_vars/webservers/vault.yml
Exemplo de nome de variável criptografada antes da criptografia:
ansible_become_password: "substituir-pela-senha-real"
3. "usuário não está no arquivo sudoers"
Este é um problema de configuração do host de destino. O Ansible não pode corrigi-lo a menos que já possa se conectar como um usuário com privilégios suficientes.
No host de destino, use visudo ou um arquivo sob /etc/sudoers.d/:
devops_user ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/apt, /usr/bin/yum
Isso é mais restrito que NOPASSWD: ALL, mas funciona apenas se seus playbooks precisarem desses comandos exatos. Módulos de pacote podem chamar binários diferentes dependendo do SO, então teste com cuidado.
4. become_user Errado
A maioria das tarefas de administração Linux usa become_user: root. Se você definir become_user para uma conta de aplicação, esse usuário pode ainda não ter permissão para modificar arquivos do sistema ou gerenciar serviços.
Use uma verificação rápida:
- name: Confirmar usuário efetivo
ansible.builtin.command: whoami
become: true
changed_when: false
Se a saída não for o usuário que você esperava, verifique as variáveis do playbook, variáveis de inventário e ansible.cfg em busca de valores conflitantes de become_user.
Uma Lista de Verificação Segura para Solução de Problemas
Trabalhe do host de destino de volta ao playbook:
- Faça SSH no host como
ansible_user. - Execute
sudo -le confirme que o usuário tem os direitos necessários. - Execute
sudo -n whoamise você espera sudo sem senha. - Execute
ansible all -b -m command -a 'whoami'contra um host de teste. - Adicione
-vvvà execução do playbook com falha se o erro ainda não estiver claro.
Conclusão Principal
O become do Ansible apenas diz ao Ansible para escalar privilégios. O host de destino ainda deve permitir que o usuário de conexão faça isso através do sudo ou outro método become. Corrija ambos os lados: defina become onde a tarefa precisa, depois verifique os direitos sudo diretamente no host.