Created
November 6, 2025 08:36
-
-
Save proofrock/55c7338336eb69e2713f9597f9a7c646 to your computer and use it in GitHub Desktop.
IP filtering for Pangolin console, with HaProxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| This adds IP filtering for the Pangolin console; it will work normally for the Pangolin resources, but access to the console will be restricted to connections coming from a given IP. | |
| I tested it with the following versions; it should work with several other too. | |
| - Pangolin 1.12.1 | |
| - Gerbil 1.2.2 | |
| - Traefik 3.5.4 | |
| - Badger 1.2.1 | |
| Things to replace in the instructions below: | |
| - base URL of the console (below, look for `pan.example.com`) | |
| - IP address to allow (below, look for `123.456.789.123`) | |
| ## Step 1 - install haproxy and configure gerbil | |
| 1. Edit the `docker-compose.yaml` you already have, adding the `haproxy` service and disabling port 80/443 for `gerbil`. | |
| ```yaml | |
| services: | |
| haproxy: | |
| image: haproxy:alpine | |
| container_name: haproxy | |
| networks: | |
| - default | |
| ports: | |
| - "80:80" | |
| - "443:443" | |
| volumes: | |
| - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro | |
| restart: unless-stopped | |
| [...] | |
| gerbil: | |
| [...] | |
| ports: | |
| - 51820:51820/udp | |
| # Commented out as they're managed by haproxy | |
| # - 443:443 # Port for traefik because of the network_mode | |
| # - 80:80 # Port for traefik because of the network_mode | |
| [...] | |
| ``` | |
| # Step 2 - enable proxy protocol for `traefik` | |
| 1. Get the internal CIDR of the `pangolin` (also called `default`) subnet in Pangolin | |
| ```bash | |
| #> docker network inspect pangolin | grep Subnet | |
| "Subnet": "172.18.0.0/16", | |
| ``` | |
| 2. Edit the `traefik` config file, `config/traefik/traefik_config.yml`: | |
| ```yaml | |
| [...] | |
| entryPoints: | |
| web: | |
| address: ":80" | |
| proxyProtocol: # Add this block | |
| trustedIPs: | |
| - "172.18.0.0/16" | |
| websecure: | |
| address: ":443" | |
| proxyProtocol: # Add this block | |
| trustedIPs: | |
| - "172.18.0.0/16" | |
| [...] | |
| ``` | |
| ## Step 3 - define the `haproxy.cfg` config file for `haproxy` | |
| 1. Put this in the same path as `docker-compose.yaml` and replace the placeholder values (`pan.example.com` and `123.456.789.123`) in the `acl` lines | |
| ``` | |
| global | |
| log stdout format raw local0 | |
| maxconn 4096 | |
| defaults | |
| log global | |
| mode tcp | |
| option tcplog | |
| timeout connect 5s | |
| timeout client 50s | |
| timeout server 50s | |
| frontend http_in | |
| bind *:80 | |
| mode tcp | |
| default_backend pangolin_http | |
| frontend https_in | |
| bind *:443 | |
| mode tcp | |
| tcp-request inspect-delay 5s | |
| # Define ACLs | |
| acl is_ip_limited req.ssl_sni -i pan.example.com | |
| acl allowed_ip src 123.456.789.123 | |
| # Block limited endpoint unless from allowed IP | |
| tcp-request content reject if is_ip_limited !allowed_ip | |
| # Else accept SSL traffic | |
| tcp-request content accept if { req_ssl_hello_type 1 } | |
| default_backend pangolin_https | |
| backend pangolin_http | |
| mode tcp | |
| server pangolin gerbil:80 send-proxy-v2 check | |
| backend pangolin_https | |
| mode tcp | |
| server pangolin gerbil:443 send-proxy-v2 check | |
| ``` | |
| ## Step 4 - apply everything | |
| ```bash | |
| #> docker compose pull | |
| #> docker compose up -d | |
| #> docker restart traefik | |
| ``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment