lewazo / boreale

:evergreen_tree: A very lightweight authentication service for Traefik

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ArgumentError at GET?

sorcerer-merlin opened this issue · comments

So I am trying to use this with my docker-compose setup to have some extra security for a few containers vs. basic auth prompts. When I get the user/password combo right, I just get this message and nothing happens:

image

Of course, testing with wrong user/password combination just gives me an error saying wrong user/password. I've removed my secure headers and I am only using the middleware configuration (in TOML) format that you provided in the example for Traefik 2.x. Any ideas?

Thanks.

Hey,

would you be able to copy / paste the content of the alert window? There should be a stacktrace in there that would be useful in figuring out what is happening.

I am at work now, so I may not be able to look at this for a few hours. I'll look on my break... if not when I get home. When I encountered this error last night during my initial setup with docker-compose, I was using Google Chrome and it would only show the box but not let me click inside of it and copy the error text. I can try with MS Edge or Firefox and see what happens. At first I thought maybe my custom security headers in my middleware chain were causing problems, so I removed them and even stopped using the whole chain and just setup the exact configuration (again in TOML format, I just came from Traefik 1.x and haven't figured out how to convert my whole configuration to YAML yet) in your example. If it is helpful I can post part of my docker-compose.yml, middlewares.toml, etc. and see if that helps you pinpoint the problem.

Your app looks clean and its tiny and I'm just looking for something a bit better than basic auth so I think if I can get it to work it will be great! Authelia was too heavy for my uses, and same with Key Cloak, and I'm trying to get away from all things Google (eventually even the browser!) so I don't want to use OAuth. Anyway, let me know what you think.

I was using your app to secure an instance of VS code-server, but I also tried an instance of Homer Dashboard (neither of which provide their own auth mechanism and so I'm using basic auth currently).

Thanks for your help and response and for developing a cool and lightweight forward auth solution for people to use.

No worries, I'm also at work so won't be getting to it just now anyway.

Your use-case sounds perfect for Boréale. It's definitely meant to be a replacement for basic auth!

I remember having these kind of issues while developing it. I'm sure we'll find what's causing the problem here.

In the meantime, yes I think it would be helpful to have a look at your config files.

docker-compose.yml: (trunicated)

version: "3.6"

########################### NETWORKS
networks:
  traefik_proxy:
    external:
      name: traefik_proxy
  default:
    driver: bridge

########################### SERVICES
services:

######### PROXY'S ##########

# Traefik 2 - Reverse Proxy
  traefik:
    container_name: traefik
    image: traefik:2.2.1 # the chevrotin tag refers to v2.2.x but introduced a breaking change in 2.2.2
    restart: always
    command: # CLI arguments
      - --global.checkNewVersion=true
      - --global.sendAnonymousUsage=true
      - --entryPoints.http.address=:80
      - --entryPoints.https.address=:443
        # Allow these IPs to set the X-Forwarded-* headers - Cloudflare IPs: https://www.cloudflare.com/ips/
      - --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22
      - --entryPoints.traefik.address=:8080
      - --api=true
#      - --serversTransport.insecureSkipVerify=true      # leave this alone, it doesn't play nice with NextCloud and other services
      - --log=true
      - --log.level=DEBUG # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
      - --accessLog=true
      - --accessLog.filePath=/traefik.log
      - --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines
      - --accessLog.filters.statusCodes=400-499
      - --providers.docker=true
      - --providers.docker.endpoint=unix:///var/run/docker.sock
      - --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME`)
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=traefik_proxy
      - --providers.docker.swarmMode=false
      - --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory.
      - --providers.file.watch=true # Only works on top level files in the rules folder
      - --certificatesResolvers.dns-cloudflare.acme.email=${CLOUDFLARE_USER}
      - --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json
      - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare
    networks:
      - default
      - traefik_proxy
    ports:
      - "80:80"
      - "443:443"
#      - "8888:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /mnt/1TB/Share/Docker/traefik2/rules:/rules 
      - /mnt/1TB/Share/Docker/traefik2/acme/acme.json:/acme.json 
      - /mnt/1TB/Share/Docker/traefik2/traefik.log:/traefik.log 
      - /mnt/1TB/Share/Docker/shared:/shared
    environment:
      - CF_API_EMAIL=${CLOUDFLARE_USER}
      - CF_API_KEY=${CLOUDFLARE_KEY}
    labels:
      - "traefik.enable=true"
      # HTTP-to-HTTPS Redirect
      - "traefik.http.routers.http-catchall.entrypoints=http"
      - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # HTTP Routers
      - "traefik.http.routers.traefik-rtr.entrypoints=https"
      - "traefik.http.routers.traefik-rtr.rule=Host(`proxy.$DOMAINNAME`)"
      - "traefik.http.routers.traefik-rtr.tls=true"
      - "traefik.http.routers.traefik-rtr.tls.domains[0].main=$DOMAINNAME"
      - "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME"
      ## Services - API
      - "traefik.http.routers.traefik-rtr.service=api@internal"
      ## Middlewares
      - "traefik.http.routers.traefik-rtr.middlewares=chain-basic-auth@file"

  boreale:
    container_name: "boreale"
    hostname: "boreale"
    image: "lewazo/boreale:latest"
    ports:
      - "5252:4000"
    environment:
      - "SECRET_KEY_BASE=hVmYq3t6w9z^C&F)J@NcRfUjXnZr4u7x"
      - "COOKIE_NAME=_mkybiz_auth"
      - "SIGNING_SALT=J@McQfTjWnZr4u7x!A%D*G-KaPdRgUkX"
      - "ENCRYPTION_SALT=eShVmYq3t6w9y^B&E)H@McQfTjWnZr4u"
      - "PAGE_TITLE=Authenticate | MKY-BIZ.COM"
#      - SSO_DOMAIN_NAME           # enable after we figure out how many subdomains we want authenticate (i.e. will this work for all of them??)
    networks:
      - default
      - traefik_proxy
    volumes:
      - /mnt/1TB/Share/Docker/boreale:/opt/app/data
# Homer - Dead simple static Homepage for Apps with YAML configuration
  homer:
    container_name: homer
    hostname: homer
    restart: always
    image: b4bz/homer
#    ports:
#      - 8080:8080
    volumes:
      - /mnt/1TB/Share/Docker/homer/assets:/www/assets
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    networks:
      - traefik_proxy
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.homer-rtr.entrypoints=https"
      - "traefik.http.routers.homer-rtr.rule=Host(`home.$DOMAINNAME`)"
      - "traefik.http.routers.homer-rtr.tls=true"
      ## Middlewares
      #- "traefik.http.routers.homer-rtr.middlewares=chain-no-auth@file" # No Authentication
      - "traefik.http.routers.homer-rtr.middlewares=middlewares-boreale@file"  # Boreale
      ## HTTP Services
      - "traefik.http.routers.homer-rtr.service=homer-svc"
      - "traefik.http.services.homer-svc.loadbalancer.server.port=8080"
      ## Watchtower Updates
      - "com.centurylinklabs.watchtower.enable=true"

middlewares.toml:

[http.middlewares]
  [http.middlewares.middlewares-basic-auth]
    [http.middlewares.middlewares-basic-auth.basicAuth]
      users = [
        "admin:{SHA}y1PAFVf2fxWqG9ZEMlt/CcpHr+Q=",
      ]
      realm = "Traefik2 Basic Auth"

  [http.middlewares.middlewares-https-redirectscheme]
    [http.middlewares.middlewares-https-redirectscheme.redirectScheme]
      scheme = "https"
      permanent = true

  [http.middlewares.middlewares-rate-limit]
    [http.middlewares.middlewares-rate-limit.rateLimit]
      average = 100
      burst = 50

# Available Header Options: 
#####https://github.com/unrolled/secure#available-options
#####https://docs.traefik.io/middlewares/headers/
# A great resource for these headers is your preferred browser's docs. Firefox: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
# https://developers.google.com/search/reference/robots_meta_tag
# https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Clickjacking_Defense_Cheat_Sheet.md
# CSP for VNC: https://github.com/cockpit-project/cockpit/pull/5932
# Check headers here, don't include OAuth when checking headers, otherwise you are checking google's headers: https://securityheaders.com
# or check them here: https://observatory.mozilla.org/

# CAUTION: Any headers defined in docker-compose (yml) will OVERWRITE ALL of the headers defined below.

  [http.middlewares.middlewares-secure-headers]
    [http.middlewares.middlewares-secure-headers.headers]
      accessControlAllowMethods= ["GET", "OPTIONS", "PUT"]
      accessControlMaxAge = 100
      hostsProxyHeaders = ["X-Forwarded-Host"]
      # sslRedirect = true #replaced with middlewares-https-redirectscheme for v2.5.x
      stsSeconds = 63072000
      stsIncludeSubdomains = true
      stsPreload = true
      forceSTSHeader = true
#      frameDeny = true #overwritten by customFrameOptionsValue
      customFrameOptionsValue = "allow-from https:mky-biz.com" #CSP takes care of this but may be needed for organizr. 
      contentTypeNosniff = true 
      browserXssFilter = true 
#      sslForceHost = true # add sslHost and all of the 
#      sslHost = "mky-biz.com"
      referrerPolicy = "same-origin" 
#      Setting contentSecurityPolicy is more secure but it can break things. Proper auth will reduce the risk.
#      the below line also breaks some apps due to 'none' - sonarr, radarr, etc.
#      contentSecurityPolicy = "frame-ancestors '*.mky-biz.com:*';object-src 'none';script-src 'none';"
      # Line below, featurePolicy, was deprecated in v2.5.x in favor permissionPolicy
      # featurePolicy = "camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';"
      permissionsPolicy = "camera=(), microphone=(), geolocation=(), payment=(), usb=(), vr=()"
      [http.middlewares.middlewares-secure-headers.headers.customResponseHeaders]
        X-Robots-Tag = "none,noarchive,nosnippet,notranslate,noimageindex,"
        server = ""

  ### BOREALE
  [http.middlewares.middlewares-boreale]
    [http.middlewares.middlewares-boreale.forwardAuth]
      address = "https://192.168.3.4:5252"
    [http.middlewares.middlewares-boreale.forwardAuth.tls]
      insecureSkipVerify = true

middleware-chains.toml (not using the chain, but just so you can see what I tried):

[http.middlewares]
  [http.middlewares.chain-no-auth]
    [http.middlewares.chain-no-auth.chain]
      middlewares = [ "middlewares-rate-limit", "middlewares-https-redirectscheme", "middlewares-secure-headers"]

  [http.middlewares.chain-basic-auth]
    [http.middlewares.chain-basic-auth.chain]
      middlewares = [ "middlewares-rate-limit", "middlewares-secure-headers", "middlewares-basic-auth"]

  [http.middlewares.chain-boreale-auth]
    [http.middlewares.chain-boreale-auth.chain]
      middlewares = [ "middlewares-rate-limit", "middlewares-boreale"]

  [http.middlewares.chain-nextcloud]
    [http.middlewares.chain-nextcloud.chain]
      middlewares = [ "middlewares-rate-limit", "nextcloud-middlewares-secure-headers", "nextcloud-redirect"]

I also checked into the browser alert and I cannot find a way to capture what is written there besides a screenshot. It's a lot of javascript/HTML from the looks of it, and all I can really get from it is a bad argument(s) to GET. Let me know if you want to see anything else.

Also, I used an online key generator for all of the keys, I've never generated them like this before, so I wasn't sure where to go. If there is a better/easier way and if what I did was wrong maybe that will help. I can change the keys so I'm not worried about them being posted here. All of that will change if I can get this solution to work, at this point I'm just trying it out.

Thanks for helping!!

I haven't checked your configs just yet, but it just occured to me we should be able to see the actual stack trace in the docker logs.

Running docker logs <CONTAINER_ID> should give us a hint to where it is crashing.

I didn't even think of that. I would have looked much sooner, I'm such a noob! Anyway, it seems like my encryption key isn't right. Is there an easy way to create them and ensure that they are the right size for your app's usage? Never done that before... and here are the logs to support it:

,
53:00.309 [debug] GET /,
,
01:53:00.312 [debug] Sent 401 in 3ms,
,
53:03.354 [debug] GET /,
,
01:53:03.777 [debug] Sent 500 in 422ms,
,
01:53:03.779 [error] #PID<0.1216.0> running Boreale.Router (connection #PID<0.1207.0>, stream id 5) terminated,
Server: 192.168.3.4:5252 (https),
Request: GET /,
** (exit) an exception was raised:,
    ** (ArgumentError) cookie store expects conn.secret_key_base to be at least 64 bytes,
        (plug) lib/plug/session/cookie.ex:178: Plug.Session.COOKIE.validate_secret_key_base/1,
        (plug) lib/plug/session/cookie.ex:170: Plug.Session.COOKIE.derive/3,
        (plug) lib/plug/session/cookie.ex:112: Plug.Session.COOKIE.put/4,
        (plug) lib/plug/session.ex:95: anonymous fn/3 in Plug.Session.before_send/2,
        (elixir) lib/enum.ex:1940: Enum."-reduce/3-lists^foldl/2-0-"/3,
        (plug) lib/plug/conn.ex:1548: Plug.Conn.run_before_send/2,
        (plug) lib/plug/conn.ex:403: Plug.Conn.send_resp/1,
        (boreale) lib/plug/router.ex:259: Boreale.Router.dispatch/2,
,
53:08.969 [debug] GET /,
,
01:53:09.285 [debug] Sent 401 in 315ms,
,
54:26.105 [debug] GET /,
,
01:54:26.109 [debug] Sent 401 in 4ms,
,
54:26.610 [debug] GET /,
,
01:54:26.616 [debug] Sent 401 in 5ms,
,
54:29.613 [debug] GET /,
,
01:54:29.946 [debug] Sent 500 in 332ms,
,
01:54:29.948 [error] #PID<0.1245.0> running Boreale.Router (connection #PID<0.1236.0>, stream id 5) terminated,
Server: 192.168.3.4:5252 (https),
Request: GET /,
** (exit) an exception was raised:,
    ** (ArgumentError) cookie store expects conn.secret_key_base to be at least 64 bytes,
        (plug) lib/plug/session/cookie.ex:178: Plug.Session.COOKIE.validate_secret_key_base/1,
        (plug) lib/plug/session/cookie.ex:170: Plug.Session.COOKIE.derive/3,
        (plug) lib/plug/session/cookie.ex:112: Plug.Session.COOKIE.put/4,
        (plug) lib/plug/session.ex:95: anonymous fn/3 in Plug.Session.before_send/2,
        (elixir) lib/enum.ex:1940: Enum."-reduce/3-lists^foldl/2-0-"/3,
        (plug) lib/plug/conn.ex:1548: Plug.Conn.run_before_send/2,
        (plug) lib/plug/conn.ex:403: Plug.Conn.send_resp/1,
        (boreale) lib/plug/router.ex:259: Boreale.Router.dispatch/2,
,
54:40.552 [debug] GET /,
,
01:54:40.876 [debug] Sent 500 in 323ms,
,
01:54:40.881 [error] #PID<0.1249.0> running Boreale.Router (connection #PID<0.1236.0>, stream id 7) terminated,
Server: 192.168.3.4:5252 (https),
Request: GET /,
** (exit) an exception was raised:,
    ** (ArgumentError) cookie store expects conn.secret_key_base to be at least 64 bytes,
        (plug) lib/plug/session/cookie.ex:178: Plug.Session.COOKIE.validate_secret_key_base/1,
        (plug) lib/plug/session/cookie.ex:170: Plug.Session.COOKIE.derive/3,
        (plug) lib/plug/session/cookie.ex:112: Plug.Session.COOKIE.put/4,
        (plug) lib/plug/session.ex:95: anonymous fn/3 in Plug.Session.before_send/2,
        (elixir) lib/enum.ex:1940: Enum."-reduce/3-lists^foldl/2-0-"/3,
        (plug) lib/plug/conn.ex:1548: Plug.Conn.run_before_send/2,
        (plug) lib/plug/conn.ex:403: Plug.Conn.send_resp/1,
        (boreale) lib/plug/router.ex:259: Boreale.Router.dispatch/2,
,
54:50.984 [debug] GET /,
,
01:54:50.992 [debug] Sent 401 in 7ms,
,
57:56.508 [debug] GET /,
,
01:57:56.515 [debug] Sent 401 in 6ms,
,
57:56.626 [debug] GET /,
,
01:57:56.629 [debug] Sent 401 in 3ms,
,
57:58.762 [debug] GET /,
,
01:57:59.085 [debug] Sent 500 in 322ms,
,
01:57:59.087 [error] #PID<0.1272.0> running Boreale.Router (connection #PID<0.1263.0>, stream id 5) terminated,
Server: 192.168.3.4:5252 (https),
Request: GET /,
** (exit) an exception was raised:,
    ** (ArgumentError) cookie store expects conn.secret_key_base to be at least 64 bytes,
        (plug) lib/plug/session/cookie.ex:178: Plug.Session.COOKIE.validate_secret_key_base/1,
        (plug) lib/plug/session/cookie.ex:170: Plug.Session.COOKIE.derive/3,
        (plug) lib/plug/session/cookie.ex:112: Plug.Session.COOKIE.put/4,
        (plug) lib/plug/session.ex:95: anonymous fn/3 in Plug.Session.before_send/2,
        (elixir) lib/enum.ex:1940: Enum."-reduce/3-lists^foldl/2-0-"/3,
        (plug) lib/plug/conn.ex:1548: Plug.Conn.run_before_send/2,
        (plug) lib/plug/conn.ex:403: Plug.Conn.send_resp/1,
        (boreale) lib/plug/router.ex:259: Boreale.Router.dispatch/2,

It was the size of the encryption key 64 bytes = 512 bits. I had made a key that was 256-bits. This is the problem. It works great now. Sorry for the waste of time, thanks for the great app!!

Hey, no worries!

Yeah it can be confusing and I would lie if I said it didn't happen to me on multiple occasions too.

Glad you could get it to work!