Document UniFi OpenClash proxy bypass
This commit is contained in:
@@ -27,6 +27,8 @@ Also readable as `agent.md` (symlink → this file).
|
|||||||
| **mx2.windy.me** | mailcow (`/opt/mail`, project `cow`) | `ssh -4 windy@mx2.windy.me` | [hosts/mx2.windy.me.md](hosts/mx2.windy.me.md) |
|
| **mx2.windy.me** | mailcow (`/opt/mail`, project `cow`) | `ssh -4 windy@mx2.windy.me` | [hosts/mx2.windy.me.md](hosts/mx2.windy.me.md) |
|
||||||
| **us2.wsvc.info** | Vaultwarden + Traefik (+ Soft Serve, …) | `ssh -4 windy@us2.wsvc.info` | [hosts/us2.wsvc.info.md](hosts/us2.wsvc.info.md) |
|
| **us2.wsvc.info** | Vaultwarden + Traefik (+ Soft Serve, …) | `ssh -4 windy@us2.wsvc.info` | [hosts/us2.wsvc.info.md](hosts/us2.wsvc.info.md) |
|
||||||
| **hk2.chans.xyz** | PowerDNS auth ns1 (`/opt/pdns`) | `ssh -4 windy@hk2.chans.xyz` | [hosts/hk2.chans.xyz.md](hosts/hk2.chans.xyz.md) |
|
| **hk2.chans.xyz** | PowerDNS auth ns1 (`/opt/pdns`) | `ssh -4 windy@hk2.chans.xyz` | [hosts/hk2.chans.xyz.md](hosts/hk2.chans.xyz.md) |
|
||||||
|
| **gfw.windy.lan** | OpenWrt LAN gateway / OpenClash | `ssh -4 root@192.168.66.1` | [hosts/gfw.windy.lan.md](hosts/gfw.windy.lan.md) |
|
||||||
|
| **ubnt** | UniFi Network Controller | `ssh -4 windy@192.168.66.46` | [hosts/ubnt.md](hosts/ubnt.md) |
|
||||||
|
|
||||||
### Public services
|
### Public services
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ Also readable as `agent.md` (symlink → this file).
|
|||||||
| Matrix health | [runbooks/matrix-health.md](runbooks/matrix-health.md) |
|
| Matrix health | [runbooks/matrix-health.md](runbooks/matrix-health.md) |
|
||||||
| Matrix upstream refs | [docs/matrix-upstream.md](docs/matrix-upstream.md) |
|
| Matrix upstream refs | [docs/matrix-upstream.md](docs/matrix-upstream.md) |
|
||||||
| Hermes Agent Matrix channel | [docs/hermes-matrix.md](docs/hermes-matrix.md) |
|
| Hermes Agent Matrix channel | [docs/hermes-matrix.md](docs/hermes-matrix.md) |
|
||||||
|
| UniFi local-service proxy bypass | [docs/unifi-openclash-localhost.md](docs/unifi-openclash-localhost.md) |
|
||||||
| Routine Ansible operations | [runbooks/ansible-operations.md](runbooks/ansible-operations.md) |
|
| Routine Ansible operations | [runbooks/ansible-operations.md](runbooks/ansible-operations.md) |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# UniFi local HTTPS through OpenClash — proxy bypass contract
|
||||||
|
|
||||||
|
## Symptom
|
||||||
|
|
||||||
|
OpenClash on `gfw.windy.lan` can log:
|
||||||
|
|
||||||
|
```text
|
||||||
|
[TCP] dial DIRECT (match IPCIDR/127.0.0.0/8) 192.168.66.46:<port> --> localhost:8443
|
||||||
|
error: dial tcp 127.0.0.1:8443: connect: connection refused
|
||||||
|
```
|
||||||
|
|
||||||
|
This does **not** mean OpenClash should listen on port 8443. The gateway's
|
||||||
|
loopback interface has no UniFi service.
|
||||||
|
|
||||||
|
## Cause
|
||||||
|
|
||||||
|
`ubnt` runs the UniFi controller locally on `*:8443`. Its container also uses
|
||||||
|
HTTP/HTTPS proxy variables. If `NO_PROXY` / `no_proxy` omit loopback addresses,
|
||||||
|
a request for its own `localhost:8443` is sent to the OpenClash HTTP proxy.
|
||||||
|
OpenClash correctly applies its loopback direct rule, but that direct request is
|
||||||
|
then made from the gateway, where port 8443 is not open.
|
||||||
|
|
||||||
|
## Required configuration
|
||||||
|
|
||||||
|
In `/home/windy/unifi-9/compose.yml`, keep both environment entries enabled:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- NO_PROXY=localhost,127.0.0.1,::1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
|
||||||
|
- no_proxy=localhost,127.0.0.1,::1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep the upper- and lowercase forms because different processes and libraries
|
||||||
|
consult different spellings.
|
||||||
|
|
||||||
|
## Apply and verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/windy/unifi-9
|
||||||
|
docker compose config -q
|
||||||
|
docker compose up -d --force-recreate unifi
|
||||||
|
docker inspect --format '{{.State.Health.Status}}' unifi-controller
|
||||||
|
curl -k -sS -o /dev/null -w '%{http_code}\n' https://127.0.0.1:8443/
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected result: Docker health is `healthy` and the local HTTPS request returns
|
||||||
|
an HTTP success or redirect response. Recheck OpenClash logs afterwards; the
|
||||||
|
`localhost:8443` connection-refused entries should stop.
|
||||||
|
|
||||||
|
## Safety
|
||||||
|
|
||||||
|
- Do not add a dummy listener on the gateway's `127.0.0.1:8443`.
|
||||||
|
- Do not solve this with a router redirect rule; that would hide a client-side
|
||||||
|
proxy error and could send local controller traffic to the wrong host.
|
||||||
|
- Back up `compose.yml` before changing it and avoid `docker compose down -v`.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [gfw.windy.lan host facts](../hosts/gfw.windy.lan.md)
|
||||||
|
- [ubnt host facts](../hosts/ubnt.md)
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# gfw.windy.lan — OpenWrt LAN gateway
|
||||||
|
|
||||||
|
## Role and access
|
||||||
|
|
||||||
|
| Item | Value |
|
||||||
|
|---|---|
|
||||||
|
| Role | LAN gateway and OpenClash transparent/explicit-proxy host |
|
||||||
|
| IPv4 | `192.168.66.1` |
|
||||||
|
| SSH | `ssh -4 root@192.168.66.1` |
|
||||||
|
| OS | OpenWrt, Linux `6.12.87` |
|
||||||
|
|
||||||
|
Do not store the root password in this repository. Prefer a verified SSH key for
|
||||||
|
future management access.
|
||||||
|
|
||||||
|
## OpenClash
|
||||||
|
|
||||||
|
OpenClash runs `/etc/openclash/clash` with configuration
|
||||||
|
`/etc/openclash/pass-cat.yaml`.
|
||||||
|
|
||||||
|
| Listener | Port |
|
||||||
|
|---|---:|
|
||||||
|
| HTTP | `7890` |
|
||||||
|
| SOCKS | `7891` |
|
||||||
|
| Redirect | `7892` |
|
||||||
|
| Mixed | `7893` |
|
||||||
|
| TPROXY | `7895` |
|
||||||
|
| DNS | `7874` |
|
||||||
|
|
||||||
|
`8443` is not an OpenClash listener and has no runtime nftables forwarding rule.
|
||||||
|
It is included only in OpenClash's common TLS-sniffing port list.
|
||||||
|
|
||||||
|
## Operational note
|
||||||
|
|
||||||
|
When OpenClash logs a LAN client request such as
|
||||||
|
`<client> --> localhost:8443` followed by a connection refusal, it is normally
|
||||||
|
an explicit-proxy client sending its own loopback request to the gateway. Fix
|
||||||
|
the originating host's `NO_PROXY` / `no_proxy` configuration; do not create a
|
||||||
|
listener on this router to mask the problem. See
|
||||||
|
[the UniFi localhost proxy note](../docs/unifi-openclash-localhost.md).
|
||||||
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# ubnt — UniFi Network Controller
|
||||||
|
|
||||||
|
## Role and access
|
||||||
|
|
||||||
|
| Item | Value |
|
||||||
|
|---|---|
|
||||||
|
| Role | UniFi Network Controller host |
|
||||||
|
| IPv4 | `192.168.66.46` |
|
||||||
|
| SSH | `ssh -4 windy@192.168.66.46` |
|
||||||
|
| Hostname | `ubnt` |
|
||||||
|
| Privilege | `windy` has passwordless sudo and is in the `docker` group |
|
||||||
|
|
||||||
|
The current SSH ED25519 host-key fingerprint is
|
||||||
|
`SHA256:TTZtonJnnnNS6vk4xqo+CJPuZGXwwkf46wR1SLmqc10` (verified 2026-08-03).
|
||||||
|
Verify a changed key out of band before accepting it.
|
||||||
|
|
||||||
|
## UniFi stack
|
||||||
|
|
||||||
|
| Item | Value |
|
||||||
|
|---|---|
|
||||||
|
| Compose directory | `/home/windy/unifi-9` |
|
||||||
|
| Compose file | `/home/windy/unifi-9/compose.yml` |
|
||||||
|
| Compose service | `unifi` |
|
||||||
|
| Container | `unifi-controller` |
|
||||||
|
| Image | `jacobalberty/unifi:v9.5.21` |
|
||||||
|
| Network mode | host |
|
||||||
|
| HTTPS UI | `https://192.168.66.46:8443` |
|
||||||
|
|
||||||
|
The controller binds `*:8443`. A local HTTPS request to
|
||||||
|
`https://127.0.0.1:8443/` is the primary quick health check.
|
||||||
|
|
||||||
|
## Proxy contract
|
||||||
|
|
||||||
|
The container has HTTP/HTTPS proxy environment variables. Its Compose
|
||||||
|
`environment` list must keep **both** `NO_PROXY` and `no_proxy` enabled and
|
||||||
|
include at least:
|
||||||
|
|
||||||
|
```text
|
||||||
|
localhost,127.0.0.1,::1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
|
||||||
|
```
|
||||||
|
|
||||||
|
Without this bypass, a controller request to `localhost:8443` can be sent to
|
||||||
|
the OpenClash gateway instead of remaining local. Details and verification are
|
||||||
|
in [the UniFi localhost proxy note](../docs/unifi-openclash-localhost.md).
|
||||||
|
|
||||||
|
## Safe reconciliation and verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/windy/unifi-9
|
||||||
|
docker compose config -q
|
||||||
|
docker compose up -d --force-recreate unifi
|
||||||
|
docker inspect --format '{{.State.Health.Status}}' unifi-controller
|
||||||
|
curl -k -sS -o /dev/null -w '%{http_code}\n' https://127.0.0.1:8443/
|
||||||
|
```
|
||||||
|
|
||||||
|
Recreating the service briefly interrupts the controller. Do not use `docker
|
||||||
|
compose down -v`; it can remove persistent data.
|
||||||
|
|
||||||
@@ -20,6 +20,8 @@ diagnosis and procedures that are deliberately interactive or destructive; see
|
|||||||
| pdns.wsvc.info | Poweradmin UI | — (HTTPS) | → hk2 | active | see hk2 |
|
| pdns.wsvc.info | Poweradmin UI | — (HTTPS) | → hk2 | active | see hk2 |
|
||||||
| pgweb.wsvc.info | PowerDNS Postgres UI | — (HTTPS) | → hk2 | active | see hk2 |
|
| pgweb.wsvc.info | PowerDNS Postgres UI | — (HTTPS) | → hk2 | active | see hk2 |
|
||||||
| **synapse.chans.xyz** | Matrix homeserver (ESS: Synapse + MAS + Element) | `ssh -4 windy@synapse.chans.xyz` | `169.58.86.13` | **active** | [hosts/synapse.chans.xyz.md](../hosts/synapse.chans.xyz.md) |
|
| **synapse.chans.xyz** | Matrix homeserver (ESS: Synapse + MAS + Element) | `ssh -4 windy@synapse.chans.xyz` | `169.58.86.13` | **active** | [hosts/synapse.chans.xyz.md](../hosts/synapse.chans.xyz.md) |
|
||||||
|
| **gfw.windy.lan** | OpenWrt LAN gateway / OpenClash | `ssh -4 root@192.168.66.1` | `192.168.66.1` | **active** | [hosts/gfw.windy.lan.md](../hosts/gfw.windy.lan.md) |
|
||||||
|
| **ubnt** | UniFi Network Controller | `ssh -4 windy@192.168.66.46` | `192.168.66.46` | **active** | [hosts/ubnt.md](../hosts/ubnt.md) |
|
||||||
|
|
||||||
`status: stub` = known to exist; fill `hosts/<name>.md` when next touched.
|
`status: stub` = known to exist; fill `hosts/<name>.md` when next touched.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user