/Linux-WPA3-Personal

WPA3-Personal (the most secure as of 2020) Access Point using Linux

WPA3-Personal Wi-Fi Access Point on Linux

This document describes how to set up a WPA3-Personal Access Point using Linux, that can always have the latest security patches applied

WPA3-Personal is the only password-based Wi-Fi that as of 2020 is safe to use

WPA3-Personal published in 2018 is supported by Android 10 and macOS Catalina 10.15 or later

Why is WPA3-Personal more secure?

• sae (explained below) is a safe exchange of secrets with forward secrecy

• sae only connects Access Points and clients that prove to have the secret, thereby mitigating the evil-twin problem

WPA2-Personal does not offer any of the above characteristics, it is unsafe to use at all without vpn. The intermediate fix for WPA2 is to always use WPA2-Enterprise eap-tls, everybody else is a victim. Once an attacker is in the WPA2 network which takes only seconds, crafted packets can be sent to any authenticated node exploiting every feature of their typically low-quality software

Process

Get a Compliant Adapter

As of July 2020 the Wi-Fi Alliance only certifies WPA3-capable hardware. To run WPA3-Personal, the hardware must support sae, Simultaneous Authentication of Equals IEEE 802.11-2016

A safe way to determine that the hardware is capable of WPA3-Personal is to verify that the Wi-Fi Alliance has certified it for WPA3 using their Product Finder. At present, vendors claim WPA3 when they only support a certain feature like sae but cannot actually communicate with WPA3-Personal devices. Much hardware does work but is not directly certified

Wi-Fi under Linux generally is troublesome

A USB adapter known to work is NETGEAR A6210, other internal adapters may work if an AP-capable driver can be found

Adapter Must support pmf protected management frames

PMF (protected management frames) certification IEEE 802.11w, also called mfp management frame protection

The only way to determine whether pmf is supported is to run it. hostapd will error on start when provided the following option: ieee80211w=2

Plug the Adapter in

If it is usb, it should be recognized by lsusb You can monitor how the command output changes in order to detect it

Most other adapters appear using lspci In edge cases use lshw

This will give you the vendor and product id which is a two-value hexadecimal number like 846:9053

Find Network Interface

If the device has a driver, a network interface will appear with a name like wlan0. Wireless devices can be listed with iw dev Their names ususally begin with w double-u

iw dev
phy#2
        Interface wlan0
                ifindex 7
                wdev 0x200000001
                addr 00:11:22:33:44:55
                type managed
                txpower 20.00 dBm

phy2 is the iw numbering for the device. To see everything it can do, about 200 lines: iw phy2 info

All network interfaces are listed by ip l

One can also examine which driver claims a certain vendor and product:

modprobe --showconfig | grep v0846p9053
alias usb:v0846p9053d*dc*dsc*dp*ic*isc*ip*in* mt76x2u

Here we can see that the usb product 0846:9053 is claimed by the mt76x2u driver. A driver name is a short word

If no driver claims your product, search the vendor’s web site or search generally on the Internet, many drivers are maintained by volunteers on github. Success is more likely if a tutorial is found by someone else with the same product

If a network interface appears and you want to know which driver provides it, here is for the wlp2s0b1 network interface:

ls /sys/class/net/wlp2s0b1/device/driver/..
b43

The wlp2s0b1 interface was provided by the b43 driver

If it is a usb device with a known driver name, its connected speed can be displayed:

lsusb -t | grep mt76x2u
    |__ Port 2: Dev 2, If 0, Class=Vendor Specific Class, Driver=mt76x2u, 5000M

The device claimed by the mt76x2u driver is connected via usb at 5 Gb/s

Disable NetworkManager

To use hostapd, the device should not be managed by NetworkManager. You have NetworkManager if the directory /etc/NetworkManager/conf.d exists There can only be one file with unmanaged-devices directive

Check for a file to append to:

grep unmanaged /etc/NetworkManager/conf.d/*
/etc/NetworkManager/conf.d/00-unmanaged.conf:unmanaged-devices=interface-name:enp4s0;interface-name:enx*;interface-name:wlx08beac12be74

If /etc/NetworkManager/conf.d does not eixst, move on

If the grep command above produces output, add to the line that already exists

otherwise create a file with extension .conf like:

nano /etc/NetworkManager/conf.d/00-unmanaged.conf
[keyfile]
unmanaged-devices=interface-name:wlan0

systemctl restart NetworkManager.service

Verify that NetworkManager no longer manages your device:

nmcli d s
DEVICE           TYPE      STATE         CONNECTION 
wlan0            wifi      unmanaged     --         

Assign IP

Pick an unused area of 256 ip addresses, like 10.0.5.0. Create a file with .network extension, here for the wlan0 interface:

nano /etc/systemd/network/10-wlan0.network
[Match]
Name=wlan0
[Link]
RequiredForOnline=no
[Network]
ConfigureWithoutCarrier=true
Address=10.0.5.1/24

systemctl reload systemd-networkd

ip a should now show that the interface has an ip address

ip a s dev wlan0
7: wlan0:  mtu 2312 qdisc mq state UP group default qlen 1000
    link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff
    inet 10.0.5.1/24 brd 10.0.5.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::847b:41ff:fe34:da20/64 scope link 
       valid_lft forever preferred_lft forever

Get dhcp and dns

Install dnsmasq and hostapd: apt install --yes dnsmasq hostapd

If your interface is wlan0 and ip 10.0.5.0, create two files:

nano /etc/hostapd/wlan0-dnsmasq
bind-interfaces
listen-address=10.0.5.1
no-hosts
dhcp-range=10.0.5.32,10.0.5.254
dhcp-option=option:router,10.0.5.1

nano /etc/systemd/system/dnsmasq@.service
[Unit]
Description=dhcp and dns for interface %i
Requires=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
After=network.target
[Service]
PIDFile=/run/dnsmasq/%i.pid
Restart=on-failure
RestartSec=5
ExecStart=/usr/sbin/dnsmasq --keep-in-foreground --conf-file=/etc/hostapd/%i-dnsmasq
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target

systemctl start dnsmasq@wlan0

dns and dhcp are now running:

ps -fCdnsmasq | cat
UID          PID    PPID  C STIME TTY          TIME CMD
nobody     45081       1  0 Dec12 ?        00:00:02 /usr/sbin/dnsmasq --keep-in-foreground --conf-file=/etc/hostapd/wlan0-dnsmasq

Unblock the Transmitter

From iw dev you have your interface’s phy number

Then verify it to be unblocked using rfkill:

rfkill
ID TYPE      DEVICE      SOFT      HARD
 0 wlan      phy0   unblocked unblocked
 1 bluetooth hci0   unblocked unblocked
 2 wlan      phy1   unblocked unblocked

• For the line with the phy number, if it says blocked in the HARD column, there is a switch on the computer needing to be toggled

If the SOFT column says blocked, unblock using the number in the ID column: rfkill unblock 2

Start hostapd

Create a file named using your interface wlan0 and extension .conf: also decide on your ssid and password. The password should not be known or guessable to an attacker

nano /etc/hostapd/wlan0.conf
# © 2020-present Harald Rudell  (https://haraldrudell.github.io/haraldrudell)
# License: ISC
# 0846:9053 NetGear, Inc. A6210 WPA3-Personal 2.4 GHz 54 Mb/s: 802.11g
# directive order: https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf
interface=wlan0
ssid=anything
logger_stdout=63
logger_stdout_level=0
country_code=US
ieee80211d=1
hw_mode=g
channel=9
auth_algs=1
ap_isolate=1
wpa=2
wpa_key_mgmt=SAE
rsn_pairwise=CCMP
ieee80211w=2
sae_password=unguessable
sae_require_mfp=1

To test you access point: hostapd -t /etc/hostapd/wlan0.conf

To run your access point: systemctl start hostapd@wlan0

Access Points under linux are implemented using hostapd: hostapd reference

To see what hostapd is running:

ps -fChostapd | cat
UID          PID    PPID  C STIME TTY          TIME CMD
root       44929       1  0 Dec12 ?        00:00:18 /usr/sbin/hostapd -B -P /run/hostapd.pid -B /etc/hostapd/wlan0.conf

Provide Internet Access

The steps above allows Wi-Fi clients to access the host machine. For clients to access the Internet, ip forwarding and SNAT must be added; a template is here for wi-fi interface wlan0 and Internet interface eth0:

iptables --insert FORWARD --in-interface wlan0 --out-interface eth0 --jump ACCEPT
iptables --insert FORWARD --in-interface wlan0 --out-interface eth0 --jump MARK --set-mark 0x123
iptables --insert FORWARD --in-interface eth0 --out-interface wlan0 --match state --state RELATED,ESTABLISHED --jump ACCEPT
iptables --append FORWARD --jump DROP
iptables --table nat --insert POSTROUTING --match mark --mark 0x123 --jump MASQUERADE
echo -n 1 >/proc/sys/net/ipv4/ip_forward

To see iptable rules, which may be a lot:

iptables-save | less

Note: as of Linux 5.4.0, bugs prevents speeds faster than 54 Mb/s 802.11g. NETGEAR A6210 can otherwise do 867 Mb/s on 5 GHz

Updated: 12/13/2020