metalgamer - A blog about music, computer science, politics and philosophy

This tutorial will show how to setup an Archlinux machine for wardriving.

1: Naming your wireless antennas interfaces

Since systemd v197, there is a new naming scheme to network interface names, which doesn’t help us. Also the tra­di­tion­al naming scheme wasn’t better for our case, as it depended on the kernel driver probes. The naming of the interfaces depends (for both schemes) on the order, on which the external antennas are plugged-in or in which USB port they are inserted in.

So to prevent this, we need to give the antennas always the same name, based on their mac addresses. This is especially needed, if you use multiple antennas for wardriving.

1.1: Get the mac addresses of the external wifi antennas

First of all, let’s see what devices we have, without having the external antenna plugged-in. Run the following command in a shell:

ip link

You should see an output similar to this.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wifi0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
    link/ether a4:4e:31:19:8c:f0 brd ff:ff:ff:ff:ff:ff
3: net0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3c:97:0e:b8:6e:af brd ff:ff:ff:ff:ff:ff

Now plug in our external wifi antenna and re-run the command. You should see a new added interface.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wifi0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000
    link/ether a4:4e:31:19:8c:f0 brd ff:ff:ff:ff:ff:ff
3: net0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3c:97:0e:b8:6e:af brd ff:ff:ff:ff:ff:ff
4: wlp0s26u1u2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:c0:ca:87:59:66 brd ff:ff:ff:ff:ff:ff

The macaddress can be found after the link/ether part of the message and has the form of xx:xx:xx:xx:xx:xx. In my case the macaddress is 00:c0:ca:87:59:66. Record this macaddress as we need it in the next step.

1.2: Creating udev rule

To set a consistent name for your external wifi-antenna, we need to create an udev rule. Open the file /etc/udev/rules.d/10-network.rules in a favourite editor and add the following line, be sure to replace YOUR_­MACAD­DRESS with the macaddress of our antenna and YOUR_PREF­FERED_­NAME with a suitable name, I suggest extwifi0:

SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="YOUR_MACADDRESS", NAME="YOUR_PREFFERED_NAME"

In my case, the line would look like:

SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:c0:ca:87:59:66", NAME="extwifi1"

2: Installing & con­fig­ur­ing Kismet

2.1: Installing Kismet

Kismet is a wireless network detector, sniffer, and intrusion detection system. Kismet works pre­dom­i­nate­ly with Wi-Fi (IEEE 802.11) networks, but can be expanded via plug-ins to handle other network types.

Installing Kismet is very simple. Kismet is in the official repos­i­to­ries.

You can use this command to install kismet:

pacman -S kismet

2.2: Adding your username to the kismet group

After we installed Kismet, we need to add our username to the kismet group. Here is the excerpt from the Kismet install file, lining out why this is needed:

Kismet has been installed with a SUID ROOT CAPTURE HELPER ex­e­cute­able by users in the group ‘ kismet ‘. This WILL ALLOW USERS IN THIS GROUP TO ALTER YOUR NETWORK INTERFACE STATES, but is more secure than running all of Kismet as root. ONLY users in this group will be able to run Kismet and capture from physical network devices.

To add your username to the kismet group, execute the following command, replacing YOUR_USER­NAME with your username.

gpasswd -a YOUR_USERNAME kismet

In my case, the command would look like:

gpasswd -a metalgamer kismet

2.3: Adding sources to kismet config

Open the file /etc/kismet.conf in your favorite editor and scroll down until you see the lines starting with ncsource.

Now, for every wifi antenna, add the following line, with replacing INTERFACE with the name, you choose for that antenna in step 1.2:

ncsource=INTERFACE

In my case, the lines would look like:

ncsource=extwifi0
ncsource=extwifi1

Optional: Adding names to sources

There is the pos­si­bil­i­ty to add different options to the ncsources. One is the name option. This is useful, to give your interface an extra name, for example the product name of the antenna.

Simple add the following, behind the interface:

:name=YOUR_PREFERRED_NAME

In my case, it would look like this:

ncsource=extwifi0:name=ALFA_AWUS036H_2.4Ghz
ncsource=extwifi1:name=ALFA_AWUS051NG_Dual_Band

2.4: Setting privacy options

As we aren’t interested in data frames, it is advised to enable the hidedata setting in the kismet config file.

Open the kismet config file with your favorite editor and find the line with:

# hidedata=true

Remove the # in the beginning of the line. After that, the line should look like the following:

hidedata=true

2.5: Setting log files

By default, kismet creates a lot of log files. Not all off them are needed in our case. Here is a list of all posible logtypes, taken from the comment in the config file.

alert     Text file of alerts
gpsxml    XML per-packet GPS log
nettxt    Networks in text format
netxml    Networks in XML format
pcapdump  tcpdump/wireshark compatible pcap log file
string    All strings seen (increases CPU load)

For our case, we only need netxml.

Open the kismet config file with you favorite editor and fine the following line:

logtypes=pcapdump,gpsxml,netxml,nettxt,alert

And change it to the following:

logtypes=netxml

Optional 2.6: Creating channel list for 802.11a in Europe

If you are in Europe, there are some channels, specified in IEEE 802.11 standard, which are restricted in Europe. So that kismet, will not hop to those restricted channels, we need to modify the channel list.

Search for the following line in /etc/kismet.conf:

channellist=IEEE80211a:36,40,44,48,52,56,60,64,149,153,157,161,165

And replace it with the following:

channellist=IEEE80211a:36,40,44,48,52,56,60,64

You need also to modify the following line:

channellist=IEEE80211ab:1:3,6:3,11:3,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64,149,153,157,161,165

To the following:

channellist=IEEE80211ab:1:3,6:3,11:3,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64

Optional 2.7: Setting dual-band antenna to capture 802.11a (5Ghz band) only

If you have an dual-band antenna and want to only capture the 5Ghz band, you need to set the chan­nel­list option in the ncsource.

Add the following to the ncsource option:

:channellist=IEEE80211a

In my case, it would look like this:

ncsource=extwifi1:name=ALFA_AWUS051NG_Dual_Band:channellist=IEEE80211a

Optional 2.8: Kismet Server service

Kismet uses a classical client-server model. Normally, the client asks if it should start the server, if it is not running yet. To prevent this, we can use systemd for the service management.

Creating service file

Open the file /etc/systemd/system/kismet@.service with your favorite editor and add the following:

[Unit]
Description=Kismet Server
After=network.target

[Service]
Type=simple
User=%I
ExecStart=/usr/bin/kismet_server

[Install]
Alias=multi-user.target

Enabling the service

Now run the following commands:

systemctl daemon-reload
systemctl start kismet@YOUR_USERNAME.service

Optional 3: Installing & con­fig­ur­ing gpsd

Optional 3.1: Con­fig­ur­ing gps receiver

In this step, we give our gps receiver a consistent name under the /dev tree.

Getting needed in­for­ma­tion from udev

First we need to get the subsystems our gps receiver uses in the kernel. Attach your gps receiver to your machine and run dmesg to see what name your gps receiver gets from the kernel.

I use an Navilock NL-8002U and my dmesg looks something like this:

usb 1-1: new full-speed USB device number 8 using xhci_hcd
cdc_acm 1-1:1.0: ttyACM0: USB ACM device

Here you see that the Linux kernel gives ttyACM0 as name for the gps receiver.

Now, we get the subsystems it uses by running the following command:

udevadm info -a -p $(udevadm info -q path -n /dev/NAME)

In my case the command looks like this:

udevadm info -a -p $(udevadm info -q path -n /dev/ttyACM0)

The output looks something like this:

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/tty/ttyACM0':
   KERNEL=="ttyACM0"
   SUBSYSTEM=="tty"
   DRIVER==""

looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0':
   KERNELS=="1-1:1.0"
   SUBSYSTEMS=="usb"
   DRIVERS=="cdc_acm"
   ATTRS{bInterfaceClass}=="02"
   ATTRS{bmCapabilities}=="2"
   ATTRS{bInterfaceSubClass}=="02"
   ATTRS{bInterfaceProtocol}=="01"
   ATTRS{bNumEndpoints}=="01"
   ATTRS{supports_autosuspend}=="1"
   ATTRS{bAlternateSetting}==" 0"
   ATTRS{bInterfaceNumber}=="00"

looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-1':
   KERNELS=="1-1"
   SUBSYSTEMS=="usb"
   DRIVERS=="usb"
   ATTRS{bDeviceSubClass}=="00"
   ATTRS{bDeviceProtocol}=="00"
   ATTRS{devpath}=="1"
   ATTRS{idVendor}=="1546"
   ATTRS{speed}=="12"
   ATTRS{bNumInterfaces}==" 2"
   ATTRS{bConfigurationValue}=="1"
   ATTRS{bMaxPacketSize0}=="64"
   ATTRS{busnum}=="1"
   ATTRS{devnum}=="8"
   ATTRS{configuration}==""
   ATTRS{bMaxPower}=="100mA"
   ATTRS{authorized}=="1"
   ATTRS{bmAttributes}=="c0"
   ATTRS{bNumConfigurations}=="1"
   ATTRS{maxchild}=="0"
   ATTRS{bcdDevice}=="0201"
   ATTRS{avoid_reset_quirk}=="0"
   ATTRS{quirks}=="0x0"
   ATTRS{version}==" 1.10"
   ATTRS{urbnum}=="9"
   ATTRS{ltm_capable}=="no"
   ATTRS{manufacturer}=="u-blox AG - www.u-blox.com"
   ATTRS{removable}=="unknown"
   ATTRS{idProduct}=="01a8"
   ATTRS{bDeviceClass}=="02"
   ATTRS{product}=="u-blox GNSS receiver"

looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
   KERNELS=="usb1"
   SUBSYSTEMS=="usb"
   DRIVERS=="usb"
   ATTRS{bDeviceSubClass}=="00"
   ATTRS{bDeviceProtocol}=="01"
   ATTRS{devpath}=="0"
   ATTRS{idVendor}=="1d6b"
   ATTRS{speed}=="480"
   ATTRS{bNumInterfaces}==" 1"
   ATTRS{bConfigurationValue}=="1"
   ATTRS{bMaxPacketSize0}=="64"
   ATTRS{authorized_default}=="1"
   ATTRS{busnum}=="1"
   ATTRS{devnum}=="1"
   ATTRS{configuration}==""
   ATTRS{bMaxPower}=="0mA"
   ATTRS{authorized}=="1"
   ATTRS{bmAttributes}=="e0"
   ATTRS{bNumConfigurations}=="1"
   ATTRS{maxchild}=="4"
   ATTRS{bcdDevice}=="0319"
   ATTRS{avoid_reset_quirk}=="0"
   ATTRS{quirks}=="0x0"
   ATTRS{serial}=="0000:00:14.0"
   ATTRS{version}==" 2.00"
   ATTRS{urbnum}=="167"
   ATTRS{ltm_capable}=="no"
   ATTRS{manufacturer}=="Linux 3.19.3-1-ARCH xhci-hcd"
   ATTRS{removable}=="unknown"
   ATTRS{idProduct}=="0002"
   ATTRS{bDeviceClass}=="09"
   ATTRS{product}=="xHCI Host Controller"

 looking at parent device '/devices/pci0000:00/0000:00:14.0':
   KERNELS=="0000:00:14.0"
   SUBSYSTEMS=="pci"
   DRIVERS=="xhci_hcd"
   ATTRS{irq}=="27"
   ATTRS{subsystem_vendor}=="0x17aa"
   ATTRS{broken_parity_status}=="0"
   ATTRS{class}=="0x0c0330"
   ATTRS{driver_override}=="(null)"
   ATTRS{consistent_dma_mask_bits}=="64"
   ATTRS{dma_mask_bits}=="64"
   ATTRS{local_cpus}=="00000000,00000000,00000000,0000000f"
   ATTRS{device}=="0x1e31"
   ATTRS{enable}=="1"
   ATTRS{msi_bus}=="1"
   ATTRS{local_cpulist}=="0-3"
   ATTRS{vendor}=="0x8086"
   ATTRS{subsystem_device}=="0x21fa"
   ATTRS{numa_node}=="-1"
   ATTRS{d3cold_allowed}=="1"

 looking at parent device '/devices/pci0000:00':
   KERNELS=="pci0000:00"
   SUBSYSTEMS==""
   DRIVERS==""

We see that the gps receiver uses the tty subsystem and the USB subsystems. We need to record also the idVendor and the idProduct. They are found in the output.

looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-1':
  SUBSYSTEMS=="usb"
  ...
  ATTRS{idVendor}=="1546"
  ...
  ATTRS{idProduct}=="01a8"

Creating udev rule

Open the file /etc/udev/rules.d/20-gps.rules in a favourite editor and add the following line, be sure to replace YOUR_ID_VEN­DOR with the idVendor, idProduct with the idProduct and YOUR_PREF­ERED_­NAME with a suitable name, I suggest gps:

SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="YOUR_ID_VENDOR", ATTRS{idProduct}==YOUR_ID_PRODUCT", SYMLINK+="YOUR_PREFERED_NAME"

In my case it looks like:

SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a8", SYMLINK+="gps"

3.1: Installing gpsd

Installing gpsd is as simple as this:

pacman -S gpsd

3.2: Setting up gpsd service

Now open the file /etc/gpsd in your favourite editor and add the path to your device in the DEVICES options.

In my case it would look like this:

DEVICES="/dev/gps"

We can now enable gpsd socket and start the daemon by running:

systemctl enable gpsd.socket
systemctl start gpsd.service