Pi router with pihole - internet from wifi, routed to ethernet

Hi everyone,

I'm looking for some advice on how to achieve the above. I've trying to set this up for days and I still cannot managed. I've read good info here:

and here:

but just cannot make both work together.

BACKGROUND - SETUP

I get internet from my landlord wifi via dhcp. 192.168.1.1 gives me the connection.
I've got a mac mini connecting to this network, get a 192.168.1.X IP address on the wireless interface and then the macos internet sharing is doing the rest so I have full connectivity on the ethernet 192.168.2.1 form the mini which deal with dhcp and routing on 192.168.2.0/24. Also have an AP (192.168.2.2) giving my personal wifi access for phones/tablet access to internet and local NAS routing etc...

OBJECTIVE

I would like to replace the mac mini with the pi running pihole.

So right now I have:
landlord wifi - 192.168.1.0/24
mac mini - dhcp connect to wifi and share connection to 192.168.2.1

So as not to risk bugging off by landlord wifi while experimenting, let's run it where the pi connect to my AP on wifi, get a dhcp address in 192.168.2.X, and distribute connectivity on the eth interface (192.168.3.0/24). Anything coming from this should run through pihole.

Everything I tried so far is I either get the pihole hole working or the routing working (very usefulscript here : raspbian-recipes/wifi-to-eth-route.sh at master · arpitjindal97/raspbian-recipes · GitHub). Impossible to get both.

I've been resinstalling the pi a few times...

It should be simpler than above as I should not have to mess with hostapd, but still cannot make to work. Would anyone have an idea/advice on how to do this properly ?

This is what I'm looking to achieve with pihole on the raspberry:

  1. First of all you need Network manager since the basic raspbian does not have a really good manager to share connections.
  2. Install the necessary network manager
sudo apt install network-manager network-manager-gnome openvpn \
openvpn-systemd-resolved network-manager-openvpn \
network-manager-openvpn-gnome
  1. Remove unneeded packages
    sudo apt purge openresolv dhcpcd5
  2. Replace /etc/resolv.conf with a symlink to /lib/systemd/resolv.conf:
    (do not execute this command on Raspbian 10, it will break your DNS || you can check with cat /etc/os-release )
    sudo ln -sf /lib/systemd/resolv.conf /etc/resolv.conf
  3. Check policy:
    apt-cache policy dhcpcd5
    Create new file:
    sudo nano /etc/apt/preferences.d/dhcpcd5
    Containing:
Package: dhcpcd5
Pin: release *
Pin-Priority: -1

Run update:
sudo apt-get update
And check again:
apt-cache policy dhcpcd5

  1. sudo apt-get purge dhcpcd5

  2. reboot <- you should have NetworkManager (going forward to be called NM) taking over right next your clock.

  3. Run this and normally you can see that lighttpd and dnsmasq are there
    sudo netstat -nltup | grep 'Proto|:53 |:67 |:80 |:547 |:471[1-8] '

Go to your NM settings. Configure wifi normally as you would. Then go to your LAN settings, go straight to IPv4 settings and method -> Shared to other computers. In the address (optional) click on Add and put your local raspberry pi IP address (static). in your case, I would mimic the mac mini, so 192.168.2.1, 24 and leave for the time being the gateway free. Check if you can ping www.google.com

  1. Install pihole
    curl -sSL https://install.pi-hole.net | bash

  2. Remove the middleman called mac-mini. This is the tricky part. It will ask for your IP stuff. You pick eth0 (as your devices will connect there), and as IP: 192.168.2.1/24 but as a gateway, you need to put 192.168.1.1/24 (since it is your landloard's wifi the gateway part). I have disabled the logs since it is bad for the sd card. But I show everything. But that is up to you. Pihole should have finished installing so far.

  3. you go to 192.168.2.1/admin and settings -> dhcp server enabled -> 192.168.2.10 till 192.168.2.200 (your pick) and as a gateway again 192.168.1.1. You need to disable anything else for DHCP in your lan and let pihole deal with it.

  4. connect your pihole to your hub. Now if that were a router instead of a hub, then you need to connect the LAN to the router's LAN and let it behave without DHCP. Otherwise you need to create a new subnet because the router will think it needs a new subnet. Let me know if it s a hub or a router you connect it to. The hub does not deal with IPs networking. A router has a separate port for "Internet". You then need to ask all your devices to be using your pi as both a gateway and a DHCP server. :wink:

I can't think of anything else. Let us know how it works.

PS: You will upon reboot that pi-hole is not working, since dnsmasq is taking over instead of pihole-FTL. We are still trying to resolve this as you can see from the thread you replied :wink:

Thanks for your write up - but did you noticed you answered a question 11 months old? I hope the issue is still relevant and your effort was not in vain.

I am helping someone who still has the issue as per

:wink:

1 Like

Dont need to do all that.
Just hookup Pi with WiFi like you normaly do.
Enable IP-forwarding in the kernel.
And add persistent MASQUERADE rule with iptables.
IP-forwarding and masquerading can be nicked from below Raspi doc though its the other way around with devices on WiFi getting routed to ethernet:

And might want to setup a firewall to lock down the place.

So after further digging and off track search, I found that:

Combined with you help above, that should work quite well. Will try later and revert.

sudo apt-get update
sudo apt-get upgrade
sudo nano /etc/dhcpcd.conf

----
interface eth0
static ip_address=192.168.2.1/24
-----------
sudo nano /etc/sysctl.conf
sudo iptables -t nat -A POSTROUTING -o wlan0 -s 192.168.2.2 -j MASQUERADE
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
sudo nano /etc/rc.local
----
iptables-restore < /etc/iptables.ipv4.nat
sudo reboot
curl -sSL https://install.pi-hole.net | bash
sudo reboot

What is it happening with sudo nano /etc/sysctl.conf ? anyway, best of luck!

Your suppose to enable IP-forwarding like described in below link.
The "sudo nano /etc/sysctl.d/routed-ap.conf" part:

The link also describes how to make rules added/altered with iptables reboot persistent.
Better use/install netfilter-persistent and iptables-persistent, like described in above link, instead of using iptables-save & iptables-restore.

Right, it seems to be working but had to tinker quite a bit to find a way through, mainly because I took the long way round... I did not want to kill my working setup to got it to work first with extra hop from mini to pi to laptop, then took the mini out and reconfigure the wlan to replace the mini.

Starting from scratch this should look like that:

1 - install Raspberry OS
2 - Setup the wifi (unless it has been pre configured in wpa_supplicant.conf on the boot)

network={
    ssid="NETWORKNAME"
    psk="PASSWORD"
    priority=1

Check what IP you get and maybe use "Fing" mobile phone tool on the same network to figure out what would be a good Static IP to choose later, I used 100.

3 -

sudo apt-get update
sudo apt-get upgrade

4 - setup interfaces. (thanks - http://www.knight-of-pi.org/setup-simultanous-ethernet-and-wifi-access-for-the-raspberry-pi-3/)

sudo nano /etc/network/interfaces

Fill the file with the following:

auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet static
address X1.Y1.Z1.1
netmask 255.255.255.0

auto wlan0
allow-hotplug wlan0
iface wlan0 inet static
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
address X2.Y2.Z2.100
netmask 255.255.255.0
broadcast X2.Y2.Z2.255
gateway X2.Y2.Z2.1

iface default inet dhcp

X1.Y1.Z1 need to be the first three places of the ethernet connection IP and X2.Y2.Z2 the first three places of the wireless network IP.

5 - then setup port forwarding and NAT.

sudo iptables -F INPUT
sudo iptables -F OUTPUT
sudo iptables -F FORWARD
sudo iptables -t nat -F PREROUTING
sudo iptables -t nat -F INPUT
sudo iptables -t nat -F OUTPUT
sudo iptables -t nat -F POSTROUTING
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -A FORWARD -d X1.Y1.Z1.0/24 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -s X1.Y1.Z1.0/24 -i $eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
sudo iptables -t nat -P PREROUTING ACCEPT
sudo iptables -t nat -P INPUT ACCEPT
sudo iptables -t nat -P OUTPUT ACCEPT
sudo iptables -t nat -P POSTROUTING ACCEPT
sudo iptables -t nat -A POSTROUTING -s X1.Y1.Z1.0/24 ! -d X1.Y1.Z1.0/24 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
sudo nano /etc/rc.local
----
iptables-restore < /etc/iptables.ipv4.nat
----
sudo reboot

6 - install pihole
select wlan as pihole interface.

7 - once up and running use pihole as dhcp to allocate X1.Y1.Z1.0/24

Well, I think that's what I've done...

Edit:
Then NordVPN did not work on the Nvidia Shield. Thanks to https://www.reddit.com/r/nordvpn/comments/htznr5/pihole_blocking_android_app_launch/, I whitelisted launches.appsflyer.com, and all is good.

First, most Pi's have Raspbian installed.
Raspbian IP details are not stored in /etc/network/interfaces:

pi@ph5:~ $ cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

They should be stored/configured below:

pi@ph5:~ $ tail /etc/dhcpcd.conf
[..]
interface eth0
  static ip_address=10.0.0.4/24
  static routers=10.0.0.1
  static domain_name_servers=10.0.0.1

You should be able to configure everything WiFi related and assign static IP's with below tool for Raspbian:

sudo raspi-config

Second, your not suppose to port forward anything with iptables.
I think you've done too much.
You activate IP-forarding first by creating a new file like for example /etc/sysctl.d/ipforwarding.conf.
And put below in that file:

# Enable IPv4 routing
net.ipv4.ip_forward=1

Next you only have to add one single rule using iptables:

sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE

Make current kernel Netfilter rules reboot persistent:

sudo apt install -y netfilter-persistent iptables-persistent

sudo netfilter-persistent save

Reboot and test if the eth0 IP can be used as a GW/default route for your clients.
traceroute or Windows tracert will do.

For better understanding what above bits do, I direct you to that doc I posted previously:

Why did I try? The above broke it.

Essentially when I use dhcpcd it breaks down, pi even though connected to the wlan does not have access to internet.

Basically it seems that if both are connected it prefer to use eth0 than wlan0 but not smart enough (me for for
it figuring it out, not the pi) too realise that it should go the other way.

So all was working, and it's broken now. (Don't touch what works!!!).

Anyway, keen to set it up the right way so happy to learn here. Need to hurry and set up the Mac mini back up now.

Seems this should resolve the issue:
https://raspberrypi.stackexchange.com/questions/96287/how-to-prioritize-wifi-over-ethernet

I think your having issues with routes but not sure.
If connect two interfaces, you have to make sure the default route (gateway) is configured via the IP of the interface connected upstream to Internet (wlan0 in your case).

IP 10.0.0.1 residing on the network connected to eth0 in below example on my Pi:

pi@ph5:~ $ tail /etc/dhcpcd.conf
[..]
interface eth0
  static ip_address=10.0.0.4/24
  static routers=10.0.0.1
  static domain_name_servers=10.0.0.1

pi@ph5:~ $ ip -br -4 address show
lo               UNKNOWN        127.0.0.1/8
eth0             UP             10.0.0.4/24

pi@ph5:~ $ ip -4 route show
default via 10.0.0.1 dev eth0 src 10.0.0.4 metric 202
10.0.0.0/24 dev eth0 proto dhcp scope link src 10.0.0.4 metric 202

If have other default routes that lead to nowhere, it breaks as you say "the Internet".
You have to have a good understanding how network packets gets routed and under which conditions (metrics etc).
No one said its easy :wink:

EDIT: ow ps. above is only the IP part.
If DNS via Pi-hole isnt setup properly, it will also "break the Internet".
Thats why you need to test with traceroute -n 8.8.8.8 (or Windows tracert) first on a client before diagnosing DNS.

I used to say if everyone understands, I would be out of a job :wink:

Magical !!!!! it works...

So trying to summarise what I will do starting from scratch

1- Prepare a fresh raspbian SD card

2- Create the ssh blank file for remote connection on the boot drive

3- Create the wpa_supplicant.conf file on the boot drive. not mandatory but save time for later use of the pi. For example if in a hotel where you want to share the connection, just change the details in the sd card and you're good to go.

network={
    ssid="NETWORKNAME"
    psk="PASSWORD"
    priority=1

4- start you pi

5- ssh into you pi and run

sudo raspi-config

here you can finish a nice setup, I like to get vnc running so I get a nice desktop view remotely and run the command line directly from the pi. then you can kill ssh service if you want, up to you.

6- update the network config as follow:

sudo apt-get update
sudo apt-get upgrade
sudo nano /etc/dhcpcd.conf

at the end of the file, configure the eth0 interface as follow (change 192.168.10.x to what you which your local network to be):

interface eth0
static ip_address=192.168.10.1/24
static routers=192.168.10.1
static domain_name_servers=192.168.10.1
nogateway

The "nogateway" is important !!! if cable is connected to ethernet, dhcpd will favor that for internet and then you go nowhere.

7- enable nat for IPv4

sudo nano /etc/sysctl.conf

and un-comment the line

#net.ipv4.ip_forward=1

8- setup the forwarding from eth0 to wlan0

sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE

9- save the forwarding rules (haven't tried yet the persistent method)

sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
sudo nano /etc/rc.local
----
iptables-restore < /etc/iptables.ipv4.nat
----
sudo reboot

10- you should now have a working pi as a wifi to ethernet bridge router but no dhcp running.

11- install pihole selecting eth0 as pihole interface.

12- setup dhcp in pihole web-interface

I think that's it !

1 Like

Sweet.

pi@ph5:~ $ man dhcpcd.conf
[..]
     nogateway
             Don't install any default routes.

rc.local is a remnant from the depreciated system-v init system era (systemd or upstart used now by modern distro's).
Not sure for how long that will be supported.

Bridging is the opposite of routing.
Routing segregates two networks.
Bridging does the opposite and aggregates.

EDIT:

You might want to setup firewall to block dhcp requests coming from the wlan side (and other traffic initiated from wlan).
Try out UFW:

pi@ph5:~ $ apt show ufw
[..]
Description: program for managing a Netfilter firewall
 The Uncomplicated FireWall is a front-end for iptables, to make managing a
 Netfilter firewall easier. It provides a command line interface with syntax
 similar to OpenBSD's Packet Filter. It is particularly well-suited as a
 host-based firewall.

EDIT2: below ports need to be allowed on the eth0 interface (skip the IPv6 ones):

pi@noads:~ $ sudo netstat -nltup | grep 'Proto\|:22 \|:53 \|:67 \|:80 '
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      5279/lighttpd
tcp        0      0 0.0.0.0:53              0.0.0.0:*               LISTEN      966/pihole-FTL
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      481/sshd
tcp6       0      0 :::80                   :::*                    LISTEN      5279/lighttpd
tcp6       0      0 :::53                   :::*                    LISTEN      966/pihole-FTL
tcp6       0      0 :::22                   :::*                    LISTEN      481/sshd
udp        0      0 0.0.0.0:53              0.0.0.0:*                           966/pihole-FTL
udp        0      0 0.0.0.0:67              0.0.0.0:*                           966/pihole-FTL
udp6       0      0 :::53                   :::*                                966/pihole-FTL

Everything coming from wlan0 side (except established connections) should be dropped.

Further from the above, and thanks to this link, I guess the most standard basic setup for iptables before any additional security is implemented or any specific ports are opened, should be as follow:

#Basic Router setup

# Default policy to drop all incoming packets.
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP

# Accept incoming packets from localhost and the LAN (eth0) interface.
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -i eth0 -j ACCEPT

# Accept incoming packets from the WAN (wlan0) if the router (Pi) initiated the connection.
sudo iptables -A INPUT -i eth0 -m -m state --state RELATED,ESTABLISHED -j ACCEPT

# Forward LAN packets to the WAN.
sudo iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT

# Forward WAN packets to the LAN if the LAN initiated the connection.
sudo iptables -A FORWARD -i wlan0 -o eth0 -m conntrack -m state --state RELATED,ESTABLISHED -j ACCEPT

# NAT traffic going out the WAN interface.
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE

#Save rules so it works at next reboot (still to work with persistent method).
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
sudo nano /etc/rc.local
----
iptables-restore < /etc/iptables.ipv4.nat
----
sudo reboot