How to turn your Linux machine into a wifi Access Point

Wifi Access Point

Update on 08-jul-2014: To easily create a wifi AP on ubuntu and other distros, use the hotspotd daemon – Opensource, available on github.

To install:

wget https://github.com/prahladyeri/hotspotd/raw/master/dist/hotspotd-0.1.4.tar.gz
tar xvf hotspotd-0.1.tar.gz
cd hotspotd-0.1/
sudo python setup.py install

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:

1. 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.

2. Hostapd software: Hostapd is the standard linux daemon that will be used to create your access-point.

3. 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)

4. 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:

1. Install the hostapd package. On ubuntu:
sudo apt-get install hostapd

2. Install Dhcp server. On ubuntu:
sudo apt-get install dhcp3-server

3. 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

4. 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;
}

5. 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:

1. Save existing rules to a file using “sudo iptables-save > /home/user_xyz/iptables.rules”.
2. Copy the iptables.rules file to your /etc folder.
3. 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

4. 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.

6. 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 options

In 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.

7. 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

8. 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://ubuntulinux.co.in/blog/ubuntu/nat-configuration-with-iptables-in-ubuntu/
http://www.howtoforge.com/nat-gateway-iptables-port-forwarding-dns-and-dhcp-setup-ubuntu-8.10-server

(If you have some specific issue, you can always get back to me).

Advertisements

Published by

Prahlad Yeri

I am a Freelance Web Developer and Blogger. I like sharing my knowledge and contribute to open source.

49 thoughts on “How to turn your Linux machine into a wifi Access Point”

  1. finally i found someone who knows how to provide relevant information on the subject i have been searching for? thanks, at last i can study with pleasure..

  2. m trying to get it working on ubuntu 12.04 …. i debuged almost all error but this line is causing trouble ( iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT )
    any suggestions ???

    1. @sangeet – What error is coming on this line? This line just tells your linux system to accept already established incoming connections.
      Try running this command from your command line in this way:

      sudo iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT

      and tell me what happens

  3. when type ” sudo iptables –list” in terminal :
    it sayes :
    Bad argument `–list’
    Try `iptables -h’ or ‘iptables –help’ for more information.

      1. @mashnirovic – Thanks for letting me know about the typos!

        It should be “sudo iptables-save > /home/ahmad/iptables.rules”

        I was missing the greater than sign, I’ve now corrected the same.

    1. can you help me again pleas , when i type

      sudo iptables-save /home/ahmad/iptables.rules
      it says :
      Unknown arguments found on commandline
      what’s the problem!

    1. also this errors are coming–

      wlan0: ERROR while getting interface flags: No such device
      SIOCSIFADDR: No such device
      wlan0: ERROR while getting interface flags: No such device
      SIOCSIFNETMASK: No such device

      what to do???

      1. @Gaurav – first of all make sure that wifi is enabled on your device. What happens when you issue the below command in linux terminal:

        modinfo ath9k | grep ‘depend’
        (replace ath9k by your kernel driver)

        If mac80211 could not be found in the output, then your wifi adapter may not support infrastructure mode. Just to be sure, you can try out two things:

        1. Try a different linux distro other than the one you are currently using (By burning Live CD/USB of the image. I hope you are aware of the process).
        2. Secondly, if you have a Windows-7 dual-boot system, you can use the below DOS commands and see if you can start infrastructure mode in windows-7:
        netsh wlan set hostednetwork mode=allow ssid=gauravwan key=12345678
        (where ssid = your Wi-Fi hotspot name, and key = your password key)

        netsh wlan start hostednetwork

        If you can start wifi routing in infrastructure mode in either windows-7 or another distro, then it means there could be a linux/distro-specific driver issue.

      2. @prahlad- oh yes, i use a software called ‘virtual wifi router’ in my windows7 platform and it’s working flawlessly , but when i come 2 linux its disappointing me…..i don’t know how to fix this mac80211 issue, by the way i shall look forward for another distro…… can you suggest me a distro which is also helpful for linux kernel and embedded designer, better than ubuntu?

  4. Hi Prahlad,

    Thanks for this wonderful post. Can you please tell me where I can find logs related to the wifi card on a Linux machine?

    Cheers,

    Kalyan

  5. I just purchased a Mintbox 2 (nice computer by the way) and I’m going to give this a shot. Thanks for taking the time to post and develop the python program. You obviously know networking. If anyone else has tried this on a Mintbox, please post.

  6. up interface: wlan0: on IP: 192.168.5.1
    SIOCSIFFLAGS: Cannot assign requested address
    ….
    nl80211: Failed to set interface wlan0 into AP mode
    nl80211 driver initialization failed.
    router is running.

    I am frustrated but any effort to fix this failed here. Maybe you will at a glance.
    I can only add that I tried manual steps you suggested, but on fedora 20 the step about dhcpd didn’t work. Something left from those steps that is interfering??

    1. @heyricardo
      >>nl80211: Failed to set interface wlan0 into AP mode
      Looks like your wifi adapter doesn’t support infrastructure mode. Does the output of below command include mac80211 ?

      modinfo ath9k | grep ‘depend’

      (Replace ath9k with your kernel driver. Read the pre-requisites section in the article for more info)

      You can also try with the new GUI based script I’ve written:
      http://sourceforge.net/p/pyforward

      Instead of dhcpd, this uses dnsmasq which is light-weight and installed by default on most Linux distros. Also, I’ve tested the script successfully on Fedora-20-Xfce.

  7. Hi, sorry for late, i haven’t received follow up email..
    well, yes definitely I am using b43 driver which reports mac80211.
    I have used your script after manual setup procedure, as i said, and I got that error.
    It is a setup problem on my machine, I am aware of that and trying to work it out…

  8. Awesome job. Followed it step by step and had it working.
    Note: Please re-format the iptables script. The double hyphens have concatenated and as such upon pasting in text file and running, it gives an error.

  9. hi i’m trying to use pyforward and its says router is running but it is not
    any ideas? thanks!

    found interface:eth0
    found interface:lo
    found interface:ppp0
    found interface:wlan0
    hostapd found.
    hostapd is not running.
    dnsmasq found.
    dnsmasq is running.
    python web server is not running.
    up interface: wlan0 on IP: 192.168.5.1

    sleeping for 2 seconds.
    stopping dnsmasq
    enabling forward in sysctl.
    enabling forward rules in iptables.
    running dnsmasq

    created: /home/adarsh/pyforward/hostapd.conf
    running hostapd
    sleeping for 2 seconds.
    Configuration file: /home/adarsh/pyforward/hostapd.conf
    nl80211: Failed to set interface wlan0 into AP mode
    nl80211 driver initialization failed.
    ELOOP: remaining socket: sock=4 eloop_data=0x820c908 user_data=0x820cea8 handler=0x807c5e0
    ELOOP: remaining socket: sock=6 eloop_data=0x820ecb0 user_data=(nil) handler=0x8086770
    router is running.

      1. Hey Adarsh,

        This message is surprising:
        nl80211: Failed to set interface wlan0 into AP mode
        nl80211 driver initialization failed.

        Are you sure that wifi drivers on your distro are properly installed or you are able to access wifi generally (other than routing) ?
        If yes, then it might be failing due to conflicts with built-in Networkmanager. Try disabling wifi from the Networkmanager applet, and retry this. If it still doesn’t work, use rfkill:

        rfkill list all

        Issue above command to see if there are any blocks on your wifi interface. If yes, then issue this command to unblock them:

        rfkill unblock all

  10. sudo ./AccessPoint
    Internet Systems Consortium DHCP Server 4.2.4
    Copyright 2004-2012 Internet Systems Consortium.
    All rights reserved.
    For info, please visit https://www.isc.org/software/dhcp/
    Wrote 0 leases to leases file.
    Listening on LPF/wlan0/74:2f:68:79:a2:30/192.168.5.0/24
    Sending on LPF/wlan0/74:2f:68:79:a2:30/192.168.5.0/24
    Sending on Socket/fallback/fallback-net

    And it returns the prompt here. The program does not continue running for some reason, I’m unable to figure out why :/

    Any help is appreciated.

  11. root@HostisleDiscoporationHost42:~# sudo ./AccessPoint
    Internet Systems Consortium DHCP Server 4.2.2
    Copyright 2004-2011 Internet Systems Consortium.
    All rights reserved.
    For info, please visit https://www.isc.org/software/dhcp/
    /etc/dhcp/dhcpd.conf line 110: semicolon expected.
    interface
    ^
    /etc/dhcp/dhcpd.conf line 115: semicolon expected.
    option subnet-mask
    ^
    /etc/dhcp/dhcpd.conf line 125: range declaration not allowed here.
    range
    ^
    /etc/dhcp/dhcpd.conf line 127: expecting a declaration
    max-lease-time 1814400;
    ^
    Configuration file errors encountered — exiting
    dhcpd: no process found

  12. And I have checked The dhcpd conf ..All is fine ..I am using Kali Linux ..Don’t know what Is going wrong

      1. i followed the instructions and finally ‘hotspot has started’ message appeared on my terminal. However my other devices cannot find this network. Did I make mistake in its configuration or is there anything else ?

  13. hi @Prahlad Yeri i try using the pyforwarder software but it is no working… i check my wifi driver (RT2880) on wireless kernel and it is avalable but still i am having issues… Then i tried installing the hotspotd application too, also i had issues with that one too.

    ➜ hotspotd-0.1.1 git:(master) ✗>sudo hotspotd start
    Traceback (most recent call last):
    File “/usr/local/bin/hotspotd”, line 9, in
    hotspotd.main(sys.argv[1:])
    AttributeError: ‘module’ object has no attribute ‘main’

    ➜ hotspotd-0.1.1 git:(master) ✗>hotspotd
    Traceback (most recent call last):
    File “/usr/local/bin/hotspotd”, line 9, in
    hotspotd.main(sys.argv[1:])
    AttributeError: ‘module’ object has no attribute ‘main’

    also i want to ask you @Prahlad Yeri is your software like connectify, does it share from a wifi network to a hostspot like connectify.

    1. The latest version is hotspotd-0.1.4.tar.gz and not hotspotd-0.1.1.tar.gz. Install it and the router will work. This post was not updated since long, now I’ve updated it.

      Yup, this works exactly like connectify on windows. It will turn your laptop/desktop computer into a wifi access point.

  14. After executing this script in the terminal by “./AccessPoint”, i get an error “Can’t create PID file /var/run/dhcpd.pid: Permission denied”. Could you help me? thanks before

  15. Hi,Ojus here
    I was trying to install hotspotd0.1.1. Installation was successfull but , finally running it get
    ojus@ojus-VPCEB44EN:~/hotspotd-0.1.1$ sudo python hotspotd.py start
    Verifying interfaces

    done.
    created interface: mon.wlan0 on IP: 192.168.45.1
    wait..
    stopping hostapd
    enabling forward in sysctl.
    net.ipv4.ip_forward = 1
    creating NAT using iptables: wlan0eth0
    running dnsmasq
    hotspot is running.

    But the hotspot is not visible or can not be detected. How can I do that.?.

    I am working on a Ubuntu 12.04, My wireless card uses ath9k , also AP mode.
    I was trying to use this for setting a WEP based AP for capturing WiFi pacekts , modify it and send.

  16. Excellent post. I have recently bought a leoxsys usb wifi device and after a lot of struggle couldn’t set it up as a wifi hotspot so that I can connect to it from my android. I’m yet to try out your advices above, and also the pyforward. I got an error earlier that my wifi device doesn’t support AP. Is that a hardware limitation or a software one? In that latter case, I hope to find a suitable driver to make it work. Need suggestions on that.

  17. This completely ruined my net access. Was not able to use any website. All ping requests gave unknow host error. Had to completely delete the iptables file. Linux Mint 17!!

      1. I have installed it successfully. Just unable to view the network on cell phones. Looks like visibility issue.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s