Files
vps/docs/unifi-network.md
T

273 lines
11 KiB
Markdown

# UniFi network configuration
## Controller
| Item | Value |
|---|---|
| Host | [ubnt](../hosts/ubnt.md) |
| Address | `192.168.66.46` |
| Deployment | Docker, `jacobalberty/unifi:v9.5.21`, host networking |
| Inform endpoint | `http://192.168.66.46:9080/inform` |
| MongoDB database / port | `ace` / `27117` |
Although `8080` is a common UniFi inform port, this controller uses `9080`.
All AP adoption and recovery procedures must use the endpoint above.
## Login and MFA
On 2026-08-08, **"Sync Local Admin with Ubiquiti SSO"** was disabled
(`super_sdn.sso_login_enabled: false`). Previously every login was forced
through Ubiquiti SSO (sso.ui.com) and required MFA, which blocked programmatic
access: the `unifi-network-mcp` write operations failed with
`api.err.Ubic2faTokenRequired`.
Now local accounts (`windy`, `zhiqiangf`) sign in with their local passwords
and no MFA. The `unifi-network-mcp` tool uses the `zhiqiangf` local account and
works for both read and write operations (verified 2026-08-08 with a reversible
client rename).
Impact: unifi.ui.com remote access (Site Manager) no longer works.
Manage the setting idempotently via Ansible:
```bash
cd ansible
ansible-playbook playbooks/unifi-sso.yml --limit unifi --check # read-only
ansible-playbook playbooks/unifi-sso.yml --limit unifi \
-e '{"unifi_sso_confirm": true, "unifi_sso_target_value": false}' # apply
```
See [runbooks/ansible-operations.md](../runbooks/ansible-operations.md).
## Inter-VLAN reachability
The AP management networks are routed by [gw](../hosts/gw.md),
`192.168.66.254`. On 2026-08-05, a probe sourced from the LAN55 gateway
(`192.168.55.254`) reached the controller (`192.168.66.46`) with 3/3 ICMP
replies. The UAP-AC-Lite is online through the `:9080/inform` endpoint, which
also confirms the required application path in practice.
`LAN_IN` contains explicit allow rules for `192.168.55.0/24 ↔
192.168.66.0/24`, but the firewall set is currently inactive (not attached to
an interface). Treat the networks as bidirectionally reachable by default;
do not rely on those inactive rules as an access boundary. Recheck this after
attaching any LAN firewall policy or changing VLAN routing.
To inspect device records from the controller host:
```bash
docker exec -it unifi-controller bash
mongo --port 27117
```
```javascript
use ace
db.device.find(
{ type: "uap" },
{ name: 1, ip: 1, model: 1, inform_url: 1 }
).pretty()
```
## IPv6 status (verified 2026-08-20)
IPv6 is **enabled and live** on the main Wi-Fi networks. Read-only
verification, no changes made.
**Controller (`networkconf` in the `ace` DB):** the `Default` LAN network has
`ipv6_enabled: true`, `ipv6_client_address_assignment: slaac`,
`ipv6_ra_enabled: true`, `ipv6_ra_priority: high`, and
`dhcpdv6_allow_slaac: true`. `ipv6_interface_type: "none"` is expected: the
network's gateway is the third-party EdgeRouter (`gw`), so the controller does
not manage WAN-side IPv6 — RA/SLAAC is served by the router.
All active SSIDs map to the `Default` network: `ubnt-windy` (5G),
`ubnt-windy-2` (2.4G), `ubnt-haas` (2.4G) — clients on them receive SLAAC IPv6.
Exception: the dormant `ubnt-upg` VLAN 10 network (and its `ubnt-upg` SSID) has
no IPv6 configuration (default off). See
[Dedicated Wi-Fi through a third-party gateway](#dedicated-wi-fi-through-a-third-party-gateway).
**APs (live):** both managed APs hold global SLAAC addresses on `br0` with a
default route learned via RA from `gw`:
| AP | Global IPv6 on `br0` (at check time) | Default route |
|---|---|---|
| U6 Lite (`192.168.66.6`) | `240e:3bd:235:1fb1:...`/64 | `default via fe80::... dev br0 proto ra` |
| UAP-AC-Lite (`192.168.55.5`) | `240e:3bd:235:1fb2:...`/64 | `default via fe80::... dev br0 proto ra` |
The delegated prefixes are dynamic ISP allocations (PPPoE PD `/60`) and rotate
on redial; only the structure is stable.
**Gateway (`gw`):** the IPv6 routing table shows connected `/64`s on `eth0`
(LAN66) and `switch0` (LAN55) plus `::/0` via `pppoe0`.
Re-verify:
```bash
ssh -4 -o BatchMode=yes zhiqiangf@192.168.66.6 'ip -6 addr show br0; ip -6 route show'
ssh -4 -o BatchMode=yes zhiqiangf@192.168.55.5 'ip -6 addr show br0; ip -6 route show'
```
> **2026-08-21 (W1N-207):** SmartThings Element/vWire provisioning SSIDs
> (`element-8a0d5133c9438f12`, `vwire-8b2d67469e455785`, `vport-F09FC22004E9`) were
> removed (element_adopt setting disabled + element wlanconf deleted + device vwire
> fields cleared) and confirmed off on both APs (normal SSIDs unchanged: `ubnt-windy`,
> `ubnt-windy-2`, `ubnt-haas`, `ubnt-upg`). Root cause of Matter onboarding failure that
> day: HA's matter-server advertised a stale IPv6 GUA (two prefix generations old) in
> mDNS; fixed by restarting the add-on — see [hosts/hass.windy.lan.md](../hosts/hass.windy.lan.md).
>
> **SSID ↔ subnet split (Matter-relevant):** `ubnt-windy` (5G) is served only by the
> U6 Lite on LAN66; `ubnt-haas` / `ubnt-windy-2` (2.4G) only by the UAP-AC-Lite on
> LAN55. mDNS is link-local multicast and does **not** cross the routed 55/66
> boundary (no mDNS reflector). Matter commissioning therefore requires phone and
> device on the **same subnet (LAN55)**; a phone on 5G (LAN66) cannot discover a
> LAN55 Matter device.
>
> **Cleanup side-effects (left as-is, harmless):** after the direct-DB cleanup,
> `db.device.cfgversion` holds placeholder values (`0000000000000000` /
> `1111111111111111`) and UAP-AC-Lite has `mesh_sta_vap_enabled=false`; the
> controller has not reverted them and no functional impact was observed.
## Dedicated Wi-Fi through a third-party gateway
### Architecture boundary discovered on 2026-08-08
`gfw` is a virtual machine connected only to the native LAN 66 network; the
physical Wi-Fi uplink is also an ER-X LAN 66 path. The ER-X provides DHCP for
that LAN. There is no verified 802.1Q-capable path from the U6 Lite to `gfw`.
Consequently, the proposed `ubnt-upg` design is **not implementable on the
current topology without an additional VLAN-capable L2 path**. Giving the VM
an `eth0.10` interface alone does not create VLAN 10 on the physical switch or
deliver tagged frames to it.
UniFi APs associate clients and bridge an SSID into a selected 802.1Q VLAN;
they do not allocate DHCP addresses. The controller configures that AP
behavior, but it is not a DHCP service for a third-party-gateway VLAN. The
gateway on the corresponding VLAN provides DHCP. In the existing topology, the
ER-X DHCP service legitimately answers untagged LAN 66 requests.
The observed `192.168.66.91` lease on `ubnt-upg` is therefore expected when
traffic reaches the existing untagged LAN 66. It is not a failure that can be
fixed by changing the controller or by adding another DHCP server to the same
broadcast domain.
### Conditions for a future implementation
The design becomes viable only after adding and proving one of these:
1. A VLAN-capable switch/trunk from the U6 Lite to a VLAN-10 interface on the
actual gateway, with native LAN 66 retained for AP management; or
2. A hypervisor/vSwitch and physical uplink configured to pass VLAN 10 end to
end to the `gfw` VM, plus the corresponding tagged port towards the U6.
Then configure one UniFi virtual network with **Router: Third-party Gateway**
and VLAN ID `10`, map only `ubnt-upg` to it, and have the VLAN 10 gateway be
the sole DHCP server for `192.168.10.0/24`. A test client must obtain
`192.168.10.x`, with traffic and its lease visible on that gateway, before the
SSID is considered working.
### Protecting existing Wi-Fi
`ubnt-windy` is the existing 5 GHz SSID and has been restored on the U6 Lite.
Keep its network and broadcast/device assignment unchanged. If the dedicated
SSID is ever retried, use the controller's normal **Specific -> U6 Lite**
broadcast selection for `ubnt-upg` only; do not reuse, move, or manually edit
an existing SSID's AP group. An AP configuration push can still briefly
reassociate clients, so zero-impact work on the same AP cannot be guaranteed.
### References
- [Feasibility and DHCP responsibility](unifi-third-party-vlan10-dhcp.md)
- [Supported topology and implementation examples](unifi-openwrt-vlan10-implementation-examples.md)
- Ubiquiti: [Creating Virtual Networks (VLANs)](https://help.ui.com/hc/en-us/articles/9761080275607-Creating-Virtual-Networks-VLANs),
[Creating WiFi SSIDs](https://help.ui.com/hc/en-us/articles/26136823938583-Creating-UniFi-WiFi-SSIDs), and
[Switch Port VLAN Assignment](https://help.ui.com/hc/en-us/articles/26136855808919-Switch-Port-VLAN-Assignment-Trunk-Access-Ports).
## Managed access points
| Name | Model | Management IP | Firmware | Management network | Inform port |
|---|---|---|---|---|---|
| U6 Lite | U6 Lite (`UAL6`) | `192.168.66.6` | `6.7.54.15663` | LAN66 (`192.168.66.0/24`, gateway `192.168.66.254`) | `9080` |
| UAP-AC-Lite | `U7LT` | `192.168.55.5` | `6.8.2.15592` | LAN55 (`192.168.55.0/24`, gateway `192.168.55.254`) | `9080` |
AP MAC addresses are recorded only where operationally needed: U6 Lite
`78:45:58:4d:cc:30`; UAP-AC-Lite `f0:9f:c2:20:04:e9`.
## SSH administration
Adopted APs use the SSH account configured in the controller, rather than the
factory `ubnt/ubnt` credential. The password is stored in the password manager
and must not be added to this repository.
In UniFi Network `9.5.21`, configure it at:
```text
Devices → Device Updates and Settings → Device SSH Settings
→ Device SSH Authentication
```
Use `ssh zhiqiangf@AP_IP` for the adopted-device account. Do not query or copy
the controller's `mgmt` database setting into logs or documentation: it can
contain the managed SSH password.
Key-only IPv4 SSH was verified for both managed APs using the `zhiqiangf`
account on 2026-08-06 and re-verified 2026-08-20 (BatchMode with password and
keyboard-interactive disabled; both APs still log in key-only). Verify future
access without permitting password or keyboard-interactive fallback:
```bash
ssh -4 -o BatchMode=yes -o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no -o StrictHostKeyChecking=yes \
zhiqiangf@192.168.66.6 'mca-cli-op info'
ssh -4 -o BatchMode=yes -o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no -o StrictHostKeyChecking=yes \
zhiqiangf@192.168.55.5 'mca-cli-op info'
```
Both devices reported `Connected` to
`http://192.168.66.46:9080/inform` during that verification. The AP shell maps
this management account to UID 0, so treat it as administrative access.
## Offline AP recovery
An AP can be reachable via ICMP and SSH but offline in the controller when its
saved inform URL still points to port `8080`. This occurred for UAP-AC-Lite
after its inform configuration had diverged from the controller endpoint.
From the AP, inspect the active endpoint and test controller reachability:
```bash
info
nc 192.168.66.46 9080
```
The AP's BusyBox `nc` may not support `-zv`; use the plain `nc` invocation
above when testing the TCP path.
If `info` reports `http://192.168.66.46:8080/inform` (or another obsolete
endpoint), correct it. UniFi devices commonly require the command twice while
adoption is completed:
```bash
set-inform http://192.168.66.46:9080/inform
set-inform http://192.168.66.46:9080/inform
```
Verify that the AP changes to connected/online in the controller.
## Controller migration check
After a controller migration or restore, inspect stored device records for a
stale default-port endpoint before treating an AP as faulty:
```javascript
use ace
db.device.find(
{ inform_url: /8080/ },
{ name: 1, ip: 1, inform_url: 1 }
)
```
Do not include credentials or controller database dumps in incident notes.