Role to configure nextcloud with LDAP User backend. First test passed. New modules: - occ: set coniguration values using `php occ` nextcloud command-line tool.python3
@ -0,0 +1,36 @@ | |||||
#!/bin/bash | |||||
# wrapper for conditional setting of nextcloud occ variables | |||||
# derived from ansible-openwrt | |||||
# parameters are command, key, value | |||||
source ${1} | |||||
logger occ $(cat ${1}) | |||||
unquoted_key="$(echo $key | sed -e s/\'//g)" | |||||
unquoted_value="$(echo $value | sed -e s/\'//g)" | |||||
# Hardcoded | |||||
cd /opt/nextcloud | |||||
# test if we need to apply a change | |||||
case "$command" in | |||||
'config:app:set') | |||||
[ "$(sudo -u www-data php occ config:app:get $unquoted_key)" = "$unquoted_value" ] | |||||
changed=$? | |||||
;; | |||||
'config:system:set') | |||||
[ "$(sudo -u www-data php occ config:system:get $unquoted_key)" = "$unquoted_value" ] | |||||
changed=$? | |||||
;; | |||||
esac | |||||
if [ $changed -eq 0 ] | |||||
then | |||||
echo -n '{"changed": false}' | |||||
else | |||||
if [ -z "${_ansible_check_mode}" -o "${_ansible_check_mode}" = "False" ] | |||||
then | |||||
logger occ $(sudo -u www-data php occ "${command}" ${unquoted_key} --value="${unquoted_value}") | |||||
fi | |||||
echo -n '{"changed": true, "msg": "executed sudo -u www:data php occ '${command}' '${unquoted_key}' --value='${value}'"}' | |||||
fi |
@ -0,0 +1,25 @@ | |||||
--- | |||||
- hosts: 'cloud' | |||||
gather_facts: false | |||||
tasks: | |||||
- import_role: name='lxc_guest' | |||||
vars: | |||||
vm_name: '{{ inventory_hostname }}' | |||||
vm_size: '4G' | |||||
vg_name: '{{ hostvars[ansible_lxc_host]["vg_name"] }}' | |||||
delegate_to: '{{ ansible_lxc_host }}' | |||||
- set_fact: ansible_connection='ssh_lxc' | |||||
- setup: | |||||
- import_role: name='ssh_server' | |||||
- set_fact: ansible_connection='ssh' | |||||
- hosts: 'cloud' | |||||
roles: | |||||
- role: 'dns_record' | |||||
- role: 'reverse_proxy' | |||||
hostname: 'cloud' | |||||
- role: 'nextcloud' | |||||
- hosts: 'status' | |||||
roles: | |||||
- role: 'icinga2-monitoring' |
@ -0,0 +1,5 @@ | |||||
--- | |||||
server_fqdn: '{{ ansible_hostname }}.{{ domain }}' | |||||
ldap_server: 'ldap1.dmz.{{ domain }}' | |||||
ldap_basedn: 'dc={{ domain.replace(".", ",dc=") }}' | |||||
... |
@ -0,0 +1,22 @@ | |||||
# | |||||
# LDAP Defaults | |||||
# | |||||
# See ldap.conf(5) for details | |||||
# This file should be world readable but not world writable. | |||||
#BASE dc=example,dc=com | |||||
#URI ldap://ldap.example.com ldap://ldap-master.example.com:666 | |||||
#SIZELIMIT 12 | |||||
#TIMELIMIT 15 | |||||
#DEREF never | |||||
# TLS certificates (needed for GnuTLS) | |||||
TLS_CACERT /etc/ldap/root_ca.crt | |||||
#TLS_CERT /etc/ldap/ldap.crt | |||||
#TLS_KEY /etc/ldap/ldap.key | |||||
# TLSv1.3 Only | |||||
TLS_CIPHER_SUITE SECURE:-VERS-ALL:+VERS-TLS1.3 | |||||
@ -0,0 +1,4 @@ | |||||
--- | |||||
dependencies: | |||||
- role: nginx | |||||
@ -0,0 +1,195 @@ | |||||
- name: 'install requirements' | |||||
apt: | |||||
pkg: | |||||
- 'sudo' | |||||
- 'bzip2' | |||||
- 'php7.3-fpm' | |||||
- 'php7.3-common' | |||||
- 'php7.3-xml' | |||||
- 'php7.3-gd' | |||||
- 'php7.3-json' | |||||
- 'php7.3-mbstring' | |||||
- 'php7.3-zip' | |||||
- 'php7.3-pgsql' | |||||
- 'php7.3-ldap' | |||||
- 'php7.3-curl' | |||||
- 'php7.3-intl' | |||||
- 'php7.3-bz2' | |||||
#- 'php7.3.-imagick' | |||||
#- 'ffmpeg' | |||||
- 'postgresql' | |||||
- 'postgresql-contrib' | |||||
- 'python3-psycopg2' | |||||
- 'ca-certificates' | |||||
state: 'present' | |||||
update_cache: true | |||||
cache_valid_time: 3600 | |||||
tags: | |||||
- 'packages' | |||||
- block: | |||||
- name: 'create nextcloud DB' | |||||
postgresql_db: | |||||
name: 'nextcloud' | |||||
- name: 'create nextcloud DB user' | |||||
postgresql_user: | |||||
name: 'www-data' | |||||
db: 'nextcloud' | |||||
priv: 'ALL' | |||||
become: true | |||||
become_method: 'su' | |||||
become_user: 'postgres' | |||||
- name: 'download latest nextcloud' | |||||
get_url: | |||||
url: 'https://download.nextcloud.com/server/releases/nextcloud-18.0.3.tar.bz2' | |||||
dest: '/opt/nextcloud.tar.bz2' | |||||
register: 'new_download' | |||||
tags: | |||||
- 'packages' | |||||
- name: 'unpack nextcloud' | |||||
unarchive: | |||||
src: '/opt/nextcloud.tar.bz2' | |||||
dest: '/opt' | |||||
owner: 'www-data' | |||||
group: 'www-data' | |||||
copy: no | |||||
when: new_download.changed | |||||
tags: | |||||
- 'packages' | |||||
- name: 'create nextcloud data folder' | |||||
file: | |||||
path: '/opt/nextcloud_data' | |||||
owner: 'www-data' | |||||
group: 'www-data' | |||||
state: 'directory' | |||||
- name: 'create nginx configuration' | |||||
template: | |||||
src: 'nextcloud.conf.j2' | |||||
dest: '/etc/nginx/locations/{{ server_fqdn }}/nextcloud.conf' | |||||
notify: 'restart nginx' | |||||
- import_tasks: 'occ.yaml' | |||||
vars: | |||||
occ_args: '--no-warnings status --output json' | |||||
ignore_changes: true | |||||
- set_fact: | |||||
installed: '{{ occ_out.installed }}' | |||||
- block: | |||||
- name: 'create random root password' | |||||
gen_passwd: length=20 | |||||
register: 'password' | |||||
- set_fact: | |||||
initial_root_password: '{{ new_passwd.passwd }}' | |||||
- name: 'store root password plaintext' | |||||
copy: | |||||
content: '{{ initial_root_password }}' | |||||
dest: '/etc/nextcloud.secret' | |||||
- fail: | |||||
msg: >- | |||||
Warning! First Install and `initial_root_password` not provided. | |||||
Random password generated and stored in /etc/nextcloud.secret. | |||||
**WIPE AS SOON AS POSSIBLE** | |||||
failed_when: false | |||||
when: (initial_root_password is not defined) and (not installed) | |||||
- name: 'install nextcloud' | |||||
include_tasks: 'occ.yaml' | |||||
vars: | |||||
occ_args: >- | |||||
maintenance:install | |||||
--database 'pgsql' | |||||
--database-name 'nextcloud' | |||||
--database-host '/var/run/postgresql' | |||||
--database-user 'www-data' | |||||
--database-pass '' | |||||
--admin-pass '{{ initial_root_password }}' | |||||
--data-dir '/opt/nextcloud_data' | |||||
--no-interaction | |||||
nojson: true | |||||
when: not installed | |||||
- name: 'set trusted_domains' | |||||
occ: | |||||
command: 'config:system:set' | |||||
key: 'trusted_domains {{ idx }}' | |||||
value: '{{ item }}' | |||||
loop: | |||||
- 'localhost' | |||||
- '{{ server_fqdn }}' | |||||
loop_control: | |||||
index_var: idx | |||||
- name: 'update tls ca' | |||||
copy: | |||||
content: '{{ tls_root_ca }}' | |||||
dest: '/etc/ldap/root_ca.crt' | |||||
tags: | |||||
- 'tls_int' | |||||
- name: 'configure ldap client' | |||||
copy: | |||||
src: 'ldap.conf' | |||||
dest: '/etc/ldap/ldap.conf' | |||||
- name: 'enable user_ldap' | |||||
occ: | |||||
command: 'config:app:set' | |||||
key: 'user_ldap enabled' | |||||
value: 'yes' | |||||
tags: | |||||
- 'service_password' | |||||
- name: 'configure user_ldap' | |||||
occ: | |||||
command: 'config:app:set' | |||||
key: 'user_ldap s01{{ item.key }}' | |||||
value: '{{ item.value }}' | |||||
loop: '{{ ldap_settings|dict2items }}' | |||||
vars: | |||||
ldap_settings: | |||||
has_memberof_filter_support: '1' | |||||
ldap_host: '{{ ldap_server }}' | |||||
ldap_port: '389' | |||||
ldap_dn: 'cn={{ ansible_hostname }},ou=Server,{{ ldap_basedn }}' | |||||
ldap_base: 'ou=People,{{ ldap_basedn }}' | |||||
ldap_base_users: 'ou=People,{{ ldap_basedn }}' | |||||
ldap_base_groups: 'ou=Groups,{{ ldap_basedn }}' | |||||
ldap_login_filter: '(&(cn=%uid)(authorizedService=nextcloud))' | |||||
ldap_user_filter: '(authorizedService=nextcloud)' | |||||
ldap_attributes_for_user_search: 'cn' | |||||
ldap_attributes_for_group_search: 'cn' | |||||
ldap_email_attr: 'mail' | |||||
ldap_tls: '1' | |||||
ldap_experienced_admin: '1' | |||||
ldap_configuration_active: '1' | |||||
- name: 'generate nextcloud ldap password' | |||||
gen_passwd: 'length=32' | |||||
register: 'new_passwd' | |||||
tags: | |||||
- 'service_password' | |||||
- name: 'set nextcloud ldap password in ldap' | |||||
delegate_to: 'localhost' | |||||
ldap_passwd: | |||||
dn: 'cn={{ ansible_hostname }},ou=Server,{{ ldap_basedn }}' | |||||
passwd: '{{ new_passwd.passwd }}' | |||||
server_uri: 'ldap://{{ ldap_server }}' | |||||
start_tls: true | |||||
bind_dn: '{{ ldap_admin_dn }}' | |||||
bind_pw: '{{ ldap_admin_pw }}' | |||||
tags: | |||||
- 'service_password' | |||||
- import_tasks: 'occ.yaml' | |||||
vars: | |||||
occ_args: 'ldap:set-config s01 ldapAgentPassword {{ new_passwd.passwd }}' | |||||
nojson: true | |||||
tags: | |||||
- 'service_password' | |||||
... |
@ -0,0 +1,13 @@ | |||||
--- | |||||
- command: 'php occ {{ occ_args }}' | |||||
become: true | |||||
become_user: 'www-data' | |||||
args: | |||||
chdir: '/opt/nextcloud' | |||||
register: occ_out_raw | |||||
changed_when: occ_out_raw.changed and (not ignore_changes|default(false)) | |||||
- set_fact: | |||||
occ_out: '{{ occ_out_raw.stdout | from_json }}' | |||||
when: nojson is not defined | |||||
... |
@ -0,0 +1,22 @@ | |||||
# | |||||
# LDAP Defaults | |||||
# | |||||
# See ldap.conf(5) for details | |||||
# This file should be world readable but not world writable. | |||||
#BASE dc=example,dc=com | |||||
#URI ldap://ldap.example.com ldap://ldap-master.example.com:666 | |||||
#SIZELIMIT 12 | |||||
#TIMELIMIT 15 | |||||
#DEREF never | |||||
# TLS certificates (needed for GnuTLS) | |||||
TLS_CACERT /etc/ldap/ca.crt | |||||
#TLS_CERT /etc/ldap/ldap.crt | |||||
#TLS_KEY /etc/ldap/ldap.key | |||||
# TLSv1.3 Only | |||||
TLS_CIPHER_SUITE SECURE:-VERS-ALL:+VERS-TLS1.3 | |||||
@ -0,0 +1,90 @@ | |||||
add_header Referrer-Policy "no-referrer" always; | |||||
add_header X-Content-Type-Options "nosniff" always; | |||||
add_header X-Download-Options "noopen" always; | |||||
add_header X-Frame-Options "SAMEORIGIN" always; | |||||
add_header X-Permitted-Cross-Domain-Policies "none" always; | |||||
add_header X-Robots-Tag "none" always; | |||||
add_header X-XSS-Protection "1; mode=block" always; | |||||
fastcgi_hide_header X-Powered-By; | |||||
root /opt/nextcloud; | |||||
location = /robots.txt { | |||||
allow all; | |||||
log_not_found off; | |||||
access_log off; | |||||
} | |||||
location = /.well-known/carddav { | |||||
return 301 $scheme://$host:$server_port/remote.php/dav; | |||||
} | |||||
location = /.well-known/caldav { | |||||
return 301 $scheme://$host:$server_port/remote.php/dav; | |||||
} | |||||
# set max upload size | |||||
client_max_body_size 512M; | |||||
fastcgi_buffers 64 4K; | |||||
# Enable gzip but do not remove ETag headers | |||||
gzip on; | |||||
gzip_vary on; | |||||
gzip_comp_level 4; | |||||
gzip_min_length 256; | |||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; | |||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; | |||||
location / { | |||||
rewrite ^ /index.php; | |||||
} | |||||
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ { | |||||
deny all; | |||||
} | |||||
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) { | |||||
deny all; | |||||
} | |||||
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) { | |||||
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$; | |||||
set $path_info $fastcgi_path_info; | |||||
try_files $fastcgi_script_name =404; | |||||
include fastcgi_params; | |||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |||||
fastcgi_param PATH_INFO $path_info; | |||||
fastcgi_param HTTPS on; | |||||
# Avoid sending the security headers twice | |||||
fastcgi_param modHeadersAvailable true; | |||||
# Enable pretty urls | |||||
fastcgi_param front_controller_active true; | |||||
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; | |||||
fastcgi_intercept_errors on; | |||||
fastcgi_request_buffering off; | |||||
} | |||||
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) { | |||||
try_files $uri/ =404; | |||||
index index.php; | |||||
} | |||||
# Adding the cache control header for js, css and map files | |||||
# Make sure it is BELOW the PHP block | |||||
location ~ \.(?:css|js|woff2?|svg|gif|map)$ { | |||||
try_files $uri /index.php$request_uri; | |||||
add_header Cache-Control "public, max-age=15778463"; | |||||
add_header Referrer-Policy "no-referrer" always; | |||||
add_header X-Content-Type-Options "nosniff" always; | |||||
add_header X-Download-Options "noopen" always; | |||||
add_header X-Frame-Options "SAMEORIGIN" always; | |||||
add_header X-Permitted-Cross-Domain-Policies "none" always; | |||||
add_header X-Robots-Tag "none" always; | |||||
add_header X-XSS-Protection "1; mode=block" always; | |||||
access_log off; | |||||
} | |||||
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ { | |||||
try_files $uri /index.php$request_uri; | |||||
access_log off; | |||||
} |