Network
Overview
[edit | edit source]
The network consists of a cable modem feeding an OpenWrt router/AP, which in turn uplinks to the mezzanine Ubiquiti managed switch. From there, connections run to two loft patch panels: one Blue, one Grey. Each network drop in the space has a corresponding Blue and Grey jack; only some are wired through to the switch, and only some are currently used. The main table has a small managed switch.
Blue and Grey cables are functionally identical. The colours reflect physical routing rather than logical separation.
Static Devices
[edit | edit source]Most fixed equipment uses static DHCP leases on the OpenWrt router. If you add a static IP address, give it a static DHCP lease on the openwrt router, even if the device doesn't use dhcp. These are the main devices:
| Device | IP Address |
|---|---|
| OpenWrt loft router | 192.168.0.1 |
| Home Assistant | 192.168.0.2 |
| OpenWrt table AP | 192.168.0.3 |
| Lazzor | 192.168.0.4 |
| OpenWrt lobby AP | 192.168.0.6 |
Patch Panel Map
[edit | edit source]| Grey device / location | Switch port | Label | Switch port | Blue device / location |
|---|---|---|---|---|
| Lobby black cable (unterminated) | 1 | 1 Laser Loft | 2 | Lobby AP |
| Lazzor | 3 | 2 Laser Room | 4 | Laser room computer |
| (unused) | 5 | 3 Craft Shelf Arch | 6 | (unused) |
| (unused) | 7 | 4 Craft Shelf Top | 8 | Payphone |
| (unused) | 9 | 5 Cubesville | 10 | Denon AVR |
| Game of Life cube | 11 | 6 Main Room Beam Front | 12 | Main table Ethernet (phone, switch) |
| (unused) | 13 | 7 Main Room Beam Back | 14 | Main Room AP |
| (unused) | 15 | 8 Tool Town L (breaker panel) | 16 | Sherline computer |
| (unused) | 9 Tool Town R (shopbot) | (unused) | ||
| (unused) | 10 Mezzanine R (unterminated) | (unused) | ||
| (unused) | 11 Mezzanine L (unterminated) | (unused) | ||
| (unused) | 12 Main Room Couches (unterminated) | (unused) | ||
|
Unconnected Grey ↔ Blue runs: 13–24 | ||||
Router
[edit | edit source]| Port | Connected device |
|---|---|
| WAN | Spectrum modem |
| LAN 1 | (Woody's undocumented HAM stuff?) |
| LAN 2 | Mezzanine switch (uplink) |
Mezzanine Switch
[edit | edit source]The ports on the left are for the patch panel.
The SFP ports on the right are:
17 Home Assistant (purple) 18 Uplink (yellow)
The switch is managed through the Ubiquiti app in Home Assistant
ToDo
[edit | edit source]- Ubiquiti setup
OpenWRT router and Wi-Fi access points
[edit | edit source]The space has three Comfast CF-WA933 running OpenWRT: one router and two wired access points. All three provide Wi-Fi. The main router supplies Internet access, DHCP, DNS, IPv6 and the NYC Mesh connection over vpn; the other two extend coverage.
The two APs are powered by PoE; Main is powered by a 12V barrel jack adapter.
| Device | Where it is |
|---|---|
| Main router | Loft |
| Satellite | Above the hack table |
| Lobby | Above the front door in the lobby |
Hostnames and IP addresses are in the shared password vault.
Administration is by SSH as root or LuCI. The AP addresses are reservations on main, so changing or replacing an AP's DHCP identity also requires updating main.
Two networks, two exits
[edit | edit source]NYCR / NYCR24 / NYCR-IoT
-> LAN: VLAN 1, 192.168.0.0/24
-> main (192.168.0.1) -> cable modem -> Internet
-NYC Mesh Community WiFi-
-> public mesh: VLAN 30, 192.168.30.0/24
-> main (192.168.30.1) -> wgmesh (WireGuard) -> NYC Mesh SN3
The private SSIDs all join the same LAN. NYCR-IoT is not an isolated IoT network. The public mesh SSID is on a separate VLAN and firewall zone, with client isolation enabled on its BSSes.
The main router provides DHCP/DNS for both networks. It routes LAN traffic to cable WAN and public-mesh traffic through WireGuard.
Mesh depends on
three pieces agreeing: meshvpn/wgmesh firewall policy,
the PBR policy "NYC Mesh SSID through WireGuard", and the tunnel/routes in
network config. There is also an explicit 10.0.0.0/8 route through
wgmesh. WireGuard does not automatically install its peer's
allowed-IP routes here.
Main's Internet interfaces are wan and wan6; its
internal ports are lan1 and lan2.
The modem is reachable (only ping) at 192.168.100.1 through
main's cablemodem interface (192.168.100.2/24).
Between the router, switches and APs, VLAN 1 is native/untagged and VLAN 30 is tagged. Each AP bridges all three wired ports. An AP's port labelled WAN is part of this internal bridge. The APs do not route VLAN 30 or run DHCP/DNS servers.
IPv6 access policy is explicit in main's firewall: there are inbound LAN-forwarding and router-management exceptions. Include those rules when reviewing external access; the IPv4 NAT policy is not the whole access policy.
Wi-Fi
[edit | edit source]| SSID | Bands | Authentication | Network | Purpose |
|---|---|---|---|---|
NYCR |
2.4 and 5 GHz | WPA3-Personal / SAE | LAN | 'Main' network. What you should be using. |
NYCR24 |
2.4 and 5 GHz | WPA2-Personal | LAN | WPA2 compatibility; no 802.11r fast transition. Legacy network, both bands despite the name |
NYCR-IoT |
2.4 GHz | WPA2-Personal | LAN | For IoT devices inside Resistor. Backwards compatibility over speed. |
-NYC Mesh Community WiFi- |
2.4 and 5 GHz | Open | Public mesh / VLAN 30 | NYC Mesh; can't access the Resistor internal network |
NYCR has fast roaming configured across all three devices. The two NYCR BSSes per device have unique MAC/NAS identities; their peer tables and shared roaming keys must be maintained together across all three devices.
usteer handles inter-AP information/steering;
it is separate from the fast-roaming peer configuration.
| Configured radio plan | Main | Satellite | Lobby |
|---|---|---|---|
| 2.4 GHz | 6 / HE20 | 1 / HE20 | 11 / HE20 |
| 5 GHz | 36 / HE160 | 100 / HE160 | 149 / HE160 |
After a radio change, verify the operating channel and width rather than just the saved setting.
Where changes belong
[edit | edit source]Most settings are under /etc/config/:
| Change | Device(s) | Files / dependencies |
|---|---|---|
| WAN, modem, VLANs, IPv6 or WireGuard | Main; VLAN bridging also on APs | network
|
| DHCP reservations, local DNS or upstream resolvers | Main | dhcp
|
| Mesh egress or network access policy | Main | network, pbr, firewall
|
| SSIDs, passwords or roaming | All three | wireless; usteer for steering policy. Preserve per-BSS identities.
|
| Home Assistant monitoring access | Affected device(s) | rpcd, luci and their integration account/ACLs
|
| Hostname or location notes | Affected device | system
|
If something breaks
[edit | edit source]| Failure boundary | Look here |
|---|---|
| All APs affected, including wired LAN clients | Main is the shared dependency: WAN/modem for Internet, DHCP/DNS for client configuration. Keep AP configuration out of the initial investigation. |
| New clients can't get an IP address | Check the DHCP service on Main |
| Clients can't resolve hostnames | Main's dnsmasq and upstream resolvers; distinguish local-name failures from external DNS failures. |
| Public mesh fails but private LAN works | Separate VLAN 30 transport from main's mesh DHCP, WireGuard, PBR and firewall. A tunnel handshake does not prove the SSID's egress route. |
| Public mesh fails on only one AP | Its SSID-to-VLAN attachment and the tagged VLAN 30 path through the Ubiquiti switches. |
| Association works but moving between APs fails | The affected BSS identities and roaming peers/keys; then effective steering behaviour. |
| Only HTTPS management fails | That device's certificate paths/renewal and DNS/challenge reachability; SSH is the alternative access path. |
Adding a device
[edit | edit source]To add another access point:
- Give it a unique hostname and management identity. Add its DHCP reservation on main; leave the AP's management interface as a DHCP client. Assign a unique IPv6 identity/suffix as well.
- Configure its bridge and upstream switch port to carry native/untagged VLAN 1 and tagged VLAN 30. Keep DHCP/DNS servers disabled on the AP; it bridges both networks rather than providing another routed WAN.
- Use an existing AP's shared SSID/security settings, with credentials from the shared vault. Give every BSS a unique MAC address and choose its radio channels as part of the space's channel plan. Do not duplicate the source AP's management or BSS identities.
- Give its two NYCR BSSes unique NAS IDs, following
nycr-LOCATIONandnycr-LOCATION-2g, and keep mobility domain1337. Add both new peers to ther0kh/r1khtables on every existing device; the new AP needs the complete peer set too. Preserve the shared roaming keys and reload Wi-Fi on affected devices after coordinating the updates. - Use a full wpad variant and enable
usteeron LAN, matching the other APs. - Verify management access after reboot, private-LAN DHCP/DNS and Internet access, public-mesh DHCP and WireGuard egress, and roaming to/from the existing APs. Check both radio bands.
- Record its management details in the vault, add its location and channels to this page, record the switch port and PoE source, and take a backup.
Replacing a device
[edit | edit source]Restore a backup for that logical device. An AP replacement must retain both VLANs, DHCP/DNS disabled, integration access and the intended BSS/roaming identity. Update main's DHCP reservation if the replacement's management identity changes. Do not connect old and replacement units with duplicate BSS identities.
Main's replacement also needs all DHCP reservations, WAN/modem and IPv6 configuration, WireGuard credentials, PBR and firewall policy. Verify private LAN Internet access and public-mesh egress independently. Keep the recovery image and procedure with the device's private backup.
Dynamic DNS
[edit | edit source]NYC Resistor has dynamic IPv6 DNS for selected hosts under:
*.dyn.nycresistor.com
The public IPv6 prefix assigned by Spectrum changes every few weeks. Hosts on the Resistor LAN have stable IPv6 host IDs, so when the /64 changes we update the network prefix of all published AAAA records while preserving the lower 64 bits.
The low 64 bits of each AAAA record are persistent. Most of these correspond to hostid entries configured in OpenWrt.
The initial AAAA record in deSEC must therefore contain the correct host ID. Future updates only replace the /64 prefix.
For example:
espressomachine.dyn.nycresistor.com
2603:7000:1234:5678::cafe
The hostid is cafe
If the ISP changes our prefix from:
2603:7000:1234:5678::/64
to:
2603:7000:90ab:cdef::/64
the DNS record becomes:
2603:7000:90ab:cdef::cafe
Adding a host
[edit | edit source]- Give the device a stable IPv6 host ID in OpenWrt.
- Create its AAAA record in the
dyn.nycresistor.comdeSEC zone with the correct host ID. - Add its FQDN to
/config/ddns-hosts.txt. - Run the Resistor DDNS automation manually from Home Assistant.
- Check that the resulting AAAA record contains the current Resistor /64 and the expected host ID.
DNS provider
[edit | edit source]dyn.nycresistor.com is delegated separately from the main nycresistor.com DNS zone and is hosted by deSEC. This means the dynamic-DNS credentials cannot modify unrelated Resistor DNS records.
The credentials are in the usual place.
Home Assistant general setup
[edit | edit source]Home Assistant updates the prefix at deSEC through the "Resistor DDNS" automation. It runs on boot, on prefix change and weekly.
Hosts which should be published are listed one per line in /config/ddns-hosts.txt. Blank lines and lines beginning with # are ignored. Changing this file does not require restarting or reloading Home Assistant.
Do not add arbitrary LAN devices here just because they have a stable IPv6 address. This list is for things which should actually have a public DNS name.
Update process detail
[edit | edit source]Home Assistant has sensor.resistor_ipv6_prefix, a command-line sensor which looks directly at interface end0:
ip -6 -o a s dev end0|awk '$4~/^[23]/{split($4,a,":");print a[1]":"a[2]":"a[3]":"a[4]"::/64";exit}'
Home Assistant then has a shell_command.update_resistor_ddns command.
It:
- reads
/config/ddns-hosts.txt; - removes comments and blank lines and joins the names with commas;
- sends one batched request to deSEC;
- passes
sensor.resistor_ipv6_prefixas the new IPv6 /64; - tells deSEC to preserve IPv4 records (currently none).
The deSEC API token is stored in Home Assistant's secrets.yaml, not in an automation.
The command uses roughly:
hosts="$(grep -Ev "^[[:space:]]*(#|$)" /config/ddns-hosts.txt | paste -sd, -)" curl -fsS \ -H "Authorization: Token verySecret" \ --get \ --data-urlencode "hostname=$hosts" \ --data-urlencode "myipv4=preserve" \ --data-urlencode "myipv6=$prefix" \ https://update.dedyn.io/
Batching all hosts like this matters: an earlier setup updated records individually and ran into deSEC rate limiting.
The Resistor DDNS Home Assistant automation runs when:
sensor.resistor_ipv6_prefixchanges;- Home Assistant starts, after a short delay;
- once a week as a sanity/reconciliation update.
When Spectrum gives us a new IPv6 prefix switch it causes:
OpenWrt receives new IPv6 prefix
↓
HAOS receives address in new /64
↓
sensor.resistor_ipv6_prefix changes
↓
Resistor DDNS automation runs
↓
one batched deSEC request
↓
all published AAAA records get the new /64
The periodic update is only a fallback in case a prefix-change event was missed.
ESP32 near elevator door
[edit | edit source](TODO new page dedicated to space access controls)
Currently, there's a m5stack ATOM-Lite (very small) ESP32 board hanging above the elevator door/intercom/laser loft stairs area. This serves:
- Elevator door sensor inside(?) maglock housing (it is a reed switch)
- Keypad in elevator shaftway (a direct wired 4x3 key matrix on the end of a cat5 cable)
ATOM-Lite publishes these into HA, where the sensor states are used in various automations related to locks. I think it publishes the elevator door sensor state over Bluetooth (why?) and publishes codes entered into the keypad over MQTT. See the config in ESPHome though.
Wiring (rat nest) "diagram":
[Pictures are worth 1000 words, but only if you can upload them. --Ed]
jumpers:
- ATOM-Lite GND <=> WAGO <=> white twisted pair a terminal <=> elevator door sensor (reed switch)
- ATOM-Lite GPIO21 <=> not connected
- ATOM-Lite GPIO 19 <=> grey jacket cat5, green-white <=> keypad terminal 5 (col 3) [2]
- ATOM-Lite GPIO 23 <=> grey jacket cat5, green <=> keypad terminal 6 (col 2)
- ATOM-Lite GPIO 33 <=> grey jacket cat5, brown-white <=> keypad terminal 7 (col 1)
breadboard:
- ATOM-Lite 3v3 <=> 1 kΩ pull-ups to each of GPIO 25,32,26,33 [1]
- ATOM-Lite GPIO 21 <=> pull-up & grey jacket cat5, blue-white <=> keypad terminal 1 (row 1) [2]
- ATOM-Lite GPIO 26 <=> pull-up & grey jacket cat5, blue <=> keypad terminal 2 (row 2)
- ATOM-Lite GPIO 32 <=> pull-up & grey jacket cat5, orange-white <=> keypad terminal 3 (row 3)
- ATOM-Lite GPIO 22 <=> pull-up & grey jacket cat5, orange <=> keypad terminal 4 (row 4)
[1] Without these strong external pull-ups, the ~2meter twisted pairs run to the keypad is too noisy for the matrix scanning to work. Ask me how I know. 3.3 kΩ is better than the 45 kΩ (?) on-chip pull-ups but still not enough.
[2] here, 4 rows and 3 cols of the physical keypad layout; the ESPHome config calls the physical columns "rows" (pins configured as strobed outputs) and calls the physical rows "columns" (pins configured as inputs)
"Shelly" near elevator door
[edit | edit source]Switches 12v power to the elevator door maglock...