4/1/2020 - Small update: Can you drop a line to let us know what brought you here? This has been pretty popular and we would like to know how you found us. Drop a quick email to firstname.lastname@example.org if you're up to it, thanks!
Here's a Scenario: Your regular internet is broken. You don't want to reconfigure all your devices connect to your smartphone Wi-Fi hotspot, but you want all internet traffic to go through a HotSpot. In this guide, I'll show you how using a Raspberry Pi that can take your smartphone Wi-Fi or any other hotspot and convert it into an Ethernet link.
Say this is your home network:
1. How the System Will Work
If you saw my post about Silverpeak SD-WAN, you'll recognize my network map with my RaspiJails (which we are going to recreate in the guide).
After completing this guide, your Raspberry Pi will perform the following:
On boot up the Raspberry Pi will automatically login to an existing WiFi Access Point as a client.
The Raspberry Pi will then acquire a IP address via DHCP across the WiFi (wlan0) interface.
A stateful firewall (iptables) will be enabled to allow traffic from inside (eth0) to outside (wlan0) and to deny outside (wlan0) to inside (eth0).
Nat rules will be created so that any traffic routed to the Ethernet interface will be forwarded out the WiFi interface and hidden behind the IP that was assigned via step 2.
IP forwarding will be enabled. This will allow packets to route between interfaces like a router.
A DHCP server will be started on the Ethernet interface advertising IP, subnet mask, default route, DNS. (While this isn't needed it does make configuration of Ethernet connected devices easier. You can always not use DHCP and skip that section if you want.)
At the end of this guide your Raspberry Pi will share the WiFi connection that is connected via wlan0 with any devices connected via Ethernet to the PI.
2. Overview of Configuration Files
In this section, I'll be describing all the config files that are going to be modified and their purpose. NOTE: This guide assumes your Raspberry Pi is running Raspbian version 10.
/etc/rc.local - This is an existing file. The contents of this file will hold our firewall rules, nat and ip forwarding configurations. It will also be where the DHCP Server will be started for the Ethernet network.
/etc/udhcpd.conf - This file needs to be created. This file is the configuration file for the DHCP server that will run on the Raspberry Pi. NOTE: This is the DHCP "server" and not the DHCP "client" (for WiFi). This is how IP addresses will be offered via the Ethernet interface of the P.
/etc/dhcpcd.conf - This file is an existing configuration file. We will be editing this file to set a static IP on the Ethernet interface. This seems like a strange place but this is the correct way.
/bin/udhcpd - This is technically not a configuration file and does not exist by default. You need to create a symbolic link from /bin/busybox to /bin/udhcpd to enable the busybox to act as udhcpd. This symbolic link only needs to be created once.
/etc/wpa_supplicant/wpa_supplicant.conf - This is a file that needs to be created, but can be done using the Raspbian configuration program - raspi-config.
3. The Actual Configuration Files
In this section I will show the configurations to add or files to create in detail.
1. /etc/rc.local - Add the following to the end of /etc/rc.local but above the "exit 0" line, which needs to remain.
# delete all existing rules.
iptables -t nat -F
iptables -t mangle -F
# Always accept loopback traffic
iptables -A INPUT -i lo -j ACCEPT
# Allow established connections, and those not coming from the outside
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -i eth0 -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow outgoing connections from the LAN side.
iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
# Masquerade / Hide Nat / PAT / whatever you want to call it.
# Note these should each be one line starting with the word
iptables -t nat -A POSTROUTING -o wlan0 -p UDP -j MASQUERADE --to-ports 32000-50000
iptables -t nat -A POSTROUTING -o wlan0 -p TCP -j MASQUERADE --to-ports 32000-50000
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
# Don't forward from the outside to the inside
iptables -A FORWARD -i wlan0 -o wlan0 -j REJECT
# Enable routing.
echo 1 > /proc/sys/net/ipv4/ip_forward
# Enable DHCP server.
/bin/udhcpd -S /etc/udhcpd.conf
# required to say script completed without issue
# there should only be one exit 0 and it should be the last line.
2. /etc/udhcpd.conf - This assumes a configured subnet of 192.168.100.0/24, offering addresses .50 - .254, default route to .1, dns to 220.127.116.11 and a lease time of 1 hour. This is also a full configuration example.
opt dns 18.104.22.168
option subnet 255.255.255.0
opt router 192.168.100.1
option domain spikefishsolutions.local
option lease 3600
3. /etc/dhcpcd.conf - I will show the lines that need to be un-commented to set a static IP address to the Ethernet interface. This must be the same IP as the "router" line from udhcpd.conf listed above. Notice "interface" and "static" are not commented out.
# Example static IP configuration:
#static domain_name_servers=192.168.0.1 22.214.171.124 fd51:42f8:caae:d92e::1
4. /bin/udhcpd - This is a symbolic link that needs to be created. NOTE: You only have to add it once because there can only be one, so there is no need to add to rc.local. Here I create the symbolic link, show the link then show the file the link is pointing to. You should see the exact same output save prompt/date/time. This is black magic brought to you by busybox.
root@RaspJail100# ln -s /bin/busybox /bin/udhcpd
root@RaspJail100# ls -l /bin/udhcpd
lrwxrwxrwx 1 root root 12 Mar 25 20:34 /bin/udhcpd -> /bin/busybox
root@RaspJail100# ls -l /bin/busybox
-rwxr-xr-x 1 root root 743212 Apr 1 2019 /bin/busybox
5. /etc/wpa_supplicant/wpa_supplicant.conf - This is the configuration file that tells the WiFi interface (wlan0) which Access Point (SSID) to join and what the WPA password is. In this example the Pi is joining an Access Point called "Highlander 2 electric booagloo".
NOTE: the client code doesn't seem to deal with special characters in the SSID very well. For example iPhones by default have a special ' that is in the name by default. There is a way around this but its easiest if you just remove the ' from the name of the phone. So ...
or something like that.
Here is a full example wpa_supplicant.conf. This shows the name of the AP, the password, and also sets the country value, which also controls the WiFi frequencies that can be used. We're using the US version. (This can also be configured using the raspi-config command.)
ssid="Highlander 2 electric boogaloo"
Pro Tip: if you are unsure which SSIDs are being broadcasted, you can run this command to see a list of SSIDs. The output will be one line showing the SSID per SSID found.
iwlist wlan0 scanning | egrep 'ESSID:' | less
4. That's a wrap!
You should have a Pi that is ready to do WiFi routing now. Your home network would look like this for example.
For any question or concerns about setting up Linux, Raspberry Pi's, Silver Peak, or any other networking questions, please reach out to us at email@example.com. We’d be happy to answer any questions or concerns you may have.