Wifi-hotspot
experimental setup, use at your own risk!
Lots of random info here, just so I have a central place to keep configs, tips, links, etc..
What's this about?
The wireless range extender I bought (D-Link DAP-1530) didn't quite work the way I wanted with the systems I was using:
- after boot-up, the extender takes 11 minutes to finally settle if it can't detect an Internet connection
- the device I wanted it to connect to is a Linux box that is configured as an access point, but every time I need to reboot the Linux box, the range extender loses its mind and needs a cold restart to regain connectivity with the Linux box.
These issues made me look at rolling my own wifi extender using a raspberry pi.
What I discovered
There are a lot of articles and howto's on setting up a shared hotspot, but many of them use several components (hostapd, dhcpcd, resolveconf, wpa_supplicant, dnsmasq) that all need to be talking to each other the right way. With too many variables, many things can go wrong. Although these solutions may work, the simplicity of a more integrated network managing system like NetworkManager makes a lot more sense to me. The setup below still uses wpa_supplicant and dnsmasq alongside NetworkManager, but the work to get it set up is way less.
- Terminology: a Hotspot is the same as an Access Point; they do the same things.
- Don't use iwd, hostapd or dnsmasq(*) but instead use NetworkManager; it's the modern way to manage network configurations
- You can safely uninstall iwd, hostapd, dhcpcd, dhclient as NetworkManager has a built-in DHCP and DNS server and can set up Access Points just fine
- You do not need any editing in /etc/network/interfaces and friends
- You do not need /etc/hostapd*, or /etc/dhcpcd*, or /etc/dnsmasq* files
- You do not need resolvconf; the systemd installed version of systemd-resolved is fine and is used by NetworkManager
- The out-of-the-box NetworkManager does not need any further config files (I'm looking at you /etc/NetworkManager/conf.d/dns.conf with your dns=dnsmasq)
- Running a wifi-client and an Access Point on the same network card (it's called AP-STA) may be possible, but try with two separate adapters first
- learn the basic commands of nmcli; it's a very nice tool to manipulate the network configurations
- NetworkManager uses simple key-files which are in plain text readable ascii
- If you want to manually edit any of the configurations files under /etc/NetworkManager be sure to load the new config with nmcli general reload
- the creation of a hotspot with NetworkManager has it's own shortcut 'wifi hotspot', which really simplifies things, see example below
- You do not need to put any additional configuration in /etc/wpa_supplicant/* (the default wpa_supplicant.conf is fine)
- once the hotspot has been configured it does not load up automatically, do this from /etc/rc.local (maybe use autoconnect=yes?)
- the setup created by the scripts shown below creates a NAT-shared wifi extender; i.e. the clients will be on a completely different subnet than the HomeWifi network
- when the AP (connects to the HomeWifi) and the hotspot (broadcasts its own SSID) are running, you should have two green/connected lines in nmcli con (if using two adapters)
- Use a USB Wireless adapter that is supported by the Linux kernel out of the box, otherwise you'll have to compile the drivers for it (doable, example: Linux wifi dongles)
(*) NetworkManager does use the dnsmasq binary, but it only needs dnsmasq-base and the dnsmasq systemd service should be set to masked/disabled/stopped.
So far I have only been using 2.4Ghz 802.11 bg modes. This is probably less efficient than n mode, but for now I'm documenting just bg mode.
Sample scripts
Create the normal client connection to another wifi router
# use this to create a wifi connection using wlan0 to connect to your Internet-connected home wifi network SSID="HomeWifi" IF="wlan0" nmcli con add con-name $SSID type wifi ssid $SSID ifname $IF nmcli con mod $SSID 802-11-wireless-security.key-mgmt WPA-PSK nmcli con mod $SSID 802-11-wireless-security.psk "secretpassword"
Create the hotspot connection
# use this to create a hotspot (aka Access Point) using wlan1 so other wireless clients can connect and use the internet from wlan0 # WPA-PSK is implied with 'wifi hotspot' IF="wlan1" SSID="HomeWifi-EXT" nmcli dev wifi hotspot ssid $SSID password "secretpasswordext" ifname $IF band bg
Setup port forwarding:
# /etc/NetworkManager/dispatcher.d/pre-up/90-modify-nft-firewall nft flush ruleset nft -f - <<EOF table ip nm-shared-wlan1 { chain nat_postrouting { type nat hook postrouting priority srcnat; policy accept; ip saddr 10.42.0.0/24 ip daddr != 10.42.0.0/24 masquerade } chain filter_forward { type filter hook forward priority filter; policy accept; ip daddr 10.42.0.0/24 oifname "wlan1" iifname "wlan0" accept ip saddr 10.42.0.0/24 iifname "wlan1" oifname "wlan0" accept } chain prerouting { type nat hook prerouting priority dstnat; policy accept; tcp dport 5901 dnat to 10.42.0.26 } } EOF
Setup client ip address reservations:
# /etc/NetworkManager/dnsmasq-shared.d/10-reserved-client-ip-addresses dhcp-host=28:11:a8:f4:8d:91,10.42.0.26 dhcp-host=c0:55:12:da:f3:12,10.42.0.27
Troubleshooting
If things don't work, try to get as much information as you can:
# show all wireless interfaces iwconfig # show currently configured adapters ip a # show default route ip route
wpa_cli -i <interface> log_level debug # show lots of activity # show logs (-f or --follow) as they get produced journalctl -u NetworkManager -u wpa_supplicant -u systemd-networkd --follow wpa_cli -i <interface> log-level info # default (not sure if it has to be set back)
Check country and permitted wifi bands/frequencies:
iw reg get iw reg set <CC> iw phy phy0 info
# /etc/NetworkManager/conf.d/99-wifi.conf # disable mac address randomization (optional, I didn't have to disable it on my system) [device-wifi-no-scan-mac-rand] wifi.scan-rand-mac-address=no
# show DHCP leases obtained by clients on the wlan1 network: cat /var/lib/NetworkManager/dnsmasq-wlan1.leases
# show netfilter ip rules nft list ruleset
TODO
- autoconnect hotspot (not with rc.local)
- connect with 802.11n mode (ideally 40MHz bandwidth)
- ability to set different wifi channels (if nearby congestion)
- move from NAT to bridge (DHCP forward and everything on same subnet)
- have AP_STA (Access Point + Client) on one network adapter
Resources
General info:
- https://www.raspberrypi.com/tutorials/host-a-hotel-wifi-hotspot/
- https://wiki.archlinux.org/title/Software_access_point
- https://wiki.archlinux.org/title/NetworkManager
Troubleshooting: