Using nginx/pi-hole to reverse proxy (the dodgy way)

Hi All,

I wanted a nice way to stop remembering ports, and having the Pi-Hole rockon + the native Nginx server seemed like a reasonable way to do it.

The scripts are configured to run all services as hosts under a non-existant gTLD ‘.home’. Other configurations should be fairly self-explanatory.

The following method will factor in Rockstor potentially updating the nginx config, and ensure pi-hole is running before making changes.

/etc/crontab

* * * * * root /root/scripts/nginx-proxy.sh
* * * * * root /root/scripts/pi-hole-update.sh

/root/scripts/nginx-proxy.sh

#!/usr/bin/bash

# Check for inclide directory in rockstor nginx config
grep -q conf.d /opt/rockstor/etc/nginx/nginx.conf || {
    # Add config in place, create backup nginx.conf.bak
    perl -plni.bak -e 'print "\tinclude\t\t/root/conf.d/\*;\n" if(/\s+server \{/)' /opt/rockstor/etc/nginx/nginx.conf;

    # Restart the service
    systemctl restart rockstor.service || {
        # Failed! Retrieve backup and restart again
        mv /opt/rockstor/etc/nginx/nginx.conf.bak /opt/rockstor/etc/nginx.conf;
        systemctl restart rockstor.service;
    }
}

/root/scripts/pi-hole-update.sh

#!/usr/bin/bash

# Create an associative array of host entries
mainIP='192.168.0.7'

declare -A aa hosts
hosts=(
    [tv]=$mainIP
    [pihole]=$mainIP
    [sonarr]=$mainIP
    [nzbget]=$mainIP
    [torrent]=$mainIP
    [couchpotato]=$mainIP
)

# Ensure pi-hole rockon is running
docker container ls | grep -q pi-hole-diginc || { echo "Failed to identify running Pi-Hole rockon instance"; exit 1; }

changes=0
for host in "${!hosts[@]}"; do
    # Check for host entry in docker's hosts file
    { docker container exec pi-hole-diginc grep -q "${host}\.home" /etc/hosts; } || {
        # If missing, add it and log the change
        docker container exec pi-hole-diginc bash -c "echo -e \"${hosts[$host]}\t${host}.home\" >> /etc/hosts";
        changes=$(($changes + 1));
    }
done

# If changes were made, restart dnsmasq to reload config.
[ "$changes" -lt "1" ] || docker container exec pi-hole-diginc service dnsmasq restart

/root/conf.d/custom.conf

# Couchpotato
server {
    listen 80;
    server_name couchpotato.home cp.home;
    location / {
        proxy_pass http://localhost:5050;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# Sonarr
server {
    listen 80;
    server_name sonarr.home;
    location / {
        proxy_pass http://localhost:8989;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# NZBGet
server {
    listen 80;
    server_name nzbget.home dl.home;
    location / {
        proxy_pass http://localhost:6789;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# Transmission
server {
    listen 80;
    server_name torrent.home;
    location / {
        proxy_pass http://localhost:9091;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# Pi-Hole
server {
    listen 80;
    server_name pi.hole;
    location / {
        proxy_pass http://localhost:83/admin/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
# Plex
upstream plex-upstream {
    server localhost:32400;
}

server {
    listen 80;
    server_name tv.home;
    location / {
        if ($http_x_plex_device_name = '') {
            rewrite ^/$ http://$http_host/web/index.html;
        }

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;

        proxy_set_header Host $http_host;

        proxy_pass http://plex-upstream;
    }
}

Comments/constructive criticism welcome. :slight_smile:

This is less dodgy than my way, where I just disable port 80 in Rockstor’s nginx config, and spin up a second instance using the OS default config and on a different interface. I did that to make sure that the settings I wanted for websites and the settings Rockstor wants/needs never bite. Also, I’m running on hardware with two Ethernet ports (three, counting the dedicated ILO one), so using separate interfaces makes sense.