Friday 5 February 2016

Carpi #3: network

For the software aspect of the Carpi, I had these constraints in mind:
- Control of the player should be done through phones to avoid loging remotes and removing the need to access the pi's display.
- The Carpi needs internet access once in a while for updates and library rescan.
- The phones connected to the Carpi will need internet access while talking to the Carpi.

I therefore opted for the following solution:
- 1 wifi interface for the phones to connect to.
- 1 wifi interface to connect to a wifi provider (mobile or house).
- Once in a while I might connect via ethernet to the home nerwork.
- Kodi setup to be controlled via the web/remote interface.
- Carpi acting as a firewall/router.

The external wifi interface is easily setup as standard. I called it wlan0. The internal interface needs to run DHCP and i need some routing. So let's install the software needed:

Install the DHCP server and hostapd:
sudo apt-get update
sudo apt-get install hostapd isc-dhcp-server

Setup the DHCP daemon:
sudo nano /etc/dhcp/dhcpd.conf

Make sure "authoritative;" is NOT commented out. Now create a DHCP block:
subnet 192.168.200.0 netmask 255.255.255.0 {
range 192.168.200.100 192.168.200.200;
option broadcast-address 192.168.200.255;
option routers 192.168.200.1;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local";
option domain-name-servers 8.8.8.8, 8.8.4.4;
}
The Carpi's internal interface will be 192.168.200.1.

Then edit the DHCP server options:
sudo nano /etc/default/isc-dhcp-server

Change the line "INTERFACES=" to
INTERFACES="wlan1"

Now make wlan1's IP address static.
sudo nano /etc/network/interfaces

Find the wlan1 section and channge it to:
auto wlan1
allow-hotplug wlan1
iface wlan1 inet static
address 192.168.200.1
netmask 255.255.255.0
network 192.168.200.0
broadcast 192.168.200.255

At the end of the file, add:
up iptables-restore < /etc/iptables.ipv4.nat
(you'll see why later)

Bring down the wlan1 interface and bring it back up:
sudo ifdown wlan1
sudo ifconfig wlan1 192.168.200.1

Now we need to setup hostapd:
sudo nano /etc/hostapd/hostapd.conf

Type in:
ctrl_interface=/var/run/hostapd
driver=rtl871xdrv
ieee80211n=1
ctrl_interface_group=0
beacon_int=100
interface=wlan1
ssid=OnTheMove
hw_mode=g
channel=6
auth_algs=1
wmm_enabled=1
eap_reauth_period=360000000
macaddr_acl=0
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=00000000
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Change the SSID to your liking (for me it's OnTheMove) and the password to yours (here it's 00000000).

Now setup hostapd's options:
sudo nano /etc/default/hostapd

Change the DAEMON_CONF line (normally commented out) to:
DAEMON_CONF="/etc/hostapd/hostapd.conf"

Now we need to setup the IP forwarding in the kernel:
sudo nano /etc/sysctl.conf

Find the line with net.ipv4.ip_forward and set it to 1:
net.ipv4.ip_forward=1

Also activate it right now. Run:
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

We now need a bit of network filtering magic. As I explained, I need interfaces eth0 and wlan0 to face the outside world, and wlan1 to be the internal interface where phones connect. I therefore setup routing that way and I open a few ports:
# Clear the tables
sudo iptables -F
# Make eth0 and wlan0 masquerading interfaces
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Setup forward between interfaces
sudo iptables -A FORWARD -i wlan0 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan1 -o wlan0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan1 -o eth0 -j ACCEPT
# Accept all pings
sudo iptables -A INPUT -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT
# Open a few ports
sudo iptables -A INPUT -i wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -i wlan0 -p tcp --dport ssh -j ACCEPT
sudo iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --dport ssh -j ACCEPT
# On outside interfaces we drop by default
sudo iptables -A INPUT -i wlan0 -j DROP
sudo iptables -A INPUT -i eth0 -j DROP
# Save the rules so they can be reloaded at startup
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

Now, things might work for you out of the box. But with the wifi dongles I've used (TP-Link and Edimax), the default hostapd provided with Raspbian can't handle being an access point. We therefore need to update it:
wget http://adafruit-download.s3.amazonaws.com/adafruit_hostapd_14128.zip
unzip adafruit_hostapd_14128.zip
sudo mv /usr/sbin/hostapd /usr/sbin/hostapd.old
sudo mv hostapd /usr/sbin
sudo chmod 755 /usr/sbin/hostapd

Now let's test it:
sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf

Everything should be ok. You should see your wifi network appear from other devices (though don't try to connect to it yet, the DHCP daemon isn't running). To finalise, let's start the daemons:
sudo systemctl start hostapd
sudo systemctl start isc-dhcp-server

And enable the services:
sudo systemctl enable hostapd
sudo systemctl enable isc-dhcp-server 

Now, we can setup the outside wifi interface to connect to the house wifi network or another network (e.g. 3G mobile router as I did).

Back in /etc/network/interfaces, edit the wlan0 section:
sudo nano /etc/network/interfaces

Change the wlan0 section for this:
auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Now edit the wpa options:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

Input your wifi network's options (the following lines are just an example):
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
 ssid="Home"
 scan_ssid=1
 key_mgmt=NONE
 wep_key0=12345678901234567890123456
 wep_tx_keyidx=0
 priority=5
}

Now the Carpi should connect to the home wifi when in range.

The Carpi is ready to go network-wise.

Optional:
- Create a script that connects to the house's wifi to download the new files from the central sound file repository (especially useful for podcasts). Sheduled for phase 2.


No comments:

Post a Comment