How to hack your Linux Wireless interface in 5 steps

Last week I was looking into my laptop wireless configuration and I was trying to figure out what was going on in the background (user space software, kernel drivers ...). The point is that CentOS 7, which is the distribution I am currently using at home, comes with the Network Manager configured by default and even if it makes the life easier for the most, it hides all the background configuration and processes... which I really don't like!

So I decided to uninstall the Network Manager from my personal laptop and manually create the scripts required to bring up my WPA2 home wireless network !

In this blog I will provide you with an overview of the Linux Wireless subsystem and a step by step procedure to set up your wireless network (based upon CentOS 7 but possibly good for all the RedHat based distributions)

Commands will be described inline within the document where needed: I used the convention to write each command and option in bold while your "personal stuff" will be in Italic (ie your wireless card name).

Comments and criticism are always welcome.

1 - Overview of the Linux Wireless subsystem

In our description we will consider a simple configuration which involves a subscriber (our Linux box) and an Access Point (our wireless router). This typical architecture is called "Infrastracture BSS" (BSS stands for Basic Service Set). Whenever you have multiple BSS connected through a wired network, then the new architecture is called ESS or "Extended Service Set".



An Access Point can be defined as a wireless device working in "master mode". When a device is set in "master mode" it cannot scan the "media" (air).

These are the possible modes a wireless device can be configure to work:
  1. Master
  2. Monitor
  3. Managed
  4. Ad-hoc
  5. Mesh
  6. Repeater
Interfaces in Managed Mode are considered clients or stations and are the devices connected to an access point.

2 - Probing your system and environment


Let's start to identify our wireless card. If it is an embedded card it is probably connected to the PCI bus:
# lcpci | grep -A2 -i net

My output:
03:00.0 Network controller [0280]: Intel Corporation Centrino Advanced-N 6200 [8086:4239] (rev 35)
Subsystem: Intel Corporation Centrino Advanced-N 6200 2x2 AGN [8086:1311]
Kernel driver in use: iwlwifi

The -A2 option within grep let you print the trailing context (which provide us with the driver name).

Otherwise we can check the content of the file /proc/bus/pci/devices I will find the name of the driver my kernel is using to manage the device. If none ... than we need to google the card name and search for the driver for your distribution, then install it ...
The output maybe a bit confusing but what we are searching for is easy to be found (highlighted in bold):

0300 80864239 1c        f2400004               0
               0               0               0        
       0               0            2000               0
              0               0               0
               0               0 iwlwifi

Currently (August 16) all Intel wireless network adaptor use the "iwlwifi" driver.

Using the command, you can get further (detailed) information of which driver you are currently using.
# modinfo iwlwifi

To figure out if everything is fine with your driver you can grep the name of the driver within the output of dmesg:
# dmesg | grep -i iwlwifi

[   13.061858] iwlwifi 0000:03:00.0: can't disable ASPM; OS doesn't have ASPM control
[   13.062028] iwlwifi 0000:03:00.0: irq 28 for MSI/MSI-X
[   13.730994] iwlwifi 0000:03:00.0: loaded firmware version 9.221.4.1 build 25532 op_mode iwldvm
[   14.650374] iwlwifi 0000:03:00.0: CONFIG_IWLWIFI_DEBUG disabled
[   14.650379] iwlwifi 0000:03:00.0: CONFIG_IWLWIFI_DEBUGFS enabled
[   14.650381] iwlwifi 0000:03:00.0: CONFIG_IWLWIFI_DEVICE_TRACING disabled
[   14.650383] iwlwifi 0000:03:00.0: Detected Intel(R) Centrino(R) Advanced-N 6200 AGN, REV=0x74
[   14.650481] iwlwifi 0000:03:00.0: L1 Enabled - LTR Disabled
[   20.003810] iwlwifi 0000:03:00.0: L1 Enabled - LTR Disabled
[   20.004071] iwlwifi 0000:03:00.0: Radio type=0x1-0x3-0x1
[   20.213744] iwlwifi 0000:03:00.0: L1 Enabled - LTR Disabled
[   20.213955] iwlwifi 0000:03:00.0: Radio type=0x1-0x3-0x1

At this point the kernel should have created a device associated to your wireless card. The device name should help you to identify it quickly. You can check which is your device by typing the following command:
# ip link

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s25: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether f0:de:f1:4c:49:45 brd ff:ff:ff:ff:ff:ff
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT qlen 1000
    link/ether 18:3d:a2:0b:3d:04 brd ff:ff:ff:ff:ff:ff
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT 
    link/ether 02:42:43:03:3e:55 brd ff:ff:ff:ff:ff:ff
5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT 
    link/ether 52:54:00:88:4e:4b brd ff:ff:ff:ff:ff:ff
6: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT qlen 500
    link/ether 52:54:00:88:4e:4b brd ff:ff:ff:ff:ff:ff

As you can see the name is wlp3s0 where:
wl : stand for wireless
p3: PCI bus 3
s0: slot 0

You should find something similar !

3 - Configuring your wireless interface


At this point we have collected all the information we need to proceed with the configuration of our wireless network. If you are working on a laptop is highly possible you are going to move and use several wireless network (several Access Point). In this scenario you need to create different profiles (one per each BSS).

Before creating a profile it is a good idea to try to setup your network manually so that we can understand which are the process involved.

I will take into consideration only encryption using WPA2 standard (the only strong protocol available at the moment).

At this point we need to run a scan to discover the available networks and the configuration parameters of each (SSID, frequency/channel, supported rate, signal strength).
You need to run the following command:
# iw dev wlp3s0 scan

[ the output has been cut to what needed for the purpose of this tutorial] 

BSS e4:f4:c6:a7:0a:58(on wlp3s0) -- associated
TSF: 3776302891890 usec (43d, 16:58:22)
freq: 5180
beacon interval: 100 TUs
capability: ESS Privacy SpectrumMgmt ShortSlotTime (0x0511)
signal: -41.00 dBm
last seen: 0 ms ago
Information elements from Probe Response frame:
SSID: MYSSID
Supported rates: 6.0* 9.0 12.0* 18.0 24.0* 36.0 48.0 54.0
DS Parameter set: channel 36
Country: GB Environment: Indoor/Outdoor
Channels [36 - 36] @ 22 dBm
Channels [40 - 40] @ 22 dBm
Channels [44 - 44] @ 22 dBm
Channels [48 - 48] @ 22 dBm
                .......
                .......
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: (0x0000)

You should find similar entries for each of the wireless network which are close to your location (they provide enough signal to be detected by your antenna). The more close to zero is the signal, the more strong it is. As you can see the above network is "associated" which means connected, you can get the SSID of your Access Point (MYSSID) and, if your AP provides WPA2, the section RSN (Robust Security Network) the Authentication suites you need to use PSK (which is used by WPA2).

After the discovery phase we need to set the running mode for our wireless network interface; to do this it is better to "bring down" the network interface before changing the mode:

# ip link set wlp3s0 down
# iw dev wlp3s0 set type managed
# ip link set wlp3s0 up

Now you can create the wireless link (we are still without an IP ... we are just setting a bare media connection L1/L2 of the OSI stack).

# wpa_supplicant -D nl80211,wext -i wlp3s0 -c <(wpa_passphrase "MY_SSID" "AP_passphrase_KEY")

If something go wrong you may have the wpa_supplicant process "hanging" and you need to remove the following file and correct the wpa_supplicant command (to find all the option use the man page !):

# rm /var/run/wpa_supplicant/wlp3s0

If the wpa_supplicant command succeed you should have an output like this:

Successfully initialized wpa_supplicant
wlp3s0: Trying to associate with e4:f4:c6:a7:0a:58 (SSID='MY_SSID' freq=5180 MHz)
ioctl[SIOCSIWFREQ]: Device or resource busy
wlp3s0: Association request to the driver failed
wlp3s0: Associated with e4:f4:c6:a7:0a:58
wlp3s0: WPA: Key negotiation completed with e4:f4:c6:a7:0a:58 [PTK=CCMP GTK=CCMP]
wlp3s0: CTRL-EVENT-CONNECTED - Connection to e4:f4:c6:a7:0a:58 completed [id=0 id_str=]

You can do CTRL-C to interrupt wpa_supplicant as the above was just a test to see if the command is correct !!! If you get a Connection to 00:00:00:00:00:00 completed then you are half the road to have a working connection.
Interrupt the process, and run it again with the option -B which set the process to run in background.

# wpa_supplicant -B -D nl80211,wext -i wlp3s0 -c <(wpa_passphrase "MY_SSID" "AP_passphrase_KEY")

Following the description of the options:
-B to run the wpa_supplicant command in background
-D specify to try the drivers nl80211 or wext as part of the kernel space drivers
-i specify the interface name
-c tell to wpa_supplicant to use the following configuration file (which for us was just an input redirection to provide SSID and passphrase).

You may check the connection link with the below command:
# iw dev wlan0 link

Now that the wireless link is up and running we need to set an IP: manually with the ip command:
# ip addr add 192.168.0.8/24 dev wlp3s0
 or through DHCP with the command:
# dhclient wlp3s0
configure the gateway:
# ip route add default via AP_IP
and configure the DNS (edit the file /etc/resolv.conf).

If everything is fine, then you should be able to ping 8.8.8.8 (Google DNS). Just to close the "manual setup" or "test phase", we need to be able to properly close the link (cleaning all the rubbish). The way you properly close depend upon who you configured the IP address.

If you chose to configure it through DHCP then the following are the command to close the connection:
# ip addr flush dev wlp3s0
# ip route flush dev wlp3s0
# ip link set dev wlp3s0 down

If you chose to configure the IP statically:
# ip addr flush dev wlp3s0
# ip route flush dev wlp3s0
# ip link set dev wlp3s0 down

4 - Making it persistent

Let's make things simple !! If all the above worked, then good we can write some scripts and configuration file to automate the process and to hide the passphrase.

Let's create (if not existing) the folder: /etc/wpa_supplicant
# mkdir /etc/wpa_supplicant

Then create the file wpa_supplicant_MYSSID.conf (replace MYSSID with your SSID ... just to remind which file is for which AP); use your preferred editor. The file should look like the below:

ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=wheel

network={
      ssid="MYSSID"
      key_mgmt=WPA-PSK
      psk="AP_passphrase_KEY"
}

Then you need to create a configuration file for the network interface under the following path:
/etc/sysconfig/network-scripts

The file name should be like:
ifcfg-wlp3s0

The content like the following (if you are going to use DHCP):

HWADDR=00:00:00:00:00:00
ESSID="MYSSID"
MODE=Managed
KEY_MGMT=WPA-PSK
TYPE=Wireless
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=no
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
NAME=MyHomeWirelessNetwork
ONBOOT=no
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
PEERDNS=yes
PEERROUTES=yes

The file ifcfg-wlp3s0 will be invoked by the ifup command when followed by the device name, such as:
# ifup wlp3s0

We are now ready to go and with only two commands we can enable the wireless connection and configure the network interface:

Enable wireless connection:
# wpa_supplicant -B -i wlp3s0 -c /etc/wpa_supplicant/wpa_supplicant_MYSSID.conf

Configure the network interface (IP, gateway...)
# ifup wlp3s0

5 - Troubleshooting and references

Apart from the command listed above, you can check event related to the wireless interface use:
# iw event -t

The 802.11 subsystems – for kernel developers: https://www.kernel.org/doc/htmldocs/80211/
The official Linux Wireless WiKi: https://wireless.wiki.kernel.org/
Wireless Network Configuration: https://wiki.archlinux.org/index.php/Wireless_network_configuration


No comments:

Post a Comment