403 Forbidden in reverse proxy configuration

Hello. I am trying to access my Vikunja instance through the internet. I have Vikunja set up with docker, using nginx as proxy. On the outside, I’m using SWAG, by LinuxServer. Thus, my access layout looks like this:

WAN → vikunja.mydomain.com → SWAG (nginx as Reverse Proxy + Authelia) → Vikunja’s nginx → Vikunja

I’ve managed to configure access through SWAG correctly, but when arriving at Vikunja, I get a 403 Forbidden error. Everything works correctly when Vikunja is accessed from within my local network. If I were to guess, I think it’s because the frontend URL is not specified correctly (since I’m not really sure what it is). Here are my configurations:

Vikunja’s docker-compose.yml:

version: '3'

services:
  db:
    image: ghcr.io/linuxserver/mariadb
    container_name: vikunja_db
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=db_rootpassword
      - TZ=Europe/London
      - MYSQL_DATABASE=db_name
      - MYSQL_USER=db_user
      - MYSQL_PASSWORD=db_password
    volumes:
      - /home/user/data/vikunja/mariadb:/config
    restart: unless-stopped
  api:
    image: vikunja/api
    container_name: vikunja_api
    ports:
      - 3456:3456
    environment:
      VIKUNJA_DATABASE_HOST: vikunja_db
      VIKUNJA_DATABASE_PASSWORD: db_password
      VIKUNJA_DATABASE_TYPE: mysql
      VIKUNJA_DATABASE_USER: db_user
      VIKUNJA_DATABASE_DATABASE: db_name
      VIKUNJA_SERVICE_ENABLETASKATTACHMENTS: 1
    volumes: 
      - /home/user/data/vikunja:/app/vikunja/files
    depends_on:
      - db
    restart: unless-stopped
  frontend:
    image: vikunja/frontend
    container_name: vikunja_frontend
    restart: unless-stopped
  proxy:
    image: nginx
    container_name: vikunja_proxy
    ports:
      - 8022:80
    volumes:
      - /home/user/data/vikunja/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - api
      - frontend
    restart: unless-stopped

SWAG’s nginx reverse proxy configuration:

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name vikunja.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    # enable for Authelia
    include /config/nginx/authelia-server.conf;

    # geoip block
    if ($denied_highrisk = no) { return 444; }

    location / {
        # enable for Authelia
        include /config/nginx/authelia-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app vikunja_proxy;
        set $upstream_port 8022;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

        root   /;
        try_files $uri $uri/ /;
        index  index.html index.htm;
        
    }
    
    location ~* ^/(api|dav|\.well-known)/ {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $api_app  vikunja_api;
        set $api_port 3456;
        set $api_proto http;
        proxy_pass $api_proto://$api_app:$api_port;
        client_max_body_size 20M;
    }
}

Perhaps it has something to do with the root parameter?

Thank you for your help and work.

You probably don’t need the root, try_files, or index parameters in your config. Those are used to serve files.

What are you using as an nginx config in vikunjas proxy? Did you take a look at the example in the docs?

You should be fine proxying swag to vikunjas proxy, with no need to configure the api proxy in swag.

I’ve commented out root, try_files and index, as well as the API section in SWAG’s reverse proxy configuration. My Vikunja’s nginx.conf looks like this:

server {
    listen 80;

    location / {
        proxy_pass http://frontend:80;
    }

    location ~* ^/(api|dav|\.well-known)/ {
        proxy_pass http://api:3456;
        client_max_body_size 20M;
    }
}

I am still getting a 403 error. Thanks for taking your time to look into my issue.

Where does the 403 happen? In Vikunja’s frontend? In the proxy? In swag? Please check the logs.

They seem to happen at SWAG’s level:

/swag/log/nginx/access.log:

[02/Nov/2021:17:43:37 +0100] "GET / HTTP/2.0" 302 138 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0"
[02/Nov/2021:17:43:37 +0100] "GET /authelia/?rd=https://vikunja.mydomain.com/ HTTP/2.0" 200 510 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0"
[02/Nov/2021:17:43:37 +0100] "GET /authelia/static/js/index.829172be.js HTTP/2.0" 200 57310 "https://vikunja.mydomain.com/authelia/?rd=https://vikunja.mydomain.com/" "Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0"
[02/Nov/2021:17:43:38 +0100] "GET /authelia/static/js/vendor.d0bc79df.js HTTP/2.0" 200 482039 "https://vikunja.mydomain.com/authelia/static/js/index.829172be.js" "Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0"
[02/Nov/2021:17:43:38 +0100] "GET /authelia/api/state HTTP/2.0" 200 92 "https://vikunja.mydomain.com/authelia/?rd=https://vikunja.mydomain.com/" "Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0"
[02/Nov/2021:17:43:53 +0100] "POST /authelia/api/firstfactor HTTP/2.0" 200 68 "https://vikunja.mydomain.com/authelia/?rd=https%3A%2F%2Fvikunja.mydomain.com%2F" "Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0"
[02/Nov/2021:17:43:53 +0100] "GET / HTTP/2.0" 403 107 "https://vikunja.mydomain.com/authelia/?rd=https%3A%2F%2Fvikunja.mydomain.com%2F" "Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0"

I don’t really know anything about sawg, not sure how I can help you there.

One thing I did notice was the port of the frontend you specified in the config: you exposed port 8022 to the outside world (outside of docker) but then set it to use that and the docker network name of the frontend container. Does it work if you set that to port 80 in swags config file?

Can you reach the api through swag? For example at /api/v1/info ?

I’m using the alternative port because 80 is already occupied by SWAG’s reverse proxy, which function is to redirect it to 443. I don’t know what could be wrong. I now understand that my problem isn’t related to Vikunja itself. I’ll try asking around LinuxServer Discord. Thanks for your help!

1 Like

But it only uses port 80 inside of the container. You don’t need to expose it when talking to the container directly from another container in the same network.

That sounds like a good idea! If you find something useful, let me know so we can add that to the docs.

Ugh, I feel so dumb. I forgot to whitelist the subdomain in Authelia’s configuration. Sorry to bother you. Everything works now. Many thanks for the help!

1 Like

Don’t worry, happens to the best :slight_smile: