I would suggest signing up for a free Cloudflare account and setting up any DNS for your Pi through there, using the Cache feature.
Once that is done, setup an automated script that will pull down Cloudflare IPs into a file:
#!/bin/bash
set -e
cf_ips() {
echo "# https://www.cloudflare.com/ips"
for type in v4 v6; do
echo "# IP$type"
curl -sL "https://www.cloudflare.com/ips-$type/" | sed "s|^|allow |g" | sed "s|\$|;|g"
echo
done
echo "# Generated at $(LC_ALL=C date)"
}
cf_ips > allow-cloudflare.conf
(cf_ips && echo "deny all; # deny all remaining ips") > allow-cloudflare-only.conf
Then in your web server config to only accept connections from Cloudflare IPs:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
root /var/www/html;
include /etc/nginx/allow-cloudflare-only.conf;
}
I prefer this method over UFW/iptables block as it allows you to control the IP block per web config, so if needed, you can make exceptions by not adding the include /etc/nginx/allow-cloudflare-only.conf; into that specific site's conf file.