NOTE: Although this guide should work in most cases, it is not flawless and may require minor modifications to make the process work for your use case. Please do point out corrections and changes.
UPDATE (22-Oct-2018): Since this post still gets lots of hits despite being 6 years old, I have made some revisions to make it compatible with modern times. Major changes include:
- Remove useless information
- Replace ifconfig with ip
- Replace dhcpd with dnsmasq
HOSTAPD
“hostapd is a user space daemon for access point and authentication servers. “
Hostapd allows you to create software wifi access points with decent amount of configuration options. In rest of this post, we will create a software access point in Linux using hostapd and share your internet to the devices through it. I have used my Thinkpad E570 with ath10k_pci wifi driver under Arch Linux. But the method is also applicable for other Linux distros and supported hardware.
REQUIREMENTS
- Supported Wireless Card (ie. supports AP mode)
- If you want to share your internet connection or some other network, it should be on an interface other than the wifi interface your hostapd is bind to.
- A dhcp server to assign ip addresses to clients. We will use dnsmasq.
- iptables to forward internet traffic.
CHECKING WIFI CARD SUPPORT
Most modern wireless cards should work with hostapd. To check what modes your card supports, type the following in your terminal:
$ iw list | grep "Supported interface modes" -A 8
You will get something like this:
Supported interface modes: * IBSS * managed * <strong>AP</strong> * monitor * mesh point * P2P-client * P2P-GO * P2P-device
You want that bold AP (which stands for access point) to show up if you want to use hostapd with your wireless card. Take a look at https://wiki.gentoo.org/wiki/Hostapd for more details.
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
Or Download Hostapd here and compile it.
NOTE: Before proceeding, make sure your network manager (for example NetworkManager or netctl-auto) is not managing your wireless interface.
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 this point.
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 interface=wlan0 #driver to use, nl80211 works in most cases driver=nl80211 #sets the ssid of the virtual wifi access point ssid=myhotspot #sets the mode of wifi, depends upon the devices you will be using. It can be a,b,g,n. Not all cards support 'n'. 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 (remove this section if you don't need encryption)##### #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
So, here is my complete /etc/hostapd/hostapd.conf with WPA authentication.
interface=wlan0 driver=nl80211 ssid=myhotspot 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
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 for dnsmasq.
Install dhcp server from your distro’s repo.
# Arch Linux $ sudo pacman -S dnsmasq # Ubuntu $ sudo apt-get install dnsmasq
The default /etc/dnsmasq.conf explains all its configuration options pretty well, so I will jump straight to what a simple /etc/dnsmasq.conf should look like
# Interface to bind to interface=wlan0 # Specify starting_range,end_range,lease_time dhcp-range=10.0.0.3,10.0.0.20,12h # Uncomment and modify the following lines if you don't want to forward dns from the host's /etc/resolv.conf ## disables dnsmasq reading any other files like /etc/resolv.conf for nameservers #no-resolv ## dns addresses to send to the clients #server=8.8.8.8 #server=8.8.4.4
Start dnsmasq and your clients should be able to connect to the wireless hotspot:
# Setup the interface $ ip link set wlp5s0 down $ ip addr flush dev wlp5s0 $ ip link set wlp5s0 up $ ip addr add 10.0.0.1/24 dev wlan0 # start hostapd $ sudo killall dnsmasq; dnsmasq $ sudo hostapd
SHARING THE INTERNET
This final steps involves enabling NAT to share internet (or any network) in one network interface with the clients connected through hostapd. I just use few lines of iptables to achieve this. Refer to https://wiki.archlinux.org/index.php/Internet_sharing for more information or how to achieve the same using nftables. Ignore this step if all you want to do is setup an internal wifi network and clients don’t need access to any external network.
I have included all the steps to configure wlan interface, enable NAT, start DHCP server and hostapd in the BASH script below.
Copy the content below to the file initSoftAP. (and make changes to file according to your needs)
#!/bin/bash # Usage: ./initSoftAP ########### Initial wifi interface configuration ############# ip link set $1 down ip addr flush dev $1 ip link set $1 up ip addr add 10.0.0.1/24 dev $1 # If you still use ifconfig for some reason, replace the above lines with the following # ifconfig $1 up 10.0.0.1 netmask 255.255.255.0 sleep 2 ########### ########### Start dnsmasq ########## if [ -z "$(ps -e | grep dnsmasq)" ] then dnsmasq fi ########### ########### Enable NAT ############ iptables -t nat -A POSTROUTING -o $2 -j MASQUERADE iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i $1 -o $2 -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 killall dnsmasq
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
Now your devices should be able to access the internet (or any network) through your hotspot.
Problems, Errors, Feedback or any alternatives? Feel free to reply.
Pingback: My Android Device Doesn't Connect to openSUSE HotSpot
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 !
you can do it with iptables, google about it.
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?
try
touch /var/run/dhcpd.pid
chmod 777 /var/run/dhcpd.pid
Thanks for writing this. I found it very useful!
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.)
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!
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.
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.
correct me if i am wrong. don’t you just need to remove dhcp lines and configure the ifconfig ip for static ip setup?
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?
make sure the password is 8 to 63 characters. also try connecting with ‘open’ authentication option in your hostapd.conf.
so, finally, i decided to give another shot in my ubuntu12.04 since last august…..yes, i tried to do it again this january 😀
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???
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.
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??
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
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.
I did double check the password, but I was using an old hostapd.conf, updated and it works like a charm! Thanks again! 😀
How do I deal with ports? I would like to block everything but basic web traffic and app/game specific ports, how would I do that?
You might want to take a look at iptables. it is capable of doing what you wish for.