diff --git a/defaults/main.yml b/defaults/main.yml index c5182f9..d4f592d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,27 +1,54 @@ --- -nextcloud_version: 21.0.4 -nextcloud_dist_filename: 'nextcloud-{{ nextcloud_version }}.tar.bz2' -nextcloud_download_url: 'https://download.nextcloud.com/server/releases/{{ nextcloud_dist_filename }}' -nextcloud_local_redis: True +nextcloud_major_version: 22 +nextcloud_version: '{{ nextcloud_major_version }}.0.4' +# Choose from releases, prereleases, daily +nextcloud_release_channel: 'releases' +nextcloud_get_latest_stable: True +nextcloud_user: nextcloud +nextcloud_timezone: 'Europe/Rome' +nextcloud_redis_cache_enabled: True +nextcloud_local_redis: '{{ nextcloud_redis_cache_enabled }}' +nextcloud_redis_params: + - { name: 'memcache.locking', value: '\OC\Memcache\Redis' } + - { name: 'memcache.distributed', value: '\OC\Memcache\Redis' } + - { name: 'redis host', value: 'localhost' } + - { name: 'redis dbindex', value: '0'} + - { name: 'redis timeout', value: '1.5'} +nextcloud_apcu_cache_enabled: True nextcloud_local_memcache: False +nextcloud_mail_enabled: True +nextcloud_mail_sendmail_mode: True +nextcloud_mail_smtp_settings: + - { name: 'mail_sendmailmode', value: 'smtp' } + - { name: 'mail_smtpsecure', value: 'tls' } + - { name: 'mail_smtpauth', value: 1 } + - { name: 'mail_from_address', value: 'nextcloud@localdomain' } + - { name: 'mail_domain', value: 'localdomain' } + - { name: 'mail_smtphost', value: 'localhost' } + - { name: 'mail_smtpport', value: '587' } + - { name: 'mail_smtpauthtype', value: 'LOGIN' } + - { name: 'mail_smtpname', value: '' } + - { name: 'mail_smtppassword', value: '' } nextcloud_local_postgresql: True nextcloud_web_basedir: /var/www nextcloud_web_root: '{{ nextcloud_web_basedir }}/nextcloud' nextcloud_data_base_dir: /srv nextcloud_data_dir: '{{ nextcloud_data_base_dir }}/nextcloud/data' nextcloud_oc_dir: '{{ nextcloud_data_base_dir }}/nextcloud/oc_keys' +nextcloud_log_timezone: '{{ nextcloud_timezone }}' nextcloud_log_directory: /var/log/nextcloud nextcloud_log_backend: file # debug|info|warning|error|fatal nextcloud_log_level: info nextcloud_log_rotation_frequency: weekly nextcloud_log_rotation: 52 +nextcloud_audit_log_enabled: True +nextcloud_encryption_enabled: True nextcloud_servername: '{{ ansible_fqdn }}' nextcloud_servernames: - { webroot: '{{ nextcloud_web_root }}', id: 1, name: '{{ nextcloud_servername }}' } - -nextcloud_user: nextcloud - +nextcloud_trusted_proxies: [] +# - { proxy_ip: '127.0.0.1/8', proxy_id: 0 } nextcloud_db: pgsql nextcloud_db_host: localhost nextcloud_db_name: nextcloud @@ -31,10 +58,11 @@ nextcloud_db_user: nextcloud_u nextcloud_admin_user: nc_admin #nextcloud_admin_u_pwd: 'Use a vault file' -nextcloud_encryption_enabled: True nextcloud_ldap_auth: False nextcloud_phpfpm_default_memory_limit: "512M" php_global_settings: '{{ nextcloud_php_global_settings }}' phpfpm_pools: '{{ nextcloud_phpfpm_pools }}' -nextcloud_phpfpm_listen_on_socket: True \ No newline at end of file +nextcloud_phpfpm_listen_on_socket: True + +nextcloud_nginx_max_body_size: 512M diff --git a/tasks/nextcloud-config.yml b/tasks/nextcloud-config.yml index b1cc7d3..f78dd7f 100644 --- a/tasks/nextcloud-config.yml +++ b/tasks/nextcloud-config.yml @@ -1,43 +1,120 @@ --- - block: + - name: Create a directory used by the 'creates' rules + file: + dest: '{{ nextcloud_data_dir }}/.ht_setup' + state: directory + - name: Configure the nextcloud instance - shell: cd {{ item.doc_root }} && php occ maintenance:install --database="{{ nextcloud_db }}" --database-host "{{ nextcloud_db_host }}" --database-name "{{ nextcloud_db_name }}" --database-user "{{ nextcloud_db_user }}" --database-pass "{{ nextcloud_db_pwd }}" --admin-user "{{ nextcloud_admin_user }}" --admin-pass "{{ nextcloud_admin_u_pwd }}" --data-dir={{ nextcloud_data_dir }} && mkdir {{ nextcloud_data_dir }}/.ht_setup && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_setup + shell: > + cd {{ item.doc_root }} && php occ maintenance:install + --database="{{ nextcloud_db }}" + --database-host "{{ nextcloud_db_host }}" + --database-name "{{ nextcloud_db_name }}" + --database-user "{{ nextcloud_db_user }}" + --database-pass "{{ nextcloud_db_pwd }}" + --admin-user "{{ nextcloud_admin_user }}" + --admin-pass "{{ nextcloud_admin_u_pwd }}" + --data-dir={{ nextcloud_data_dir }} args: - creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_setup' + creates: '{{ item.doc_root }}/config/config.php' with_items: '{{ phpfpm_pools }}' - name: Set the trusted domains list - shell: cd {{ item.webroot }} && php occ config:system:set trusted_domains {{ item.id }} --value={{ item.name }} && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_trusted_domains_{{ item.id }} + shell: > + cd {{ item.webroot }} && php occ config:system:set trusted_domains {{ item.id }} + --value={{ item.name }} + && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_trusted_domains_{{ item.id }} args: creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_trusted_domains_{{ item.id }}' with_items: '{{ nextcloud_servernames }}' + - name: Set the trusted proxies + shell: > + php occ config:system:set trusted_proxies {{ item.proxy_id }} --value={{ item.proxy_ip }} + args: + chdir: '{{ nextcloud_web_root }}' + with_items: '{{ nextcloud_trusted_proxies }}' + + - name: Setup the email configuration with SMTP + shell: > + php occ config:system:set {{ item.name }} --value={{ item.id }} + args: + chdir: '{{ nextcloud_web_root }}' + loop: '{{ nextcloud_mail_smtp_settings }}' + when: + - nextcloud_mail_enabled + - not nextcloud_mail_sendmail_mode + + - name: Setup the email configuration with sendmail mode + shell: > + php occ config:system:set mail_sendmailmode --value=sendmail + args: + chdir: '{{ nextcloud_web_root }}' + when: + - nextcloud_mail_enabled + - nextcloud_mail_sendmail_mode + - name: Set the nextcloud log file path - shell: cd {{ item.doc_root }} && php occ log:file --file {{ nextcloud_log_directory }}/nextcloud.log && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_logfile + shell: > + cd {{ item.doc_root }} + && php occ log:file --file {{ nextcloud_log_directory }}/nextcloud.log + && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_logfile args: creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_logfile' with_items: '{{ phpfpm_pools }}' - name: Set the audit log file path - shell: cd {{ item.doc_root }} && php occ config:app:set admin_audit logfile --value={{ nextcloud_log_directory }}/audit.log && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_logfile + shell: > + cd {{ item.doc_root }} + && php occ config:app:set admin_audit logfile --value={{ nextcloud_log_directory }}/audit.log + && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_auditfile args: creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_auditfile' with_items: '{{ phpfpm_pools }}' + # - name: Enable the audit log even if the loglevel is <= 1 + # shell: > + # cd {{ item.doc_root }} + # && php occ config:system:set log.condition apps --value="admin_audit" + # && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_auditlog + # args: + # creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_auditlog' + # with_items: '{{ phpfpm_pools }}' + # when: nextcloud_audit_log_enabled + - name: Set the log level - shell: cd {{ item.doc_root }} && php occ log:manage --level {{ nextcloud_log_level }} && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_level + shell: > + cd {{ item.doc_root }} + && php occ log:manage --level {{ nextcloud_log_level }} + && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_level + args: + creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_level' + with_items: '{{ phpfpm_pools }}' + + - name: Set the log timezone + shell: > + cd {{ item.doc_root }} + && php occ config:system:set logtimezone --value="{{ nextcloud_log_timezone }}" + && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_level args: creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_level' with_items: '{{ phpfpm_pools }}' - name: Set the log backend - shell: cd {{ item.doc_root }} && php occ log:manage --backend {{ nextcloud_log_backend }} && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_backend + shell: > + cd {{ item.doc_root }} + && php occ log:manage --backend {{ nextcloud_log_backend }} + && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_backend args: creates: '{{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_log_backend' with_items: '{{ phpfpm_pools }}' - name: Setup the cron configuration - shell: cd {{ item.webroot }} ; php occ background:cron ; touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_cron + shell: > + cd {{ item.webroot }} + && php occ background:cron + && touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_cron args: creates: 'touch {{ nextcloud_data_dir }}/.ht_setup/ht_nextcloud_cron' with_items: '{{ nextcloud_servernames }}' @@ -79,12 +156,48 @@ when: not phpfpm_create_users - name: Activate global encryption - shell: cd {{ item.doc_root }} ; php occ app:enable encryption ; php occ encryption:enable ; php occ encryption:enable-master-key ; php occ encryption:change-key-storage-root {{ nextcloud_oc_dir }} ; touch {{ nextcloud_oc_dir }}/.ht_nextcloud_oc + shell: > + cd {{ item.doc_root }} + && php occ app:enable encryption + && php occ encryption:enable + && php occ encryption:enable-master-key + && php occ encryption:change-key-storage-root {{ nextcloud_oc_dir }} + && touch {{ nextcloud_oc_dir }}/.ht_nextcloud_oc args: creates: '{{ nextcloud_oc_dir }}/.ht_nextcloud_oc' - with_items: '{{ phpfpm_pools }}' + loop: '{{ phpfpm_pools }}' become: True become_user: '{{ nextcloud_user }}' when: nextcloud_encryption_enabled tags: [ 'nextcloud', 'nextcloud_config', 'nextcloud_config_oc' ] + +- name: Redis cache management + block: + - name: Enable file locking + shell: > + cd {{ nextcloud_web_root }} + && php occ config:system:set --type boolean filelocking.enabled --value="true" + + - name: Configure the Redis cache + shell: > + cd {{ nextcloud_web_root }} + && php occ config:system:set {{ item.name }} --value="{{ item.value }}" + loop: '{{ nextcloud_redis_params }}' + + become: True + become_user: '{{ nextcloud_user }}' + when: nextcloud_redis_cache_enabled + tags: [ 'nextcloud', 'nextcloud_config', 'nextcloud_config_cache' ] + +- name: APCu cache management + block: + - name: Configure the Redis cache + shell: > + cd {{ nextcloud_web_root }} + && php occ config:system:set memcache.distributed --value="\OC\Memcache\APCu" + + become: True + become_user: '{{ nextcloud_user }}' + when: nextcloud_apcu_cache_enabled + tags: [ 'nextcloud', 'nextcloud_config', 'nextcloud_config_cache' ] diff --git a/tasks/nextcloud-install.yml b/tasks/nextcloud-install.yml index 325d950..82826f7 100644 --- a/tasks/nextcloud-install.yml +++ b/tasks/nextcloud-install.yml @@ -45,6 +45,16 @@ loop: '{{ phpfpm_pools }}' when: not phpfpm_create_users + - name: Set the nextcloud archive filename when we want the latest stable + set_fact: + nextcloud_dist_filename: '{{ nextcloud_dist_filename_prefix.latest }}.{{ nextcloud_archive_format }}' + when: nextcloud_get_latest_stable + + - name: Set the nextcloud archive filename when we do NOT want the latest stable + set_fact: + nextcloud_dist_filename: '{{ nextcloud_dist_filename_prefix[nextcloud_release_channel] }}.{{ nextcloud_archive_format }}' + when: not nextcloud_get_latest_stable + - name: Get nextcloud get_url: url={{ nextcloud_download_url }} dest=/srv/{{ nextcloud_dist_filename }} diff --git a/templates/nginx-virthost.conf.j2 b/templates/nginx-virthost.conf.j2 index 86ee5e1..baf3ce3 100644 --- a/templates/nginx-virthost.conf.j2 +++ b/templates/nginx-virthost.conf.j2 @@ -7,6 +7,7 @@ upstream php-handler { } server { + listen 80; server_name {{ item.nginx_servername }}; # enforce https location ~ /\.(?!well-known).* { @@ -53,6 +54,12 @@ server { # Path to the root of your installation root {{ item.doc_root }}; + location = / { + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + } + location = /robots.txt { allow all; log_not_found off; @@ -63,21 +70,30 @@ server { log_not_found off; access_log off; } - # The following 2 rules are only needed for the user_webfinger app. - # Uncomment it if you're planning to use this app. - #rewrite ^/.well-known/host-meta /public.php?service=host-meta last; - #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json - # last; + # 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 rules in this block are an adaptation of the rules + # in `.htaccess` that concern `/.well-known`. - location = /.well-known/carddav { - return 301 $scheme://$host/remote.php/dav; - } - location = /.well-known/caldav { - return 301 $scheme://$host/remote.php/dav; + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + location = /.well-known/acme-challenge { try_files $uri $uri/ =404; } + location = /.well-known/pki-validation { try_files $uri $uri/ =404; } + + # according to the documentation these two lines are not necessary, but version 21.0.0 will produce warnings in the overview setup check + location = /.well-known/webfinger { return 301 /nextcloud/index.php$uri; } + location = /.well-known/nodeinfo { return 301 /nextcloud/index.php$uri; } + + # Let Nextcloud's API for `/.well-known` URIs handle all other + # requests by passing them to the front-end controller. + return 301 /index.php$request_uri; } # set max upload size - client_max_body_size 512M; + client_max_body_size {{ nextcloud_nginx_max_body_size }}; fastcgi_buffers 64 4K; # Enable gzip but do not remove ETag headers @@ -92,28 +108,32 @@ server { # This module is currently not supported. #pagespeed off; - location / { - rewrite ^ /index.php; - } + # Rules borrowed from `.htaccess` to hide certain paths from clients + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } - location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ { - deny all; - } - location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) { - deny all; - } + # Ensure this block, which passes PHP files to the PHP process, is above the blocks + # which handle static assets (as seen below). If this block is not declared first, + # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` + # to the URI, resulting in a HTTP 500 error response. + location ~ \.php(?:$|/) { + # Required for legacy support + rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; + + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + set $path_info $fastcgi_path_info; - location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) { - fastcgi_split_path_info ^(.+\.php)(/.*)$; try_files $fastcgi_script_name =404; + include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param PATH_INFO $path_info; fastcgi_param HTTPS on; - #Avoid sending the security headers twice - fastcgi_param modHeadersAvailable true; - fastcgi_param front_controller_active true; + + fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice + fastcgi_param front_controller_active true; # Enable pretty urls fastcgi_pass php-handler; + fastcgi_intercept_errors on; fastcgi_request_buffering off; } @@ -125,30 +145,16 @@ server { # Adding the cache control header for js and css files # Make sure it is BELOW the PHP block - location ~ \.(?:css|js|woff|svg|gif|map)$ { + location ~ \.(?:css|js|svg|gif)$ { try_files $uri /index.php$request_uri; - 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 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; + expires 6M; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } - # Optional: Don't log access to assets - access_log off; + location ~ \.woff2?$ { + try_files $uri /index.php$request_uri; + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets } location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ { @@ -156,5 +162,16 @@ server { # Optional: Don't log access to other assets access_log off; } + + # Rule borrowed from `.htaccess` + location /remote { + return 301 /remote.php$request_uri; + } + + location / { + rewrite ^ /index.php; + } + + } diff --git a/vars/main.yml b/vars/main.yml index 6bb0af0..4380223 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -8,11 +8,17 @@ https_port: 443 php_version: 7.4 -nextcloud_dl_file_name: - latest: "{{ ['latest', nextcloud_version_major]|reject('undefined')|join('-') }}" - releases: "{{ ['nextcloud', nextcloud_version_full]|reject('undefined')|join('-') }}" - beta: "nextcloud-{{ [nextcloud_version_full, nextcloud_version_special]|reject('undefined')|join() }}" - daily: "nextcloud-{{ nextcloud_version_major|d('') }}-daily-{{ nextcloud_version_special|d('') }}" +# Pprereleases: "rc|beta" +# daily "YYYY-MM-DD" +nextcloud_version_suffix: "" +nextcloud_dist_filename_prefix: + latest: "latest-{{ nextcloud_major_version }}" + releases: "nextcloud-{{ nextcloud_version }}" + prereleases: "nextcloud-{{ nextcloud_version }}{{ nextcloud_version_special }}" + daily: "nextcloud-{{ nextcloud_major_version }}-daily-{{ nextcloud_version_suffix }}" +nextcloud_archive_format: 'tar.bz2' +nextcloud_download_url: 'https://download.nextcloud.com/server/{{ nextcloud_release_channel }}/{{ nextcloud_dist_filename }}' + nextcloud_php_required_packages: - 'php{{ php_version }}-gd' @@ -56,6 +62,7 @@ nextcloud_phpfpm_pools: app_context: '{{ phpfpm_default_context }}' user: '{{ phpfpm_default_user }}' group: '{{ phpfpm_default_group }}' + shell: '/bin/bash' listen: '{{ phpfpm_default_listen }}' allowed_clients: '{{ phpfpm_default_allowed_clients }}' pm: '{{ phpfpm_default_pm }}'