docker icon indicating copy to clipboard operation
docker copied to clipboard

Documentation for Traefik 2.0 Setup

Open JanoschDeurer opened this issue 4 years ago • 22 comments

I didn't know where to put this, so sorry if this is the wrong place. I have a setup of traefik 2 and Nextcloud and wanted to know where I could add it in the documentation. There is some documentation for Traefik 1 in the manual of Nextcloud: https://docs.nextcloud.com/server/18/admin_manual/configuration_server/reverse_proxy_configuration.html?highlight=traefik#traefik

In this location I could certainly add the documentation for the reverse proxy settings in traefik 2, however there are a lot of other settings that are recommended by Nextcloud that should also be set. My current config looks like this:

    labels:
      - "traefik.http.routers.cloud.rule=Host(`cloud.example.com`)"
      - "traefik.http.routers.cloud.middlewares=cloud_headers,cloud_redirectregex"
      - "traefik.http.middlewares.cloud_headers.headers.customFrameOptionsValue=SAMEORIGIN"
      - "traefik.http.middlewares.cloud_headers.headers.framedeny=true"
      - "traefik.http.middlewares.cloud_headers.headers.stsIncludeSubdomains=true"
      - "traefik.http.middlewares.cloud_headers.headers.stsPreload=true"
      - "traefik.http.middlewares.cloud_headers.headers.stsSeconds=15552001"
      - "traefik.http.middlewares.cloud_redirectregex.redirectregex.regex=/.well-known/(card|cal)dav"
      - "traefik.http.middlewares.cloud_redirectregex.redirectregex.replacement=/remote.php/dav/"

If you want to add this to the documentation and tell me where to put it, I am happy to write a PR. Also if anyone has any feedback about my configuration I would appreciate it.

JanoschDeurer avatar Apr 06 '20 14:04 JanoschDeurer

Relevant: https://github.com/nextcloud/server/issues/13612

jtagcat avatar Apr 13 '20 21:04 jtagcat

Hi @JanoschDeurer Thanks for the traefik 2.0 based docker-compose file. I created full docker-compose.yml for with required containers and parameter.

It is available at https://gist.github.com/ismailyenigul/f03b4f5f15e5e61ac5b80905c5d2890a and feel free for any comments

Adding here full YAML here also.

# docker network create nextcloud

NOTES:

  1. Edit [email protected]
  2. Set TRUSTED_PROXIES values based on your 'nexcloud docker network'
  3. remove traefik.http.middlewares.nextcloud.headers.contentSecurityPolicy and
    traefik.http.middlewares.nextcloud.headers.customFrameOptionsValue if you don't want to allow iframe your domain
# cat docker-compose.yml
version: '3.1'

volumes:
  nextcloud-www:
    driver: local
  nextcloud-db:
    driver: local
  redis:
    driver: local
  letsencrypt:
    driver: local


services:

  traefik:
    image: traefik:v2.2
    container_name: traefik
    restart: always
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
      - "[email protected]"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    ports:
      - 80:80
      - 443:443
    networks:
      - nextcloud
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - letsencrypt:/letsencrypt
  db:
    restart: always
    image: postgres:11
    networks:
      - nextcloud
    environment:
    - POSTGRES_USER=nextcloud
    - POSTGRES_PASSWORD=password
    - POSTGRES_DB=nextcloud
    volumes:
    - nextcloud-db:/var/lib/postgresql/data
  redis:
    image: redis:latest
    restart: always
    networks:
      - nextcloud
    volumes:
      - redis:/var/lib/redis

  nextcloud:
    image: nextcloud:latest
    restart: always
    networks:
      - nextcloud
    depends_on:
      - redis
      - db
    labels:
      - traefik.protocol=http
      - traefik.port=80
      - traefik.http.routers.nextcloud.middlewares=nextcloud,nextcloud_redirect
      - traefik.http.routers.nextcloud.tls=true
      - traefik.http.routers.nextcloud.entrypoints=websecure
      - traefik.http.routers.nextcloud.tls.certresolver=myresolver
      - traefik.http.routers.nextcloud.rule=Host(`nextcloud.mydomain.com`)
      - traefik.http.middlewares.nextcloud.headers.customFrameOptionsValue=ALLOW-FROM https://mydomain.com
      - traefik.http.middlewares.nextcloud.headers.contentSecurityPolicy=frame-ancestors 'self' mydomain.com *.mydomain.net
      - traefik.http.middlewares.nextcloud.headers.stsSeconds=155520011
      - traefik.http.middlewares.nextcloud.headers.stsIncludeSubdomains=true
      - traefik.http.middlewares.nextcloud.headers.stsPreload=true
      - traefik.http.middlewares.nextcloud_redirect.redirectregex.regex=/.well-known/(card|cal)dav
      - traefik.http.middlewares.nextcloud_redirect.redirectregex.replacement=/remote.php/dav/
    environment:
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=password
      - POSTGRES_HOST=db
      - NEXTCLOUD_ADMIN_USER=admin
      - NEXTCLOUD_ADMIN_PASSWORD=adminpass
      - REDIS_HOST=redis
      - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.mydomain.com
      - TRUSTED_PROXIES=172.18.0.0/16
    volumes:
      - nextcloud-www:/var/www/html

networks:
  nextcloud:
    external: true

ismailyenigul avatar May 09 '20 22:05 ismailyenigul

I have two comments: First of all I thinks in most setups traefik should be in a separate docker-compose.yml. If you want to provide a single docker-compose.yml with traefik I think that it should have two different networks, such that traefik can only talk to nextcloud and not to the databases.

For the traefik labels there are a view options in the new traefik versions which enable you to configure more of these options globally and omit them for the containers. If you have a traefik configuration like this (sorry I don't have a configuration with labels at hand):

entryPoints:       
  web:    
    address: ":80"  
    http:           
      redirections:      
        entryPoint:     
          to: web-secure
          scheme: https
                    
  web-secure:
    address: ":443"
    http:                         
      tls:
        certResolver: letsencrypt

you can ommit the following lables:

      - traefik.protocol=http
      - traefik.http.routers.nextcloud.tls=true
      - traefik.http.routers.nextcloud.tls.certresolver=myresolver

you can also ommit:

      - traefik.port=80

as there is only one port exposed by Nextcloud, but I think it can still be useful to write this here anyway for documentation purposes.

JanoschDeurer avatar May 10 '20 08:05 JanoschDeurer

Hi,

As you said if we deploy traefik with a different docker-compose.yml then we need to configure two networks for nextcloud. I just keep the config simple for nextcloud deployment only. Maybe we can create another example deployment for this. I submitted a PR for the above example at https://github.com/nextcloud/docker/pull/1115 I am going to create another example for two different network setup.

Yes, we can omit protocol, tls and port parameters. I was also deploying owncloud which uses port 8080 when I for it when modifying yml for nextcloud

We must set certresolver

 traefik.http.routers.nextcloud.tls.certresolver=myresolver

Ref: https://docs.traefik.io/https/acme/#the-different-acme-challenges

Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must reference it.

I removed - traefik.http.routers.nextcloud.tls.certresolver=myresolver then traefik started using self-signed certificate for nextcloud

time="2020-05-10T09:25:04Z" level=debug msg="No default certificate, generating one"

 $ curl -I https://nextcloud.mydomain.com
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

I added certresolver and traefik generated Let's Encrypt certificate.

ismailyenigul avatar May 10 '20 09:05 ismailyenigul

Why cant we fix the problem where the problem is caused from?

An environmental variable telling nextcloud that it is behind a reverse-proxy and should behave properly.

I should not have to have two route stacks to work around nextcloud trying to "help" me by refusing to act properly in the manner it should be doing so. Very few people place nextcloud as their https facing application, the overwhelming majority put it behind a reverseproxy.

@JanoschDeurer are those labels suppose to work? If so, nextcloud must have just updated the look to show "404 page not found" as a social engineering tactic to trick people into thinking that the page does not exist and is not route-able via the reverseproxy. Interesting move by the people in charge of nextcloud, I do not see any updates on this in the documentation.

Motophan avatar May 10 '20 11:05 Motophan

@Motophan We are just discussing Traefik 2.0 based deployment. Can you give more details about the problem that you mention ?

ismailyenigul avatar May 10 '20 12:05 ismailyenigul

@ismailyenigul None of the labels posted in this thread will work.

The first persons labels will not route, your labels not pass the trusted ssl cert. Neither of your "solutions" should be used.

The problem is the labels posted in this thread. Delete them. Or at a minimum preface them with a warning not to be used. They will not work.

Motophan avatar May 10 '20 12:05 Motophan

@Motophan Still not clear to me. What do you mean trusted cert does not pass? I created another docker-compose files for multi-network deployment at https://gist.github.com/ismailyenigul/0d25f37337bf9b56f537488670121365 I just tested and it created Lets Encrypt SSL for my domain and it works fine. Can you send me your docker-compose, and docker logs, errors?

Also you mention about image https://github.com/nextcloud/docker/issues/1113#issuecomment-626323915 I don't provide an image?

ismailyenigul avatar May 10 '20 13:05 ismailyenigul

fam lmao that wont werk xDDDDDDDDD https://i.imgur.com/IY9ljvw.png

now, if you take his compose file and add under lables - "traefik.enable=true" to the labels section it will.

But we should not do this. This is bad.

Nextcloud should fix thier crap "sekur" features and let me pass an env variable that will let me send a reverseproxy at it and be done w/ this. Why do they make this harder than it should.

Motophan avatar May 10 '20 13:05 Motophan

Are you aware of --providers.docker.exposedByDefault=true parameter?

Check https://docs.traefik.io/providers/docker/#exposedbydefault

exposedByDefault
Optional, Default=true
Expose containers by default through Traefik. If set to false, containers that don't have a traefik.enable=true label will be ignored from the resulting routing configuration.

And this is config from my traefik container deployment

services:

  traefik:
    image: traefik:v2.2
    container_name: traefik
    restart: always
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.network=traefik"
      - "--providers.docker.exposedbydefault=true"

ismailyenigul avatar May 10 '20 13:05 ismailyenigul

@Motophan I created this ticket to document nextcloud specific lables for Traefik 2.0. There are other lables required as well, as you can see in the examples of @ismailyenigul. An example of such labels is given by him, however the labels for you really depend on your Traefik setup.

Setting

- "traefik.enable=true"

is totally fine. I also don't understand what your problem with "Nextclouds crap sekur features" my traefik config is working fine and I never had any problem running Nextclound behind a reverse proxy.

JanoschDeurer avatar May 10 '20 14:05 JanoschDeurer

@ismailyenigul Thanks for creating all these examples :) My intention was that you can also create multiple networks in a single docker-compose.yml to increase security.

The cert resolver works for me with the above config without setting it for each container as it is configured as a default resolver. So I think we can omit the resolver.

JanoschDeurer avatar May 10 '20 14:05 JanoschDeurer

Here is my configuration with an external traefik 2 instance running withing the http_network namespace.

Note: Within this config bind volume mounts are used. Adapt to your use-case...

version: '3'

networks:
    http_network:
        external: true
    nextcloud_network:
        external: false

services:
  db:
    image: postgres:12-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    volumes:
      - /data/<service_name>/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=<db_password>
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
    networks:
      - nextcloud_network

  app:
    image: nextcloud:18
    container_name: nextcloud-app
    restart: unless-stopped
    labels:
      - traefik.enable=true
      - traefik.http.services.<service_name>.loadbalancer.server.port=80
      - traefik.http.routers.<service_name>.rule=Host(`<url>`)
      - traefik.http.routers.<service_name>.middlewares=<service_name>,<service_name>_redirect
      - traefik.http.routers.<service_name>.entrypoints=websecure
      - traefik.http.middlewares.<service_name>.headers.stsSeconds=155520011
      - traefik.http.middlewares.<service_name>.headers.stsIncludeSubdomains=true
      - traefik.http.middlewares.<service_name>.headers.stsPreload=true
      - traefik.http.middlewares.<service_name>.headers.contentTypeNosniff=true
      - traefik.http.middlewares.<service_name>.headers.browserXSSFilter=true
      - traefik.http.middlewares.<service_name>_redirect.redirectregex.permanent=true
      - traefik.http.middlewares.<service_name>_redirect.redirectregex.regex=/.well-known/(card|cal)dav
      - traefik.http.middlewares.<service_name>_redirect.redirectregex.replacement=/remote.php/dav/

    environment:
      - POSTGRES_HOST=db
      - NEXTCLOUD_TRUSTED_DOMAINS=<url>
      - TRUSTED_PROXIES=172.16.0.0/12
    depends_on:
      - db
    volumes:
      - /data/<service_name>/data:/var/www/html
    networks:
      - nextcloud_network
      - http_network

r0l1 avatar Jun 25 '20 10:06 r0l1

Hello everyone, thank you for these configs, the work for me but still Nextcloud reports:

There are some warnings regarding your setup.

    The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the documentation.
    The "Strict-Transport-Security" HTTP header is not set to at least "15552000" seconds. For enhanced security, it is recommended to enable HSTS as described in the security tips ↗.

Is this because of the reverse proxy situation and Nextcloud can simply not detect that I set these things correctly?

Best regards.

freekvh avatar Jan 10 '21 20:01 freekvh

@freekvh check your config and verify traefik.http.middlewares.<service_name>.headers.stsSeconds=155520011 The TRUSTED_PROXIES environment variable should fix the second warning. Maybe you must adapt the IP range.

r0l1 avatar Jan 11 '21 14:01 r0l1

@freekvh check your config and verify traefik.http.middlewares.<service_name>.headers.stsSeconds=155520011 The TRUSTED_PROXIES environment variable should fix the second warning. Maybe you must adapt the IP range.

Thanx, indeed the first warning is silenced with the TRUSTED_PROXIES. I'm still getting the STS warning tough... I now have these labels:

labels:
      - traefik.enable=true
      - traefik.http.routers.nextcloud_freek_app-http.entrypoints=web
      - traefik.http.routers.nextcloud_freek_app-http.rule=Host(`cloud.x.x`)
      - traefik.http.routers.nextcloud_freek_app-http.middlewares=nextcloud_freek_app-https
      - traefik.http.middlewares.nextcloud_freek_app.headers.stsSeconds=155520011
      - traefik.http.middlewares.nextcloud_freek_app.headers.stsIncludeSubdomains=true
      - traefik.http.middlewares.nextcloud_freek_app.headers.stsPreload=true
      - traefik.http.middlewares.nextcloud_freek_app.headers.contentTypeNosniff=true
      - traefik.http.middlewares.nextcloud_freek_app.headers.browserXSSFilter=true
      - traefik.http.middlewares.nextcloud_freek_app_redirect.redirectregex.permanent=true
      - traefik.http.middlewares.nextcloud_freek_app_redirect.redirectregex.regex=/.well-known/(card|cal)dav
      - traefik.http.middlewares.nextcloud_freek_app_redirect.redirectregex.replacement=/remote.php/dav/
      - traefik.http.middlewares.nextcloud_freek_app-https.redirectscheme.scheme=https
      - traefik.http.routers.nextcloud_freek_app.entrypoints=websecure
      - traefik.http.routers.nextcloud_freek_app.rule=Host(`cloud.x.x`)
      - traefik.http.routers.nextcloud_freek_app.tls=true
      - traefik.http.routers.nextcloud_freek_app.tls.certresolver=mytlschallenge

It also still complains about carddav and caldav

Your web server is not properly set up to resolve "/.well-known/caldav". Further information can be found in the documentation.

And apparently Module php-imagick in this instance has no SVG support, which I probably should file as a feature request.

freekvh avatar Jun 22 '21 19:06 freekvh

any updates on this? I've been trying to set up this for months without any success.

On Tue, Jun 22, 2021, 11:04 AM Freek van Hemert @.***> wrote:

@freekvh https://github.com/freekvh check your config and verify traefik.http.middlewares.<service_name>.headers.stsSeconds=155520011 The TRUSTED_PROXIES environment variable should fix the second warning. Maybe you must adapt the IP range.

Thanx, indeed the first warning is silenced with the TRUSTED_PROXIES. I'm still getting the STS warning tough... I now have these labels:

labels: - traefik.enable=true - traefik.http.routers.nextcloud_freek_app-http.entrypoints=web - traefik.http.routers.nextcloud_freek_app-http.rule=Host(cloud.x.x) - traefik.http.routers.nextcloud_freek_app-http.middlewares=nextcloud_freek_app-https - traefik.http.middlewares.nextcloud_freek_app.headers.stsSeconds=155520011 - traefik.http.middlewares.nextcloud_freek_app.headers.stsIncludeSubdomains=true - traefik.http.middlewares.nextcloud_freek_app.headers.stsPreload=true - traefik.http.middlewares.nextcloud_freek_app.headers.contentTypeNosniff=true - traefik.http.middlewares.nextcloud_freek_app.headers.browserXSSFilter=true - traefik.http.middlewares.nextcloud_freek_app_redirect.redirectregex.permanent=true - traefik.http.middlewares.nextcloud_freek_app_redirect.redirectregex.regex=/.well-known/(card|cal)dav - traefik.http.middlewares.nextcloud_freek_app_redirect.redirectregex.replacement=/remote.php/dav/ - traefik.http.middlewares.nextcloud_freek_app-https.redirectscheme.scheme=https - traefik.http.routers.nextcloud_freek_app.entrypoints=websecure - traefik.http.routers.nextcloud_freek_app.rule=Host(cloud.x.x) - traefik.http.routers.nextcloud_freek_app.tls=true - traefik.http.routers.nextcloud_freek_app.tls.certresolver=mytlschallenge

It also still complains about carddav and caldav

our web server is not properly set up to resolve "/.well-known/caldav". Further information can be found in the documentation.

And apparently Module php-imagick in this instance has no SVG support, which I probably should file as a feature request.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nextcloud/docker/issues/1061#issuecomment-866254260, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKEIUFDQ5NMTRUQFXSCQUUTTUDNCZANCNFSM4MCKH3OQ .

Motophan avatar Jun 23 '21 19:06 Motophan

I wonder if this is a valid warning. I have the redirects setup and I confirmed that going to them directly redirects to the appropriate URL and prints this message "This is the WebDAV interface. It can only be accessed by WebDAV clients such as the Nextcloud desktop sync client." But I still get the warning in "Security & setup warnings"

patbakdev avatar Sep 10 '21 21:09 patbakdev

has anyone gotten this to work yet?

On Fri, Sep 10, 2021, 1:54 PM Patrick Baker @.***> wrote:

I wonder if this is a valid warning. I have the redirects setup and I confirmed that going to them directly redirects to the appropriate URL and prints this message "This is the WebDAV interface. It can only be accessed by WebDAV clients such as the Nextcloud desktop sync client." But I still get the warning in "Security & setup warnings"

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nextcloud/docker/issues/1061#issuecomment-917236302, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKEIUFFZ3Z7TQN5LXNP34U3UBJ5CRANCNFSM4MCKH3OQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

Motophan avatar Sep 11 '21 02:09 Motophan

has anyone gotten this to work yet?

It depends on what you mean by "working".

I believe that this is "working" for me despite the warnings under "Overview -> Security and setup warnings". I can interrogate the endpoint and it is properly redirected. I tested with Thunderbird and it seems to work just fine.

I "think" I have narrowed the warning down to one of two issues:

1. The Overview page is using the wrong scheme. Looking at the network panel after refreshing the overview page I see this:

Blocked loading mixed active content “http://MYDOMAIN/remote.php/dav/”

Notice the http instead of https

2. My configuration for http to https is somehow not setup properly (despite working in all other situations). I'm configuring this in my docker-compose file as command line arguments:

    command:
      - --entryPoints.http.address=:80
      - --entryPoints.http.http.redirections.entryPoint.to=https
      - --entryPoints.http.http.redirections.entryPoint.scheme=https
      - --entryPoints.http.http.redirections.entryPoint.permanent=true

I also see the following 301:

PROPFIND: 
  from: https://MYDOMAIN/.well-known/caldav
  to: http://MYDOMAIN/remote.php/dav/  

So I am leaning toward problem number 2.

One additional item I noticed was that I have some middleware defined via file, but added the "dav" redirects as labels. This probably was working, but I wasn't sure so I moved all of the labeled' middleware under a single chain.

    middlewares-nextcloud-caldav-redirect:
      redirectRegex:
        regex: "/.well-known/(cal|card)dav/"
        replacement: "/remote.php/dav/"
        permanent: "true"

patbakdev avatar Sep 11 '21 17:09 patbakdev

Follow Up: I have tried to reconfigure my https redirect by moving it from static command line configuration to dynamic middleware file and it didn't seem to have an effect. Also tweaked the tls settings a bit. Nothing made the warning go away. So maybe it is problem number 1.

At this point I am just going to ignore the warning since it seems to functionally work unless I come across any other ideas.

patbakdev avatar Sep 11 '21 18:09 patbakdev

So does everyone using Traefik suffer this warning, or is there actually a way to fix it?

Your web server is not properly set up to resolve .well-known URLs

danepowell avatar Apr 26 '24 22:04 danepowell