Ansible Copiar módulo y convertirse en: Permiso denegado

Ansible Copiar módulo y convertirse en: Permiso denegado

Estoy ejecutando un script ansible localhostpara copiar una carpeta a otra ubicación. Sin embargo,

- name: Copy Network
  become: yes
  become_user: root
  copy:
    src: /d/
    dest: "/dest/d/"
    mode: 0644
  tags: [network]

me está dando [Errno 13] Permission denied: b'd/f1'. Esperaba become_userque el comando se ejecutara como root, pero no funcionó. El permiso de este archivo es 0600(root:root).

¿Puede darme sugerencias para acceder a este archivo y copiarlo usando ansible?

Nota:

  • sudo ansible-playbook p.ymlfunciona perfectamente, sin embargo, no quiero usarlo sudocon el comando ansible si no es necesario y ansible tiene un truco para ello.

  • command: cp -r /d/ /dest/d/funciona sin agregar sudoal comando ansible ( ansible-playbook p.yml). Sin embargo, no quiero usarlo commandsi puedo evitarlo debido a la idempotencia y copyel módulo tiene modela opción requerida para la tarea.

Respuesta1

Actualización: si puede escalar el privilegio a root en localhost master, la solución es configurarlo remote_src: true(crédito @ivandov)

- copy:
    src: /d/
    dest: /dest/d/
    mode: '0644'
    remote_src: true
  become: true
  become_user: root

Los detalles a continuación describen el caso en el que no puede escalar a root en localhost. Dado el archivo en localhost

shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1

el móduloCopiarfunciona como se esperaba

- copy:
    src: /tmp/test/d/
    dest: /tmp/test/dest/
  become: true
  become_user: root

Primero, intenta leer el archivo y falla.

fatal: [localhost]: ¡FALLÓ! => msg: 'se produjo un error al intentar leer el archivo ''/tmp/test/d/f1'': [Errno 13] Permiso denegado: b''/tmp/test/d/f1''. [Errno 13] Permiso denegado: b''/tmp/test/d/f1'''

Por defecto, móduloCopiarcopia archivos desrc(ruta local a un archivo para copiar al servidor remoto) adestino(ruta absoluta remota donde se debe copiar el archivo). En este caso, become: truesignifica que Ansible aumenta los privilegios en el host remoto, pero no en el maestro del host local. A pesar de que la tarea se ejecuta en el host local, es decir, tanto el host maestro como el remoto son host local, sin remote_src: truela configuración become: truese aplica solo a escribir el archivo, no a leerlo. Si no puede escalar a root en la configuración de localhostremote_src: true

- copy:
    src: /tmp/test/d/
    dest: /tmp/test/dest/
    remote_src: true
  become: true
  become_user: root

fallará

fatal: [localhost]: ¡FALLÓ! => cambiado=falso ansible_facts: discover_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: se requiere una contraseña module_stdout: '' msg: |- FALLO DEL MÓDULO Consulte stdout/stderr para conocer el error exacto rc: 1


P:"¿Existe alguna solución para esto?"

R: Sin escalar a la raíz, no hay solución alternativa. Violaría la propiedad y los permisos de los archivos. Por ejemplo, dado el archivo en el controlador

shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1

El siguiente manual fue iniciado por un usuario sin privilegios.

shell> cat playbook.yml
- hosts: test_01
  become: true
  tasks:
    - copy:
        src: f1
        dest: /tmp

se estrellará

TASK [copy] ****
fatal: [test_01]: FAILED! => 
  msg: 'an error occurred while trying to read the file ''/scratch/f1'':
       [Errno 13] Permission denied: b''/scratch/f1'''

Si no puede escalar a root en el servidor maestro local, la solución es hacer que el archivo sea legible para el usuario que ejecuta el libro de estrategias.

Respuesta2

A partir de la respuesta de Vladimir, ¡en realidad HAY una solución alternativa simple!

El comentario a continuación (y el énfasis que agregué en negrita) fue la clave.

En la copia del módulo, conviértase en: sí se aplica solo para escribir el archivono leerlo.

Simplemente use remote_src: true, aunque esté copiando el archivo localmente. Esto hace que becomeaumente los privilegios correctamente al leer el srcarchivo/directorio de la máquina local porque lo trata srccomo una máquina remota y aplica correctamente la escalada de privilegios.

- name: Copy Network
  become: yes
  become_user: root
  copy:
    src: /d/
    dest: "/dest/d/"
    remote_src: true  # this allows become to work as expected
    mode: 0644
  tags: [network]

Respuesta3

tl;dr: Ansible become: rootse aplica a la máquina de destino, no al host de Ansible que ejecuta el libro de jugadas. Son posibles soluciones alternativas.

escribí una respuestaaquípara solucionar este problema para un solo archivo: el host Ansible que ejecuta el libro de estrategias no genera sus propios permisos rootcon become: root; esto sólo se aplica a la máquina de destino. En la pregunta original, ambos lo son, localhostpero creo que este comportamiento todavía se aplica; considérelo como una root"fuente" no privilegiada y un rootdestino privilegiado.

La solución utiliza delegate_to: localhostel slurparchivo requerido en la memoria: delegate_to:permite become: roothacer su magia localmente y luego escribir el archivo guardado en la máquina de destino.

Sin embargo, la pregunta original se refiere a cómo hacer esto para directorios: slurptambién se ha discutido la creación de directoriosaquílo que debería proporcionar un punto de partida adecuado cuando se combina con la solución por archivo slurp, especialmente. tenga en cuenta el comentario de @guzmonne sobre esa respuesta con respecto a. construir una lista de archivos slurpantes de usar la solución alternativa por archivo (que no es excelente, pero puede ser preferible a alterar los permisos de archivos/directorios).

información relacionada