diff --git a/roles/nextcloud_instance/readme.md b/roles/nextcloud_instance/readme.md index fad10e6244a0f95b1ac410765d8552a7faea9317..c4034cfcecb6f80609920c5820a6011f00f286bd 100644 --- a/roles/nextcloud_instance/readme.md +++ b/roles/nextcloud_instance/readme.md @@ -1,4 +1,4 @@ - +# Nextcloud ## Create a volume diff --git a/roles/nextcloud_instance/tasks/alias_create.yml b/roles/nextcloud_instance/tasks/alias_create.yml new file mode 100644 index 0000000000000000000000000000000000000000..53790a737398e14b84d341c85f1ba0120b10a573 --- /dev/null +++ b/roles/nextcloud_instance/tasks/alias_create.yml @@ -0,0 +1,57 @@ +--- +- name: Alias_create + block: + - name: "template {{ rev_proxy }}_nextcloud_alias.j2 {{ app_instance_id }}" + template: + src: "{{ rev_proxy }}_nextcloud_alias.j2" + dest: "/etc/{{ rev_proxy }}/sites-available/{{ app_instance_id }}_alias_{{ a_domain }}.conf" + tags: + - rev_proxy + - nc_alias_create + + - name: "enable site for {{ a_domain }}" + file: + state: link + path: "/etc/{{ rev_proxy }}/sites-enabled/{{ app_instance_id }}_alias_{{ a_domain }}.conf" + src: "/etc/{{ rev_proxy }}/sites-available/{{ app_instance_id }}_alias_{{ a_domain }}.conf" + tags: + - nc_alias_create + + - name: "test certificate presence" + stat: + path: "{{ letsencrypt_cert_root }}/{{ a_domain | quote }}" + register: cert + tags: + - nc_alias_create + + - name: "stop nginx" + service: name=nginx state=stopped + when: (rev_proxy == "nginx") and not (cert.stat.exists) + tags: + - nc_alias_create + + - name: "letsencrypt certificate for {{ a_domain }}" + command: "certbot certonly --standalone --agree-tos -n -m {{ base_postmaster | mandatory }} -d {{ a_domain | quote }}" + when: not (cert.stat.exists) + tags: + - nc_alias_create + + - name: "start nginx" + service: name=nginx state=started + when: (rev_proxy == "nginx") and not (cert.stat.exists) + tags: + - nc_alias_create + + - name: "Add alias to Nextcloud configuration" + shell: "/usr/bin/php{{ php_version }} {{ app_instance_root }}/occ config:system:set trusted_domains {{ inc }} --value=\"{{ a_domain }}\"" + become_user: "www-data" + tags: + - nc_alias_create + + - name: "Define new disk structure" + set_fact: + inc: "{{ inc + 1 }}" + tags: + - nc_alias_create + tags: + - nc_alias_create diff --git a/roles/nextcloud_instance/tasks/install.yml b/roles/nextcloud_instance/tasks/install.yml index 5153d5cd52286ac118ae76190d957175919c2efe..84a809f67f0482264b32754a8b9b58dcfd0ddd44 100644 --- a/roles/nextcloud_instance/tasks/install.yml +++ b/roles/nextcloud_instance/tasks/install.yml @@ -127,4 +127,19 @@ - name: Set up monit import_role: - name: _app_monit \ No newline at end of file + name: _app_monit + +# Ajout des alias + - name: "Define new disk structure" + set_fact: + inc: 1 + tags: + - nc_alias_create + + - name: Add alias domains + include_tasks: alias_create.yml + loop: "{{ alias_domains | default([]) }}" + loop_control: + loop_var: a_domain + tags: + - nc_alias_create diff --git a/roles/nextcloud_instance/tasks/main.yml b/roles/nextcloud_instance/tasks/main.yml index dd92f23396f493b2ab87d31531034c64e348d469..c8c27d2d12d01fe7a4c75a553fbad36d193a197c 100644 --- a/roles/nextcloud_instance/tasks/main.yml +++ b/roles/nextcloud_instance/tasks/main.yml @@ -17,4 +17,4 @@ - import_role: name: _app_restore_instance - when: app_run == 'restore' + when: app_run == 'restore' \ No newline at end of file diff --git a/roles/nextcloud_instance/tasks/uninstall.yml b/roles/nextcloud_instance/tasks/uninstall.yml index ad8c299677a514e4b4cc61d425de7466011b1fb2..ef6edc8cee44591742219ca890b535a556811ef9 100644 --- a/roles/nextcloud_instance/tasks/uninstall.yml +++ b/roles/nextcloud_instance/tasks/uninstall.yml @@ -51,3 +51,32 @@ state: absent path: "/etc/{{ rev_proxy }}/sites-enabled/{{ app_instance_id }}.conf" notify: reload {{ rev_proxy }} nextcloud_instance + + - name: remove alias domains + block: + - name: "test certificate presence" + stat: + path: "{{ letsencrypt_cert_root }}/{{ a_domain | quote }}" + register: cert + tags: + - revoke_certificate + loop: "{{ alias_domain | default([]) }}" + loop_control: + loop_var: a_domain + - name: "revoke and delete certificate for {{ a_domain }}" + command: "certbot revoke --delete-after-revoke --cert-path /etc/letsencrypt/live/{{ a_domain }}/fullchain.pem" + when: cert.stat.exists + tags: + - revoke_certificate + loop: "{{ alias_domain | default([]) }}" + loop_control: + loop_var: a_domain + - name: "disable site for {{ app_domain }}" + file: + state: absent + path: "/etc/{{ rev_proxy }}/sites-available/{{ app_instance_id }}_alias_{{ a_domain }}.conf" + notify: reload {{ rev_proxy }} nextcloud_instance + loop: "{{ alias_domain | default([]) }}" + loop_control: + loop_var: a_domain + diff --git a/roles/nextcloud_instance/templates/nextcloud_app_install.j2 b/roles/nextcloud_instance/templates/nextcloud_app_install.j2 index 3ecf1479aaeca8910d164dcce68f8a427dcf4806..d6b26eb51a5e942f95377c694b085421776b6d8e 100644 --- a/roles/nextcloud_instance/templates/nextcloud_app_install.j2 +++ b/roles/nextcloud_instance/templates/nextcloud_app_install.j2 @@ -12,6 +12,14 @@ sudo -u www-data php occ maintenance:install \ --admin-pass "{{ nextcloud_default_password | mandatory }}" sudo -u www-data php occ config:system:set trusted_domains 0 --value="{{ app_domain }}" + +{% if alias_domain is defined %} +{% set inc = 1 %} +{% for domain_t in alias_domain %} +sudo -u www-data php occ config:system:set trusted_domains {{ inc }} --value="{{ domain_t }}" +{% set inc = inc + 1 %} +{% endif %} + sudo -u www-data php occ config:system:set overwrite.cli.url --value="https://{{ app_domain }}" sudo -u www-data php occ config:system:set redis host port diff --git a/roles/nextcloud_instance/templates/nginx_nextcloud_alias.j2 b/roles/nextcloud_instance/templates/nginx_nextcloud_alias.j2 new file mode 100644 index 0000000000000000000000000000000000000000..f56194a1ec341e7f3d97afa854b8b6dc8a90cb96 --- /dev/null +++ b/roles/nextcloud_instance/templates/nginx_nextcloud_alias.j2 @@ -0,0 +1,156 @@ +upstream php-handler{{ app_instance_id }} { + #server 127.0.0.1:9000; + server unix:/var/run/php/php{{ php_version }}-fpm.sock; + #server unix:/var/run/php5-fpm.sock; +} + +map $http_user_agent $log_ua { + ~Monit 0; + default 1; +} + +server { + listen 80; + listen [::]:80; + server_name {{ a_domain | mandatory }}; + # enforce https + return 301 https://$server_name$request_uri; +} + +server { + + # Both IpV6 and IpV4 + # + listen 443 ssl http2; + listen [::]:443 ssl http2; + + server_name {{ a_domain | mandatory }}; + + ssl_certificate /etc/letsencrypt/live/{{ a_domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ a_domain }}/privkey.pem; + + # Add headers to serve security related headers + # Before enabling Strict-Transport-Security headers please read into this + # topic first. + # add_header Strict-Transport-Security "max-age=15768000; + # includeSubDomains; preload;"; + # + # WARNING: Only add the preload option once you read about + # the consequences in https://hstspreload.org/. This option + # will add the domain to a hardcoded list that is shipped + # in all major browsers and getting removed from this list + # could take several months. + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + add_header Strict-Transport-Security "max-age=15768000"; + add_header Referrer-Policy no-referrer; + add_header X-Frame-Options "SAMEORIGIN" always; + + # Path to the root of your installation + root {{ app_instance_root }}/; + + access_log {{ www_log | mandatory }}/{{ app_instance_id }}/access.log combined if=$log_ua; + error_log {{ www_log | mandatory }}/{{ app_instance_id }}/error.log; + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Make a regex exception for `/.well-known` so that clients can still + # access it despite the existence of the regex rule + # `location ~ /(\.|autotest|...)` which would otherwise handle requests + # for `/.well-known`. + location ^~ /.well-known { + # The following 6 rules are borrowed from `.htaccess` + + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + # Anything else is dynamically handled by Nextcloud + location ^~ /.well-known { return 301 /index.php$uri; } + + try_files $uri $uri/ =404; + } + + # 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; + + # Uncomment if your server is build with the ngx_pagespeed module + # This module is currently not supported. + #pagespeed off; + + location / { + rewrite ^ /index.php$uri; + } + + 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/.+|ocs-provider/.+)\.php(?:$|/) { + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param HTTPS on; + #Avoid sending the security headers twice + fastcgi_param modHeadersAvailable true; + fastcgi_param front_controller_active true; + fastcgi_pass php-handler{{ app_instance_id }}; + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + } + + location ~ ^/(?:updater|ocs-provider)(?:$|/) { + try_files $uri/ =404; + index index.php; + } + + # Adding the cache control header for js and css files + # Make sure it is BELOW the PHP block + location ~ \.(?:css|js|woff|svg|gif)$ { + try_files $uri /index.php$uri$is_args$args; + add_header Cache-Control "public, max-age=15778463"; + # Add headers to serve security related headers (It is intended to + # have those duplicated to the ones above) + # Before enabling Strict-Transport-Security headers please read into + # this topic first. + # add_header Strict-Transport-Security "max-age=15768000; + # includeSubDomains; preload;"; + # + # WARNING: Only add the preload option once you read about + # the consequences in https://hstspreload.org/. This option + # will add the domain to a hardcoded list that is shipped + # in all major browsers and getting removed from this list + # could take several months. + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + # Optional: Don't log access to assets + access_log off; + } + + location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ { + try_files $uri /index.php$uri$is_args$args; + # Optional: Don't log access to other assets + access_log off; + } +} \ No newline at end of file