[GH-ISSUE #2749] iOS client connects, but any private site resource causes endless registering / no LAN access in Docker self-host setup #8995

Closed
opened 2026-04-30 05:11:12 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @Mathdbn on GitHub (Mar 31, 2026).
Original GitHub issue: https://github.com/fosrl/pangolin/issues/2749

Describe the Bug

Summary

I am self-hosting Pangolin in Docker with the standard Pangolin-style architecture:

  • pangolin
  • gerbil
  • traefik
  • newt

Traefik runs with:

  • network_mode: service:gerbil

The setup is hosted on Docker/Portainer on a single host.

Public access works:

  • Pangolin dashboard works
  • OIDC login works
  • iOS client can authenticate
  • base VPN/client connection works when no private/internal site resource is assigned

But as soon as I assign any private site resource to the iOS client, the client stops working correctly.

Environment

  • Pangolin: 1.16.2
  • Newt: 1.10.4
  • Self-hosted with Docker / Docker Compose / Portainer
  • Reverse proxy: Traefik
  • Gerbil ports exposed on Docker host:
    • 80/tcp
    • 443/tcp
    • 51820/udp
    • 21820/udp
  • Public IPv4: full stack, not shared
  • Router: Freebox Pop
  • iPhone client tested on iOS app
  • Mobile operator tested: Bouygues

Networking layout

Docker host LAN IP:

  • 192.168.1.99

Example LAN resources tested:

  • 192.168.1.254
  • 192.168.1.200

Expected behavior

  • iOS client connects
  • private site resource is pushed to client
  • client can access LAN/internal target through Pangolin

Actual behavior

If no private site resource is assigned:

  • iOS client can connect
  • VPN/client session appears OK
  • but no internal site is reachable (No site connected)

If I assign one private site resource:

  • client starts failing
  • access to internal resources no longer works
  • the client may stay in Registering
  • removing the private resource makes the client work again

This happens even after:

  • recreating the iPhone client
  • archiving/removing old iPhone clients
  • recreating the newt site entirely
  • testing with different internal destinations
  • testing both host mode and CIDR mode

Important observation

The problem is not tied to one single host.

I first suspected 192.168.1.254, but the same problem happens with another LAN target like 192.168.1.200.

So the pattern seems to be:

  • VPN base connectivity: OK
  • adding any private/internal site resource: KO

Logs

Pangolin

I repeatedly get logs like:

Client last hole punch is too old and we have sites to send; skipping this register

In some cases, after assigning private resources, I also saw:
handleOlmServerPeerAddMessage: No endpoint found for client 2

Client behavior
iOS app authenticates successfully
device/session looks connected
but internal routing never becomes usable once private resources are assigned
Things already checked
Docker stack is healthy
Pangolin, Gerbil, Traefik, Newt are up
gerbil listens on:
51820/udp
21820/udp
router/NAT forwards these UDP ports correctly
public IPv4 is full stack
no CGNAT issue
recreating the newt site did not solve it
recreating iPhone client did not solve it
issue persists with different private resources
Question
Is this a known limitation or bug of:

iOS OLM clients with private site resources
Docker self-host with pangolin + gerbil + traefik + newt
or site resource routing/state handling in Pangolin?
Is there a recommended way to make private/internal site resources work reliably for iOS clients in a Docker deployment like this?


### Environment

OS Type & Version: Debian/Ubuntu-based Docker host on Portainer-managed MiniPC (host LAN IP 192.168.1.99)
Si tu veux être exact, donne-moi le résultat de cat /etc/os-release sur le host et je te mets la valeur exacte.

Pangolin Version: 1.16.2

Gerbil Version: latest
Si tu veux l’exacte, je peux te la lire depuis l’image runtime.

Traefik Version: 3.6.12

Newt Version: 1.10.4

Olm Version: iOS client app

### To Reproduce

1. Deploy Pangolin in Docker with:
   - `pangolin`
   - `gerbil`
   - `traefik`
   - `newt`
   - `traefik` using `network_mode: service:gerbil`

2. Expose the standard ports on `gerbil`:
   - `80/tcp`
   - `443/tcp`
   - `51820/udp`
   - `21820/udp`

3. Create a `newt` site and connect it successfully.

4. Install the iOS client and authenticate it successfully.

5. Confirm that with no private/internal site resource assigned, the client can connect but shows no internal site access.

6. Create a private site resource (tested with both host and CIDR modes), for example:
   - `192.168.1.254`
   - `192.168.1.254/32`
   - `192.168.1.200`
   and assign it to the user/role/client.

7. Reconnect the iOS client.

8. Observe that the client stops working correctly:
   - stays on `Registering` or
   - no longer gets usable internal access
   - removing the private resource restores base connectivity


### Expected Behavior

When a private site resource is assigned to the iOS client, the client should remain connected and be able to reach the internal destination through Pangolin.

In other words:
- client authentication succeeds
- OLM/VPN tunnel remains usable
- assigned private/internal site resources become reachable
- adding a private resource should not break the client connection state
Originally created by @Mathdbn on GitHub (Mar 31, 2026). Original GitHub issue: https://github.com/fosrl/pangolin/issues/2749 ### Describe the Bug ## Summary I am self-hosting Pangolin in Docker with the standard Pangolin-style architecture: - `pangolin` - `gerbil` - `traefik` - `newt` Traefik runs with: - `network_mode: service:gerbil` The setup is hosted on Docker/Portainer on a single host. Public access works: - Pangolin dashboard works - OIDC login works - iOS client can authenticate - base VPN/client connection works when no private/internal site resource is assigned But as soon as I assign any private site resource to the iOS client, the client stops working correctly. ## Environment - Pangolin: `1.16.2` - Newt: `1.10.4` - Self-hosted with Docker / Docker Compose / Portainer - Reverse proxy: Traefik - Gerbil ports exposed on Docker host: - `80/tcp` - `443/tcp` - `51820/udp` - `21820/udp` - Public IPv4: full stack, not shared - Router: Freebox Pop - iPhone client tested on iOS app - Mobile operator tested: Bouygues ## Networking layout Docker host LAN IP: - `192.168.1.99` Example LAN resources tested: - `192.168.1.254` - `192.168.1.200` ## Expected behavior - iOS client connects - private site resource is pushed to client - client can access LAN/internal target through Pangolin ## Actual behavior If no private site resource is assigned: - iOS client can connect - VPN/client session appears OK - but no internal site is reachable (`No site connected`) If I assign one private site resource: - client starts failing - access to internal resources no longer works - the client may stay in `Registering` - removing the private resource makes the client work again This happens even after: - recreating the iPhone client - archiving/removing old iPhone clients - recreating the `newt` site entirely - testing with different internal destinations - testing both host mode and CIDR mode ## Important observation The problem is not tied to one single host. I first suspected `192.168.1.254`, but the same problem happens with another LAN target like `192.168.1.200`. So the pattern seems to be: - VPN base connectivity: OK - adding any private/internal site resource: KO ## Logs ### Pangolin I repeatedly get logs like: ```text Client last hole punch is too old and we have sites to send; skipping this register In some cases, after assigning private resources, I also saw: handleOlmServerPeerAddMessage: No endpoint found for client 2 Client behavior iOS app authenticates successfully device/session looks connected but internal routing never becomes usable once private resources are assigned Things already checked Docker stack is healthy Pangolin, Gerbil, Traefik, Newt are up gerbil listens on: 51820/udp 21820/udp router/NAT forwards these UDP ports correctly public IPv4 is full stack no CGNAT issue recreating the newt site did not solve it recreating iPhone client did not solve it issue persists with different private resources Question Is this a known limitation or bug of: iOS OLM clients with private site resources Docker self-host with pangolin + gerbil + traefik + newt or site resource routing/state handling in Pangolin? Is there a recommended way to make private/internal site resources work reliably for iOS clients in a Docker deployment like this? ### Environment OS Type & Version: Debian/Ubuntu-based Docker host on Portainer-managed MiniPC (host LAN IP 192.168.1.99) Si tu veux être exact, donne-moi le résultat de cat /etc/os-release sur le host et je te mets la valeur exacte. Pangolin Version: 1.16.2 Gerbil Version: latest Si tu veux l’exacte, je peux te la lire depuis l’image runtime. Traefik Version: 3.6.12 Newt Version: 1.10.4 Olm Version: iOS client app ### To Reproduce 1. Deploy Pangolin in Docker with: - `pangolin` - `gerbil` - `traefik` - `newt` - `traefik` using `network_mode: service:gerbil` 2. Expose the standard ports on `gerbil`: - `80/tcp` - `443/tcp` - `51820/udp` - `21820/udp` 3. Create a `newt` site and connect it successfully. 4. Install the iOS client and authenticate it successfully. 5. Confirm that with no private/internal site resource assigned, the client can connect but shows no internal site access. 6. Create a private site resource (tested with both host and CIDR modes), for example: - `192.168.1.254` - `192.168.1.254/32` - `192.168.1.200` and assign it to the user/role/client. 7. Reconnect the iOS client. 8. Observe that the client stops working correctly: - stays on `Registering` or - no longer gets usable internal access - removing the private resource restores base connectivity ### Expected Behavior When a private site resource is assigned to the iOS client, the client should remain connected and be able to reach the internal destination through Pangolin. In other words: - client authentication succeeds - OLM/VPN tunnel remains usable - assigned private/internal site resources become reachable - adding a private resource should not break the client connection state
Author
Owner

@Mathdbn commented on GitHub (Mar 31, 2026):

The issue was not related to open ports, but to the internal subnet used by Gerbil.

By default, Pangolin uses the subnet 100.89.137.0/20, which belongs to the CGNAT address space. While this range is intended to avoid conflicts with common private networks (192.168.x.x, 10.x.x.x, etc.), the documentation also states that you should change it if it conflicts with your network environment.

In my case, the VPN worked fine over Wi-Fi but failed on 4G/5G. This strongly suggests a routing conflict with the mobile network, which also relies on CGNAT. Since the ports (51820/udp and 21820/udp) were correctly opened and reachable, the issue was not network exposure but the internal tunnel addressing.

The fix was to update the Pangolin configuration (config.yml) in the gerbil section, replacing: subnet_group: "100.89.137.0/20"

with a non-conflicting private range: subnet_group: "10.250.0.0/16"

Final working configuration:
gerbil:
start_port: 51820
clients_start_port: 21820
base_endpoint: "xx.xx.comr"
subnet_group: "10.250.0.0/16"
block_size: 24
site_block_size: 30

Summary:
• The problem was caused by a subnet conflict in Pangolin’s internal VPN network.
• The fix is to change subnet_group in config.yml to a range that does not overlap with your environment.
• This resolves issues where the VPN works on Wi-Fi but fails on mobile networks.

<!-- gh-comment-id:4164793101 --> @Mathdbn commented on GitHub (Mar 31, 2026): The issue was not related to open ports, but to the internal subnet used by Gerbil. By default, Pangolin uses the subnet 100.89.137.0/20, which belongs to the CGNAT address space. While this range is intended to avoid conflicts with common private networks (192.168.x.x, 10.x.x.x, etc.), the documentation also states that you should change it if it conflicts with your network environment. In my case, the VPN worked fine over Wi-Fi but failed on 4G/5G. This strongly suggests a routing conflict with the mobile network, which also relies on CGNAT. Since the ports (51820/udp and 21820/udp) were correctly opened and reachable, the issue was not network exposure but the internal tunnel addressing. The fix was to update the Pangolin configuration (config.yml) in the gerbil section, replacing: subnet_group: "100.89.137.0/20" with a non-conflicting private range: subnet_group: "10.250.0.0/16" Final working configuration: gerbil: start_port: 51820 clients_start_port: 21820 base_endpoint: "xx.xx.comr" subnet_group: "10.250.0.0/16" block_size: 24 site_block_size: 30 Summary: • The problem was caused by a subnet conflict in Pangolin’s internal VPN network. • The fix is to change subnet_group in config.yml to a range that does not overlap with your environment. • This resolves issues where the VPN works on Wi-Fi but fails on mobile networks.
Author
Owner

@latiche commented on GitHub (Apr 14, 2026):

I have the same issue (client stuck on "Registering" when adding private resource)
I thought it would be a similar cause since I am also testing on LTE network with CGNAT so I updated the gerbil section as you did
Unfortunately, that was not enough to solve the issue for me

edit : I am having this issue : https://github.com/fosrl/olm/issues/108

For reference, if you change the subnet, you either have to recreate all sites / resources, or update database

here is what I did (docker) :

cd /opt/pangolin
docker compose down
cd /opt/pangolin/config/db
cp db.sqlite db.sqlite.backup
apt install sqllite3
sqlite3
UPDATE sites SET subnet = REPLACE(subnet, '100.89', '10.250') WHERE subnet LIKE '100.89%'; UPDATE sites SET address = REPLACE(address, '100.90', '10.251') WHERE address LIKE '100.90%';
UPDATE orgs SET subnet = REPLACE(subnet, '100.90', '10.251') WHERE subnet LIKE '100.90%';
UPDATE orgs SET utilitySubnet = REPLACE(utilitySubnet, '100.96', '10.252') WHERE utilitySubnet LIKE '100.96%';
UPDATE exitNodes SET address = REPLACE(address, '100.89', '10.250') WHERE address LIKE '100.89%';
UPDATE clients SET subnet = REPLACE(subnet, '100.90', '10.251') WHERE subnet LIKE '100.90%';
SELECT * FROM clients;
SELECT * FROM sites;
SELECT * FROM orgs;
SELECT * FROM exitNodes;
docker compose down && docker compose up -d
<!-- gh-comment-id:4242622736 --> @latiche commented on GitHub (Apr 14, 2026): I have the same issue (client stuck on "Registering" when adding private resource) I thought it would be a similar cause since I am also testing on LTE network with CGNAT so I updated the gerbil section as you did Unfortunately, that was not enough to solve the issue for me edit : I am having this issue : https://github.com/fosrl/olm/issues/108 For reference, if you change the subnet, you either have to recreate all sites / resources, or update database here is what I did (docker) : ``` cd /opt/pangolin docker compose down cd /opt/pangolin/config/db cp db.sqlite db.sqlite.backup apt install sqllite3 sqlite3 UPDATE sites SET subnet = REPLACE(subnet, '100.89', '10.250') WHERE subnet LIKE '100.89%'; UPDATE sites SET address = REPLACE(address, '100.90', '10.251') WHERE address LIKE '100.90%'; UPDATE orgs SET subnet = REPLACE(subnet, '100.90', '10.251') WHERE subnet LIKE '100.90%'; UPDATE orgs SET utilitySubnet = REPLACE(utilitySubnet, '100.96', '10.252') WHERE utilitySubnet LIKE '100.96%'; UPDATE exitNodes SET address = REPLACE(address, '100.89', '10.250') WHERE address LIKE '100.89%'; UPDATE clients SET subnet = REPLACE(subnet, '100.90', '10.251') WHERE subnet LIKE '100.90%'; SELECT * FROM clients; SELECT * FROM sites; SELECT * FROM orgs; SELECT * FROM exitNodes; docker compose down && docker compose up -d ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/pangolin#8995