[GH-ISSUE #3112] Login to Pangolin via Keycloak from internet doesn't work #19407

Open
opened 2026-05-21 20:29:06 -05:00 by GiteaMirror · 8 comments
Owner

Originally created by @alessandroarosio1977 on GitHub (May 19, 2026).
Original GitHub issue: https://github.com/fosrl/pangolin/issues/3112

Describe the Bug

  • Pangolin Hosted on VPS
  • Newt on LAN (that see all servers keycloack too)
  • Keycloak self hosted in LAN

DNS autoritative in LAN for domain (split horizon)

  • Private DNS entry for pangolin point to Pangolin IP public VPS
  • Private DNS entry for Keycloak point to keycloack LAN IP
  • Public DNS entry for pangolin point to Pangolin IP public VPS
  • Public DNS entry for Keycloak point to Pangolin IP public VPS

Pangolin resouces

  • Pangolin public resource for keycloak with target keycloak in LAN (reachable via newt)
  • Pangolin public resource for webserver with target webserver in LAN (reachable via newt)

Problem:

  • If I try to login to Keycloak from internet WORKS
  • If I try to login to webserver from internet via Keycloak, WORKS
  • If I try to login to pagolin with keycloak (properly configured) from LAN WORKS
  • If I try to login to pagolin with keycloak (properly configured) I reach keycloak login page, but when insert credentials, return error: Unable to reach the identity provider while exchanging the authorization code. Please try again. NOT WORKS

Environment

  • OS Type & Version: Ubuntu 22.04
  • Pangolin Version: 1.18.4
  • Gerbil Version: 1.4.0
  • Traefik Version: 3.7.1
  • Newt Version: 1.12.5

To Reproduce

  • If I try to login to pagolin with keycloak (properly configured) I reach keycloak login page, but when insert credentials, return error: Unable to reach the identity provider while exchanging the authorization code. Please try again. NOT WORKS

Expected Behavior

If I try to login to pagolin with keycloak (properly configured) I reach keycloak login page without issues

Originally created by @alessandroarosio1977 on GitHub (May 19, 2026). Original GitHub issue: https://github.com/fosrl/pangolin/issues/3112 ### Describe the Bug - Pangolin Hosted on VPS - Newt on LAN (that see all servers keycloack too) - Keycloak self hosted in LAN **DNS autoritative in LAN for domain (split horizon)** - Private DNS entry for pangolin point to Pangolin IP public VPS - Private DNS entry for Keycloak point to keycloack LAN IP - Public DNS entry for pangolin point to Pangolin IP **public** VPS - Public DNS entry for Keycloak point to Pangolin IP public VPS **Pangolin resouces** - Pangolin public resource for keycloak with target keycloak in LAN (reachable via newt) - Pangolin public resource for webserver with target webserver in LAN (reachable via newt) **Problem:** - If I try to login to Keycloak from internet WORKS - If I try to login to webserver from internet via Keycloak, WORKS - If I try to login to pagolin with keycloak (properly configured) from LAN WORKS - If I try to login to pagolin with keycloak (properly configured) I reach keycloak login page, but when insert credentials, return error: Unable to reach the identity provider while exchanging the authorization code. Please try again. **_NOT WORKS_** ### Environment - OS Type & Version: Ubuntu 22.04 - Pangolin Version: 1.18.4 - Gerbil Version: 1.4.0 - Traefik Version: 3.7.1 - Newt Version: 1.12.5 ### To Reproduce - If I try to login to pagolin with keycloak (properly configured) I reach keycloak login page, but when insert credentials, return **error: Unable to reach the identity provider while exchanging the authorization code. Please try again.** _NOT WORKS_ ### Expected Behavior If I try to login to pagolin with keycloak (properly configured) I reach keycloak login page without issues
Author
Owner

@deskstorm commented on GitHub (May 20, 2026):

Any way you can capture packets of what pangolin is sending in when it does a call to that proxy?
I do wonder if its like some issue talking to itself and doesnt think via the proxy?

<!-- gh-comment-id:4493603495 --> @deskstorm commented on GitHub (May 20, 2026): Any way you can capture packets of what pangolin is sending in when it does a call to that proxy? I do wonder if its like some issue talking to itself and doesnt think via the proxy?
Author
Owner

@AstralDestiny commented on GitHub (May 20, 2026):

Throw pangolin into debug,

services:
 pangolin:
  environment:
   - LOG_LEVEL=DEBUG

Though never used keycloak myself, sure it's a great program but alas it's java, I use authelia myself and no issues that and it's openID certified just like keycloak.

Also ment to post earlier forgot to press enter >.>

<!-- gh-comment-id:4494700333 --> @AstralDestiny commented on GitHub (May 20, 2026): Throw pangolin into debug, ```yml services: pangolin: environment: - LOG_LEVEL=DEBUG ``` Though never used keycloak myself, sure it's a great program but alas it's java, I use authelia myself and no issues that and it's openID certified just like keycloak. Also ment to post earlier forgot to press enter >.>
Author
Owner

@alessandroarosio1977 commented on GitHub (May 21, 2026):

This is output of pangolin docker log catched within error login:

user@pangolin:/opt/pangolin# docker compose logs pangolin -f
pangolin |
pangolin | > @fosrl/pangolin@0.0.0 start
pangolin | > ENVIRONMENT=prod node dist/migrations.mjs && ENVIRONMENT=prod NODE_ENV=development node --enable-source-maps dist/server.mjs
pangolin |
pangolin | Starting migrations from version 1.18.4
pangolin | Migrations to run:
pangolin | All migrations completed successfully
pangolin | 2026-05-21T15:30:08+00:00 [info]: Pangolin gathers anonymous usage data to help us better understand how the software is used and guide future improvements and feature development. You can find more details, including instructions for opting out of this anonymous data collection, at: https://docs.pango
lin.net/telemetry
pangolin | 2026-05-21T15:30:09+00:00 [info]: Dashboard API server is running on http://localhost:3000
pangolin | 2026-05-21T15:30:09+00:00 [info]: Internal API server is running on http://localhost:3001
pangolin | 2026-05-21T15:30:15+00:00 [info]: Dashboard Web UI server is running on http://localhost:3002
pangolin | 2026-05-21T15:30:15+00:00 [info]: Updated exit node with reachableAt to http://gerbil:3004
pangolin | 2026-05-21T15:30:22+00:00 [info]: Establishing websocket connection
pangolin | 2026-05-21T15:30:22+00:00 [info]: Client added to tracking - NEWT ID: aaaaaaaaaaaaaaaaaaaa, Connection ID: e413034e-0e14-4859-a08b-3dc24fca41c4, Total connections: 1
pangolin | 2026-05-21T15:30:22+00:00 [info]: WebSocket connection established - NEWT ID: aaaaaaaaaaaaaaaaaaaa
pangolin | 2026-05-21T15:30:22+00:00 [warn]: Newt ping with outdated config version: 30 (current: 0)
pangolin | 2026-05-21T15:30:22+00:00 [info]: Updated peer ghM+B0P0lRm2lNo9bNu039GeWnayoJ8x8T6WJx6rdFg= on olm bbbbbbbbbbbbbbbbbbbb
pangolin | 2026-05-21T15:30:22+00:00 [info]: Updated peer ghM+B0P0lRm2lNo9bNu039GeWnayoJ8x8T6WJx6rdFg= on olm ccccccccccccccccccc
pangolin | 2026-05-21T15:30:22+00:00 [info]: Initiated peer add handshake for site 1 to olm bbbbbbbbbbbbbbbbbbbb
pangolin | 2026-05-21T15:30:22+00:00 [info]: Initiated peer add handshake for site 1 to olm ccccccccccccccccccc
pangolin | 2026-05-21T15:30:22+00:00 [info]: Handling healthcheck status message
pangolin | (node:26) [DEP0169] DeprecationWarning: url.parse() behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for url.parse() vulnerabilities.
pangolin | (Use node --trace-deprecation ... to show where the warning was created)
pangolin | Making OIDC URL generation request to: http://localhost:3000/api/v1/auth/idp/2/oidc/generate-url
pangolin | Making OIDC callback validation request to: http://localhost:3000/api/v1/auth/idp/2/oidc/validate-callback
pangolin | 2026-05-21T15:31:05+00:00 [error]: Failed to reach OIDC provider while exchanging authorization code {"error":"Failed to send request"}

As you can see, seem that pangolin try to communicate with itself (http://localhost:3000...)
On keycloak, after login failed, I see user session up from IP of my PC

<!-- gh-comment-id:4509887657 --> @alessandroarosio1977 commented on GitHub (May 21, 2026): This is output of pangolin docker log catched within error login: _user@pangolin:/opt/pangolin# docker compose logs pangolin -f pangolin | pangolin | > @fosrl/pangolin@0.0.0 start pangolin | > ENVIRONMENT=prod node dist/migrations.mjs && ENVIRONMENT=prod NODE_ENV=development node --enable-source-maps dist/server.mjs pangolin | pangolin | Starting migrations from version 1.18.4 pangolin | Migrations to run: pangolin | All migrations completed successfully pangolin | 2026-05-21T15:30:08+00:00 [info]: Pangolin gathers anonymous usage data to help us better understand how the software is used and guide future improvements and feature development. You can find more details, including instructions for opting out of this anonymous data collection, at: https://docs.pango lin.net/telemetry pangolin | 2026-05-21T15:30:09+00:00 [info]: Dashboard API server is running on http://localhost:3000 pangolin | 2026-05-21T15:30:09+00:00 [info]: Internal API server is running on http://localhost:3001 pangolin | 2026-05-21T15:30:15+00:00 [info]: Dashboard Web UI server is running on http://localhost:3002 pangolin | 2026-05-21T15:30:15+00:00 [info]: Updated exit node with reachableAt to http://gerbil:3004 pangolin | 2026-05-21T15:30:22+00:00 [info]: Establishing websocket connection pangolin | 2026-05-21T15:30:22+00:00 [info]: Client added to tracking - NEWT ID: aaaaaaaaaaaaaaaaaaaa, Connection ID: e413034e-0e14-4859-a08b-3dc24fca41c4, Total connections: 1 pangolin | 2026-05-21T15:30:22+00:00 [info]: WebSocket connection established - NEWT ID: aaaaaaaaaaaaaaaaaaaa pangolin | 2026-05-21T15:30:22+00:00 [warn]: Newt ping with outdated config version: 30 (current: 0) pangolin | 2026-05-21T15:30:22+00:00 [info]: Updated peer ghM+B0P0lRm2lNo9bNu039GeWnayoJ8x8T6WJx6rdFg= on olm bbbbbbbbbbbbbbbbbbbb pangolin | 2026-05-21T15:30:22+00:00 [info]: Updated peer ghM+B0P0lRm2lNo9bNu039GeWnayoJ8x8T6WJx6rdFg= on olm ccccccccccccccccccc pangolin | 2026-05-21T15:30:22+00:00 [info]: Initiated peer add handshake for site 1 to olm bbbbbbbbbbbbbbbbbbbb pangolin | 2026-05-21T15:30:22+00:00 [info]: Initiated peer add handshake for site 1 to olm ccccccccccccccccccc pangolin | 2026-05-21T15:30:22+00:00 [info]: Handling healthcheck status message pangolin | (node:26) [DEP0169] DeprecationWarning: `url.parse()` behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities. pangolin | (Use `node --trace-deprecation ...` to show where the warning was created) pangolin | Making OIDC URL generation request to: http://localhost:3000/api/v1/auth/idp/2/oidc/generate-url pangolin | Making OIDC callback validation request to: http://localhost:3000/api/v1/auth/idp/2/oidc/validate-callback pangolin | 2026-05-21T15:31:05+00:00 [error]: Failed to reach OIDC provider while exchanging authorization code {"error":"Failed to send request"}_ As you can see, seem that pangolin try to communicate with itself (**http://localhost:3000...**) On keycloak, after login failed, I see user session up from IP of my PC
Author
Owner

@AstralDestiny commented on GitHub (May 21, 2026):

Can you put a,

services:
 gerbil:
  networks:
   default:
    aliases: 
      - keycloak.domain.com # replace me

Then down and up and see if it's happy at that point?

<!-- gh-comment-id:4510026973 --> @AstralDestiny commented on GitHub (May 21, 2026): Can you put a, ```yml services: gerbil: networks: default: aliases: - keycloak.domain.com # replace me ``` Then down and up and see if it's happy at that point?
Author
Owner

@alessandroarosio1977 commented on GitHub (May 21, 2026):

My docker-compose.yml is created by installer:

_name: pangolin
services:
pangolin:
image: docker.io/fosrl/pangolin:1.18.4
container_name: pangolin
restart: unless-stopped
deploy:
resources:
limits:
memory: 1g
reservations:
memory: 256m
volumes:
- ./config:/app/config
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
interval: "10s"
timeout: "10s"
retries: 15

gerbil:
image: docker.io/fosrl/gerbil:1.4.0
container_name: gerbil
restart: unless-stopped
depends_on:
pangolin:
condition: service_healthy
command:
- --reachableAt=http://gerbil:3004
- --generateAndSaveKeyTo=/var/config/key
- --remoteConfig=http://pangolin:3001/api/v1/
volumes:
- ./config/:/var/config
cap_add:
- NET_ADMIN
- SYS_MODULE
ports:
- 51820:51820/udp
- 21820:21820/udp
- 443:443
- 443:443/udp # For http3 QUIC if desired
- 80:80

traefik:
image: docker.io/traefik:v3.7.1
container_name: traefik
restart: unless-stopped
network_mode: service:gerbil # Ports appear on the gerbil service
depends_on:
pangolin:
condition: service_healthy
command:
- --configFile=/etc/traefik/traefik_config.yml
volumes:
- ./config/traefik:/etc/traefik:ro # Volume to store the Traefik configuration
- ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates
- ./config/traefik/logs:/var/log/traefik # Volume to store Traefik logs

networks:
default:
driver: bridge
name: pangolin_

When you say:
services:
gerbil:
networks:
default:
aliases:
- keycloak.domain.com # replace me

you mean under my networks session in docker compose or inside gerbil section of file?

<!-- gh-comment-id:4512185913 --> @alessandroarosio1977 commented on GitHub (May 21, 2026): My docker-compose.yml is created by installer: _name: pangolin services: pangolin: image: docker.io/fosrl/pangolin:1.18.4 container_name: pangolin restart: unless-stopped deploy: resources: limits: memory: 1g reservations: memory: 256m volumes: - ./config:/app/config healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"] interval: "10s" timeout: "10s" retries: 15 gerbil: image: docker.io/fosrl/gerbil:1.4.0 container_name: gerbil restart: unless-stopped depends_on: pangolin: condition: service_healthy command: - --reachableAt=http://gerbil:3004 - --generateAndSaveKeyTo=/var/config/key - --remoteConfig=http://pangolin:3001/api/v1/ volumes: - ./config/:/var/config cap_add: - NET_ADMIN - SYS_MODULE ports: - 51820:51820/udp - 21820:21820/udp - 443:443 - 443:443/udp # For http3 QUIC if desired - 80:80 traefik: image: docker.io/traefik:v3.7.1 container_name: traefik restart: unless-stopped network_mode: service:gerbil # Ports appear on the gerbil service depends_on: pangolin: condition: service_healthy command: - --configFile=/etc/traefik/traefik_config.yml volumes: - ./config/traefik:/etc/traefik:ro # Volume to store the Traefik configuration - ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates - ./config/traefik/logs:/var/log/traefik # Volume to store Traefik logs networks: default: driver: bridge name: pangolin_ When you say: **_services: gerbil: networks: default: aliases: - keycloak.domain.com # replace me_** you mean under my networks session in docker compose or inside **gerbil** section of file?
Author
Owner

@AstralDestiny commented on GitHub (May 22, 2026):

It says gerbil there. it's line by line nested into the proper location.

<!-- gh-comment-id:4513968196 --> @AstralDestiny commented on GitHub (May 22, 2026): It says gerbil there. it's line by line nested into the proper location.
Author
Owner

@AstralDestiny commented on GitHub (May 22, 2026):

It's via default as compose automatically grouped them via the "default" network,
so services: gerbil: networks: default: aliases: - key.domain.com

<!-- gh-comment-id:4514013677 --> @AstralDestiny commented on GitHub (May 22, 2026): It's via default as compose automatically grouped them via the "default" network, so services: gerbil: networks: default: aliases: - key.domain.com
Author
Owner

@deskstorm commented on GitHub (May 22, 2026):

@AstralDestiny correct me if im wrong, but this should almost be a copy and paste for them? (As i might try a SSO soon too for Pangolin) @alessandroarosio1977

gerbil:
    image: docker.io/fosrl/gerbil:1.4.0
    container_name: gerbil
    restart: unless-stopped
    depends_on:
      pangolin:
        condition: service_healthy
    command:
      - --reachableAt=http://gerbil:3004
      - --generateAndSaveKeyTo=/var/config/key
      - --remoteConfig=http://pangolin:3001/api/v1/
    volumes:
      - ./config/:/var/config
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    ports:
      - 51820:51820/udp
      - 21820:21820/udp
      - 443:443
      - 443:443/udp # For http3 QUIC if desired
      - 80:80
    networks:
      default:
        aliases: 
          - keycloak.domain.com # replace me 
<!-- gh-comment-id:4514123398 --> @deskstorm commented on GitHub (May 22, 2026): @AstralDestiny correct me if im wrong, but this should almost be a copy and paste for them? (As i might try a SSO soon too for Pangolin) @alessandroarosio1977 ``` gerbil: image: docker.io/fosrl/gerbil:1.4.0 container_name: gerbil restart: unless-stopped depends_on: pangolin: condition: service_healthy command: - --reachableAt=http://gerbil:3004 - --generateAndSaveKeyTo=/var/config/key - --remoteConfig=http://pangolin:3001/api/v1/ volumes: - ./config/:/var/config cap_add: - NET_ADMIN - SYS_MODULE ports: - 51820:51820/udp - 21820:21820/udp - 443:443 - 443:443/udp # For http3 QUIC if desired - 80:80 networks: default: aliases: - keycloak.domain.com # replace me ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/pangolin#19407