Magic Box of Pi-ternets — Part One

I recently picked up an adorable little Raspberry Pi 3 for some small projects. Some of the tests I want to run require me to be able to see a lot more information about the connecting client than a standard retail router can show me. The first step is to configure my Raspberry Pi to act as a simple wireless access point. An evil, simple wireless access point.

Could this cute face be evil ?

These instructions were tested on Raspbian but should work on other Debian-derived distributions.

First we need to install the necessary services and tools. hostapd is a lightweight daemon to handle the wireless access point and authentication. dnsmasq is a simple DNS and DHCP server designed for small networks.

root@darkstar:~# apt install hostapd dnsmasq
Reading package lists... Done
Building dependency tree

You can use any editor you are comfortable with to follow these steps.

The ethernet interface will get an IP address from my router on my home network, but the wireless connection must be configured with a static IP on a different network. Edit /etc/network/interfaces and add the configuration block below. You may want to pick a different network if the example conflicts with your existing home network.

root@darkstar:~# vim /etc/network/interfaces
auto wlan0
iface wlan0 inet static
address 192.168.0.1
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255

Cycle the interface to bring it up with the new settings.

root@darkstar:~# ifdown wlan0; ifup wlan0

Now we can configure hostapd. First, we must edit the startup script to insert the location of the hostapd configuration file. Edit /etc/init.d/hostapd and find the line DAEMON_CONF. Add the path as shown below.

root@darkstar:~# vim /etc/init.d/hostapd
<snip>
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON_SBIN=/usr/sbin/hostapd
DAEMON_DEFS=/etc/default/hostapd
DAEMON_CONF=/etc/hostapd/hostapd.conf

Create the configuration file /etc/hostapd/hostapd.conf and populate it with the block as shown. I am choosing to configure a passphrase to ensure that no-one accidentally stumbles across my access point when it turns to the dark side. Choose your own details for the network name (SSID) and password (wpa_passphrase).

root@darkstar:~# vim /etc/hostapd/hostapd.conf
interface=wlan0 
driver=nl80211
ssid=darkstar
hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=sorrynotsorry
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

We can now service hostapd start and should be able to see our SSID if we check from a wireless client. We can connect to it, but we won’t get an IP address. The next step is to set up dnsmasq to provide DHCP and DNS services.

Edit /etc/dnsmasq.conf and set the following options. We will need to use the same network for DNS leases as we configured for our wireless interface earlier.

root@darkstar:~# vim /etc/dnsmasq.conf
dhcp-range=192.168.0.50,192.168.0.150,12h
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log

Some of them may be present in the default configuration file for your distribution commented out.

This simple configuration will give DHCP clients an address between the range above with a lease expiry of 12 hours. DNS entries will be provided based on what is configured in /etc/resolv.conf on the Pi itself. The other settings simply enable logging for DHCP and DNS requests.

If we now start dnsmasq with service dnsmasq start we should be able to connect to the wireless SSID and receive an IP address and DNS servers. Before the Pi will start routing our packets we now need to enable ip forwarding with the following command.

root@darkstar:~# echo 1 > /proc/sys/net/ipv4/ip_forward

For this setting to persist across restart we must also add it to the default system configuration. Edit /etc/sysctl.conf and add the line as shown below. Depending on your distribution it may already be present in the file, commented out.

root@darkstar:~# vim /etc/sysctl.conf
net.ipv4.ip_forward=1

We now need to configure iptables to SNAT the traffic coming in over the wireless interface and route it over the wired interface.

root@darkstar:~# iptables -A FORWARD -i wlan0 -j ACCEPT
root@darkstar:~# iptables -A FORWARD -o wlan0 -j ACCEPT
root@darkstar:~# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

For this configuration to persist across restarts we need to save the iptables configuration that is currently in memory and restore it on startup. The simplest way to do this is by using iptables-save to output the configuration somewhere sensible and then add iptables-restore to /etc/rc.local. The contents of /etc/rc.local are executed as the last step of the startup process.

root@darkstar:~# iptables-save > /etc/iptables.save
root@darkstar:~# vim /etc/rc.local
iptables-restore < /etc/iptables.save
exit 0

Now our client can connect, receive an IP address and DNS servers and access the internet and internal LAN through the Raspberry Pi. At this point we try to figure out how to ask iptables what the NAT table for our client looks like and realise that apparently ipchains -ML didn’t make it across some twenty years ago and we hadn’t noticed yet. Thanks Rusty Russell, we love you too.

To get a view of the NAT connections from the perspective of iptables we can install the package netstat-nat.

root@darkstar:~# apt install netstat-nat
<snip>
root@darkstar:~# netstat-nat
Proto NATed Address Destination Address State
tcp Vaelestrasz:51446 162.125.34.129:https ESTABLISHED
tcp Vaelestrasz:51474 syd09s15-in-f3.1e100.net:http ESTABLISHED
tcp Vaelestrasz:51445 17.188.138.71:5223 ESTABLISHED
tcp Vaelestrasz:51473 104.16.123.127:https ESTABLISHED

There is one last configuration step before we can call the configuration complete. By default the hostapd and dnsmasq startup scripts are set a little too early in the startup sequence and try to come up before the wireless interface. This causes the services to fail and not start up.

Check your previous run-level to determine which startup scripts to modify.

root@darkstar:~# who -r
run-level 5 2017-02-15 15:22

In our example the previous run-level is run-level 5. Let’s check the scripts for that run-level.

root@darkstar:~# cd /etc/rc5.d/
root@darkstar:/etc/rc5.d# ls
README S01rsyslog S02ntp S03cron S04rmnologin
S01bootlogs S01triggerhappy S02pptpd S03lightdm
S01dhcpcd S02dbus S02ssh S03rsync
S01hostapd S02dnsmasq S03avahi-daemon S04plymouth
S01motd S02dphys-swapfile S03bluetooth S04rc.local

We can see that hostapd and dnsmasq are set to be first and second startup order. Let’s shift them both by one to give a little more time for networking to come up.

root@darkstar:/etc/rc5.d# mv S01hostapd S02hostapd
root@darkstar:/etc/rc5.d# mv S02dnsmasq S03dnsmasq

We should now be able to reboot the Raspberry Pi and have our wireless access point come up automatically ready to route packets.

At this point clients can not only browse the internet through the Raspberry Pi but they can also access my internal LAN. This is fine for my first configuration which will be to configure the Pi as a VPN appliance but please be careful with what clients you allow to connect. Locking down the Pi for use as a honeypot I will cover in a future post.

Happy Pi-ternets!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.