Few weeks ago I stumbled upon the challenge of creating a wifi access-point on my ubuntu 12.04 linux machine. Whilst I knew about ubuntu’s built-in wifi hotspot feature that works in adhoc mode, it was pretty much useless to connect to my new Android smartphone since it did not support the ad-hoc wifi mode. Most phones these days only support the infrastructure mode (a.k.a access-point mode), and in fact, they won’t even detect devices running on ad-hoc mode. After doing some research, I gathered this simple (though a bit lengthy) set of steps to turn your linux machine into a wifi access-point:
Pre-requsites:
- Ability of your wireless card to support infrastructure mode. To find out:
(i) Find your kernel driver module in use by issuing the below command:
lspci -k | grep -A 3 -i “network”
(In my case, the driver in use was ath9k)
(ii) Now, use the below command to find out your wifi capabilities (replace ath9k by your kernel driver):
modinfo ath9k | grep ‘depend’
(iii) If the above output includes “mac80211” then it means your wifi card will support the AP mode. - Hostapd software: Hostapd is the standard linux daemon that will be used to create your access-point.
- Dhcp software: Even after hostapd creates the AP and your device detects it, you will still need a dhcp server to assign a dynamic ip-address to your AP client. (unless you are assigning static address to each device)
- Iptables: In order to share internet on your AP clients through wifi (a.k.a reverse-tethering), you will have to setup a NAT (Network Address Translation), so that your linux machine, acting as a middleman transfers the internet packets to and from your AP client and the internet modem card (typically ppp0).
EDIT: As of 06-Jul-2013, I’ve developed a python program with GTK+ front end called ‘pyforward’ which automates the below procedure for you. You can find it here:https://sourceforge.net/projects/pyforward/
Procedure:
- Install the hostapd package. On ubuntu:
sudo apt-get install hostapd - Install Dhcp server. On ubuntu:
sudo apt-get install dhcp3-server - Make sure that packet forwarding is turned on. This means that your computer is able to forward request of connected clients to other devices, which in my case happened to be from wlan0 to ppp0. (forwarding is different than sending and receiving packets). To enable packet forwarding, issue the following linux command:
sysctl -w net.ipv4.ip_forward=1
To make the change permanent, make sure that the below line is uncommented in your /etc/sysctl.conf file. If not, change it and restart your machine:
net.ipv4.ip_forward=1 - The next step is to set up your dhcp. First, decide the subnet and ip-address range in which your virtual AP will sit and your clients will be automatically assigned using dhcp. In my case, I used the subnet 192.168.5.0. My virtual AP is assigned 192.168.5.1 and each connecting wifi device gets an IP in range of 192.168.5.3-45. In order to set the rule, add this block to your /etc/dhcp/dhcpd.conf:
subnet
192.168.5.0 netmask 255.255.255.0 {
interface “wlan0″;
# — default gateway
option routers
192.168.5.1;
# — Netmask
option subnet-mask
255.255.255.0;
# — Broadcast Address
option broadcast-address
192.168.5.255;
# — Domain name servers, tells the clients which DNS servers to use.
#option domain-name-servers
#10.0.0.1, 8.8.8.8, 8.8.4.4;
option time-offset
0;
#range 10.0.0.3 10.0.0.13;
range 192.168.5.3 192.168.5.45;
default-lease-time 1209600;
max-lease-time 1814400;
} - Now that packet forwarding and dhcp are set up, we have to create a NAT (Network Address Translation) table using iptables. Please note that if you are using any other controlling software on top of iptables such as ufw firewall or firestarter, then you have to manage the NAT yourself. In that case, there is no need to follow this step:
Create a file called iptables_start in your home folder using gedit or nano and add the below contents to it:
#!/bin/bash
#First, delete all existing rules
iptables –flush
iptables –delete-chain
iptables –table nat –delete-chain
iptables –table nat -F
iptables –table nat -X#Allow incoming – already established connections:
iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT#Allow outgoing on tcp80, tcp443, udp53
iptables -A OUTPUT -p tcp –dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp –dport 443 -j ACCEPT
iptables -A OUTPUT -p udp –dport 53 -j ACCEPT#NAT Forwarding for wifi access point
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
iptables -A FORWARD -i ppp0 -o wlan0 -j ACCEPT -m state –state RELATED,ESTABLISHED
iptables -A FORWARD -i wlan0 -o ppp0 -j ACCEPT#Block all incoming & outgoing traffic after that
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
Please note that some of the above rules are customized according to my particular requirement. For eg: I’m allowing outgoing traffic on only tcp80, tcp443 & udp53 ports. Your requirements may be different. Only the NAT forwarding part is what you should be concerned about. Also note that here ppp0 refers to the interface that connects to the internet using modem, and wlan0 is your wifi AP interface that connects to client devices that need internet access.
Your particular interfaces might have different names. You may query all interfaces by using ifconfig command to be sure of them.
Once you create the above file, make it executable using a command like:
sudo chmod +x /home/user_xyz/iptables_start
Now run it by issuing “sudo ./iptables_start” in your home folder. Each time you have to make any changes to your firewall, you may edit and run this file. To test your new iptables rules, issue the command “sudo iptables –list”. It will list your newly added rules.
Once you run this however, the iptables rules are set, but they are not stored permanently. To start these rules each time your computer starts, do the following:
- Save existing rules to a file using “sudo iptables-save > /home/user_xyz/iptables.rules”.
- Copy the iptables.rules file to your /etc folder.
- Now, in order for your computer to load rules from iptables.rules when your network interfaces turn up, create a file called /etc/network/if-pre-up.d/iptablesload and add below script to it:
#!/bin/sh
iptables-restore < /etc/iptables.rules
exit 0 - Make the above file executable by running “sudo chmod +x /etc/network/if-pre-up.d/iptablesload”
- Test these settings by restarting your computer and issuing “sudo iptables –list”. This will list your current firewall rules.
- Now that all hard work is done, you are ready to start your virtual AP. First, create a configuration file for the hostapd called hostapd.conf. It can be located in either /etc or your home folder:
#sets the wifi interface to use, is wlan0 in most cases
interface=wlan0
#driver to use, nl80211 works in most cases
driver=nl80211
#sets the ssid of the virtual wifi access point
ssid=YourAPName
#sets the mode of wifi, depends upon the devices you will be using. It can be a,b,g,n. Setting to g ensures backward compatiblity.
hw_mode=g
#sets the channel for your wifi
channel=6
#macaddr_acl sets options for mac address filtering. 0 means “accept unless in deny list”
macaddr_acl=0
#setting ignore_broadcast_ssid to 1 will disable the broadcasting of ssid
ignore_broadcast_ssid=0
#Sets authentication algorithm
#1 – only open system authentication
#2 – both open system authentication and shared key authentication
auth_algs=1
#####Sets WPA and WPA2 authentication#####
#wpa option sets which wpa implementation to use
#1 – wpa only
#2 – wpa2 only
#3 – both
wpa=3
#sets wpa passphrase required by the clients to authenticate themselves on the network
wpa_passphrase=your_passphrase
#sets wpa key management
wpa_key_mgmt=WPA-PSK
#sets encryption used by WPA
wpa_pairwise=TKIP
#sets encryption used by WPA2
rsn_pairwise=CCMP
#################################
#####Sets WEP authentication#####
#WEP is not recommended as it can be easily broken into
#wep_default_key=0
#wep_key0=qwert #5,13, or 16 characters
#optionally you may also define wep_key2, wep_key3, and wep_key4
#################################
#For No encryption, you don’t need to set any optionsIn above script, replace YourAPName with ssid of your AP. This will be detected when you run a scan on your device. Similarly, replace your_passphrase with the actual password you wish to set up. - The last and final step is to create an AP script and run it. Create a file called AccessPoint in your home folder:#!/bin/bash
ifconfig wlan0 up 192.168.5.1 netmask 255.255.255.0
sleep 5
###########Start DHCP, comment out / add relevant section##########
#Doesn’t try to run dhcpd when already running
if [ “$(ps -e | grep dhcpd)” == “” ]; then
dhcpd wlan0 &
fi
###########
#start hostapd
sleep 2
hostapd ~/hostapd.conf 1>/dev/null
killall dhcpd - Make above file by issuing “sudo chmod +x ~/AccessPoint”. Now execute this script in the terminal by “./AccessPoint” and keep it running. If all goes well, your devices should now be able to scan and connect to your new virtual AP.
References:
If for some reasons, all doesn’t go well, then here are some links that can help you:
Hostapd:
http://nims11.wordpress.com/2012/04/27/hostapd-the-linux-way-to-create-virtual-wifi-access-point/
http://ubuntuforums.org/showthread.php?t=151781
Iptables basics:
https://help.ubuntu.com/community/IptablesHowTo
NAT and port forwarding:
http://www.howtoforge.com/nat-gateway-iptables-port-forwarding-dns-and-dhcp-setup-ubuntu-8.10-server