Introduction
This guide shows how to set up user isolated mounts of CIFS (samba) network shares on a shared linux VM. Each user will get folders under /mnt/<user>
that they authenticate to using kerberos. In this document I’m assuming that users are members of a group and that each group all should have access to the same shares. We’ll further assume you’ve got a fact set in your playbook that maps each user to their corresponding group. If you need guidance on that you can see this post.
This is a nice way of attaching file shares because it ensures users don’t need elevated privileges to access file shares (although an administrator has to configure it for them) and that creating a share for one user doesn’t inadvertently expose it to others. For a fully user level way of attaching file shares you can use gio but I found it extremely flaky and annoying to use, so if you can handle having an administrator configure the share mount points for users I would recommend this approach.
Variable format
Somewhere in your playbook (in my case I set it in the variables folder of the role I was using, but putting in as a host variable or somewhere else may be more appropriate for your use case) we need a variable for each group that contains a list of associated shares. Something like this:
example_group1:
- local_share_name: share1
full_share_path: "//fileshare.example.com/share1"
- local_share_name: share2
full_share_path: "//fileshare.example.com/share2"
example_group2:
- local_share_name: share3
full_share_path: "//fileshare.example.com/share3"
Basic setup
In this stage we will ensure pre-requisite software is installed on the host (assuming Ubuntu here, you will have to modify for other distros), and that the mount point folder for each user has been created:
- name: Install autofs
ansible.builtin.apt:
pkg:
- autofs
- cifs-utils
- keyutils
- name: Create base file share mount point
ansible.builtin.file:
path: "/mnt/{{ item.user }}"
state: directory
owner: "{{ item.user }}"
group: "domain users@example.com"
mode: "0700"
with_items: "{{ users_dict }}"
- name: Start and enable the autofs service
ansible.builtin.systemd:
name: autofs
state: started
enabled: true
Where users_dict
looks like what I created in this post. You will also have to modify the group
variable to be appropriate for your environment.
I actually have the autofs service start task at the bottom of this play in my case, but thematically it makes more sense here.
Populate auto.master
- name: populate auto.master with entries for each users' configs
ansible.builtin.template:
src: auto.master.j2
dest: /etc/auto.master
owner: root
group: root
mode: '0644'
Each user needs an entry in /etc/auto.master
that points to a config file (which we’ll set in the next phase) with all their specific mount points. Using the template task and the template below we can accomplish this:
# {{ ansible_managed }}
{% for user in users_dict %}
/mnt/{{ user.user }} /etc/auto.sambashares-{{ user.user }} --timeout=30 --ghost
{% endfor %}
Each user gets a point below the /mnt/<user>
folder we created in the basic setup, we point to a config file for them, set a timeout so the fileshare will not stay connected if users aren’t using it and then we add the --ghost
flag so that all mount points get a directory created, even if they’re not currently attached. See here for further docs.
Conclusion
Autofs and ansible are a pretty nice way to set up a bunch of users with consistent file shares securely on a shared host or multiple hosts.