Using RaspberryPI as bridge between Eth0 and Wlan0

Recently in the office we had few troubles with our cable connection supplier. As a result we’ve signed a new contract with a wireless connection service provider… robust and efficent, when there’s enough signal. Since we cannot stay too much without internet connection we have setup a Raspberry PI to handle emergencies.

The idea is very basic but extremely efficent: the Raspberry PI (model 3) is connected to a portable 4g router (such this one) and is used to collect all the internet traffic from our LAN. This is pretty cool as we can use our whole LAN even in emergency cases.

First of all

To begin the process you have to download a Raspbian image from the Raspberrypi.org site (our is Raspbian Jessie Lite). Install it using the appropriate documentation and login with the pi user. The first thing we do is to enable ssh, as pi user type:

sudo raspi-config

and go throught Advanced->SSH to enable the ssh server. If you have an ethernet cable attached to your raspberry you can type

ifconfig

to know the raspberry ip address allocated by your DHCP server (you must have one, if not please configure the network!).

Annotate the ip address appropriately to run a ssh session from a remote machine. If everything works you can detach the pi from the screen.

Become root

I don’t like too much sudo… so i first become root:

sudo su

Enable packet forwarding

In the file /etc/sysctl.conf you can find net.ipv4.ip_forward directive. Please uncomment it if necessary and set it to 1. This should be like:

net.ipv4.ip_forward=1

Configure the network

Edit using vi (or nano or pico or whatever you are comfortable with) the /etc/network/interfaces file to match the following:

allow-hotplug eth0
iface eth0 inet static
  address 192.168.0.1
  netmask 255.255.255.0
  broadcast 192.168.0.255
allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Add the wifi username and password to /etc/wpa_supplicant/wpa_supplicant.conf by appending the following:

network={
  ssid="<your username>"
  psk="<your password>"
}

Customize the DHCP Client script to let your raspberry have assigned a static IP from the 3G router. Edit /etc/dhcpcd.conf and put these lines at the end:

interface wlan0
static ip_address=192.168.1.10/24
static routers=192.168.1.1

Configure the firewall

To configure the firewall you can start creating a script in pi’s home directory.

vi /home/pi/iptables.sh

Add the following lines:

#!/bin/sh
IPT=/sbin/iptables
LOCAL_IFACE=eth0
INET_IFACE=wlan0
INET_ADDRESS=192.168.1.10

# Flush the tables
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD

$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT

# Allow forwarding packets:
$IPT -A FORWARD -p ALL -i $LOCAL_IFACE -j ACCEPT
$IPT -A FORWARD -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT

# Packet masquerading
$IPT -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_ADDRESS

Enable the execution of the file and execute it:

chmod +x /home/pi/iptables.sh
/home/pi/iptables.sh

At this point you have to save the firewall’s contents to a text file:

iptables-save > /etc/network/iptables

Then create a pre-up script:

vi /etc/network/if-pre-up.d/iptables

and put this lines into it:

#!/bin/sh
iptables-restore < /etc/network/iptables

After you have to enable execution on the file:

chmod +x /etc/network/if-pre-up.d/iptables

Well, that’s done…. reboot and enjoy!

Recap

/etc/network/interfaces

source-directory /etc/network/interfaces.d
auto lo
iface lo inet loopback
allow-hotplug eth0
iface eth0 inet static
  address 192.168.0.1
  netmask 255.255.255.0
  broadcast 192.168.0.255
allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

/etc/dhcpcd.conf

# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel
# Inform the DHCP server of our hostname for DDNS.
hostname
# Use the hardware address of the interface for the Client ID. 
clientid
# or
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
#duid
# Persist interface configuration when dhcpcd exits.
persistent
# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit
# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Most distributions have NTP support.
option ntp_servers
# Respect the network MTU.
# Some interface drivers reset when changing the MTU so disabled by default.
#option interface_mtu
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# Generate Stable Private IPv6 Addresses instead of hardware based ones
slaac private
# A hook script is provided to lookup the hostname if not set by the DHCP
# server, but it should not be run by default.
nohook lookup-hostname
interface wlan0
static ip_address=192.168.1.10/24
static routers=192.168.1.1

Issuing ifconfig command should return:

eth0      Link encap:Ethernet  HWaddr b8:27:eb:f0:c1:bf
          inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::70f9:d593:874b:df8/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:254025 errors:0 dropped:102 overruns:0 frame:0
          TX packets:370535 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:25527867 (24.3 MiB)  TX bytes:451442667 (430.5 MiB)
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:65536  Metric:1
          RX packets:456 errors:0 dropped:0 overruns:0 frame:0
          TX packets:456 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:36968 (36.1 KiB)  TX bytes:36968 (36.1 KiB)
wlan0     Link encap:Ethernet  HWaddr b8:27:eb:a5:94:ea
          inet addr:192.168.1.10  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::b61d:874e:8b4c:2dfb/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:370991 errors:0 dropped:794 overruns:0 frame:0
          TX packets:252138 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:443230524 (422.6 MiB)  TX bytes:34625349 (33.0 MiB)

And route command:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.1.1     0.0.0.0         UG    303    0        0 wlan0
link-local      *               255.255.0.0     U     202    0        0 eth0
192.168.0.0     *               255.255.255.0   U     0      0        0 eth0
192.168.1.0     *               255.255.255.0   U     303    0        0 wlan0

My /etc/network/iptables

# Generated by iptables-save v1.4.21 on Thu Dec 29 09:56:48 2016
*nat
:PREROUTING ACCEPT [37:2637]
:INPUT ACCEPT [2:142]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o wlan0 -j SNAT --to-source 192.168.1.10
COMMIT
# Completed on Thu Dec 29 09:56:48 2016
# Generated by iptables-save v1.4.21 on Thu Dec 29 09:56:48 2016
*filter
:INPUT ACCEPT [103:7338]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [112:10296]
-A FORWARD -i eth0 -j ACCEPT
-A FORWARD -i wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Thu Dec 29 09:56:48 2016