Monday, 12 May 2014

Sharing one wifi adapter with many devices

Diagram of the network. The dotted lines are wifi connections, and the continuous line is an Ethernet cable



Why: The area where I live currently has free wifi internet for anyone to use, however the signal is very weak, and only one of my wifi devices (a TP-Link TL-WN722N USB wifi adapter) can receive the signal.
I want to be able to share the "free wifi" network with all of my devices.
This allows me to get rid of my terrible, overpriced, unreliable Telstra Bigpond ADSL.

How: I have the TP-Link TL-WN722N plugged into a Toshiba Tecra M5 laptop running Debian Stable. There are two network adapters connected to the laptop; the TP-Link TL-WN722N USB wifi adapter, which is labelled  "wlan2", and a built-in Ethernet port, labelled "eth0". The Ethernet port on the laptop is connected to the WAN port on my Belkin wireless router. The laptop is configured as a router which sends IP packets between the "wlan2" and "eth0" networks. This means that any device connected to the Belkin router (by a wired or wireless connection) will be able to access the internet through the "wlan2" adapter on the laptop.

The following instructions could serve as a basis for your own configuration.
The instructions should work on any Debian-based Linux distribution, but other distros may have things (such as the /etc/network/interfaces folder) configured differently.  Note that you should change "eth0" and "wlan2" to match your own network interface names. If you are confused about any of these steps, the list of useful links at the bottom of the page may help you.

The laptop is configured using the following steps:

1. Enable IP packet fowarding:
Open the file /etc/sysctl.conf in your preferred text editor, and add (or uncomment) the line net.ipv4.ip_forward = 1

2. Install dnsmasq:
You can do this by entering the following in a terminal: sudo apt-get install dnsmasq

3. Configure dnsmasq:
dnsmasq needs to be configured to serve IP addresses to a device conneced to the "eth0" network (in my case, the Belkin wireless router). To configure dnsmasq, add the following lines to /etc/dnsmasq.conf

interface=eth0
dhcp-range=192.168.1.100,192.168.1.200,24h



4. Configure the "eth0" interface with a permanent IP address
This is done by adding the following lines to the file 
/etc/network/interfaces

auto eth0
iface eth0 inet static
      address 192.168.1.1
      network 192.168.1.0
      netmask 255.255.255.0
      broadcast 192.168.1.255


5. Reboot the laptop

6. Create an IP packet routing script:
The following script will tell iptables to do the packet routing between the "wlan2" and "eth0" networks. To create the script, create the file /etc/network/router_firewall and add the following:

#!/bin/bash
#
# script for source Network Address Translation using iptables
#

iptables -F
iptables -t nat -F
iptables -X

iptables -N val_input
iptables -N val_output

# allow packets with NEW, ESTABLISHED and RELATED states
iptables -A val_input -m state --state NEW,ESTABLISHED,RELATED -i lo -j RETURN
iptables -A val_output -m state --state NEW,ESTABLISHED,RELATED -o lo -j RETURN

iptables -A val_input -m state --state NEW,ESTABLISHED,RELATED -i eth0 -j RETURN
iptables -A val_output -m state --state NEW,ESTABLISHED,RELATED -o eth0 -j RETURN

iptables -A val_input -m state --state NEW,ESTABLISHED,RELATED -i wlan2 -j RETURN
iptables -A val_output -m state --state NEW,ESTABLISHED,RELATED -o wlan2 -j RETURN

iptables -A val_input -j DROP
iptables -A val_output -j DROP

iptables -A INPUT -p tcp -j val_input
iptables -A OUTPUT -p tcp -j val_output

iptables -t nat -A POSTROUTING -o wlan2 -j MASQUERADE
# End of script



The script needs to be given executable permissions by entering the following into a terminal:  sudo chmod +x /etc/network/router_firewall

The script must be executed for the routing to work. This can be done manually by entering the following in a terminal: sudo /etc/network/router_firewall

7. Setting up DNS nameservers:
I changed the DNS nameserver settings on the Belkin router to "8.8.8.8" and "8.8.4.4", which are google's nameservers. 

Useful external links:
http://www.softprayog.in/troubleshooting/connecting-two-computers-with-ethernet-lan-cable 

http://www.cyberciti.biz/faq/linux-list-network-interfaces-names-command/ 

http://man7.org/linux/man-pages/man8/ifconfig.8.html 

http://manpages.debian.org/cgi-bin/man.cgi?query=iptables 

http://www.softprayog.in/tutorials/iptables 

http://www.unix.com/man-page/linux/5/interfaces/ 

http://en.wikipedia.org/wiki/IP_address 

http://en.wikipedia.org/wiki/IP_packet 

http://en.wikipedia.org/wiki/Dns 

http://www.cyberciti.biz/tips/linux-how-to-run-a-command-when-boots-up.html