Got a new Kindle and no WLAN support on your router?

What’s the motivation? You CAN transfer e-books to the Kindle via USB cable, BUT that leaves a lot to be desired. Browsing the Amazon Kindle store is a very nice feature that I wouldn’t want to miss anymore. There are quite a lot of FREE e-books, mostly older stuff with expired copyrights, that are worth reading. Quite often you can also download free samples of books – a good way to decide if you want to make a purchase or not. The whole process is very streamlined if WiFi is available.

Here’s one way to solve it if you have a linux machine with free USB ports. This is nothing new, but as I’ve just been through all of this, I might as well write it down here. I think the involved tools deserve another mentioning. As there are many (too many?) flavours of linux distributions out there, I won’t give en-detail instruction on every single step. I will only give pointers on what to do.

These are the prerequisites:

You do already have a router (dsl box…) with a running DHCP server on it which you can configure to your needs. Of course you can also run your own DHCP server, but why use 2. That only complicates things.

2ndly you’ll require a USB WLAN stick that supports ‘master’ mode or ‘AP’ mode (like the TP-Link TL-WN722N, Atheros AR9271 chipset, ath9k_htc driver, about 8€, up to 150Mb/s).

3rdly you need a machine with a recent version of some sort of linux that provides: recent version of ‘hostapd’ (does the heavy lifting), the usual network tools (ifconfig, iptables for optional firewall, …) AND last but not least ‘brctl’ (part of ‘bridge-utils’) for creating a bridged network setup!

Caveats:

Using a bridged-setup like this will conflict with using Networkmanager, so you can’t use it.

Steps:

1) Install ‘hostadp’ and ‘bridge-utils’

On debian-ish systems: “aptitude install hostapd bridge-utils”, on openSUSE: “zypper install hostapd bridge-utils”.

2) Configure the DHCP server to hand out an IP to your Kindle.

This will require the MAC address of your Kindle. You can find the latter in one of Kindle’s menus, probably device options or device info. In case of a DSL router, you just add the MAC and a free IP address that is within the range of valid ones and you’re done. If your main PC usually gets e.g. 192.168.1.5, you might use 192.168.1.6 for the Kindle.

3) Create a network bridge ‘br0′ and only add ‘eth0′ to it.

On openSUSE this can be done with YaST (Network Configuration–>Network card–>Add… device-type: bride). ‘br0′ will replace ‘eth0′ as the main network interface of your PC (including DHCP settings, routing, gateway …), you should be able to copy most of the settings over. Make sure to set the IP address of ‘eth0′ to ’0.0.0.0/32′. If that step was successful your system should have network access as before, but ‘br0′ will be used instead of ‘eth0′. The latter will still be there, but won’t have an IP address assigned to it. The wlan interface should be left alone completely.

Here are the updated config files:

/etc/sysconfig/network/ifcfg-eth0

BOOTPROTO='static'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR='0.0.0.0/32'
MTU=''
NAME='some name'
NETMASK=''
NETWORK=''
REMOTE_IPADDR=''
STARTMODE='auto'
USERCONTROL='no'
PREFIXLEN='24'

/etc/sysconfig/network/ifcfg-br0

BOOTPROTO='dhcp4'
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth0'
BRIDGE_STP='off'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR=''
MTU=''
NAME=''
NETMASK=''
NETWORK=''
REMOTE_IPADDR=''
STARTMODE='auto'
USERCONTROL='no'

Running ‘ifconfig’ as root should show something like this:

br0       Link encap:Ethernet  HWaddr AA:BB:CC:DD:EE:FF
          inet addr:192.168.1.3  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:20248 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18311 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:20977426 (20.0 Mb)  TX bytes:2236411 (2.1 Mb)

eth0      Link encap:Ethernet  HWaddr AA:BB:CC:DD:EE:FF
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:20248 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18352 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:21262204 (20.2 Mb)  TX bytes:2319341 (2.2 Mb)
          Interrupt:42 Base address:0x2000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:111 errors:0 dropped:0 overruns:0 frame:0
          TX packets:111 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:19387 (18.9 Kb)  TX bytes:19387 (18.9 Kb)

wlan0     Link encap:Ethernet  HWaddr AA:BB:CC:DD:EE:FF               
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

Running ‘brctl show br0′ should give:

bridge name      bridge id          STP enabled     interfaces
br0             -some number-       no              eth0

The wlan interface is not part of the bridge, as it is not up and running yet. The access-point daemon will take care of that on its own.

The routing table (run “route -n” as root) should look like this:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 br0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br0

This should be identical to what you had before, but with ‘br0′ instead of ‘eth0′ (assuming you had ‘eth0′ before). Again: network access should work as before!

I deliberately won’t talk much about firewall settings here. On openSUSE it works with ‘br0′ for my simple needs. Again you can use YaST to adapt the configuration. Or add ‘br0′ to /etc/sysconfig/SuSEfirewall2 manually. Carefully read the comments in that file. You will probably have to think more about this step if you have a more complicated setup, e.g. bridging enabled for XEN domains and so forth.

4) Configure and start ‘hostapd’

Open hostapd’s configuration files with a text-editor and modify them. Then restart hostapd (e.g. “/etc/init.d/hostapd restart”). These settings worked with my hardware.

/etc/hostapd.conf (main configuration file)

# wlan interface
interface=wlan0

# bridge interface: where to add/remove the wlan interface to/from
bridge=br0

# Name of the wireless network
ssid=TEST

# Hardware mode (a/b/g)
hw_mode=g
channel=1

# MAC-based access control
accept_mac_file=/etc/hostapd.accept
deny_mac_file=/etc/hostapd.deny
macaddr_acl=1

# Some authentication stuff
auth_algs=1

# WPA settings
wpa=2
wpa_passphrase=<your password>
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

# all this stuff was already enabled
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
dump_file=/var/run/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
beacon_int=100
dtim_period=2
max_num_sta=255
rts_threshold=2347
fragm_threshold=2346
ignore_broadcast_ssid=0
wmm_enabled=1
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0
eapol_key_index_workaround=0
eap_server=0
own_ip_addr=127.0.0.1

I’ve marked all lines that I had to change. The others were enabled already and may or may not be important.

/etc/hostapd.accept (list of acceptable MAC addresses)

# List of MAC addresses that are allowed to authenticate (IEEE 802.11)
# with the AP. Optional VLAN ID can be assigned for clients based on the
# MAC address if dynamic VLANs (hostapd.conf dynamic_vlan option) are used.

# Add your Kindle's MAC address
AA:BB:CC:DD:EE:FF

5) Enable the hostapd service automatically

If you need the wireless all the time, this is the best way to go. On openSUSE use YaST to change the runlevel settings. You can also use ‘chkconfig’ on the console (man chkconfig). The integration of ‘systemd’ may or may not be far enough to let you use ‘systemctl’ for that job. This will most likely change in the future.

6) Let a named user (e.g. ‘joe’) enable/disable the access point by hand

If you don’t need the wireless running all the time, you can make it a bit more user-friendly by adding start/stop scripts. Normally these would require root permissions, but thanks to ‘sudo’ this can be remedied.

I put these scripts into /usr/local/bin

wlan-stick_on.sh

#!/bin/bash

# kill any previous instances that might still hang around
sudo /usr/bin/killall -15 hostapd >/dev/null 2>&1

# let things settle a bit (network bridge seems to need some time)
sleep 2

# start hostapd 
sudo /usr/sbin/hostapd -B /etc/hostapd.conf

wlan-stick_off.sh

#!/bin/bash

# kill any instances of hostapd
sudo /usr/bin/killall -15 hostapd >/dev/null 2>&1

Now all is left is to configure sudo to let some user run these scripts with root permission without having to enter a password. This is done with ‘visudo’ as root (of course). You should NOT use a text-editor to edit the file ‘/etc/sudoers’. ‘visudo’ does some sanity checks and warns you if something is not quite right with the config file. You could seriously mess up your system otherwise. This is especially the case for linux distributions that don’t have the root-user enabled per default and use ‘sudo …’ for everything instead. Ubuntu comes to mind… make a backup of the config file(s)!

Run ‘visudo’ as root:

# sudoers file.
#
# This file MUST be edited with the 'visudo' command as root.
# Failure to use 'visudo' may result in syntax or file permission errors
# that prevent sudo from running.
#
# See the sudoers man page for the details on how to write a sudoers file.
#

# Host alias specification

# User alias specification
User_Alias HOSTAPD_OK = joe

# Cmnd alias specification
Cmnd_Alias WLANSTICK = /usr/sbin/hostapd -B /etc/hostapd.conf, /usr/bin/killall -15 hostapd

# Defaults specification

# Prevent environment variables from influencing programs in an
# unexpected or harmful way (CVE-2005-2959, CVE-2005-4158, CVE-2006-0151)
Defaults always_set_home
Defaults env_reset
Defaults lecture=always
Defaults insults

# Change env_reset to !env_reset in previous line to keep all environment variables
# Following list will no longer be necessary after this change

Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE"
# Comment out the preceding line and uncomment the following one if you need
# to use special input methods. This may allow users to compromise  the root
# account if they are allowed to run commands without authentication.
#Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER"

# In the default (unconfigured) configuration, sudo asks for the root password.
# This allows use of an ordinary user account for administration of a freshly
# installed system. When configuring sudo, delete the two
# following lines:
Defaults targetpw # ask for the password of the target user i.e. root
ALL	ALL=(ALL) ALL   # WARNING! Only use this together with 'Defaults targetpw'!

# Runas alias specification

# User privilege specification
root		ALL=(ALL) ALL
HOSTAPD_OK	ALL= NOPASSWD: WLANSTICK

# Uncomment to allow people in group wheel to run all commands
# %wheel	ALL=(ALL) ALL

# Same thing without a password
# %wheel	ALL=(ALL) NOPASSWD: ALL

# Samples
# %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users  localhost=/sbin/shutdown -h now

Now the user ‘joe’ can run these scripts and start/stop the wlan access point without having to enter the root password. I like it ;-)

After running ‘wlan-stick_on.sh’ in a console window your Kindle should be able to join the network.

This entry was posted in Electronics., Server., Software. and tagged , , , , , , , , . Bookmark the permalink.

2 Responses to Got a new Kindle and no WLAN support on your router?

  1. I think you meant to say the TL-WN722N USB dongle? Not the TL-TN722N.

Comments are closed.