Nextcloud configuration: FastCGI is giving me headaches

I am attempting to convert my nginx Nextcloud configs over to Caddy, and I am having a few issues. One is that I have a pretty comprehensive list of valid X.php scripts, and am trying to limit it to that. Two of these are 403 & 404 redirects, which I just can add to my error {} block as they aren’t being processed.

Also, my fastcgl doesn’t seem to be parsing right. It will get index.php fine, and I can login, but I need a few more scripts to parse and I am guessing they are not… here are the errors:

18/Sep/2016:21:25:35 -0700 [ERROR 0 /ocs/v2.php/apps/notifications/api/v1/notifications] Access to the script '/var/www/nextcloud/apps/notifications/api/v1/notifications' has been denied (see security.limit_extensions)
18/Sep/2016:21:25:35 -0700 [ERROR 0 /remote.php/webdav] Access to the script '/var/www/nextcloud/webdav' has been denied (see security.limit_extensions)

Below is my NGINX nextcloud config blocks that are confounding me. Everything else (aside from OCSP stapling, but I can figure that out after basic functionality) seems to be working fine.

  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]|upd
ater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
      include fastcgi_params;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      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;
      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)$ {
    try_files $uri /index.php$uri$is_args$args;
    add_header Cache-Control "public, max-age=7200";
    # 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;";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    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 ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
    try_files $uri /index.php$uri$is_args$args;
    # Optional: Don't log access to other assets
    access_log off;
  }

And here is what I have to a Caddy config so far:

nextcloud.XXXX.com {

  log /var/log/caddy/nextcloud_access.log

  tls alex@XXXX.com

  root /var/www/nextcloud

  fastcgi / unix:/run/php-fpm/www.sock php {
    env PATH /bin
    # split ^(.+\.php)(/.+)$  <--- fails miserably.
  }

  rewrite {
    r ^/index.php/.*$
      to /index.php?{query}
  }

  # client support (e.g. os x calendar / contacts)
  redir /.well-known/carddav /remote.php/carddav 301
  redir /.well-known/caldav /remote.php/caldav 301

  errors {
    log /var/log/caddy/nextcluod_error.log
    # 403 /core/templates/403.php
    # 404 /core/templates/404.php  <-- not parsing
  }

  # remove trailing / as it causes errors with php-fpm
    rewrite {
      r ^/remote.php/(webdav|caldav|carddav)(\/?)$
        to /remote.php/{1}
    }

  rewrite {
    r ^/remote.php/(webdav|caldav|carddav)/(.+)(\/?)$
      to /remote.php/{1}/{2}
  }

  # .htacces / data / config / ... shouldn't be accessible from outside
  rewrite {
    r  ^/(?:\.htaccess|data|config|db_structure\.xml|README)
      status 403
  }

  header / Strict-Transport-Security "31536000"

}

This does not work because split does not support regex

fastcgi / unix:/run/php-fpm/www.sock php {
  env PATH /bin
  split ^(.+\.php)(/.+)$ #  <--- fails miserably.
}

And this does not work because errors directive behaves independent of fastcgi. You will need to handle this on application layer if you’re not specifying static html pages.

errors {
  log /var/log/caddy/nextcluod_error.log
  403 /core/templates/403.php
  404 /core/templates/404.php #  <-- not parsing
}

Ok… got those two. My other issue is with the error message. You can see that split is commented out, yet I am still getting the errors in the error message when i try to access any PHP script aside from index.php. I thought “.php” was the default split pattern? The errors seem to indicate a wrong extension type, but I am definitely using .php scripts. Any ideas how to get the spit to work right?

Can you share the error message ?

Its the first code block (two lines) in the first message.

18/Sep/2016:21:25:35 -0700 [ERROR 0 /ocs/v2.php/apps/notifications/api/v1/notifications] Access to the script '/var/www/nextcloud/apps/notifications/api/v1/notifications' has been denied (see security.limit_extensions)
18/Sep/2016:21:25:35 -0700 [ERROR 0 /remote.php/webdav] Access to the script '/var/www/nextcloud/webdav' has been denied (see security.limit_extensions)

You get those errors even after removing split from fastcgi config ?

Yes, I just verified that is the case.

  fastcgi / unix:/run/php-fpm/www.sock php {
      env PATH /bin
  }

The error is because you have paths after the php file /remote.php/webdav. Check this link.

Ok… I do know about that, but it is common practice in NGINX/PHP installs to split base on the PHP and append the rest of the line as the query… Hence the following in Nginx:

  location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
      include fastcgi_params;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      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;
      fastcgi_intercept_errors on;
      fastcgi_request_buffering off;
    }

is there anyway to do something similar in Caddy? The other things (automated SSL is 90% functional and 100% easier, transparent proxy setup is super painless) make a compelling argument, as does the fact I am resource constraint so it’s footprint is nice, but I really don’t want to open the security.limit_extension setting unless I really need to.

Also, the following URLs works:

https://nextcloud.XXXXX.com/index.php/apps/files/
https://nextcloud.XXXXX.com/index.php/login/

So apparently fastCGI only processes index.php and not other PHP files by default? Unless I misread the documentation, it looks like it should use any .php & split on the php. Unless the fact there is an index specified overrides this ability?

From https://caddyserver.com/docs/fastcgi

ext .php
split .php
index index.php

SO i had this in my config… what if I did this?

  rewrite {
    r ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/)
      to /{1}?{query}
  }

I was trying to couple fastcgi to location/rewrite. would something like this work? I bet my regex needs a bit of massaging.

Getting closer… just need to figure out why WebDAV isn’t working… a caddy limitation?

Here is what we are at now:

  rewrite {
    r ^/(index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php/.*$
    to /{1}.php?{query}
  }

I am no longer seeing any error messages, and most calls (ocs/v2.php, updater.php, etc) seem to be working now. My issue now is seeing an error about the WebDAV service not working. Now to try and get nextcloud to pay attention to a logging level change…

I’m using the config from here so almost the same as you with Nextcloud 10 and everything appears to work but WebDAV.

The Nextcloud client for desktop works and synchronizes but manually mounting in Gnome Files with davs:// or by using the mobile client, I’m only able to get the root folder. Opening a folder returns nothing. That’s also the reason why I can’t select individual folders in the desktop client to synchronize.

Opening the default docs folder in the mobile client results in the following line in the access.log:

x.x.x.x - [19/Sep/2016:23:36:19 +0200] "PROPFIND /remote.php/webdav/docs/ HTTP/1.1" 503 287

That is the config that wasn’t fully working (Also Nextcloud 10). You can see my changes to the index.php rewrite to get other PHP scripts to work.

Here is what I am seeing in my nextcloud Admin page:

Security & setup warnings

Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken.

and here is my full caddy config. Maybe you can spot what I am missing?

nextcloud.XXXX.com {
  log /var/log/caddy/nextcloud_access.log
  tls alex@XXXX.com {
    protocols tls1.0 tls1.2
  }
  root /var/www/nextcloud
  fastcgi / unix:/run/php-fpm/www.sock php {
    env PATH /usr/bin
    split .php
    ext .php
  }
  rewrite {
    # I haven't changed the security.limit_extensions value in php-fpm from = .php
    r ^/(index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php/.*$
    to /{1}.php?{query}
  }

  # client support (e.g. os x calendar / contacts)
  redir /.well-known/carddav /remote.php/carddav 301
  redir /.well-known/caldav /remote.php/caldav 301

  errors {
    log /var/log/caddy/nextcloud_error.log
  }

  # remove trailing / as it causes errors with php-fpm
  rewrite {
    r ^/remote.php/(webdav|caldav|carddav|dav)(\/?)$
    to /remote.php/{1}
  }

  rewrite {
    r ^/remote.php/(webdav|caldav|carddav|dav)/(.+)(\/?)$
    to /remote.php/{1}/{2}
  }

  # .htacces / data / config / ... shouldn't be accessible from outside
  rewrite {
    r  ^/(?:\.htaccess|data|config|db_structure\.xml|README)
    status 403
  }

  header / Strict-Transport-Security "max-age=31536000"

}

Changed security.limit_extensions. Still no ability to see files in the web client, even ignoring WebDAV access.

I do host my data in a separate tree:

/var/www/nextcloud is my “root”
/var/www/nc_data is where my users data resides, but that is external to the web server. Or is that now my issue? It’s not an unusual set up under Nextcloud/ownCloud.

I’m trying to list my setup and the changes I’ve made. Maybe this can help you.

But first: My securiy check in the admin panel actually passes and as I said, WebDav is working atleast partially.

I’m running Caddy on ArchLinux and I installed this package for caddy and this for nextcloud.

The default user for webstuff on Arch is http so I created a override file for the systemd service so that Caddy starts as http. Nextcloud is in /usr/share/webapps/nextcloud. The following script sets the right permissions for nextcloud and is provided in the nextcloud docs:

#!/bin/bash
ncpath='/usr/share/webapps/nextcloud'
htuser='http'
htgroup='http'
rootuser='root'

printf "Creating possible missing Directories\n"
mkdir -p $ncpath/data
mkdir -p $ncpath/assets

printf "chmod Files and Directories\n"
find ${ncpath}/ -type f -print0 | xargs -0 chmod 0640
find ${ncpath}/ -type d -print0 | xargs -0 chmod 0750

printf "chown Directories\n"
chown -R ${rootuser}:${htgroup} ${ncpath}/
chown -R ${htuser}:${htgroup} ${ncpath}/apps/
chown -R ${htuser}:${htgroup} ${ncpath}/config/
chown -R ${htuser}:${htgroup} ${ncpath}/data/
chown -R ${htuser}:${htgroup} ${ncpath}/themes/
chown -R ${htuser}:${htgroup} ${ncpath}/assets/

chmod +x ${ncpath}/occ

printf "chmod/chown .htaccess\n"
if [ -f ${ncpath}/.htaccess ]
  then
    chmod 0644 ${ncpath}/.htaccess
    chown ${rootuser}:${htgroup} ${ncpath}/.htaccess
fi
if [ -f ${ncpath}/data/.htaccess ]
  then
    chmod 0644 ${ncpath}/data/.htaccess
    chown ${rootuser}:${htgroup} ${ncpath}/data/.htaccess
fi

In /etc/php/php-fpm.d/www.conf I changed the user and group to http and changed listen = /run/php-fpm/php-fpm.sock to listen = 127.0.0.1:9000 as stated in the blog post.

In /etc/php/php.ini I changed the following things:

  • memory_limit = 512M
  • post_max_size = 150G
  • upload_max_filesize = 150G
  • activated a bunch of extensions

I changed nothing in /usr/share/webapps/config. I think that’s all I did to get everything working in Nextcloud.

Yup… All looking very familiar (I am just using my nginx user for the moment).

The big difference is my data is in a different tree from my web server, I didn’t want to expose them to external access… Yay! Guess I get to troubleshoot later.

Yeah, this appears to be the main difference. Sorry that I couldn’t help.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.