NextCloud

Implentation notes

  • Reverse proxy operation with https only mod_proxy. NextCloud won't do redirects to https in location headers. ProxyPassReverse must be used.

           - ProxyPassReverse http://www.electricbrain.com.au/nextcloud
     
  • NextCloud container environment variables

           - OVERWRITEHOST=www.electricbrain.com.au
           - OVERWRITEPROTOCOL=https
           - OVERWRITEWEBROOT=nextcloud

  • trusted_domains:
    For anyone else having trouble with this, when it's asking for a trusted domain, it's the domain you GO TO to access NextCloud...not where you're trying to access FROM
    https://forums.unraid.net/topic/77853-solved-nextcloud-access-through-untrusted-domain/
     
  • Using the occ command from within the container requires more memory for the script.
    • Get a shell inside the container
    • change the www-data user's shell: usermod --shell /bin/bash www-data
    • su - www-data
    • cd /var/www/html
    • php -d memory_limit=512M occ <command goes here>
    • change back to the root user: ctrl-d
    • usermod --shell /usr/sbin/nologin www-data

email plugin

  • Basic settings for email

  • Connection details for all electricbrain hosted accounts. Note that external accounts cannot be reached due to security restrictions placed on NextCloud.

CalDav calendar with iPhone connectivity

In order to get group calendaring going with CalDav connectivity from iPhone to NextCloud you first have to install the calendar component of NextCloud. Essentially it doesn't come enabled by default so it has to be downloaded from the NextCloud app store. There are lots of good web pages on how to do this.

Once it's loaded and operational, then each user has to create an "app password". Again there are lots of good pages on how to do that. In later versions of Nextcloud that functionality is rolled into the personal security section. It's important to save the password to your password vault as it's only ever displayed once.

When armed with the password it allows the app that uses it to login and bypass 2 factor authentication.

 

The next step is to modify the .htaccess file inside the NextCloud container. This is needed when your server is behind a reverse proxy server, as is the case here. What needs to happen is that a redirect has to occur between the iPhones enquiry to https://[your_site]/.well-known/caldav and Nexcloud's https://[your_site]/remote.php/dav/. Now this sounds quite simple, however since everything inside the DMZ happens on port 80, redirecting to port 443's encryption causes the http security protocol to drop and authentication you may have passed including userid and password (because this is a hackster path to steal your passwords). So any redirection originating on the DMZ has to be rejigged to HTTPS as being used outside of the DMZ - and the same connection can continue to be used. So it's necessary to modify .htaccess to acheieve this:

<IfModule mod_headers.c>
  <IfModule mod_setenvif.c>
    <IfModule mod_fcgid.c>
       SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
       RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
    </IfModule>
    <IfModule mod_proxy_fcgi.c>
       SetEnvIfNoCase Authorization "(.+)" HTTP_AUTHORIZATION=$1
    </IfModule>
    <IfModule mod_lsapi.c>
      SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
      RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
    </IfModule>
  </IfModule>

  <IfModule mod_env.c>
    # Add security and privacy related headers
    # Avoid doubled headers by unsetting headers in "onsuccess" table,
    # then add headers to "always" table: https://github.com/nextcloud/server/pull/19002

    <If "%{REQUEST_URI} =~ m#/login$#">
      # Only on the login page we need any Origin or Referer header set.
      Header onsuccess unset Referrer-Policy
      Header always set Referrer-Policy "same-origin"
    </If>
    <Else>
      Header onsuccess unset Referrer-Policy
      Header always set Referrer-Policy "no-referrer"
    </Else>

    Header onsuccess unset X-Content-Type-Options
    Header always set X-Content-Type-Options "nosniff"

    Header onsuccess unset X-Frame-Options
    Header always set X-Frame-Options "SAMEORIGIN"

    Header onsuccess unset X-Permitted-Cross-Domain-Policies
    Header always set X-Permitted-Cross-Domain-Policies "none"

    Header onsuccess unset X-Robots-Tag
    Header always set X-Robots-Tag "noindex, nofollow"

    Header onsuccess unset X-XSS-Protection
    Header always set X-XSS-Protection "1; mode=block"

    SetEnv modHeadersAvailable true
  </IfModule>

  # Add cache control for static resources
  <FilesMatch "\.(css|js|mjs|svg|gif|png|jpg|webp|ico|wasm|tflite)$">
    <If "%{QUERY_STRING} =~ /(^|&)v=/">
      Header set Cache-Control "max-age=15778463, immutable"
    </If>
    <Else>
      Header set Cache-Control "max-age=15778463"
    </Else>
  </FilesMatch>

  # Let browsers cache OTF and WOFF files for a week
  <FilesMatch "\.(otf|woff2?)$">
    Header set Cache-Control "max-age=604800"
  </FilesMatch>
</IfModule>

<IfModule mod_php.c>
  php_value mbstring.func_overload 0
  php_value default_charset 'UTF-8'
  php_value output_buffering 0
  <IfModule mod_env.c>
    SetEnv htaccessWorking true
  </IfModule>
</IfModule>

<IfModule mod_mime.c>
  AddType image/svg+xml svg svgz
  AddType application/wasm wasm
  AddEncoding gzip svgz
  # Serve ESM javascript files (.mjs) with correct mime type
  AddType text/javascript js mjs
</IfModule>

<IfModule mod_dir.c>
  DirectoryIndex index.php index.html
</IfModule>

<IfModule pagespeed_module>
  ModPagespeed Off
</IfModule>

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{HTTP_USER_AGENT} DavClnt
  RewriteRule ^$ /remote.php/webdav/ [L,R=302]
  RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
  RewriteRule ^\.well-known/carddav https://nextcloud.electricbrain.au/remote.php/dav/ [R=301,L]
  RewriteRule ^\.well-known/caldav https://nextcloud.electricbrain.au/remote.php/dav/ [R=301,L]
  RewriteRule ^remote/(.*) remote.php [QSA,L]
  RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
  RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
  RewriteRule ^ocm-provider/?$ index.php [QSA,L]
  RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
</IfModule>

# Clients like xDavv5 on Android, or Cyberduck, use chunked requests.
# When FastCGI or FPM is used with apache, requests arrive to Nextcloud without any content.
# This leads to the creation of empty files.
# The following directive will force the problematic requests to be buffered before being forwarded to Nextcloud.
# This way, the "Transfer-Encoding" header is removed, the "Content-Length" header is set, and the request content is proxied to Nextcloud.
# Here are more information about the issue:
#  - https://docs.cyberduck.io/mountainduck/issues/fastcgi/
#  - https://docs.nextcloud.com/server/latest/admin_manual/issues/general_troubleshooting.html#troubleshooting-webdav
<IfModule mod_setenvif.c>
  SetEnvIfNoCase Transfer-Encoding "chunked" proxy-sendcl=1
</IfModule>

# Apache disabled the sending of the server-side content-length header
# in their 2.4.59 patch updated which breaks some use-cases in Nextcloud.
# Setting ap_trust_cgilike_cl allows to bring back the usual behaviour.
# See https://bz.apache.org/bugzilla/show_bug.cgi?id=68973
<IfModule mod_env.c>
  SetEnv ap_trust_cgilike_cl
</IfModule>

AddDefaultCharset utf-8
Options -Indexes
#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####

ErrorDocument 403 /index.php/error/403
ErrorDocument 404 /index.php/error/404
<IfModule mod_rewrite.c>
  Options -MultiViews
  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
  RewriteCond %{REQUEST_FILENAME} !\.(css|js|mjs|svg|gif|ico|jpg|jpeg|png|webp|html|otf|ttf|woff2?|map|webm|mp4|mp3|ogg|wav|flac|wasm|tflite)$
  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update\.php
  RewriteCond %{REQUEST_FILENAME} !/core/img/(favicon\.ico|manifest\.json)$
  RewriteCond %{REQUEST_FILENAME} !/(cron|public|remote|status)\.php
  RewriteCond %{REQUEST_FILENAME} !/ocs/v(1|2)\.php
  RewriteCond %{REQUEST_FILENAME} !/robots\.txt
  RewriteCond %{REQUEST_FILENAME} !/(ocs-provider|updater)/
  RewriteCond %{REQUEST_URI} !^/\.well-known/(acme-challenge|pki-validation)/.*
  RewriteCond %{REQUEST_FILENAME} !/richdocumentscode(_arm64)?/proxy.php$
  RewriteRule . index.php [PT,E=PATH_INFO:$1]
  RewriteBase /
  <IfModule mod_env.c>
    SetEnv front_controller_active true
    <IfModule mod_dir.c>
      DirectorySlash off
    </IfModule>
  </IfModule>
</IfModule>