I can not find a propper Caddyfile example for nextcloud revers proxy

1. Output of caddy version:

[2.4.6]

2. How I run Caddy:

in a docker container on a debian host

a. System environment:

Docker version 20.10.5+dfsg1, build 55c4c88
Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye

b. Command:

docker run -d \
  --name caddy \
  --restart=always \
  -v /var/docker/config/caddy/caddyfile:/etc/caddy/ \
  -v /var/docker/config/caddy/data:/data \
  -v /var/docker/config/caddy/config:/config \
  -v /media/daten/WEBSERVICEDATEN/caddy/www/:/srv \
  -p 80:80 \
  -p 443:443 \
  -e ACME_AGREE=true \
  caddy:2.4.6

c. Service/unit/compose file:

see above

d. My complete Caddy config:

#NEXTCLOUD on SRV-WEB - external
nc.broehlis.de {
  reverse_proxy  192.168.100.13:8020
  tls yesyesyes@yes.de
  encode gzip
  # client support (e.g. os x calendar / contacts)
  redir /.well-known/carddav /remote.php/dav 301
  redir /.well-known/caldav /remote.php/dav 301
  redir /.well-known/webfinger /remote.php/webfinger 301
#  redir /.well-known/webfinger /index.php/webfinger 301
#  redir /.well-known/nodeinfo /index.php/.well-known/nodeinfo
  redir /.well-known/nodeinfo /remote.php/.well-known/nodeinfo

  header    {
            Permissions-Policy           interest-cohort=()
            Referrer-Policy              no-referrer
            Strict-Transport-Security    max-age=31536000; includeSubdomains
            X-XSS-Protection             1; mode=block
            X-Content-Type-Options       nosniff
            X-Frame-Options              SAMEORIGIN
            Referrer-Policy              same-origin
  }

    log {
       output file  /data/log/nextcloud.log
       format single_field common_log
  }
}

3. The problem I’m having:

I can access my nextcloud instance but nextcloud is fiering security issues. I tried so much already but I found no fitting Caddyfile example to solve these messages (sorry I have them only in German)_

4. Error messages and/or full log output:

    Der „X-Content-Type-Options“-HTTP-Header ist nicht so konfiguriert, dass er „nosniff“ entspricht. Dies ist ein potentielles Sicherheitsrisiko und es wird empfohlen, diese Einstellung zu ändern.
    Der „X-Frame-Options“-HTTP-Header ist nicht so konfiguriert, dass er „SAMEORIGIN“ entspricht. Dies ist ein potentielles Sicherheitsrisiko und es wird empfohlen, diese Einstellung zu ändern.

    Dein Webserver ist nicht richtig konfiguriert, um "/.well-known/webfinger" aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation ↗.
    Dein Webserver ist nicht richtig konfiguriert, um "/.well-known/nodeinfo" aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation ↗.

5. What I already tried:

se my issue description

6. Links to relevant resources:

Please upgrade to v2.6.1. You’re on a pretty old version.

You don’t need this. Caddy v2 doesn’t use this env var.

This is removed. Caddy no longer has single_field, and no longer logs a common_log field in access logs.

If you absolutely need to keep logging in Common Log format, you can use the GitHub - caddyserver/transform-encoder: Log encoder module for custom log formats plugin.

I recommend not using Common Log though, because it omits a lot of useful information from the logs. JSON logs are much more detailed.

These are incorrect. You must use quotes around header values which have spaces, otherwise Caddy will parse this as a header replacement command (i.e. search for 1; and replace it with mode=block… which obviously doesn’t make sense).

1 Like

Thanks so much for your answer.
Should it look like this?

 header    {
            Permissions-Policy           interest-cohort=()
            Referrer-Policy              no-referrer
            Strict-Transport-Security    "max-age=31536000; includeSubdomains"
            X-XSS-Protection             "1; mode=block"
            X-Content-Type-Options       nosniff
            X-Frame-Options              SAMEORIGIN
            Referrer-Policy              same-origin
  }

I upgraded now to 2.6.1

And this is the caddyfile:

#NEXTCLOUD on SRV-WEB - external
nc.broehlis.de {
  reverse_proxy  192.168.100.13:8020
  tls yesyesyes@yes.de
  encode gzip
  # client support (e.g. os x calendar / contacts)
  redir /.well-known/carddav /remote.php/dav 301
  redir /.well-known/caldav /remote.php/dav 301
  redir /.well-known/webfinger /remote.php/webfinger 301
#  redir /.well-known/webfinger /index.php/webfinger 301
#  redir /.well-known/nodeinfo /index.php/.well-known/nodeinfo
  redir /.well-known/nodeinfo /remote.php/.well-known/nodeinfo

  header    {
            Permissions-Policy           interest-cohort=()
            Referrer-Policy              no-referrer
            Strict-Transport-Security    "max-age=31536000; includeSubdomains"
            X-XSS-Protection             "1; mode=block"
            X-Content-Type-Options       "nosniff"
            X-Frame-Options              "SAMEORIGIN"
            Referrer-Policy              "same-origin"
  }

    log {
       output file  /data/log/nextcloud.log
#       format single_field common_log
  }
}

The acme stuff in docker command is gone but the error message is even longer now:

Es gibt einige Warnungen bei deiner Systemkonfiguration.

  • Die Reverse-Proxy-Header-Konfiguration ist fehlerhaft oder du greifst auf Nextcloud über einen vertrauenswürdigen Proxy zu. Ist dies nicht der Fall, dann besteht ein Sicherheitsproblem, das einem Angreifer erlaubt, die IP-Adresse, die für Nextcloud sichtbar ist, auszuspähen. Weitere Informationen hierzu finden sich in der Dokumentation :arrow_upper_right:.

  • Der „X-Content-Type-Options“-HTTP-Header ist nicht so konfiguriert, dass er „nosniff“ entspricht. Dies ist ein potentielles Sicherheitsrisiko und es wird empfohlen, diese Einstellung zu ändern.

  • Der „X-Frame-Options“-HTTP-Header ist nicht so konfiguriert, dass er „SAMEORIGIN“ entspricht. Dies ist ein potentielles Sicherheitsrisiko und es wird empfohlen, diese Einstellung zu ändern.

  • Dein Webserver ist nicht richtig konfiguriert, um “/.well-known/webfinger” aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation :arrow_upper_right:.

  • Dein Webserver ist nicht richtig konfiguriert, um “/.well-known/nodeinfo” aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation :arrow_upper_right:.

That seems fine. Are you sure you’re connecting to Caddy, and not to another server? Make a request with curl -v to check that Caddy actually does respond with those headers.

I run my Nextcloud proxy configured with the following (using caddy-docker-proxy):

labels:
  caddy: "nextcloud.whitestrake.net"
  caddy.@dav: "path /.well-known/carddav /.well-known/caldav"
  caddy.redir: "@dav /remote.php/dav"
  caddy.header: 'Strict-Transport-Security "max-age=15552000; includeSubDomains"'
  caddy.reverse_proxy: "{{upstreams}}"

This translates to the equivalent Caddyfile:

nextcloud.whitestrake.net {
  @dav path /.well-known/carddav /.well-known/caldav
  redir @dav /remote.php/dav
  header Strict-Transport-Security "max-age=15552000; includeSubDomains"
  reverse_proxy nextcloud
}

This is fully functional for me - even putting Cloudflare in front via cloudflared pointing to Caddy pointing to Nextcloud. The only thing Nextcloud complains about is the lack of SVG support built in to the Docker container.

Strictly speaking, the following would be fully functional:

nextcloud.example.com {
  reverse_proxy nextcloud:80
}

Then add functionality as necessary (I added the DAV redirect and HSTS).

When in doubt, start with the simplest possible configuration.

2 Likes
*   Trying 82.165.67.61:443...
* Connected to nextcloud.broehlis.de (82.165.67.61) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=nextcloud.broehlis.de
*  start date: Oct  4 17:03:58 2022 GMT
*  expire date: Jan  2 17:03:57 2023 GMT
*  subjectAltName: host "nextcloud.broehlis.de" matched cert's "nextcloud.broehlis.de"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55fdf500a990)
> GET / HTTP/2
> Host: nextcloud.broehlis.de
> user-agent: curl/7.74.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 302
< alt-svc: h3=":443"; ma=2592000
< cache-control: no-store, no-cache, must-revalidate
< content-security-policy: default-src 'self'; script-src 'self' 'nonce-TVlKb0JwOXl5SkRaalh4dDBqK2xPUTBzNERaTDJGOXRwMmpnMitGYUoyND06Y09VZk5mc0tqUEt2endrSHNYR1RhMHRob21RUG1UUUw3dyttbzdZcWJpWT0='; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *; object-src 'none'; base-uri 'self';
< content-type: text/html; charset=UTF-8
< date: Wed, 12 Oct 2022 17:15:58 GMT
< expires: Thu, 19 Nov 1981 08:52:00 GMT
< location: https://nextcloud.broehlis.de/index.php/login
< permissions-policy: interest-cohort=()
< pragma: no-cache
< referrer-policy: same-origin
< server: Caddy
< server: nginx/1.20.2
< set-cookie: oc_sessionPassphrase=YDCPaquww1iTLUlhP2otMJZpTcFWmDDpoDO51CygRsvENcOCkIw8Qbw6aMGdB06jf%2FnQkaCQxHQZTv%2BNaqbvNxEZHuCejEleKPtHNuyLIPoDxL0XaB4CXEVvSO6fgDfV; path=/; secure; HttpOnly; SameSite=Lax
< set-cookie: oc7vlpufun4k=6rqp8fjet04sjluo67a9n18058; path=/; secure; HttpOnly; SameSite=Lax
< set-cookie: __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
< set-cookie: __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
< strict-transport-security: max-age=31536000; includeSubdomains
< strict-transport-security: max-age=15768000; includeSubDomains; preload;
< x-content-type-options: nosniff
< x-content-type-options: nosniff
< x-download-options: noopen
< x-frame-options: SAMEORIGIN
< x-frame-options: SAMEORIGIN
< x-permitted-cross-domain-policies: none
< x-powered-by: PHP/7.4.26
< x-robots-tag: none
< x-xss-protection: 1; mode=block
< x-xss-protection: 1; mode=block
<
* Connection #0 to host nextcloud.broehlis.de left intact

why do some entries appear double?

I tried to reduce my Caddyfile to your entry
restarted the caddy container and tried to connect again … Same errorrs/complains.
Can it be that the nextcloud container (from linuxserver team) is the reason for this missing security things?
When I was on caddy v1 everything worked well. Since v2 I am a lost

Probably because your nginx server is also setting those headers? Try not adding them in Caddy, instead.

2 Likes

Apologies, but could you indicate again for me which errors are current? Nextcloud’s online scan currently shows your instance as having an A+ for security: https://scan.nextcloud.com/results/c8e3b1c6-3605-43ca-8bd6-d79d78db9cf6

This is plausible, but I couldn’t say either way.

I use Linuxserver containers for a number of things, but see no point in using them for Nextcloud, as there is a well maintained official image from the developers of Nextcloud available in the Docker library: https://hub.docker.com/_/nextcloud

v2 is, in many ways, both simpler and more comprehensive than v1. With respect to reverse proxies, though, the only material difference in the simplest use case is that proxies are ‘transparent’ by default nowadays.

1 Like

I tried again a lot and this is now my Caddyfile:

nextcloud.broehlis.de {
  reverse_proxy  192.168.100.13:8020
  tls Yesyesyes@yes.de
  encode gzip

rewrite /.well-known/carddav /remote.php/dav
rewrite /.well-known/caldav /remote.php/dav

header {
         Strict-Transport-Security "max-age=31536000; includeSubDomains"
         Referrer-Policy no-referrer
         Referrer-Policy same-origin
         Referrer-Policy strict-origin
         Referrer-Policy strict-origin-when-cross-origin
         Referrer-Policy no-referrer-when-downgrade
         X-Content-Type-Options nosniff
       }
reverse_proxy nextcloud

    log {
       output file  /data/log/nextcloud.log
  }
}

And now this is in Nextcloud to find:

Es gibt einige Warnungen bei deiner Systemkonfiguration.

    Die Reverse-Proxy-Header-Konfiguration ist fehlerhaft oder du greifst auf Nextcloud über einen vertrauenswürdigen Proxy zu. Ist dies nicht der Fall, dann besteht ein Sicherheitsproblem, das einem Angreifer erlaubt, die IP-Adresse, die für Nextcloud sichtbar ist, auszuspähen. Weitere Informationen hierzu finden sich in der Dokumentation ↗.

    Dein Webserver ist nicht richtig konfiguriert, um "/.well-known/webfinger" aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation ↗.
    Dein Webserver ist nicht richtig konfiguriert, um "/.well-known/nodeinfo" aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation ↗.

how to handle the webfinger / nodeinfo issue?
Why is nextcloud complaining about header config errors?

here a curl -v

*   Trying 82.165.67.61:80...
* Connected to nextcloud.broehlis.de (82.165.67.61) port 80 (#0)
> GET / HTTP/1.1
> Host: nextcloud.broehlis.de
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://nextcloud.broehlis.de/
< Server: Caddy
< Date: Thu, 13 Oct 2022 12:20:05 GMT
< Content-Length: 0
<
* Closing connection 0

That’s just Caddy responding with an HTTP->HTTPS redirect response.

You need to specify https:// or use the -L option to follow redirects to get anything useful.

Oh, sorry, my fault.
I did the curl command again and saw these lines

< strict-transport-security: max-age=31536000; includeSubDomains
< strict-transport-security: max-age=15768000; includeSubDomains; preload;
< x-content-type-options: nosniff
< x-content-type-options: nosniff

I changed my Caddyfile again to this:

nextcloud.broehlis.de {
  reverse_proxy  192.168.100.13:8020
  tls mail@addr.de
  encode gzip
rewrite /.well-known/carddav /remote.php/dav
rewrite /.well-known/caldav /remote.php/dav

header {
         Referrer-Policy no-referrer
         Referrer-Policy same-origin
         Referrer-Policy strict-origin
         Referrer-Policy strict-origin-when-cross-origin
         Referrer-Policy no-referrer-when-downgrade
       }
reverse_proxy nextcloud

    log {
       output file  /data/log/nextcloud.log
  }
}

Then I did a curl again:

* Connected to nextcloud.broehlis.de (82.165.67.61) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=nextcloud.broehlis.de
*  start date: Oct  4 17:03:58 2022 GMT
*  expire date: Jan  2 17:03:57 2023 GMT
*  subjectAltName: host "nextcloud.broehlis.de" matched cert's "nextcloud.broehlis.de"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x56118c84f990)
> GET / HTTP/2
> Host: nextcloud.broehlis.de
> user-agent: curl/7.74.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 302
< alt-svc: h3=":443"; ma=2592000
< cache-control: no-store, no-cache, must-revalidate
< content-security-policy: default-src 'self'; script-src 'self' 'nonce-WkhWZjFoVkVMb1F4dDNsYkxzWWI0NmVmbG53RWxhRlloNlBGRnByNkRZND06THkwN2tTSXdmZjE5K2cwL2ZvTk1sZS9WcGlaaHBkbHJ5dHVoUXErdGZPOD0='; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *; object-src 'none'; base-uri 'self';
< content-type: text/html; charset=UTF-8
< date: Fri, 14 Oct 2022 08:14:52 GMT
< expires: Thu, 19 Nov 1981 08:52:00 GMT
< location: https://nextcloud.broehlis.de/index.php/login
< pragma: no-cache
< referrer-policy: no-referrer-when-downgrade
< server: Caddy
< server: nginx/1.20.2
< set-cookie: oc_sessionPassphrase=HsAFnr3T0tpdji7bilqsZ7bz0nW22C6tqjsYx2MM5kBsjQtGtZQO2nPJ0h0gTdDYHATo%2FBcr2iBX3ngmEj43oyvVV89kWM8b27m%2B0qLrFIAuXfLOGFXSrj6JmZRPrPSn; path=/; secure; HttpOnly; SameSite=Lax
< set-cookie: oc7vlpufun4k=glodaq6ker6698bqamt01b0tqn; path=/; secure; HttpOnly; SameSite=Lax
< set-cookie: __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
< set-cookie: __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
< strict-transport-security: max-age=15768000; includeSubDomains; preload;
< x-content-type-options: nosniff
< x-download-options: noopen
< x-frame-options: SAMEORIGIN
< x-permitted-cross-domain-policies: none
< x-powered-by: PHP/7.4.26
< x-robots-tag: none
< x-xss-protection: 1; mode=block
<
* Connection #0 to host nextcloud.broehlis.de left intact

But Nextcloud Security warning Message did not change

I note you have a whole bunch of Referrer-Policy headers you’re trying to set but only the last one is sticking.

This is because the header directive by default replaces the header.

<field> is the name of the header field. By default, will overwrite any existing field of the same name.

Prefix with + to add the field instead of overwriting (setting) the field if it already exists; header fields can appear more than once in a request.

https://caddyserver.com/docs/caddyfile/directives/header

That said, you’ve also posted a whole lot of conflicting referrer policies. I’m pretty sure these… don’t stack like that? I’m pretty sure you just wanna pick one.

That said, other than that it looks like a perfectly functional request. Is the site functional? The errors seem to link you to documentation, do those docs tell you what you need to change?

2 Likes

About Referrer-Policy
I now checked that this is … lets say … too much. One is enough.
I reduced it now to that
header {
Referrer-Policy strict-origin-when-cross-origin
}

I checked documentation where an example explicit for caddy is exactly what I have … ??? I will try to rais my issue at nextcloud forum too.

Any ideas about the webfinger issue?

  • Dein Webserver ist nicht richtig konfiguriert, um “/.well-known/webfinger” aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation :arrow_upper_right:.
  • Dein Webserver ist nicht richtig konfiguriert, um “/.well-known/nodeinfo” aufzulösen. Weitere Informationen hierzu findest du in unserer Dokumentation :arrow_upper_right:.

This topic was automatically closed after 30 days. New replies are no longer allowed.