From charlesreid1

In this section we set up Bespin to operate a wifi access point with hostapd. This involves the following:

  • Install and configure hostapd
  • Install and configure dnsmasq
  • Configure access point network interface
  • Start hostapd
  • Create hostapd startup service

Sysctl Changes

Enable bespin to forward packets, a necessary role of an access point router, in the sysctl settings:

/etc/sysctl.conf

Add this line in the .conf file, it should be there but commented out, add it in:

net.ipv4.ip_forward=1

To reload sysctl, run this command:

sysctl --system

Install hostapd

Start by installing hostapd:

sudo apt-get -y install hostapd

Configure hostapd

Create the hostapd config file:

/etc/hostapd/hostapd.conf

# Set this to wlan0 if you are using an ethernet cable
# to connect your Pi to the internet
interface=wlan1
driver=nl80211
hw_mode=g
channel=1
macaddr_acl=0
ignore_broadcast_ssid=0

# LAN10
ssid=LAN10
wpa_passphrase=cow-doctor-horse-building-5
auth_algs=1
wpa=3
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Now set the hostapd configuration file:

/etc/default/hostapd

DAEMON_CONF="/etc/hostapd/hostapd.conf"

At this point you should be able to start hostapd with this command:

sudo hostapd /etc/hostapd/hostapd.conf

You will be able to see the wifi network, and clients will be able to authenticate, but they won't be able to join it because they won't get IP addresses.

Side Note: Bridged Network with Shared DHCP

If you want your AP (wlan1) to share a network with the existing wifi connection (wlan0), and offload the DHCP functionality to the DHCP server of the existing wifi network, you can create a network bridge with hostapd and use the network bridge that hostapd creates (that wlan1 is already attached to) and attach wlan0 to the bridge. This allows clients sending packets to wlan1 to have those packets seen by wlan0.

Modify the following line from the hostapd config file:

# This is already there
interface=wlan1
# Add this line
bridge=br0

Here are the steps to bring up the bridge:

sudo ifconfig wlan0 inet 0.0.0.0  # <-- is this necessary???
sudo brctl addif br0 wlan0
sudo ifconfig br0 up
sudo dhclient br0

Breakdown:

  • The bridge already exists, and is already connected to wlan1, so we add the wlan0 device to it
  • We bring up the bridge
  • We ask for an IP address for the bridge device

Here are the steps to bring down the bridge:

sudo ifconfig br0 down
sudo brctl delif br0 wlan1
sudo brctl delif br0 wlan0
sudo ifconfig br0 down
sudo dhclient wlan0

Last step is to remove any lines from /etc/dnsmasq.conf that would hand out IP addresses for this IP space - leave that to the router.

dnsmasq for DHCP and DNS

We are going to install dnsmasq to provide a DHCP and DNS service for the AP network.

Start by installing it with apt-get:

sudo apt-get -y install dnsmasq

This will try to start dnsmasq, but it will fail and print red text. This is fine - the system's built-in systemd-resolved is already listening on port 53 so we will need to disable this service. (But we need dnsmasq installed FIRST, because disabling systemd-resolved will cause DNS queries to fail, so the internet connection will break. We need dnsmasq ready to start and take over the DNS duties.)

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved

Preserve the original dnsmasq config file, which has a lot of useful information:

sudo mv /etc/dnsmasq.conf{,.orig}

Now create the dnsmasq config file:

/etc/dnsmasq.conf

interface=wlan1
dhcp-range=192.168.10.100,192.168.10.150,255.255.255.0,24h

Here is a much better version:

# don't send external traffic that is missing a domain
domain-needed
# don't send external traffic that has bogus private ip
bogus-priv
# set the local domain
domain=mynet
local=/mynet/
# listen on these interfaces and only these interfaces
listen-address=127.0.0.1
listen-address=192.168.10.1
bind-interfaces
# define range of IP addresses to hand out
dhcp-range=192.168.10.100,192.168.10.150,255.255.255.0,24h
# define what to do if no name resolution
no-resolv
server=8.8.8.8
# send dnsmasq logs to a single place
log-facility=/var/log/dnsmasq.log

Now we are ready to start up dnsmasq:

sudo systemctl enable dnsmasq
sudo systemctl start dnsmasq

Set Preferred DNS Nameservers

Set preferred nameservers by editing the dhcp configuration file:

/etc/dhcp/dhcpcd.conf

static domain_name_servers=8.8.8.8

or for dhclient:

/etc/dhcp/dhclient.conf

prepend domain-name-servers 127.0.0.1;

(THESE INSTRUCTIONS FROM RaspberryPi/Hotspot ARE OLD)

Remove the existing file at /etc/resolv.conf (a symlink to a network manager thing). Create a new version of the file that specifies preferred nameservers:

nameserver 8.8.8.8

NOTE: this file will be overwritten at boot by Network Manager. If your DNS is broken and dnsmasq does not seem to be able to find a preferred nameserver, circle back and double-check that network manager has been disabled.

Improved Logging

Dnsmasq configuration file has a log-facility option to control where logs go. Add this to the config file:

log-facility=/var/log/dnsmasq.log

Testing the AP

Before testing everything out, do a reboot and make sure that all services are running as expected (dnsmasq in paarticular) and that network interfaces are configured as expected.

To test the AP, we will run hostapd manually first. Checklist for testing if the access point works:

  • is dnsmasq service running? (Yes)
  • is hostapd service running? (No)
  • is static ip set for the wifi card creating the AP in /etc/network/interfaces? (Yes, 192.168.10.1)
  • does ifconfig show that IP? (Yes)
  • can cients see to wifi network? (Yes)
  • can clients connect to wifi network? (Yes)
  • does handshake process succeed? (Yes)
  • does client receive an IP? (Yes)
  • can client access internet? (No)

Now run hostapd manually:

sudo hostapd /etc/hostapd/hostapd.conf

To add more debug info:

sudo hostapd -d /etc/hostapd/hostapd.conf

To log it to a file,

sudo hostapd -d /etc/hostapd/hostapd.conf 2>&1 | tee hostapd.log

From a phone or another computer, connect to the wireless network and verify you get an IP in the lease range specified in the dnsmasq config file.

Starting the Service

To start hostap in the background as a service, and enable it to start on boot, run these commands:

sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapd

Modifying Startup Service to Retry

The hostapd service is very fickle, failing the first time it is run but succeeding when run a few seconds later, so we can set up the hostapd service to retry 5 times, waiting 30 seconds each time.

To do that, edit the startup service file at /lib/systemd/system/hostapd.service

Add these two lines to the [Unit] section:

[Unit]
StartLimitInterval=200
StartLimitBurst=5

Add these two lines to the [Service] section:

[Service]
Restart=always
RestartSec=30

The final version of the hostapd startup service is given below:

/lib/systemd/system/hostapd.service

[Unit]
Description=Advanced IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP Authenticator
After=network.target
StartLimitInterval=200
StartLimitBurst=5

[Service]
Type=forking
PIDFile=/run/hostapd.pid
EnvironmentFile=/etc/default/hostapd
ExecStart=/usr/sbin/hostapd -P /run/hostapd.pid -B $DAEMON_OPTS ${DAEMON_CONF}
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target

Reload the service:

sudo systemctl daemon-reload

Now restart the service:

sudo service hostapd restart