From b1e6491f77421ae4623391a7f53af7f3e6c13f34 Mon Sep 17 00:00:00 2001 From: Ethel Morgan Date: Mon, 6 Jul 2020 18:23:10 +0100 Subject: import website from previous repo --- src/wifi.thrust | 350 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 350 insertions(+) create mode 100644 src/wifi.thrust (limited to 'src/wifi.thrust') diff --git a/src/wifi.thrust b/src/wifi.thrust new file mode 100644 index 0000000..26cbdc7 --- /dev/null +++ b/src/wifi.thrust @@ -0,0 +1,350 @@ +--- +title: home WiFi setup +configs: + router: + /etc/systemd/network/wan.network: | + [Match] + # enp1s0 is the name of my router's WAN interface. + Name=enp1s0 + + [Network] + # take a IP from my ISP's modem over DHCP. + DHCP=yes + + # use Google's public DNS servers. + DNS=8.8.8.8 + DNS=8.8.4.4 + + # prefer DNS-over-TLS if available. + DNSOverTLS=opportunistic + + # forward packets from this interface to other interfaces. + IPForward=yes + + [DHCP] + # some ISPs' DNS invent A records, so don't use them. + UseDNS=no + + /etc/systemd/network/bridge.netdev: | + [NetDev] + Name=br0 + Kind=bridge + + /etc/systemd/network/lan.network: | + [Match] + Name=enp2s0 enp3s0 + + [Network] + Bridge=br0 + + /etc/systemd/network/bridge.network: | + [Match] + Name=br0 + + [Network] + # the router's LAN IP. + Address=192.168.16.1/24 + + # run a DHCP server. + DHCPServer=yes + + # forward packets from this interface to other interfaces. + IPForward=yes + + # make forwarded packets appear to come from this device, + # a.k.a. enable NAT. + IPMasquerade=yes + + [DHCPServer] + DefaultLeaseTimeSec=600 + + # LAN DNS & Stubby DNS-over-TLS bridge. + DNS=192.168.16.1 + + # fallback DNS. + DNS=8.8.8.8 + DNS=8.8.4.4 + + bouncer: + /etc/systemd/network/bridge.netdev: | + [NetDev] + Name=br0 + Kind=bridge + + /etc/systemd/network/wired.network: | + [Match] + Name=eth0 + + [Network] + Bridge=br0 + + /etc/systemd/network/bridge.network: | + [Match] + Name=br0 + + [Network] + DHCP=yes + DNSOverTLS=opportunistic + + shared: + /etc/hostapd/hostapd.conf: | + bridge=br0 + interface=wlan0 + driver=nl80211 + ssid=something-witty + + # select a channel automatically + # using the ACS survey-based algorithm, + # instead of setting a channel manually. + channel=0 + country_code=GB + ieee80211d=1 + + # hw_mode=g for 802.11n, hw_mode=a for 802.11ac. + hw_mode=g + + # 802.11n support. + ieee80211n=1 + wmm_enabled=1 + + # WPA2 encryption settings. + # note that wpa_key_mgmt also has FT-PSK for 802.11r. + wpa=2 + wpa_passphrase=something-secret + wpa_key_mgmt=WPA-PSK FT-PSK + wpa_pairwise=TKIP + rsn_pairwise=CCMP + + # 802.11i support. + rsn_preauth=1 + rsn_preauth_interfaces=br0 + + # 802.11r support. + # mobility_domain must be shared across APs. + # nas_identifier must be different between APs. + mobility_domain=19fc + nas_identifier=8e71540f0467 + ft_psk_generate_local=1 +diagram: | + + + home network diagram + + internet + + internet + + + router + + router + + + internet -- router + + + + kitchen + + kitchen + + + router -- kitchen + + powerline + + + laptop + laptop + + + router -- laptop + + WiFi + + + kitchen -- laptop + + WiFi + + + bulb + lightbulb + + + kitchen -- bulb + + WiFi + + + +--- +{% extends 'templates/base.html' %} +{% block body %} + + + +
+

{{ title }}

+ +{% macro file(d, path) %} +
$ cat {{ path }}
+{{ d[path] }}
+{% endmacro %} + +{% markdown %} +
+contents… +
+ +[TOC] + +
+
+ +There are two Access Points (APs) in my house: one in the living room, and one in the kitchen. +They are connected via LAN-over-powerline, and have WiFi Roaming set up for a seamless connection throughout. + +{{ diagram | safe }} + +## Roaming + +WiFi Roaming allows a client device (e.g. a phone) to transparently switch from one AP to another. +Unlike "repeaters" or "boosters", which create a second WiFi network that the client needs to disconnect from and reconnect to, Roaming is _the same network_ across APs and allows for a seamless experience. + +This is implemented with two extensions of the WiFi spec, _802.11i_ and _802.11r_: + +- _802.11i_ is pre-authentication, which allows clients to start associating to a new AP while still connected to the previous one. +- _802.11r_ is Fast Transition (FT), where APs can share keys with each other. + On large networks (e.g. corporate ones) this is done properly where the APs communicate and use intermediate keys and the like, but for a home network with a Pre-Shared Key (PSK), the APs can derive all the keys themselves. + +
+How does 802.11r actually work? +
+In a given roaming connection, there are 3 keys: + +- Master Session Key (MSK). +- R0, a key derived from the MSK. +- R1, a key derived from R0. + +There are 3 players: + +- The client. +- R0KH, the R0 Key Handler, may or may not be an AP. +- R1KH, the R1 Key Handler, an AP. + +In "pull mode": + +1. The client connects to the first AP. +2. The client is given a key and an R0KH-ID (the _NAS Identifier_, named for [RADIUS'](https://en.wikipedia.org/wiki/RADIUS) [Network Access Server](https://en.wikipedia.org/wiki/Network_access_server)). +3. The client connects to the second AP. +4. The client gives R0KH-ID to the second AP. +5. The second AP, now R1KH, contacts R0KH using the ID and its own R1KH-ID. +6. R0KH sends R1KH a key R1 derived from R0 and R1KH-ID. +7. R1KH, gives the client R1. + +In "push mode": + +1. R0KH knows all its APs. +2. R0KH sends each AP a unique R1 derived from R0 and the AP's R1KH-ID. +3. the client connects normally. + +For PSK mode, the MSK is the PSK, so any AP can generate R0 and R1 for any NAS Identifier. +
+
+ +## Router configuration { #router } + +My router is a [PC Engines APU 1d4](https://www.pcengines.ch/apu1d4.htm), which has: + +- 3 ethernet ports. +- 1 wifi card. + +One of the ethernet ports is for WAN, and the other two and wifi card are LAN. +The LAN interfaces are joined with a bridge, `br0`. + +### WAN { #router/wan } + +This is a fairly normal [`systemd-networkd`](https://wiki.archlinux.org/index.php/Systemd-networkd) client config, with the addition of `IPForward=yes`: + +{{ file( configs.router, '/etc/systemd/network/wan.network' ) }} + +### LAN { #router/lan } + +The LAN is controlled with `systemd-networkd` where possible, and the wifi is managed by `hostapd`. +There are three parts to the `networkd` configuration: + +- Create a bridge network device. +- Connect the LAN ethernet ports to it. +- Configure the bridge to be a DHCP server & NAT gateway. + +First, create a bridge `br0`: + +{{ file( configs.router, '/etc/systemd/network/bridge.netdev' ) }} + +Connect the LAN ethernet ports to the bridge: + +{{ file( configs.router, '/etc/systemd/network/lan.network' ) }} + +Finally, configure the local network on the bridge itself. + +- `systemd-networkd` includes a minimal DHCP server, so also enable that. +- Note the addition of both `IPForward=yes` and `IPMasquerade=yes` to set up NAT. + +{{ file( configs.router, '/etc/systemd/network/bridge.network' ) }} + +### WiFi { #router/wifi } + +Because `hostapd` has its own bridge management, it isn't included in the `systemd-networkd` configuration. + +This configuration: + +- Uses our bridge `br0`. +- Uses the standard Linux WiFi driver set (others exist for other chipsets). +- Automatically selects a channel at start. +- Enables 802.11n (`hostapd` also supports 802.11ac). +- Enables WPA2 with a Pre-Shared Key (PSK). +- Enables pre-authentication (802.11i) on our bridge `br0`. +- Enables roaming (802.11r): + - `nas_identifier` must be 6 bytes, and different between APs. I use the interface MAC. + - `mobility_domain` must be 2 bytes, and is shared between APs. + +{{ file( configs.shared, '/etc/hostapd/hostapd.conf' ) }} + +## Kitchen + +The WiFi in the kitchen is provided by a [Raspberry Pi 2B](https://www.raspberrypi.org/products/raspberry-pi-2-model-b/) and a USB WiFi adapter that supports _host mode_. +I chose this hardware because I already owned it. + +### LAN { #kitchen/lan } + +This is a simpler version of the [Router's LAN configuration](#router/lan), but with only two steps: + +- Create a bridge network device. +- Connect the LAN ethernet ports to it. + +As before, create a bridge `br0`: + +{{ file( configs.bouncer, '/etc/systemd/network/bridge.netdev' ) }} + +Connect the ethernet port to the bridge: + +{{ file( configs.bouncer, '/etc/systemd/network/wired.network' ) }} + +Configure the local network on the bridge itself. +Because this is not the primary router, it can be just another DHCP client: + +{{ file( configs.bouncer, '/etc/systemd/network/bridge.network' ) }} + + +### WiFi { #kitchen/wifi } + +This is basically the same as the [Router's WiFi configuration](#router/wifi), although remember to change the `nas_identifier`! +{% endmarkdown %} +
+{% endblock %} -- cgit v1.2.3