Hostapd : The Linux Way to create Virtual Wifi Access Point

NOTE: Although this guide should work in most cases, it is not flawless and still requires few minor modifications to make the process bug-free. Please do point out corrections and changes.

(After you are done with this post, please do checkout my Python Hostapd Client)

I was recently looking into ways to use my laptop’s wifi adapter as a wireless access point to enable my phone (Nokia E63) and playstation portable to connect to the internet through it. Ad-hoc feature may be used to share internet through wifi, but it doesn’t work with many phones and my PSP. I found connectify and virtual router for Windows which served this purpose, unsatisfactorily. Other than the reasons like Virtual Router not detecting my 3g modem and Connectify (free version) not allowing me to set desired ssid for my virtual access point, the biggest issue with these two was the limited modes available for the access point. Both the programs offered only WPA2-PSK encryption for infrastructure mode and WEP and open encryption for ad-hoc modes. Many devices connect only through infrastructure mode and support for WPA2-PSK is absent in few devices (including the PSP). Also, since I am a Linux user, I needed something else.

This is where hostapd kicks in.

HOSTAPD

“hostapd is a user space daemon for access point and authentication servers. “

In simple words, hostapd allows you to create software wifi access points allowing decent amount of configuration options. In rest of this post, I will show how to create a software access point in Linux using hostapd and share your internet to the devices through it. I have used my Lenovo Z560 with ath9k wifi driver under Arch Linux and have also tested it under Ubuntu 11.10. But the method is also applicable for other Linux distros and supported hardware.

If the method works/doesn’t work for a non-Atheros wifi card, please do comment.

REQUIREMENTS

  • Supported Wireless Card (ie. supports master mode)
  • An internet connection you want to share. (not strictly a neccessity)
  • A linux distro

CHECKING WIFI CARD SUPPORT

First of all, you will need to find if your wireless card is supported by hostapd.

To check what kernel driver is in use for your wireless card, type the follwing in the terminal

lspci -k | grep -A 3 -i "network"

Look for the section in the output which corresponds to your Wireless controller. In my case, it is

06:00.0 Network controller: Atheros Communications Inc. AR9285 Wireless Network Adapter (PCI-Express) (rev 01)
Subsystem: Lenovo Device 30a1
Kernel driver in use: ath9k

The Bold part is my kernel driver in use. It will vary depending on your wifi card and driver you are using.

Now get the interface details of your wireless driver by

modinfo ath9k | grep 'depend'

replace ath9k by your wifi kernel driver you determined in the last step. In my case, the output was

depends: ath9k_hw,mac80211,ath9k_common,ath,cfg80211

modinfo says my Kernel driver supports mac80211 interface which is supported by hostapd which implies that my wifi card is compatible with hostapd.

Supported wireless cards/drivers

INSTALLING HOSTAPD

Install Hostapd from your distro’s repo

#Arch Linux
sudo pacman -S hostapd
#Ubuntu
sudo  apt-get update && sudo apt-get install hostapd
#Should be available in official repo of your distro

Or Download Hostapd here and compile it.

CONFIGURING HOSTAPD

The /etc/hostapd/hostapd.conf is the main configuration which you need to deal with in order to set up a SoftAP.

This is the minimal configuration setting which will let you test if hostapd is working. Create a file ~/hostapd-test.conf
with the following content:

#change wlan0 to your wireless device
interface=wlan0
driver=nl80211
ssid=test
channel=1

start hostapd by

sudo hostapd ~/hostapd-test.conf

Use a wifi device to check if the access point is being detected. You won’t be able to connect to it at present.
Once hostapd is working fine, its time to configure hostapd with more options.
Here is a brief overview of some of its options:

#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=dontMessWithVincentValentine
#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=KeePGuessinG
#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

So, here is my complete /etc/hostapd/hostapd.conf with WPA authentication options.

interface=wlan0
driver=nl80211
ssid=dontMessWithVincentValentine
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=3
wpa_passphrase=KeePGuessinG
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

SETTING UP THE DHCP SERVER

Alternative Method: I recommend using dnsmasq over dhcpd for this scenario mainly due to the ease in configuring it. I have continued this post from this point in a new separate post which uses dnsmasq instead of dhcpd. If you have any reason to choose dhcpd over dnsmasq or if dnsmasq isn’t working for you, then carry on.

Now that hostapd is running fine, you need to setup a DHCP server to run along with hostapd in order to assign ip address to the devices connecting to the access point. Setting up a dhcp server is quite straightforward.

Install dhcp server from your distro’s repo.

#Arch Linux
sudo pacman -S dhcp
#Ubuntu
sudo  apt-get update && sudo apt-get install isc-dhcp-server
#Fedora
sudo yum -y install dhcp

edit /etc/dhcpd.conf (for arch linux) or /etc/dhcp/dhcpd.conf (for Ubuntu) to

ddns-update-style none;
ignore client-updates;
authoritative;
option local-wpad code 252 = text;

subnet
10.0.0.0 netmask 255.255.255.0 {
# --- default gateway
option routers
10.0.0.1;
# --- Netmask
option subnet-mask
255.255.255.0;
# --- Broadcast Address
option broadcast-address
10.0.0.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;
default-lease-time 1209600;
max-lease-time 1814400;
}

options are easy to understand and you may change it according to your needs (if required).

FINAL STEPS

The final steps involves enabling NAT to share internet in one network interface  with the clients connected through hostapd.

I have included all the steps to configure wlan interface, enable NAT, start DHCP server and hostapd in the BASH script below

Let the name of this file be initSoftAP.
Copy the BASH file below to the file initSoftAP.(and make changes to file according to your system)

#!/bin/bash
#Initial wifi interface configuration
ifconfig $1 up 10.0.0.1 netmask 255.255.255.0
sleep 2
###########Start DHCP, comment out / add relevant section##########
#Thanks to Panji
#Doesn't try to run dhcpd when already running
if [ "$(ps -e | grep dhcpd)" == "" ]; then
dhcpd $1 &
fi
###########
#Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $2 -j MASQUERADE
iptables --append FORWARD --in-interface $1 -j ACCEPT

#Thanks to lorenzo
#Uncomment the line below if facing problems while sharing PPPoE, see lorenzo's comment for more details
#iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

sysctl -w net.ipv4.ip_forward=1
#start hostapd
hostapd /etc/hostapd/hostapd.conf 1>/dev/null
killall dhcpd

Script Changes (12/9/12) : Added check for already running dhcpd process (Thanks to Panji), Added an optional line to fix issues related to PPPoE connection sharing (See lorenzo’s comment)

It might be more convenient to use hostapd -B /etc/hostapd/hostapd.conf which runs hostapd in background. (Thanks to Enda for pointing out)

Make this file executable, and run it. The syntax for executing it is

./initSoftAP wifi_card_interface interface_with_internet

chmod +x initSoftAP
./initSoftAP wlan0 eth0

The “wifi_card_interface” will be wlan0 most of the cases. For “interface_with_internet“, since I want to share internet from my ethernet network interface, I used eth0. If I ever want to share internet from my 3g modem, I use ppp0. (These values need not be same for everyone)
You may see available network interfaces by

ifconfig -a

Note:

  • If dhcpd is failing to start and throwing errors like No subnet declaration for wlan0, take a look at these comments by Mahesh and Charlie. Either use dnsmasq, or try adding the following to the  /etc/default/isc-dhcp-server file

INTERFACES=”wlan0″
option netbios-name-servers 10.0.0.1

  • Raspberry Pi users might want to take a look at Denis Kökeny’s comment.

Problems, Errors, Feedback or any alternatives? Feel free to reply.

About these ads

413 thoughts on “Hostapd : The Linux Way to create Virtual Wifi Access Point

  1. Pingback: My Android Device Doesn't Connect to openSUSE HotSpot

  2. neeeko

    the hostapd machine has several interfaces : wlan10, eth0 and tun0 (vpn tunnel using eth0).
    using ./initAP wlan10 eth0 gives me no internet over WiFi
    using .initAP wlan10 tun0 gives me internet over WiFi
    The pb is that i would like to have access to internet and to the LAN at the same time, is there a way to achieve this ?

    Here’s my initAP :
    #!/bin/bash
    #Initial wifi interface configuration
    ifconfig $1 up 10.0.0.1 netmask 255.255.255.0
    sleep 2
    ###########Start DHCP, comment out / add relevant section##########
    #Thanks to Panji
    #Doesn’t try to run dhcpd when already running
    if [ "$(ps -e | grep dhcpd)" == "" ]; then
    dhcpd $1 &
    fi
    ###########
    #Enable NAT
    iptables –flush
    iptables –table nat –flush
    iptables –delete-chain
    iptables –table nat –delete-chain
    sudo iptables -t nat -A POSTROUTING -o $2 -j MASQUERADE
    sudo iptables -A FORWARD -o $2 -i $1 -m conntrack –ctstate NEW -j ACCEPT
    #Thanks to lorenzo
    #Uncomment the line below if facing problems while sharing PPPoE, see lorenzo’s comment for more details
    #iptables -I FORWARD -p tcp –tcp-flags SYN,RST SYN -j TCPMSS –clamp-mss-to-pmtu
    sysctl -w net.ipv4.ip_forward=1
    #start hostapd
    hostapd /etc/hostapd/hostapd.conf 1>/dev/null
    killall dhcpd

    thanks for your help !

    Reply
  3. gabbro

    mmhh…running ubuntu 12.04.1 I had troubles here:

    Internet Systems Consortium DHCP Server 4.1-ESV-R4
    Copyright 2004-2011 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/c4:46:19:6b:7f:c0/10.0.0.0/24
    Sending on LPF/wlan0/c4:46:19:6b:7f:c0/10.0.0.0/24
    Sending on Socket/fallback/fallback-net
    Can’t create PID file /var/run/dhcpd.pid: Permission denied.
    net.ipv4.ip_forward = 1

    I tried Mahesh solution, disabling the autostart of dnsmasq, then typing

    sudo dnsmasq –interface=wlan0 –dhcp-range=192.168.0.50,192.168.0.100,12h

    but I get:

    dnsmasq: failed to create listening socket for port 53: Address already in use

    some suggestion?

    Reply
  4. Guenther

    Hi,
    thanks for your great work. :-)
    My question is: Why is the reverse direction for incoming packets to wlan0 left out in the script? The returning packets are always dropped on my computer unless I also enable forwarding them with iptables. I.e., the lines with iptables read now like this in my script:
    iptables –table nat –append POSTROUTING –out-interface $2 -j MASQUERADE
    iptables –append FORWARD –in-interface $1 -j ACCEPT
    iptables –append FORWARD –out-interface $1 -j ACCEPT # must also accept reverse direction

    I wonder, how could it work _without_ this last line, as no-one complained about it so far? (I use openSUSE 12.2, where the FORWARD chain has DROP policy.)

    Reply
    1. Guenther

      Hm, I am still wondering if I did something wrong. Could you or anyone around here please explain me why I had to open the backwards direction in the firewall for the traffic returning to the wlan0-device explicitely? Why does it work in the original script without opening the back direction explicitely?

      This would be so helpful to me. I don’t want to mess around with the firewall if I don’t exactly know why it’s necessary. Thanks for your help!

      Reply
      1. Michael

        I don’t know if this applies directly to your system, but the line in my iptables setup that takes care of the return packets is:

        iptables -A FORWARD -i em1 -o wlan0 -m state –state RELATED,ESTABLISHED -j ACCEPT

        where em1 is my hardwired internet connection and wlan0 is my wireless. The default for my filter table FORWARD is ACCEPT. What I *think* this does is only returns traffic from connections that I have explicitly initiated.

  5. Michael

    Nice package. How about adding an option to the script for static IP setup? I have static IP on eth0 as well as on wlan0 and the devices I connect.

    Reply
  6. westend

    Hello,
    I did all needed installation and configuration on my Arch. My tablet sees the hotspot, but cannot pass the authentication stage. I am sure that the password is correct, but it is not accepted.
    Any idea?

    Reply
  7. winuxuser

    so, finally, i decided to give another shot in my ubuntu12.04 since last august…..yes, i tried to do it again this january :D
    everything has worked out…. with a glitch off course….
    in the /etc/hostapd/hostapd.conf file of mine, everything is same except the last 3 lines.
    All the initsoftap script is the same for me too…. and i run it as ./initsoftap wlan1 eth0 coz my ifconfig-a will give:
    eth0 Link encap:Ethernet HWaddr 00:25:64:55:9e:9d
    inet addr:192.168.1.2 Bcast:192.168.1.255 Mask:255.255.255.0
    inet6 addr: fe80::225:64ff:fe55:9e9d/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:79796 errors:0 dropped:0 overruns:0 frame:0
    TX packets:78841 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:23007807 (23.0 MB) TX bytes:16042172 (16.0 MB)
    Interrupt:45 Base address:0×8000

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    inet6 addr: ::1/128 Scope:Host
    UP LOOPBACK RUNNING MTU:16436 Metric:1
    RX packets:1771 errors:0 dropped:0 overruns:0 frame:0
    TX packets:1771 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:322754 (322.7 KB) TX bytes:322754 (322.7 KB)

    wlan1 Link encap:Ethernet HWaddr 00:26:5e:54:e8:eb
    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)

    PROBLEM: running ./initsoftap wlan1 eth0 will give simply the following line:
    net.ipv4.ip_forward=1
    the connection is established, but cant browse the internet…. do u have any suggestions???

    Reply
    1. nims11 Post author

      can’t say much here. the problems definitely seems with the iptables part of the script. try playing with it. Let me know if you find what is wrong. I will also try to figure out what might be wrong.

      Reply
      1. winuxuser

        SO, i finally was able to make the script run properly.
        I came to few conclusions from my laptop:-
        1. enabling firewall wont let ethernet to transmit the data packets.
        2. the script when run will disable the firewall, which means prone to attacks.
        3. ufw can’t be configured to adjust needs of the script.

        Can the problem of ufw and the initsoftap be solved??

    2. hooked2linux

      Yes, the hotspot can work with ufw enabled. check out this solution.
      https://help.ubuntu.com/10.04/serverguide/firewall.html
      If you follow the instructions, you can even uncomment these iptables lines & IP forwarding in “initsoftap”
      #Enable NAT
      iptables –flush
      iptables –table nat –flush
      iptables –delete-chain
      iptables –table nat –delete-chain
      iptables –table nat –append POSTROUTING –out-interface $2 -j MASQUERADE
      iptables –append FORWARD –in-interface $1 -j ACCEPT

      #Thanks to lorenzo
      #Uncomment the line below if facing problems while sharing PPPoE, see lorenzo’s comment for more details
      #iptables -I FORWARD -p tcp –tcp-flags SYN,RST SYN -j TCPMSS –clamp-mss-to-pmtu

      sysctl -w net.ipv4.ip_forward=1

      Reply
  8. one31071

    Thanks for the great script! This is the first of the many on the web that actually works.

    The script seems to be working perfectly because my Android (4.0.4) smartphone detects the AP. If I try to connect to it (I’ve double-checked the password), it reports “Authentication problem” after attempting to connect several times. The device is a TP-LINK TL-WN721N, and I’m using Arch Linux on a Raspberry Pi.

    Reply
    1. one31071

      I did double check the password, but I was using an old hostapd.conf, updated and it works like a charm! Thanks again! :D

      Reply

How did you feel about this post? Push in your 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