Up | Home

Connecting to a Wi-Fi network from Guix using ConnMan

Table of Contents

1. Introduction

I have been using iwd and its iwctl(1) tool for a long time, but when using switching to a Guix system, I realized that there is not much support for it yet.

Alternatively, one might use Guix services like network-manager-service-type or connman-service-type. I will be using the later, along with wpa-supplicant-service-type.

I would also like to note that there is a '(iwd) value we could use for the shepherd-requirement parameter, but currently (01/01/2025) it’s not really supported.

2. Setting up the ConnMan service in Guix

In your Guix system configuration, you will have to include the following modules:

(use-modules
 ;; ...
 (gnu services networking))

And then add the actual services to your (operating-system ...) declaration:

(operating-system
 ;; Other parameters...

 (services
  ;; Other services...

  (service wpa-supplicant-service-type)
  (service connman-service-type
           (connman-configuration
            (shepherd-requirement '(wpa-supplicant))
            (general-configuration
             (connman-general-configuration
              (allow-hostname-updates? #f)
              (allow-domainname-updates? #f)
              (single-connected-technology? #f)))))))

In this case we are using the default settings for WPA Supplicant, but we are specifying some other options for ConnMan. We could also specify some other ConnMan settings like (disable-vpn? #t) by adding it to the connman-configuration. For more information on available settings, see connman-general-configuration.

Once our configuration is updated, we can reconfigure our system with:

# Change the path to match your system configuration.
sudo -E guix system reconfigure ~/.config/guix/system.scm

2.1. Checking the service

Once the system is reconfigured and rebooted, make sure the service is enabled and running by checking its herd status:

$ sudo herd status
Started:
 ...
 + connman
 ...
 + wpa-supplicant
 ...

$ sudo herd status connman
- Status of connman:
  It is running since 09:04:18 AM (44 minutes ago).
  Main PID: 309
  Command: /gnu/store/[...]-connman-1.42/sbin/connmand --config=/gnu/store/[...]-main.conf --nodaemon --nodnsproxy --noplugin=vpn
  It is enabled.
  Provides: connman networking
  Requires: user-processes dbus-system loopback wpa-supplicant
  Will be respawned.
  Log file: /var/log/connman.log

$ sudo herd status wpa-supplicant
- Status of wpa-supplicant:
  It is running since 09:04:18 AM (45 minutes ago).
  Main PID: 288
  Command: /gnu/store/[...]-wpa-supplicant-2.10/sbin/wpa_supplicant -P/var/run/wpa_supplicant.pid -B -s -u
  It is enabled.
  Provides: wpa-supplicant
  Requires: dbus-system user-processes loopback syslogd
  Will be respawned.

If you get a socket error like:

herd: error: /run/user/1000/shepherd/socket: No such file or directory

It means your user doesn’t have enough privileges, so you should run that command with sudo.

3. Connecting to a protected Wi-Fi network using connmanctl

Once the service is enabled and running, we can connect to the network using connmanctl. Since we are connecting to a protected network, we will need to use the program in interactive mode by running:

$ connmanctl

First, scan for wifi networks:

connmanctl> scan wifi

Then list the available networks:

connmanctl> services
*AO MyNetwork               wifi_dc85de828967_68756773616d_managed_psk
    OtherNET                wifi_dc85de828967_38303944616e69656c73_managed_psk
    AnotherOne              wifi_dc85de828967_3257495245363836_managed_wep
    FourthNetwork           wifi_dc85de828967_4d7572706879_managed_wep
    AnOpenNetwork           wifi_dc85de828967_4d6568657272696e_managed_none

Register the agent to handle user requests:

connmanctl> agent on

Connect to one of the networks using the wifi_ name.

connmanctl> connect wifi_dc85de828967_68756773616d_managed_psk

If it’s your first time connecting, you will need to enter the password:

Agent RequestInput wifi_dc85de828967_38303944616e69656c73_managed_psk
  Passphrase = [ Type=psk, Requirement=mandatory ]
  Passphrase?

After that, you can exit the connmanctl program:

connmanctl> quit

4. Checking the interface status

ConnMan will also handle DHCP, so we should get a dynamic IP automatically. You can check the interface status with ip-address(8):

$ ip a
1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope global lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host proto kernel_lo
       valid_lft forever preferred_lft forever
2: enp0s25: <NO-CARRIER,BROADCAST,MULTICAST,DYNAMIC,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether 11:22:33:aa:bb:cc brd ff:ff:ff:ff:ff:ff
3: wlp3s0: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 44:55:66:aa:bb:cc brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.2/24 brd 192.168.0.255 scope global wlp3s0
       valid_lft forever preferred_lft forever
    inet6 aaaa::bbbb:111:2222:3333/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever