What about getting client public IPs? #1559

Closed
opened 2026-04-05 19:34:27 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @chris-coria on 4/29/2025

By default, pangolin is using this network:

networks:
  default:
    driver: bridge
    name: pangolin

So it means it is behind Docker NAT, and thus, Pangolin cannot get real IP because it is using network's default gateway.

The only solution is by exposing Gerbil to network_mode: host but doing so, Docker hostnames won't be available. But, if you change things like --reachableAt, --remoteConfig or --reportBandwidthTo, it won't work and show a HTTP Bad Gateway error in the Pangolin dashboard.

So, how to achieve this in order to log in the Traefik's access.log the real IP? Things like Traefik's plugins to achieve this won't work as I described, it is behind Docker NAT. And "mode: host" in "ports" won't work for docker compose files.

This is the docker-compose.yml I am trying to modify:

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

  gerbil:
    image: fosrl/gerbil:1.0.0
    container_name: gerbil
    restart: unless-stopped
    depends_on:
      pangolin:
        condition: service_healthy
    command:
      - --reachableAt=http://localhost:3003
      - --generateAndSaveKeyTo=/var/config/key
      - --remoteConfig=http://localhost:3001/api/v1/gerbil/get-config
      - --reportBandwidthTo=http://localhost:3001/api/v1/gerbil/receive-bandwidth
    volumes:
      - ./config/:/var/config
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    network_mode: host
      
  traefik:
    image: traefik:latest
    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
    environment:
      - CF_DNS_API_TOKEN=${CLOUDFLARE_API_KEY}
    volumes:
      - ./config/traefik:/etc/traefik:ro # Volume to store the Traefik configuration
      - ./config/crowdsec:/etc/crowdsec:ro # Volume to store the Crowdsec's Appsec configurations
      - ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates
      - ./config/logs/:/var/log/traefik/ # Storage for Traefik logs.

And this is the config.yml file:

app:
  dashboard_url: "https://pangolin.example.com"
  log_level: "info"
  save_logs: true

domains:
  domain1:
    base_domain: "example.com"
    cert_resolver: "cloudflare"
    prefer_wildcard_cert: true

server:
  external_port: 3000
  internal_port: 3001
  next_port: 3002
  internal_hostname: "localhost"
  session_cookie_name: "p_session_token"
  resource_access_token_param: "p_token"
  resource_access_token_headers:
    id: "P-Access-Token-Id"
    token: "P-Access-Token"
  resource_session_request_param: "p_session_request"

traefik:
  cert_resolver: "cloudflare"
  http_entrypoint: "web"
  https_entrypoint: "websecure"

gerbil:
  start_port: 51820
  base_endpoint: "pangolin.example.com"
  use_subdomain: false
  block_size: 24
  site_block_size: 30
  subnet_group: 100.89.137.0/20

rate_limits:
  global:
    window_minutes: 1
    max_requests: 100

email:
  smtp_host: "smtp.example.com"
  smtp_port: 465
  smtp_user: "support@example.com"
  smtp_pass: "xxxxxxxxxxx"
  no_reply: "support@example.com"

users:
  server_admin:
    email: "user@example.com"
    password: "xxxxxxxxxxxxxxxxxx"

flags:
  require_email_verification: true
  disable_signup_without_invite: true
  disable_user_create_org: true
  allow_raw_resources: true
  allow_base_domain_resources: true
*Originally created by @chris-coria on 4/29/2025* By default, pangolin is using this network: ```yml networks: default: driver: bridge name: pangolin ``` So it means it is behind Docker NAT, and thus, Pangolin cannot get real IP because it is using network's default gateway. The only solution is by exposing Gerbil to `network_mode: host` but doing so, **_Docker hostnames won't be available_**. But, if you change things like `--reachableAt`, `--remoteConfig` or `--reportBandwidthTo`, it won't work and show a **_HTTP Bad Gateway error_** in the Pangolin dashboard. So, how to achieve this in order to log in the Traefik's `access.log` the real IP? Things like Traefik's plugins to achieve this won't work as I described, it is behind Docker NAT. And "mode: host" in "ports" won't work for docker compose files. This is the docker-compose.yml I am trying to modify: ```yml services: pangolin: image: fosrl/pangolin:1.2.0 container_name: pangolin restart: unless-stopped volumes: - ./config:/app/config healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"] interval: "3s" timeout: "3s" retries: 15 network_mode: host gerbil: image: fosrl/gerbil:1.0.0 container_name: gerbil restart: unless-stopped depends_on: pangolin: condition: service_healthy command: - --reachableAt=http://localhost:3003 - --generateAndSaveKeyTo=/var/config/key - --remoteConfig=http://localhost:3001/api/v1/gerbil/get-config - --reportBandwidthTo=http://localhost:3001/api/v1/gerbil/receive-bandwidth volumes: - ./config/:/var/config cap_add: - NET_ADMIN - SYS_MODULE network_mode: host traefik: image: traefik:latest 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 environment: - CF_DNS_API_TOKEN=${CLOUDFLARE_API_KEY} volumes: - ./config/traefik:/etc/traefik:ro # Volume to store the Traefik configuration - ./config/crowdsec:/etc/crowdsec:ro # Volume to store the Crowdsec's Appsec configurations - ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates - ./config/logs/:/var/log/traefik/ # Storage for Traefik logs. ``` And this is the config.yml file: ```yml app: dashboard_url: "https://pangolin.example.com" log_level: "info" save_logs: true domains: domain1: base_domain: "example.com" cert_resolver: "cloudflare" prefer_wildcard_cert: true server: external_port: 3000 internal_port: 3001 next_port: 3002 internal_hostname: "localhost" session_cookie_name: "p_session_token" resource_access_token_param: "p_token" resource_access_token_headers: id: "P-Access-Token-Id" token: "P-Access-Token" resource_session_request_param: "p_session_request" traefik: cert_resolver: "cloudflare" http_entrypoint: "web" https_entrypoint: "websecure" gerbil: start_port: 51820 base_endpoint: "pangolin.example.com" use_subdomain: false block_size: 24 site_block_size: 30 subnet_group: 100.89.137.0/20 rate_limits: global: window_minutes: 1 max_requests: 100 email: smtp_host: "smtp.example.com" smtp_port: 465 smtp_user: "support@example.com" smtp_pass: "xxxxxxxxxxx" no_reply: "support@example.com" users: server_admin: email: "user@example.com" password: "xxxxxxxxxxxxxxxxxx" flags: require_email_verification: true disable_signup_without_invite: true disable_user_create_org: true allow_raw_resources: true allow_base_domain_resources: true ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/pangolin#1559