How to use systemd-networkd to manage your wifi

systemd
wifi
network
networkd

#1

In most manjaro editions you connect to your wifi with networkmanager. This tutorial shows you the basics of how to use systemd-networkd and wpa_supplicant instead.

Why would you want to do this?
Networkmanager usually does great job in managing your network. However, it uses a lot of resources to do this (albeit this is neglible on most modern hardware). Systemd-networkd can do the same job for a lot less - On my system networkmanager consumes about 20mb ram, plus about 15mb if I use a tray icon for it. Networkd and resolvd use together less than 2mb ram. And it is already installed on your system if you use systemd, so there is nothing extra to install.

Why not use netctl instead?
Because you don’t have to. For me, netctl has always been very buggy and unreliable. Networkd just works.

Are there any downsides?
Yes!

  1. You need sudo to access to connect to a new wifi. However, when you connect once, you automatically connect to that wifi-without any action from your part.
  2. There is no nice interactive interface to this. Seriously, even the awful netctl has more options for this. And networkmanager has excellent user friendly interface for both command line and gui.
    To connect to a new network, you need command line. I plan on writing some kind of interactive interface for this when I have the time. And also to automate setting this up. There is wpa_gui (using qt) and wpa_cli that you can use, but they really arent optimal for basic wifi management.
  3. You need to use systemd. For some people, this is a dealbreaker. But most of us use systemd anyway.
  4. if you are not carefull, your wifi password might get stored in plain text in your shell command history. To get around this, you can manually delete those lines from your history, use dash shell (instead of bash, fish or zsh) that does not log your command history, or use a wrapper script or disable command history temporarily.

Okay, I still want to try. How to do this?
You need to create a few configuration files first. You need sudo for this.
For this, you need to know the name of your wireless interface (I think you do). You can get it by running this command:

networkctl | awk '/wlan/ {print $2}'

This should give you output something like β€œwlp1s0” but that 1 can be a different number. If that does not work, run just

networkctl
to get more detailed list.

  1. Then create following files with text editor of your choice, replacing wlp1s0 with name of your interface:

/etc/systemd/network/wireless.network

# /etc/systemd/network/wireless.network
[Match]
Name=wl*

[Network]
DHCP=yes
RouteMetric=20
IPv6PrivacyExtensions=true
## to use static IP uncomment these instead of DHCP
#DNS=192.168.1.254
#Address=192.168.1.87/24
#Gateway=192.168.1.254

/etc/wpa_supplicant/wpa_supplicant-wlp1s0.conf

# /etc/wpa_supplicant/wpa_supplicant-wlp1s0.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1
eapol_version=1
ap_scan=1
fast_reauth=1

Optional: to make networkd also manage your wired connection, also create
/etc/systemd/network/wired.network

# /etc/systemd/network/wired.network
[Match]
Name=en*

[Network]
DHCP=yes
RouteMetric=10
IPv6PrivacyExtensions=true
## to use static IP uncomment these instead of DHCP
#DNS=192.168.1.254
#Address=192.168.1.87/24
#Gateway=192.168.1.254
  1. Disable networkmanager, connman, wicd or any other service you might have managing your internet. For network manager, the command is

    sudo systemctl disable networkmanager
    sudo systemctl stop networkmanager

I also had to uninstall networkmanager to prevent it from autostarting, but that might not be the case for you. Many packages, such as gnome, depend on networkmanager.

  1. Run following commands to enable right services and replace your resolv.conf with a symlink to systemd folder. Again, replace wlp1s0 with the name of your interface.

    sudo -i
    rm /etc/resolv.conf
    systemctl enable systemd-networkd
    systemctl enable wpa_supplicant@wlp1s0
    systemctl enable systemd-resolved
    systemctl start systemd-networkd
    systemctl start wpa_supplicant@wlp1s0
    systemctl start systemd-resolved
    ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

  2. Add your wifi to your configuration with

    set +o history
    sudo wpa_passphrase >> /etc/wpa_supplicant/wpa_supplicant-wlp1s0.conf
    set -o history

is the name of your wifi and is your password.

  1. Reboot. It should work.

Sources (contain also instructions how to do this for wired connection and how to use static ip instead of dhcpd):
https://wiki.archlinux.org/index.php/systemd-networkd
https://beaveris.me/systemd-networkd-with-roaming/
http://dabase.com/blog/Good_riddance_netctl/
http://blog.volcanis.me/2014/06/01/systemd-networkd/


Networkmanager, netctl or systemd-networkd for static IP toggle
Wireless error (device not ready)
Wlan an eeepc nimmt keine Verbindung auf
#2

Since I have NetworkManager on a LXDE netinstall and never need to change any settings this might be an interesting option.
This might be also an option for a new netinstall, it seems to be easy (if you know the commands) and precise.


#3

It is. Although I had to try few times, because I made some miistakes on the first try.

The main difficulty in usage is that you cant select wifi networks from a list. You just need to know the wifi name.

My plan for the frontend package is following:

  • package installation automatically generates right configs based on available interfaces
  • networkd-menu lets you choose network with fzf. Then you input the wifi password and you are asked the sudo password.

#4

Better is call

sudo -i

instead of

sudo su

@Chrysostomus


#5

Thanks, updated the guide. Why is it better?


#6

Awesome! Thank you so much for this!

That would be a much appreciated gift for all lightweight editions. nm is such a disproportionate monster in regards of RAM usage and as you say there is practically no way around it if you want to have at least some basic usability and reliability.


#7



#8

Much appreciated!


#9

This should be reliable, but

  • Still would require sudo to connect to new wifi
  • The interface would not have indicator to tell signal strength nor what wifi you are connectd to. You would need something else for that (limepanel, conky, custom status bash script or something)

I should also mention that I was planning on writing a bash interface. Other options are dmenu and zenity/spacefm. With enough time, it would be possible to include them all, with different frontends as opt-depends.


#10

Does this rule out the use of dnscrypt?
(replacing /etc/resolv.conf)


#11

I don’t know don’t know dnscrypt, but probably yes if it wants to write to your resolv.conf. However, that symlinking part is actually not mandatory if you don’t use systemd-resolvd. Networkd works also if you manually set your resolv.conf, so I would imagine dnscrypt could work woth it too.


#12

My only concern is with step 4. I know some people are going bash me for saying this. But would it be a better idea to used dash shell for step 4. Main reason is, it a bad idea to but your password to your network/modem. Inside a interactive shell terminal(bash, zsh, fish ect.). Due to the save history. Other wise maybe wpa_cli will be a nice option.

BTW nice guide.


#13

Good catch, you are absolutely right! It defeats the whole purpose of using wpa_passphrase! I’ll upsate the guide.

I think other options beside using dash are

  • manually deleting the lines from shell history. Awkward.
  • using a wrapper that runs in subshell so history does not get logged.

#14

Okay, I started to write the script (wpa_tui). Network chooser and password prompt work, but network detection is still unreliable, since I try to make it work without root access. If I donΒ΄t scan networks first with

iw list

then only the connected network gets listed. That scanning takes almost 5 seconds and requires root access. Still looking into options…


#15

It doesn’t want to write - only read.


#16

Here is a sneak peek of the script I mentioned:

#!/bin/bash
# wpa_tui, script for adding networks when you use systemd-networkd

RED='\e[41m'
BLUE='\e[44m'
ORANGE='\e[46m'
NC='\e[0m'


wpa_config_file=$(echo /etc/wpa_supplicant/wpa_supplicant-$(ip a show | grep -o "wlp.s0" | uniq).conf)

add_network()
{
chosen_network=$(wpa_cli scan_results | awk '!/^bssid/ {print $5}' | fzf-tmux --reverse --exit-0 --prompt="Select a network >")
network_password=$(read -s -p "Password for chosen network: " PASS; echo $PASS)

sudo wpa_passphrase $chosen_network $network_password >> /etc/wpa_supplicant/$wpa_config_file
}



main()
{
wpa_cli scan
    while true; do
    clear
    echo ""
    echo -e "                          ::Init menu:: "
    echo -e " β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”"
    echo -e " β”‚    1   Add a network                2   Show status         β”‚"
    echo -e " β”‚    3   Edit configration            4   List configured     β”‚"
    echo -e " β”‚    5   List available networks                              β”‚"
    echo -e " β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜"
    echo -e "          Select an item       -       0   Exit "
    echo ""
    read -s -n1 choix
    case $choix in
        1)
            echo
            add_network
            echo ""
            echo "Press any key to continue"
            read
            ;;
        2)
            echo
            wpa_cli status
            echo ""
            echo "Press any key to continue"
            read
            ;;
        3)
            echo
            $EDITOR $wpa_config_file
            echo ""
            echo "Press any key to continue"
            read
            ;;
        4)
            echo
            wpa_cli list_networks
            echo ""
            echo "Press any key to continue"
            read
            ;;
        5)
            echo
            wpa_cli scan_results
            echo ""
            echo "Press any key to continue"
            read
            ;;
        0)
            clear && exit
            read
            ;;
        *)
            echo -e "$RED Wrong option $NC"
            echo "Wait and try again later..."
            echo ""
            sleep 3
            clear
            ;;
    esac
    done

}

main

#17

Why not prior to step 4 just do set +o history then enter your command with your wifi password followed by set -o history to resume history logging?

Source: http://unix.stackexchange.com/questions/10922/temporarily-suspend-bash-history-on-a-given-shell


#18

Good idea! That seems like the best option yet.


Plans for upcoming bspwm 16.06
#19

I tested this script on the Bspwm 16.06. install, but it was a newer version with some kind of automatic setup for networkd. But this automatic setup didn’t work and it also destroyed NetworkManager and I wasn’t able to repair it. So, this is a warning if anybody wants to try this automatic networkd setup script. Before I was able to start a topicfor troubleshooting I deleted my @bspwm subvolume by accident, but I will reinstall and try it again and report.


#20

I reinstalled Bspwm 16.06, made a snapshot with working NetworkManager, then tried wpa_tui (the terminal app to set up networkd). Before that I disabled and stopped NetworkManager, but on reboot it was there in htop again (together with networkd and resolvd), so I uninstalled it. On reboot wasn’t able to connect, but then got the idea to read man wpa_cli. Then I started wpa_cli ran the commands interface wlan0 and reconfigure and the the network was up!

[code]~ >>> sudo wpa_cli 23:38:27
wpa_cli v2.5
Copyright Β© 2004-2015, Jouni Malinen j@w1.fi and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.

Selected interface β€˜wlan0’

Interactive mode

status
wpa_state=INACTIVE
address=00:16:cf:ab:43:bf
uuid=1f4d8cf1-500e-54e9-8cb4-24de2d542891
interface wlan0
Connected to interface 'wlan0.
reconfigure
OK
<3>CTRL-EVENT-SCAN-STARTED
<3>CTRL-EVENT-SCAN-RESULTS
<3>WPS-AP-AVAILABLE
<3>SME: Trying to authenticate with 00:1a:2a:89:09:99 (SSID=β€˜WLAN-890929’ freq=2422 MHz)
<3>Trying to associate with 00:1a:2a:89:09:99 (SSID=β€˜WLAN-890929’ freq=2422 MHz)
<3>Associated with 00:1a:2a:89:09:99
<3>WPA: Key negotiation completed with 00:1a:2a:89:09:99 [PTK=CCMP GTK=TKIP]
<3>CTRL-EVENT-CONNECTED - Connection to 00:1a:2a:89:09:99 completed [id=0 id_str=]
status
bssid=00:1a:2a:89:09:99
freq=2422
ssid=WLAN-890929
id=0
mode=station
pairwise_cipher=CCMP
group_cipher=TKIP
key_mgmt=WPA2-PSK
wpa_state=COMPLETED
ip_address=192.168.2.100
address=00:16:cf:ab:43:bf
uuid=1f4d8cf1-500e-54e9-8cb4-24de2d542891

[/code]

I felt like a real geek after that! :eyeglasses:

The network seems to start slow now, several minutes, or is it just the limepanel indicator? No, it was just acoincidence, now WiFi starts up fast.