mirror of
https://git.lapiole.org/dani/ansible-roles.git
synced 2025-07-27 00:05:44 +02:00
Update to 2022-10-19 17:00
This commit is contained in:
79
roles/nas/defaults/main.yml
Normal file
79
roles/nas/defaults/main.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
|
||||
# List of file shares
|
||||
nas_shares: []
|
||||
# nas_shares:
|
||||
# - name: tools
|
||||
# description: IT maintenance tools
|
||||
# path: /opt/shares/tools
|
||||
# acl:
|
||||
# read_groups:
|
||||
# - 'Domain Users'
|
||||
# - 'Domain Guests'
|
||||
# write_groups:
|
||||
# - 'Domain Admins'
|
||||
# - 'Staff'
|
||||
# read_users: []
|
||||
# write_users: []
|
||||
# protocols:
|
||||
# smb:
|
||||
# enabled: True
|
||||
# browseable: True
|
||||
# guest_ok: False
|
||||
# nt_acl: True
|
||||
# rsync:
|
||||
# enabled: True
|
||||
# read_only: True
|
||||
# users:
|
||||
# dani: s3cr3t.
|
||||
# rv: p455phrAz
|
||||
|
||||
nas_root_dir: /opt/nas
|
||||
nas_share_homes_defaults:
|
||||
description: Répertoire personnel
|
||||
recycle_bin:
|
||||
enabled: True
|
||||
dir: Corbeille
|
||||
protocols:
|
||||
smb:
|
||||
enabled: True
|
||||
full_audit: True
|
||||
nas_share_homes_extra: {}
|
||||
nas_share_homes: "{{ nas_share_homes_defaults | combine(nas_share_homes_extra) }}"
|
||||
|
||||
nas_default_share:
|
||||
description: NAS share
|
||||
name: share
|
||||
manual_permissions: False
|
||||
acl:
|
||||
read_groups: []
|
||||
write_groups: ['domain admins']
|
||||
read_users: []
|
||||
write_users: []
|
||||
recycle_bin:
|
||||
enabled: True
|
||||
dir: Corbeille
|
||||
protocols:
|
||||
smb:
|
||||
enabled: False
|
||||
browseable: True
|
||||
guest_ok: False
|
||||
full_audit: True
|
||||
nt_acl: False
|
||||
rsync:
|
||||
enabled: False
|
||||
read_only: True
|
||||
nfs:
|
||||
enabled: False
|
||||
root_squash: True
|
||||
http:
|
||||
enabled: False
|
||||
indexes: False
|
||||
public: False
|
||||
force_ssl: True
|
||||
webdav: False
|
||||
|
||||
nas_ad_http_auth:
|
||||
ldap_url: ldap://
|
||||
bind_dn: XXX
|
||||
bind_pass: XXX
|
22
roles/nas/files/mkhomedir
Normal file
22
roles/nas/files/mkhomedir
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
USER=$1
|
||||
if [ -z $USER ]; then
|
||||
echo "Need to get user as first argument"
|
||||
exit 1
|
||||
fi
|
||||
getent passwd $USER >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "User $USER not found"
|
||||
exit 1
|
||||
fi
|
||||
HOME=$(eval echo ~$USER)
|
||||
if [ ! -d $HOME ]; then
|
||||
echo "Creating $USER home directory ($HOME)"
|
||||
umask 022
|
||||
mkdir -p $HOME
|
||||
GROUP=$(id -gn $USER)
|
||||
chown $USER:"$GROUP" $HOME
|
||||
chmod 700 $HOME
|
||||
restorecon -R $HOME
|
||||
fi
|
4
roles/nas/handlers/main.yml
Normal file
4
roles/nas/handlers/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
- name: reload nfs
|
||||
command: exportfs -ra
|
6
roles/nas/meta/main.yml
Normal file
6
roles/nas/meta/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
dependencies:
|
||||
- role: samba
|
||||
- role: rsync_server
|
||||
- role: nfs_server
|
||||
- role: httpd_front
|
104
roles/nas/tasks/main.yml
Normal file
104
roles/nas/tasks/main.yml
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
|
||||
- name: Build config for shares
|
||||
set_fact: nas_shares_conf={{ nas_shares_conf | default([]) + [nas_default_share | combine(item,recursive=True)] }}
|
||||
with_items: "{{ nas_shares }}"
|
||||
tags: nas
|
||||
- set_fact: nas_shares={{ nas_shares_conf | default([]) }}
|
||||
tags: nas
|
||||
|
||||
- name: Install needed packages
|
||||
package:
|
||||
name:
|
||||
- mod_authnz_external
|
||||
tags: nas
|
||||
#
|
||||
#- name: Allow every user to use rssh
|
||||
# file: path=/bin/rssh mode=755
|
||||
# tags: nas
|
||||
|
||||
- name: Create directories
|
||||
file: path={{ nas_root_dir }}/{{ item[1] }}/{{ item[0].name }} state=directory
|
||||
with_nested:
|
||||
- "{{ nas_shares }}"
|
||||
- [data,meta]
|
||||
tags: nas
|
||||
|
||||
- name: Create rsync system user
|
||||
user:
|
||||
name: rsync
|
||||
system: True
|
||||
shell: /sbin/nologin
|
||||
tags: nas
|
||||
|
||||
- name: Deploy samba shares config
|
||||
template: src=smb.conf.j2 dest=/etc/samba/smb.conf.d/shares.conf
|
||||
notify: reload samba
|
||||
tags: nas
|
||||
|
||||
- name: Deploy NFS exports
|
||||
template: src=exports.j2 dest=/etc/exports.d/shares.exports
|
||||
notify: reload nfs
|
||||
tags: nas
|
||||
|
||||
- name: Deploy rsyncd shares config
|
||||
template: src=rsyncd.conf.j2 dest=/etc/rsyncd.conf.d/shares.conf
|
||||
tags: nas
|
||||
|
||||
- name: Deploy rsync auth files
|
||||
template: src=rsync.secrets.j2 dest={{ nas_root_dir }}/meta/{{ item.name }}/rsync.secrets owner=root group=root mode=600
|
||||
with_items: "{{ nas_shares }}"
|
||||
tags: nas
|
||||
|
||||
- name: Deploy httpd conf
|
||||
template: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode | default(omit) }}
|
||||
loop:
|
||||
- src: httpd.conf.j2
|
||||
dest: /etc/httpd/ansible_conf.d/50-shares.conf
|
||||
mode: 640
|
||||
- src: mod_dav.conf.j2
|
||||
dest: /etc/httpd/ansible_conf.modules.d/30-mod_dav.conf
|
||||
- src: mod_authnz_external.conf.j2
|
||||
dest: /etc/httpd/ansible_conf.modules.d/30-mod_authnz_external.conf
|
||||
notify:
|
||||
- reload httpd
|
||||
tags: nas
|
||||
|
||||
- name: Allow http to use PAM auth
|
||||
seboolean: name=httpd_mod_auth_pam state=True persistent=True
|
||||
when: ansible_selinux.status == 'enabled'
|
||||
tags: nas
|
||||
|
||||
- name: Deploy setfacl script
|
||||
template: src=setfacl.sh.j2 dest={{ nas_root_dir }}/meta/{{ item.name }}/setfacl.sh mode=755
|
||||
with_items: "{{ nas_shares }}"
|
||||
register: nas_acl
|
||||
tags: nas
|
||||
|
||||
- name: Reset acls
|
||||
command: "{{ nas_root_dir }}/meta/{{ item.item.name }}/setfacl.sh"
|
||||
when: item.changed
|
||||
with_items: "{{ nas_acl.results }}"
|
||||
tags: nas
|
||||
|
||||
- name: Set SELinux content
|
||||
sefcontext:
|
||||
target: "{{ nas_root_dir }}/data(/.*)?"
|
||||
setype: public_content_rw_t
|
||||
state: present
|
||||
when: ansible_selinux.status == 'enabled'
|
||||
tags: nas
|
||||
|
||||
- name: Set SEbool
|
||||
seboolean: name={{ item }} state=True persistent=True
|
||||
with_items:
|
||||
- samba_enable_home_dirs
|
||||
- samba_create_home_dirs
|
||||
- samba_export_all_rw
|
||||
tags: nas
|
||||
|
||||
- name: Deploy scripts
|
||||
copy: src={{ item }} dest=/var/lib/samba/scripts/{{ item }}
|
||||
with_items:
|
||||
- mkhomedir
|
||||
tags: nas
|
7
roles/nas/templates/exports.j2
Normal file
7
roles/nas/templates/exports.j2
Normal file
@@ -0,0 +1,7 @@
|
||||
{% for share in nas_shares %}
|
||||
{% if share.protocols.nfs.enabled %}
|
||||
{{ share.path | default(nas_root_dir + '/data/' + share.name) }} *(rw,{{ share.protocols.nfs.root_squash | ternary('','no_') }}root_squash)
|
||||
{% else %}
|
||||
# NFS not enabled for share {{ share.name }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
51
roles/nas/templates/httpd.conf.j2
Normal file
51
roles/nas/templates/httpd.conf.j2
Normal file
@@ -0,0 +1,51 @@
|
||||
{% for share in nas_shares %}
|
||||
{% if share.protocols.http.enabled %}
|
||||
Alias /{{ share.name }} {{ share.path | default(nas_root_dir + '/data/' + share.name) }}
|
||||
RewriteEngine On
|
||||
{% if share.protocols.http.force_ssl %}
|
||||
RewriteCond %{HTTPS} =off
|
||||
RewriteRule ^/{{ share.name }}(/.*|$) https://%{HTTP_HOST}/{{ share.name }}$1
|
||||
{% endif %}
|
||||
|
||||
<Directory {{ share.path | default(nas_root_dir + '/data/' + share.name) }}>
|
||||
Options None
|
||||
Options +FollowSymlinks
|
||||
{% if share.protocols.http.force_ssl %}
|
||||
SSLRequireSSL On
|
||||
{% endif %}
|
||||
{% if share.protocols.http.indexes %}
|
||||
Options +Indexes
|
||||
{% endif %}
|
||||
{% if share.protocols.http.webdav %}
|
||||
Dav On
|
||||
{% endif %}
|
||||
{% if not share.protocols.http.public %}
|
||||
AuthType Basic
|
||||
AuthName "Authenicated zone"
|
||||
AuthBasicProvider external
|
||||
AuthExternal pwauth
|
||||
|
||||
# Read only access
|
||||
<Limit GET PROPFIND OPTIONS LOCK UNLOCK REPORT>
|
||||
{% for user in share.acl.read_users %}
|
||||
Require user {{ user }}
|
||||
{% endfor %}
|
||||
{% for group in share.acl.read_groups %}
|
||||
Require unix-group {{ group }}
|
||||
{% endfor %}
|
||||
</Limit>
|
||||
# Write access through webdav always requires authentication
|
||||
<LimitExcept GET PROPFIND OPTIONS LOCK UNLOCK REPORT>
|
||||
{% for user in share.acl.write_users %}
|
||||
Require user {{ user }}
|
||||
{% endfor %}
|
||||
{% for group in share.acl.write_groups %}
|
||||
Require unix-group {{ group }}
|
||||
{% endfor %}
|
||||
</LimitExcept>
|
||||
{% endif %}
|
||||
</Directory>
|
||||
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
3
roles/nas/templates/mod_authnz_external.conf.j2
Normal file
3
roles/nas/templates/mod_authnz_external.conf.j2
Normal file
@@ -0,0 +1,3 @@
|
||||
LoadModule authnz_external_module modules/mod_authnz_external.so
|
||||
AddExternalAuth pwauth /usr/sbin/pwauth
|
||||
SetExternalAuthMethod pwauth pipe
|
2
roles/nas/templates/mod_dav.conf.j2
Normal file
2
roles/nas/templates/mod_dav.conf.j2
Normal file
@@ -0,0 +1,2 @@
|
||||
LoadModule dav_module modules/mod_dav.so
|
||||
LoadModule dav_fs_module modules/mod_dav_fs.so
|
6
roles/nas/templates/rsync.secrets.j2
Normal file
6
roles/nas/templates/rsync.secrets.j2
Normal file
@@ -0,0 +1,6 @@
|
||||
{% if item.protocols.rsync.enabled and item.protocols.rsync.users is defined and item.protocols.rsync.users.keys() | list | length > 0 %}
|
||||
{% for user in item.protocols.rsync.users.keys() | list %}
|
||||
{{ user }}:{{ item.protocols.rsync.users[user] }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
18
roles/nas/templates/rsyncd.conf.j2
Normal file
18
roles/nas/templates/rsyncd.conf.j2
Normal file
@@ -0,0 +1,18 @@
|
||||
{% for share in nas_shares %}
|
||||
{% if share.protocols.rsync.enabled %}
|
||||
[{{ share.name }}]
|
||||
path = {{ share.path | default(nas_root_dir + '/data/' + share.name) }}
|
||||
comment = {{ share.description }}
|
||||
uid = rsync
|
||||
gid = rsync
|
||||
read only = {{ share.protocols.rsync.read_only | ternary('yes','no') }}
|
||||
{% if share.protocols.rsync.users is defined and share.protocols.rsync.users.keys() | list | length > 0 %}
|
||||
auth users = {{ share.protocols.rsync.users.keys() | list | join(' ') }}
|
||||
secrets file = {{ nas_root_dir }}/meta/{{ share.name }}/rsync.secrets
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
# Rsync access is disabled for {{ share.name }}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
42
roles/nas/templates/setfacl.sh.j2
Normal file
42
roles/nas/templates/setfacl.sh.j2
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
WRITE_USERS=''
|
||||
READ_USERS=''
|
||||
WRITE_GROUPS=''
|
||||
READ_GROUPS=''
|
||||
{% if item.acl.read_users | length > 0 %}
|
||||
for U in '{{ item.acl.read_users | join("' '") }}'; do
|
||||
getent passwd "$U" > /dev/null 2>&1 && READ_USERS=$READ_USERS",u:$U:rX,d:u:$U:rX"
|
||||
done
|
||||
{% endif %}
|
||||
{% if item.acl.write_users | length > 0 %}
|
||||
for U in '{{ item.acl.write_users | join("' '") }}'; do
|
||||
getent passwd "$U" > /dev/null 2>&1 && WRITE_USERS=$WRITE_USERS",u:$U:rwX,d:u:$U:rwX"
|
||||
done
|
||||
{% endif %}
|
||||
{% if item.acl.read_groups | length > 0 %}
|
||||
for G in '{{ item.acl.read_groups | join("' '") }}'; do
|
||||
getent group "$G" > /dev/null 2>&1 && READ_GROUPS=$READ_GROUPS",g:$G:rX,d:g:$G:rX"
|
||||
done
|
||||
{% endif %}
|
||||
{% if item.acl.write_groups | length > 0 %}
|
||||
for G in '{{ item.acl.write_groups | join("' '") }}'; do
|
||||
getent group "$G" > /dev/null 2>&1 && WRITE_GROUPS=$WRITE_GROUPS",g:$G:rwX,d:g:$G:rwX"
|
||||
done
|
||||
{% endif %}
|
||||
|
||||
chmod 770 {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
chmod 700 {{ item.path | default(nas_root_dir + '/meta/' + item.name) }}
|
||||
chown root:root {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
{% if not item.protocols.smb.nt_acl and not item.manual_permissions %}
|
||||
setfacl -R --remove-all --remove-default --physical {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
setfacl -R --remove-all --remove-default --physical {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
setfacl -R --physical -m g::---"$READ_USERS$WRITE_USERS$READ_GROUPS$WRITE_GROUPS" -- {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
{% if item.protocols.rsync.enabled %}
|
||||
setfacl -R --physical -m u:rsync:{{ item.protocols.rsync.read_only | ternary('rX','rwX') }},d:u:rsync:{{ item.protocols.rsync.read_only | ternary('rX','rwX') }} -- {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
setfacl -R -m mask::rwX,d:mask:rwX -- {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
{% if ansible_selinux.status == 'enabled' %}
|
||||
restorecon -R {{ item.path | default(nas_root_dir + '/data/' + item.name) }}
|
||||
{% endif %}
|
56
roles/nas/templates/smb.conf.j2
Normal file
56
roles/nas/templates/smb.conf.j2
Normal file
@@ -0,0 +1,56 @@
|
||||
{% if nas_share_homes.protocols.smb.enabled %}
|
||||
[homes]
|
||||
comment = {{ nas_share_homes.description }}
|
||||
browseable = no
|
||||
guest ok = no
|
||||
read only = no
|
||||
writable = yes
|
||||
printable = no
|
||||
root preexec = /var/lib/samba/scripts/mkhomedir %u
|
||||
vfs objects = {{ nas_share_homes.recycle_bin.enabled | ternary('recycle','') }} {{ nas_share_homes.protocols.smb.full_audit | ternary('full_audit','') }}
|
||||
{% if nas_share_homes.recycle_bin.enabled %}
|
||||
recycle:exclude_dir = tmp,temp,cache
|
||||
recycle:repository = {{ nas_share_homes.recycle_bin.dir }}
|
||||
recycle:versions = no
|
||||
recycle:keeptree = yes
|
||||
recycle:touch = yes
|
||||
recycle:exclude = *.tmp,*.temp,*.o,*.obj,~$*
|
||||
{% endif %}
|
||||
{% if nas_share_homes.protocols.smb.full_audit %}
|
||||
full_audit:success=mkdir rmdir open opendir close closedir rename unlink
|
||||
full_audit:failure=mkdir rmdir open opendir close closedir rename unlink connect disconnect
|
||||
full_audit:prefix=%u|%D|%I|%M|%S
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endif %}
|
||||
{% if nas_shares | length < 1 %}
|
||||
# No share configured
|
||||
{% else %}
|
||||
{% for share in nas_shares %}
|
||||
{% if share.protocols.smb.enabled %}
|
||||
[{{ share.name }}]
|
||||
comment = {{ share.description | default(share.name) }}
|
||||
readonly = no
|
||||
path = {{ share.path | default(nas_root_dir + '/data/' + share.name) }}
|
||||
browseable = {{ share.protocols.smb.browseable | ternary('yes','no') }}
|
||||
inherit acls = yes
|
||||
guest ok = {{ share.protocols.smb.guest_ok | ternary('yes','no') }}
|
||||
vfs objects = {{ share.recycle_bin.enabled | ternary('recycle','') }} {{ share.protocols.smb.full_audit | ternary('full_audit','') }} {{ share.protocols.smb.nt_acl | ternary('nfs4acl_xattr','') }}
|
||||
{% if share.recycle_bin.enabled %}
|
||||
recycle:repository = {{ share.recycle_bin.dir }}
|
||||
recycle:versions = no
|
||||
recycle:keeptree = no
|
||||
recycle:touch = yes
|
||||
recycle:exclude = *.tmp,*.temp,*.o,*.obj,~$*
|
||||
{% endif %}
|
||||
{% if share.protocols.smb.full_audit %}
|
||||
full_audit:success=mkdir rmdir open opendir close closedir rename unlink
|
||||
full_audit:failure=mkdir rmdir open opendir close closedir rename unlink connect disconnect
|
||||
full_audit:prefix=%u|%D|%I|%M|%S
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
Reference in New Issue
Block a user