This is the iptables configuration I have used to secure my pihole instance before exposing it publicly.

This configuration will close all ports, then allow connections on port 80, 443, 123 and allow ping to IP 192.168.0.103 which is hosting my pihole. Allow access to port 53 from your local network. Then it will open port 53 only to IP 46.249.76.212 (you can allow multiple IPs by cloning the 4 lines from the configuration for IP 46.249.76.212 )

First we need to create a file that will hold our iptables rules.
I have chosen to name this file iptables.up.rules and create it in /etc folder. You can pick any name and location you like, just remember to use them in the auto start bash script we’ll create at the end of this tutorial.

Run the command below to list the current iptables rules:

$ sudo iptables --list

Then run this command to save the current rules in a file that we’ll modify in the next step:

$ sudo iptables-save > iptables.up.rules
$ sudo mv iptables.up.rules /etc/iptables.up.rules

Use your favorite text editor to open the file we just created /etc/iptables.up.rules it should look like the one below:

# Generated by iptables-save v1.6.0 on Thu Dec 28 12:35:47 2017
*filter
:INPUT ACCEPT [3153:549434]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [2890:317837]
COMMIT

Replace the COMMIT command with the text below:

# Don't forward traffic
-P FORWARD DROP

# Allow outgoing traffic
-P OUTPUT ACCEPT

# Allow established traffic
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow localhost traffic
-A INPUT -i lo -j ACCEPT

#############################
#  MANAGEMENT RULES
#############################
# Allow SSH (alternate port)
-A INPUT -p tcp --dport 22 -j ACCEPT

#############################
#  ACCESS RULES
#############################
# Allow web server
-A INPUT -p udp --dport 80 -j ACCEPT 
-A OUTPUT -p udp --sport 80 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT 
-A OUTPUT -p tcp --sport 80 -j ACCEPT

-A INPUT -p tcp --dport 443 -j ACCEPT 
-A OUTPUT -p tcp --sport 443 -j ACCEPT
-A INPUT -p udp --dport 443 -j ACCEPT 
-A OUTPUT -p udp --sport 443 -j ACCEPT

# Allow ping to 192.168.0.103
-A INPUT -p icmp --icmp-type 8 -s 0/0 -d 192.168.0.103 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -p icmp --icmp-type 0 -s 192.168.0.103 -d 0/0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow DNS

# for 46.249.76.212

-A OUTPUT -p udp -o eth0 -d 46.249.76.212 --sport 53 -j ACCEPT
-A OUTPUT -p udp -o eth0 -d 46.249.76.212 --dport 53 -j ACCEPT
-A INPUT -p udp -i eth0 -s 46.249.76.212 --sport 53 -j ACCEPT
-A INPUT -p udp -i eth0 -s 46.249.76.212 --dport 53 -j ACCEPT

# home - this section allows access to and from your internal network
-A OUTPUT -p udp -o eth0 -m iprange --dst-range 192.168.0.1-192.168.0.254 --sport 53 -j ACCEPT
-A OUTPUT -p udp -o eth0 -m iprange --dst-range 192.168.0.1-192.168.0.254 --dport 53 -j ACCEPT
-A INPUT -p udp -i eth0 -m iprange --src-range 192.168.0.1-192.168.0.254 --sport 53 -j ACCEPT
-A INPUT -p udp -i eth0 -m iprange --src-range 192.168.0.1-192.168.0.254 --dport 53 -j ACCEPT

# Allow NTP Assuming you are a CLIENT and want to access NTP servers you'd do:
-A OUTPUT -p udp --dport 123 -j ACCEPT 
-A INPUT -p udp --sport 123 -j ACCEPT

# Assuming you want to be a server, you'd do
-A INPUT -p udp --dport 123 -j ACCEPT 
-A OUTPUT -p udp --sport 123 -j ACCEPT

#############################
#  DEFAULT DENY
#############################
-A INPUT -j DROP
COMMIT

Run this command to apply the new rules and check if they are working as expected:

sudo /sbin/iptables-restore < /etc/iptables.up.rules

If there are no errors and you are not disconnected from the system we should be all set.

Now we need to make sure the iptables rules are loaded after the system is restarted.

To do so go to /etc/network/if-pre-up.d/ and create a file named iptables, this is a bash file that will be executed before each network connection, the content of this file should be as below:

#!/bin/sh
sudo /sbin/iptables-restore < /etc/iptables.up.rules

You’ll also need to make sure that the file iptables have executable permissions:

sudo chmod +x iptables

Everything should be configured now, restart your system to make sure the rules are loaded properly.