How to manage WiFi interfaces with rfkill command on Linux

Rfkill is an utility available in the vast majority of Linux distributions, and often installed by default. The utility allows us to list, enable or disable various types of wireless interfaces like WIFI or Bluetooth on Linux.

In this tutorial we see how to use it, and what are the most useful options we can pass to modify its behavior.

In this tutorial you will learn:

  • How to list wireless interfaces
  • How to enable or disable wireless interfaces by Id
  • How to enable or disable wireless interfaces by type
  • How to toggle the status of a wireless interface
  • How to run rfkill without administrative privileges
How to manage wireless interfaces with rfkill on Linux
How to manage wireless interfaces with rfkill on Linux

Software requirements and conventions used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution-independent
Software rfkill
Other Root permissions to perform administrative tasks
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Listing wireless interfaces

The most basic operation we can perform with rfkill is listing all the available wireless interfaces on a machine. To accomplish this action, all we have to do is to invoke the utility without specifying any option or argument:

$ sudo rfkill

Here is the output produced by the command on my machine:

ID TYPE      DEVICE                   SOFT      HARD
 0 bluetooth tpacpi_bluetooth_sw unblocked unblocked
 2 wlan      phy0                unblocked unblocked
 5 bluetooth hci0                unblocked unblocked



The output of the program, as we can see, is organized in columns. In the first column displayed by default, ID, we can see the device identifier value; in the second, TYPE, we can find the device type; in this case, for example, we can distinguish  bluetooth and wlan interfaces. The third column, DEVICE, reports the kernel device name. The last two columns report the status of the soft and hard block for an interface, respectively.

Another column is available but not included by default: TYPE-DESC, which reports the description of the device type. To make so that it is included in the output of rfkill, or more generally to specify what columns should be included in it, we can use the -o option (which is the short version of --output), and provide the comma-separated list of the columns as argument (a shortcut to make so that all available columns are displayed, instead, is --output-all).

Let’s see an example: suppose we want to include only the ID, TYPE-DESC, SOFT and HARD columns in the output of rfkill. Here is how we would invoke the program:

$ sudo rfkill -o ID,TYPE-DESC,SOFT,HARD

Here is the output we would obtain:

ID TYPE-DESC         SOFT      HARD
 0 Bluetooth    unblocked unblocked
 2 Wireless LAN unblocked unblocked
 4 Bluetooth    unblocked unblocked

There are other options we can use to format the output generated by rfkill. We can for, example, make the program generate a JSON-formatted output. All we have to do is to invoke it with the -J or --json option:

{
   "rfkilldevices": [
      {
         "id": 0,
         "type": "bluetooth",
         "device": "tpacpi_bluetooth_sw",
         "soft": "unblocked",
         "hard": "unblocked"
      },{
         "id": 2,
         "type": "wlan",
         "device": "phy0",
         "soft": "unblocked",
         "hard": "unblocked"
      },{
         "id": 5,
         "type": "bluetooth",
         "device": "hci0",
         "soft": "unblocked",
         "hard": "unblocked"
      }
   ]
}

Getting a JSON formatted output can be useful in some situations, since JSON can be easily parsed with our programming language of choice. Parsing JSON files with Python, for example, is really easy!

Block, Unblock and toggle the status of wireless interfaces

Once we obtain the list of the available wireless interfaces on our machine, managing their status with rfkill is really easy. We can block, unblock or more generically toggle the status of an interface referencing it by its ID. Let’s see some examples.

Blocking an interface by ID

A wireless interface can be subject of two type of blocks: software and hardware. The “hard” block status cannot be changed via software, and is typically a block performed by an hardware switch, or implemented via the machine firmware in specific situations: on some machines, for example, it’s possible to disable the wifi interface when a LAN cable is connected.



A “soft” block, instead, is performed via software, and we can set its status by using rfkill. Suppose we want to disable the bluetooth interface which in the previous example has the ID 0. Here is the command we would run:

$ sudo rfkill block 0

The device is now reported as “soft blocked”:

ID TYPE      DEVICE                   SOFT      HARD
 0 bluetooth tpacpi_bluetooth_sw   blocked unblocked
 2 wlan      phy0                unblocked unblocked

Blocking interfaces by type

Using rfkill we can reference devices not only by their ID, but also by the value reported in the TYPE column. This can be useful if we want to block or unblock multiple devices at once. For instance, suppose we want to block all available bluetooth devices with a single command; here is what we would run:

$ sudo rfkill block bluetooth

Unblocking interfaces

Unblocking one or more interfaces with rfkill is just as easy. All we have to do is to use the “unblock” command instead of “block”. Supposing we want to unblock the bluetooth device we blocked in the previous example, we would run:

$ sudo rfkill unblock 0

To unblock all bluetooth devices, instead:

$ sudo rfkill unblock bluetooth

Toggle the status of an interface

By using the “toggle” command, we can switch the status of an interface, without specifying it explicitly. If an interface is blocked, it will be unblocked, and vice-versa. To toggle the status of the interface with ID 0, for example, we would run:

$ sudo rfkill toggle 0

Running rfkill without administrative privileges

On distributions like Debian and Ubuntu, or more generally where not configured otherwise, to list the available wireless interfaces with rfkill and to change their status, so to soft block or unblock them, rfkill must be invoked with administrative privileges, either by prefixing the command with sudo, or by invoking it as the root user directly. On recent versions of Fedora, however, it’s possibile to perform those actions by launching the command as a normal user. Why this happens?



The rkill user interface exposed by the Linux kernel is the /dev/rfkill character device. If we take a look at the permissions of this device by running ls on it, we can see that a + sign is reported in the permissions notation:

$ ls -l /dev/rfkill
crw-rw-r--+ 1 root root 10, 242 Mar 22 09:18 /dev/rfkill

The + sign means that the file has ACL extended attributes applied. To get more information about it, we can use the getfacl command:

$ getfacl /dev/rfkill

We obtain the following output:

# file: dev/rfkill
# owner: root
# group: root
user::rw-
user:doc:rw-
group::rw-
mask::rw-
other::r--

As you can see, by default, apart from standard unix permissions, a specific rw permission on the file exists for the “doc” user, which is my username on the machine. This is done automatically by the distribution, and is why we can launch it without privilege escalation. If we want to remove those special permissions from the file, we can simply run the following command:

$ sudo setfacl -b /dev/rfkill

If you want to know more about ACLs on Linux, you can take a look at our introductory tutorial on the subject.

Conclusions

In this tutorial we learned how to use rfkill to get the list of the wireless interfaces available on a machine and we saw how to block, unblock them, and toggle their status. Finally we saw how it is possible to use rfkill as a standard user, without the need of special privileges.



Comments and Discussions
Linux Forum