Repository navigation
Description
Describe the Bug
The --tls-client-cert flag on pangolin up client is documented and accepted by the CLI, but the certificate is not used for the initial API health check. As a result, when the Pangolin server is fronted by a reverse proxy (e.g. Traefik) configured with clientAuthType: RequireAndVerifyClientCert, the client always fails before the tunnel can be established.
Root cause
In internal/client/up.go (≈ line 270 in 0.8.0):
healthClient, err = api.InitClient(endpoint, "")
...
healthOk, healthErr := healthClient.CheckHealth()
if healthErr != nil || !healthOk {
err := fmt.Errorf("the server appears to be down: %w", healthErr)
...
}The healthClient is initialized via api.InitClient(endpoint, "") with no reference to opts.TlsClientCert. The TLS client certificate is only attached later, when building the TunnelConfig:
tunnelConfig := olmpkg.TunnelConfig{
...
TlsClientCert: opts.TlsClientCert,
...
}So the CheckHealth() call on the API client always runs without a client certificate. When the Pangolin server enforces mTLS, the TLS handshake fails with tls: certificate required and the CLI exits before the tunnel is ever started.
Environment
- OS Type & Version: Linux Debian 12
- Pangolin Version: 1.17.0
- Traefik Version: v3.6.13
- Client Version: pangolin up client (CLI 0.8.0) : Tested on
0.6.0and0.8.0(linux_amd64).
To Reproduce
sudo /usr/local/bin/pangolin up \
--id \
--secret \
--endpoint https://tunnel.example.com \
--override-dns=false \
--tls-client-cert /path/to/client.p12 \
--log-level debug \
--attachOutput:
A new version is available: 0.8.0 (current: 0.6.0)
Run 'pangolin update' to update to the latest version
Error: the server appears to be down: server unreachable: Get "https://tunnel.example.com/api/v1": remote error: tls: certificate required
Please check that the server is running and accessible.
Expected Behavior
When --tls-client-cert is provided, the certificate should be used for all TLS handshakes the client makes against the Pangolin server, including the initial CheckHealth() call and any other API calls performed during startup, not only the tunnel runtime.
Workarounds tried
- PKCS12 file generated with
step certificate p12 ... --no-password --insecure— same error. - Concatenated PEM bundle (cert + key) passed to
--tls-client-cert— same error. - Upgrade
0.6.0 → 0.8.0viapangolin update— same error.
Impact
This makes mTLS-protected Pangolin admin/API endpoints unusable with the CLI client. The only current workaround on the deployment side is to remove mtls-strict from the api-router (and ws-router) entrypoints, which weakens the security posture by exposing the API to anyone who can reach the entrypoint.
Notes
- The
newtclient (1.11.0) does not have this problem because its--tls-client-cert-fileand--tls-client-keyare honored both for the WebSocket connection and the token endpoint. - I would be happy to test a patched build if a fix is proposed.
Activity