I can tell you how to turn a rasperry pi into a router as I've done it so many times I could probably write the following scripts in my sleep. I'll leave integrating them with pi-hole to you (I run pi-hole on a Beagle Bone Black under arch-linux so I can't really do that for you as it's a different environment).
A couple of things:
- Yes I said router, not access point. These steps will make rpi a router and the ethernet port will be the uplink port, and as I'm guessing you're connecting it to a network that's already behind a router, anything that connects to rpi's wifi will be double nat-ed. This means upnp won't work, and machines on ethernet side won't be able to initiate connections to those on wifi side. To make rpi behave like a pure access point (where wifi clients are on the same network that's connected to ethernet port) it means you have to bridge wifi and ethernet interfaces (I tried it once, it was a pain and much more flaky than making rpi a router).
- I've always done this using dnsmasq as a DHCP and DNS server. You can probably emulate the behaviour of my dnsmasq config with the pi-hole GUI by turning on dhcp server but you are going to have to set it to bind to wifi interface and that might mean it stops serving the ethernet side as a DNS server.
Ok first thing you want to do is make wifi totally manual, in newer versions of raspbian you this by editing /etc/dhcpcd.conf and adding:
allowinterfaces eth0
Which means only eth0 will be automatically managed, you can also use:
denyinterfaces wlan0
To just keep it away from wlan0.
Now you need to allow ipv4 forwarding so the thing can act as a router, etc /etc/sysctl.conf and add/uncomment the following line:
net.ipv4.ip_forward=1
Reboot the thing so this and the change to dhcpcd.conf can take effect. Now give wifi a static ip that's a private IP but not in your existing network's subnet:
sudo ifconfig wlan0 10.20.30.1 netmask 255.255.255.0
Next step is to use hostapd with wlan0 - save this into a config file called hostapd.conf (or whatever):
interface=wlan0
driver=nl80211
hw_mode=g
channel=6
ssid=MyAwfulWifi
wpa=1
wpa_passphrase=bestpassword
wpa_key_mgmt=WPA-PSK
Use config by running it with
sudo hostapd -B hostapd.conf
You should be able to connect to it but it won't be handing out IP's yet. At this point you'll probably want to muck around with pi-hole settings to see if you can get it to the point it hands out IP's to wifi clients, when you do set interface to wlan0 and router IP address to the IP you gave rpi wifi interface (eg: 10.20.30.1).
Here's a dnsmasq.conf file that I know works for this if you end up having to add some lines to /etc/dnsmasq.conf yourself:
interface=wlan0
bind-interfaces
except-interface=lo
listen-address=10.20.30.1
dhcp-range=10.20.30.10,10.20.30.100,60m
dhcp-option=option:router,10.20.30.1
dhcp-lease-max=50
Ok it's now accepting connections, giving IP's and acting as a DNS server but you can't actually connect to anything on the router side. Here's some iptables rules to get that happening:
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 10.20.30.0/24 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -s 10.20.30.0/24 -i wlan0 -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o wlan0 -j ACCEPT
sudo iptables -A FORWARD -o wlan0 -j REJECT --reject-with icmp-port-unreachable
sudo iptables -A FORWARD -i wlan0 -j REJECT --reject-with icmp-port-unreachable
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 10.20.30.0/24 ! -d 10.20.30.0/24 -j MASQUERADE
Fingers crossed but that should be it. You'll want to put ifconfig, hostapd and iptables commands into a script and have them load on startup (eg: from rc.local).