Example 2: Configure wpa_supplicant in Ubuntu 24.04
In this example the Ansible role:
creates wpa_supplicant configuration
starts wpa_supplicant service
netplan configured networkd configures IP address, resolver, and routing
Create a playbook
shell> cat lp.yml
---
- hosts: test_01
become: true
roles:
- vbotka.linux_postinstall
Create host_vars/test_01/lp-wpasupplicant.yml
Take a look at the wpa_supplicant services available at the remote host
test_01> systemctl list-unit-files | grep wpa
wpa_supplicant-nl80211@.service disabled enabled
wpa_supplicant-wired@.service disabled enabled
wpa_supplicant.service disabled enabled
wpa_supplicant@.service disabled enabled
The utility wpa_supplicant will be installed (4) and the services
(13, 22) will be configured to use the binary (10). The nl80211
service wpa_supplicant-nl80211@.service is available. Therefor, in
the configuration, we use type: nl80211 (41). This play will start
the service wpa_supplicant-nl80211@wlan0.service (40). However,
this service will not be started at the system start (39). The
attribute disabled (47,52) tells wpa_supplicant which AP to
connect automatically to
1shell> cat host_vars/test_01/lp-wpasupplicant.yml
2---
3lp_wpasupplicant: true
4lp_wpasupplicant_install: true
5lp_wpasupplicant_debug: false
6lp_wpasupplicant_debug_classified: false
7lp_wpasupplicant_conf_only: false
8lp_wpasupplicant_service_conf_only: false
9
10lp_wpasupplicant_bin: /usr/sbin/wpa_supplicant
11lp_wpasupplicant_service_conf:
12 - path: /lib/systemd/system
13 service: wpa_supplicant@.service
14 no_extra_spaces: true
15 handlers:
16 - 'reload systemd daemon'
17 ini:
18 - section: Service
19 option: ExecStart
20 value: "{{ lp_wpasupplicant_bin }} -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I"
21 - path: /lib/systemd/system
22 service: wpa_supplicant-nl80211@.service
23 no_extra_spaces: true
24 handlers:
25 - 'reload systemd daemon'
26 ini:
27 - section: Service
28 option: ExecStart
29 value: "{{ lp_wpasupplicant_bin }} -c/etc/wpa_supplicant/wpa_supplicant-nl80211-%I.conf -Dnl80211 -i%I"
30
31lp_wpasupplicant_conf_global:
32 - {key: ctrl_interface, value: "{{ lp_wpasupplicant_conf_ctrl_interface }}"}
33 - {key: ctrl_interface_group, value: adm}
34 - {key: fast_reauth, value: 0}
35 - {key: update_config, value: 1}
36
37lp_wpasupplicant_conf:
38 - dev: wlan0
39 enabled: false
40 state: started
41 type: nl80211
42 network:
43 - conf:
44 - {key: ssid, value: '"AP1"'}
45 - {key: psk, value: '"password"'}
46 - {key: pairwise, value: CCMP}
47 - {key: disabled, value: 0}
48 - conf:
49 - {key: ssid, value: '"AP2"'}
50 - {key: psk, value: '"password"'}
51 - {key: pairwise, value: CCMP}
52 - {key: disabled, value: 1}
In this scenario:
wpa_supplicant won’t be started at the system start. You have to start the service manually.
wpa_supplicant will automatically connect to AP1.
Warning
This role doesn’t test whether a service is already used by other interfaces or not. It’s necessary to disable such services and make sure corresponding wpa_supplicants are not running. Otherwise the restart of such service will crash.
Enable service at system start
Optionally, you might want to enable wpa_supplicant and start it. Disable all access points if you want to avoid accidental connections
lp_wpasupplicant_conf:
- dev: wlan0
enabled: true
state: started
...
In this scenario:
wpa_supplicant will be started at the system start.
wpa_supplicant will not automatically connect to any access point. You can use wpa_cli or wpa_gui to control wpa_supplicant.
Note
systemd-networkd uses internal DHCP client. See Example 2: Configure wifi interface by Netplan
If you don’t enable DHCP client in the netplan configuration create script wpa_action.sh and run wpa_cli
wpa_cli -B -i wlan0 -a /root/bin/wpa_action.sh. By default, the action script won’t be createdlp_wpa_action_script: false.
Warning
Setting lp_wpasupplicant_debug_classified: true (6) will
display also the passwords.
Configure wpa_supplicant
The below listing is abridged
shell> ansible-playbook lp.yml -t lp_wpasupplicant
TASK [vbotka.linux_postinstall : wpasupplicant: Create wpasupplicant configuration file]
changed: [test_01] => (item=None)
changed: [test_01]
TASK [vbotka.linux_postinstall : wpasupplicant: Configure wpa_supplicant services] *****
changed: [test_01] => (item=/lib/systemd/system/wpa_supplicant@.service)
changed: [test_01] => (item=/lib/systemd/system/wpa_supplicant-nl80211@.service)
TASK [vbotka.linux_postinstall : wpasupplicant: Manage wpa_supplicant services] ********
changed: [test_01] => (item=wpa_supplicant-nl80211@wlan0.service)
TASK [vbotka.linux_postinstall : wpasupplicant: Debug: Services] ***********************
skipping: [test_01]
RUNNING HANDLER [vbotka.linux_postinstall : reconfigure wpa_supplicant] ****************
changed: [test_01] => (item=wpa_supplicant-nl80211@wlan0.service)
PLAY RECAP *****************************************************************************
test_01: ok=7 changed=4 unreachable=0 failed=0 skipped=15 rescued=0 ignored=0
Note
There is no item (item=None) reported by the task Create wpasupplicant configuration file because the log is disabled
no_log: "{{ not lp_wpasupplicant_debug_classified }}"
The command is idempotent
shell> ansible-playbook lp.yml -t lp_wpasupplicant
...
PLAY RECAP ******************************************************************
test_01: ok=11 changed=0 unreachable=0 failed=0 skipped=15 rescued=0 ignored=0
Show the process at the remote host
test_01> pgrep -a wpa_supplicant
124727 /usr/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-nl80211-wlan0.conf -Dnl80211 -iwlan0
Show the status of the service at the remote host
test_01 > systemctl status wpa_supplicant-nl80211@wlan0.service
● wpa_supplicant-nl80211@wlan0.service - WPA supplicant daemon (interface- and nl80211 driver-specific version)
Loaded: loaded (/usr/lib/systemd/system/wpa_supplicant-nl80211@.service; disabled; preset: enabled)
Active: active (running) since Tue 2024-05-28 13:52:49 CEST; 3 weeks 3 days ago
Main PID: 124727 (wpa_supplicant)
Tasks: 1 (limit: 9282)
Memory: 1.3M (peak: 2.2M swap: 1.3M swap peak: 1.3M)
CPU: 2min 21.899s
CGroup: /system.slice/system-wpa_supplicant\x2dnl80211.slice/wpa_supplicant-nl80211@wlan0.service
└─124727 /usr/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-nl80211-wlan0.conf -Dnl80211 -iw>
Jun 21 12:55:25 test_01 wpa_supplicant[124727]: wlan0: WPA: Group rekeying completed with <sanitized> [GTK=CCMP]
The service is active and the connection to the access-point completed.
Display the link and IP address
test_01> iw wlan0 link
Connected to <sanitized> (on wlan0)
SSID: AP1
freq: 2412.0
RX: 250263021 bytes (2007924 packets)
TX: 2194111 bytes (16115 packets)
signal: -24 dBm
rx bitrate: 104.0 MBit/s MCS 13
tx bitrate: 144.4 MBit/s MCS 15 short GI
bss flags: short-preamble short-slot-time
dtim period: 2
beacon int: 100
test_01> ip address show wlan0
10: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether <sanitized> brd ff:ff:ff:ff:ff:ff
inet 10.1.0.150/24 metric 100 brd 10.1.0.255 scope global dynamic wlan0
valid_lft 42339sec preferred_lft 42339sec
inet6 fe80::429b:cdff:fe03:4ca/64 scope link
valid_lft forever preferred_lft forever
Show the configuration of networkd
test_01> networkctl
IDX LINK TYPE OPERATIONAL SETUP
1 lo loopback carrier unmanaged
2 eth0 ether routable configured
3 wlan0 wlan routable configured
3 links listed.