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!
Using a bridged-setup like this will conflict with using Networkmanager, so you can’t use it.
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:
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'
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
#!/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
#!/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.