4

I'm using Ansible, among other things, for backing up purposes. I run ansible-playbook with a non-root user (let's say it is user) and ssh as user. After that, I set up privilege escalation to become root on every server. Until now, no problems.

To fetch a remote directory I have something equivalent to the following rule:

- synchronize:
  mode: pull
  delete: true
  src: "{{ dir }}/"
  dest: "{{ tank_base }}/{{ inventory_hostname }}/{{ dir }}/"
  rsync_opts:
    - "--exclude=tmp*"
    - "--exclude=~*"
    - "--exclude=*~"
    - "--exclude=.gvfs/"
    - "--exclude=.cache/"

but for some subdirectory it gives the following error (slightly edited to hide personal data):

fatal: [server]: FAILED! => {"changed": false, "cmd": "/usr/bin/rsync --delay-updates -F --compress --delete-after --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no' --exclude=tmp* --exclude=~* --exclude=*~ --exclude=.gvfs/ --exclude=.cache/ --out-format='<>%i %n%L' \"server:/var/backup/\" \"/var/tank/snapshot/server/backup/\"", "failed": true, "msg": "rsync: opendir \"/var/backup/subdir\" failed: Permission denied (13)\nrsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1650) [generator=3.1.2]\n", "rc": 23}

The subdirectory that fails (/var/backup/subdir in the above case) is owned by root:root and it is readable/writable only by the owner. My guess is rsync is trying to pull the files as user instead of root.

How can I pull those directories without compromising the security and possibly without changing anything on the server side? After all privilege escalation is already in place and working.

2 Answers 2

3

After all privilege escalation is already in place and working.

Not exactly - synchronize module runs rsync locally on the management machine, not on the target node (for which you set up the privilege escalation). Module documentation describes this in details (an excerpt below):

  • The user and permissions for the synchronize src are those of the user running the Ansible task on the local host (or the remote_user for a delegate_to host when delegate_to is used).

  • The user and permissions for the synchronize dest are those of the remote_user on the destination host or the become_user if become=yes is active.

So it is accessing your source folder (server:/var/backup/ in the example) as user not root.


If you don't require password for the user to sudo on the target machine (or just do configure it this way for the rsync command) you can use delegate_to: <your_server> parameter combined with rsync_path="sudo rsync" to run it explicitly with sudo.

1
  • I don't know the ansible internals: I was hoping the sync module could tunnel its traffic by reusing the already established connection instead of creating a new one. I'll dig more on the delegate_to route...
    – ntd
    Commented Dec 12, 2016 at 9:53
3

In Ansible 2.2.1.0 this worked for me:

- synchronize:
    mode: pull
    src: "/home/vagrant/dir1"
    dest: "/my_linux/dir1"
    recursive: yes
    delete: no
    times: yes

...and with this inventory (to use ansible_ssh_private_key_file var):

[vagrant1]
192.168.77.4

[vagrant1:vars]
ansible_user=vagrant
ansible_ssh_private_key_file="/Users/Chilcano/.vagrant.d/insecure_private_key"

Hope it helps you.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .