[GH-ISSUE #741] Bypass Rules work only with Path and not IP or IP Range #1603

Closed
opened 2026-04-16 08:18:40 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @dpurnam on GitHub (May 17, 2025).
Original GitHub issue: https://github.com/fosrl/pangolin/issues/741

Thank you very much for such a great thing.

I've been testing Pangolin in an attempt to shift away from Cloudflare Tunnels.

Using the Target Rules based on IP Address (IPv4 or IPv6 - single or ranges) does not work.

However, the Target Rules based on path (for ex. /api/*) works fine on the same target, but this is a lot less secure than those based on IP addresses.

Debug logs:
2025-05-17T10:59:20.437Z [debug]: Verify session: Badger sent {"sessions":{},"originalRequestURL":"https://certs.example.com/","scheme":"","host":"certs.example.com","path":"/","method":"GET","tls":true,"requestIp":"[<correct-public-ipv6-host2>]:51002","headers":{"Accept":"*/*","User-Agent":"curl/7.88.1","X-Forwarded-Host":"certs.example.com","X-Forwarded-Port":"443","X-Forwarded-Proto":"https","X-Forwarded-Server":"amdvpn","X-Real-Ip":"<correct-public-ipv6-host2>"}} 2025-05-17T10:59:20.440Z [debug]: No more auth to check, resource not allowed 2025-05-17T10:59:20.440Z [debug]: {"data":{"valid":false,"redirectUrl":"https://pangolin.example.org/auth/resource/10?redirect=https%3A%2F%2Fcerts.example.com%2F"},"success":true,"error":false,"message":"Access denied","status":200} 2025-05-17T10:59:23.995Z [debug]: Verify session: Badger sent {"sessions":{},"originalRequestURL":"https://certs.example.com/","scheme":"","host":"certs.example.com","path":"/","method":"GET","tls":true,"requestIp":"[<correct-public-ipv6-host1>]:45430","headers":{"Accept":"*/*","User-Agent":"curl/7.88.1","X-Forwarded-Host":"certs.example.com","X-Forwarded-Port":"443","X-Forwarded-Proto":"https","X-Forwarded-Server":"amdvpn","X-Real-Ip":"<correct-public-ipv6-host1>"}} 2025-05-17T10:59:23.996Z [debug]: No more auth to check, resource not allowed 2025-05-17T10:59:23.996Z [debug]: {"data":{"valid":false,"redirectUrl":"https://pangolin.domain.com/auth/resource/10?redirect=https%3A%2F%2Fcerts.example.com%2F"},"success":true,"error":false,"message":"Access denied","status":200}

I did not use the installer but a manual docker compose and using HOST docker network_mode because using user mode pangolin network kept causing DNS 53 errors.

#networks:
#  default:
#    driver: bridge
#    name: pangolin
services:
  pangolin:
    image: fosrl/pangolin:latest
    container_name: pangolin
    network_mode: host
    restart: unless-stopped
    volumes:
      - ./config:/app/config
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
      interval: "3s"
      timeout: "3s"
      retries: 15

  gerbil:
    image: fosrl/gerbil:latest
    container_name: gerbil
    network_mode: host
    restart: unless-stopped
    depends_on:
      pangolin:
        condition: service_healthy
    command:
      - --reachableAt=http://gerbil:3003
      - --generateAndSaveKeyTo=/var/config/key
      - --remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config
      - --reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth
    volumes:
      - ./config/:/var/config
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
#    ports:
#      - 41820:41820/udp
#      - 443:443/tcp # Port for traefik because of the network_mode
#      - 80:80 # Port for traefik because of the network_mode
#      - 443:443/udp # HTTP3/QUIC

  traefik:
    image: traefik:latest #v3.3.3
    container_name: traefik
    restart: unless-stopped
#    network_mode: host
    network_mode: service:gerbil # Ports appear on the gerbil service
    depends_on:
      pangolin:
        condition: service_healthy
    command:
      - --configFile=/etc/traefik/traefik_config.yml
    # Add the environment variables for your DNS provider.
    environment:
      CLOUDFLARE_DNS_API_TOKEN: "MyToken"

    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/rules:/rules # Non-functional/Breaking mount point from Middleware Manager container

gerbil section in config.yml

gerbil:
  start_port: 41820
#  base_endpoint: "localhost"
  use_subdomain: true
  base_endpoint: "pangolin.domain.com"
#  use_subdomain: false
  block_size: 24
  site_block_size: 30
  subnet_group: 100.89.137.0/20

I feel it's some wrong configuration somewhere, I'm unable to figure out.

Originally created by @dpurnam on GitHub (May 17, 2025). Original GitHub issue: https://github.com/fosrl/pangolin/issues/741 Thank you very much for such a great thing. I've been testing Pangolin in an attempt to shift away from Cloudflare Tunnels. Using the Target Rules **based on IP Address** (IPv4 or IPv6 - single or ranges) does not work. However, the Target Rules based **on path** (for ex. /api/*) works fine on the same target, but this is _a lot less secure_ than those based on IP addresses. Debug logs: `2025-05-17T10:59:20.437Z [debug]: Verify session: Badger sent {"sessions":{},"originalRequestURL":"https://certs.example.com/","scheme":"","host":"certs.example.com","path":"/","method":"GET","tls":true,"requestIp":"[<correct-public-ipv6-host2>]:51002","headers":{"Accept":"*/*","User-Agent":"curl/7.88.1","X-Forwarded-Host":"certs.example.com","X-Forwarded-Port":"443","X-Forwarded-Proto":"https","X-Forwarded-Server":"amdvpn","X-Real-Ip":"<correct-public-ipv6-host2>"}} 2025-05-17T10:59:20.440Z [debug]: No more auth to check, resource not allowed 2025-05-17T10:59:20.440Z [debug]: {"data":{"valid":false,"redirectUrl":"https://pangolin.example.org/auth/resource/10?redirect=https%3A%2F%2Fcerts.example.com%2F"},"success":true,"error":false,"message":"Access denied","status":200} 2025-05-17T10:59:23.995Z [debug]: Verify session: Badger sent {"sessions":{},"originalRequestURL":"https://certs.example.com/","scheme":"","host":"certs.example.com","path":"/","method":"GET","tls":true,"requestIp":"[<correct-public-ipv6-host1>]:45430","headers":{"Accept":"*/*","User-Agent":"curl/7.88.1","X-Forwarded-Host":"certs.example.com","X-Forwarded-Port":"443","X-Forwarded-Proto":"https","X-Forwarded-Server":"amdvpn","X-Real-Ip":"<correct-public-ipv6-host1>"}} 2025-05-17T10:59:23.996Z [debug]: No more auth to check, resource not allowed 2025-05-17T10:59:23.996Z [debug]: {"data":{"valid":false,"redirectUrl":"https://pangolin.domain.com/auth/resource/10?redirect=https%3A%2F%2Fcerts.example.com%2F"},"success":true,"error":false,"message":"Access denied","status":200} ` I did not use the installer but a manual docker compose and using HOST docker network_mode because using user mode pangolin network kept causing DNS 53 errors. ``` #networks: # default: # driver: bridge # name: pangolin services: pangolin: image: fosrl/pangolin:latest container_name: pangolin network_mode: host restart: unless-stopped volumes: - ./config:/app/config healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"] interval: "3s" timeout: "3s" retries: 15 gerbil: image: fosrl/gerbil:latest container_name: gerbil network_mode: host restart: unless-stopped depends_on: pangolin: condition: service_healthy command: - --reachableAt=http://gerbil:3003 - --generateAndSaveKeyTo=/var/config/key - --remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config - --reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth volumes: - ./config/:/var/config cap_add: - NET_ADMIN - SYS_MODULE # ports: # - 41820:41820/udp # - 443:443/tcp # Port for traefik because of the network_mode # - 80:80 # Port for traefik because of the network_mode # - 443:443/udp # HTTP3/QUIC traefik: image: traefik:latest #v3.3.3 container_name: traefik restart: unless-stopped # network_mode: host network_mode: service:gerbil # Ports appear on the gerbil service depends_on: pangolin: condition: service_healthy command: - --configFile=/etc/traefik/traefik_config.yml # Add the environment variables for your DNS provider. environment: CLOUDFLARE_DNS_API_TOKEN: "MyToken" 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/rules:/rules # Non-functional/Breaking mount point from Middleware Manager container ``` gerbil section in config.yml ``` gerbil: start_port: 41820 # base_endpoint: "localhost" use_subdomain: true base_endpoint: "pangolin.domain.com" # use_subdomain: false block_size: 24 site_block_size: 30 subnet_group: 100.89.137.0/20 ``` I feel it's some wrong configuration somewhere, I'm unable to figure out.
GiteaMirror added the potential bugneeds investigatingbug labels 2026-04-16 08:18:40 -05:00
Author
Owner

@dpurnam commented on GitHub (May 21, 2025):

It gets weirder with IP based rules.

Why would badger treat a whitelisted IPv6 address defined under Resource Rules as an IPv4 Octet?

Error: Invalid IPv4 octet: [2402
    at <unknown> (server/lib/ip.ts:26:26)
    at Array.reduce (<anonymous>)
    at Ad (server/lib/ip.ts:23:13)
    at Ui (server/lib/ip.ts:206:21)
    at vb (server/routers/badger/verifySession.ts:602:12)
    at async DR (server/routers/badger/verifySession.ts:157:27)
  24 |                 const num = parseInt(octet);
  25 |                 if (isNaN(num) || num < 0 || num > 255) {
> 26 |                     throw new Error(`Invalid IPv4 octet: ${octet}`);
     |                          ^
  27 |                 }
  28 |                 return BigInt.asUintN(64, (acc << BigInt(8)) + BigInt(num));
  29 |             }, BigInt(0));

Additionally, I get 'internal server' error upon browsing the resource, if a combination of Active IP rules exists which includes both - IPv4 address/range along with IPv6 address/range

Accessing the Resource redirects to Pangolin Auth (and not 'internal server' error page) either with only IPv4 rules activated or only IPv6 rules activated.

I can conclude that, in my setup:

  1. Using IP based rules has no effect when Platform Auth is used
  2. Even further only one type of IP (either IPv4 or IPv6) based rules redirects to the Auth Page, instead of redirecting to the Resource Page
<!-- gh-comment-id:2896673734 --> @dpurnam commented on GitHub (May 21, 2025): It gets weirder with IP based rules. Why would badger treat a whitelisted IPv6 address defined under Resource Rules as an IPv4 Octet? ``` Error: Invalid IPv4 octet: [2402 at <unknown> (server/lib/ip.ts:26:26) at Array.reduce (<anonymous>) at Ad (server/lib/ip.ts:23:13) at Ui (server/lib/ip.ts:206:21) at vb (server/routers/badger/verifySession.ts:602:12) at async DR (server/routers/badger/verifySession.ts:157:27) 24 | const num = parseInt(octet); 25 | if (isNaN(num) || num < 0 || num > 255) { > 26 | throw new Error(`Invalid IPv4 octet: ${octet}`); | ^ 27 | } 28 | return BigInt.asUintN(64, (acc << BigInt(8)) + BigInt(num)); 29 | }, BigInt(0)); ``` Additionally, I get 'internal server' error upon browsing the resource, if a combination of Active IP rules exists which includes both - IPv4 address/range along with IPv6 address/range Accessing the Resource redirects to Pangolin Auth (and not 'internal server' error page) either with only IPv4 rules activated or only IPv6 rules activated. I can conclude that, in my setup: 1. Using IP based rules has no effect when Platform Auth is used 2. Even further only one type of IP (either IPv4 or IPv6) based rules redirects to the Auth Page, instead of redirecting to the Resource Page
Author
Owner

@github-actions[bot] commented on GitHub (Jun 5, 2025):

This issue has been automatically marked as stale due to 14 days of inactivity. It will be closed in 14 days if no further activity occurs.

<!-- gh-comment-id:2942185018 --> @github-actions[bot] commented on GitHub (Jun 5, 2025): This issue has been automatically marked as stale due to 14 days of inactivity. It will be closed in 14 days if no further activity occurs.
Author
Owner

@slimshizn commented on GitHub (Jun 5, 2025):

Still an issue.....

<!-- gh-comment-id:2943654981 --> @slimshizn commented on GitHub (Jun 5, 2025): Still an issue.....
Author
Owner

@miloschwartz commented on GitHub (Jun 5, 2025):

Will look into this

<!-- gh-comment-id:2946595713 --> @miloschwartz commented on GitHub (Jun 5, 2025): Will look into this
Author
Owner

@dpurnam commented on GitHub (Jun 24, 2025):

After upgrading to latest versions as below, this issue doesn't exist anymore. Thank you so much.
Pangolin Image - 1.5.1 (from 1.4.0)
Badger Plugin - 1.2.0 (from 1.1.0)

<!-- gh-comment-id:3000043118 --> @dpurnam commented on GitHub (Jun 24, 2025): After upgrading to latest versions as below, this issue doesn't exist anymore. Thank you so much. Pangolin Image - `1.5.1 (from 1.4.0)` Badger Plugin - `1.2.0 (from 1.1.0)`
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/pangolin#1603