Reverse Proxy w/ NGINX proxy manager

A few weeks ago I had received my Raspberry Pi. I purchased the Pi to run some services here at the house. My motivation for this was from a reddit post showing off its dashboard using homer, a docker container. I have not touched docker yet outside of some vulnerable containers for pen-testing (Web Goat/DVWA), so I figured this could also be used to get myself more familiar. Although I have not hosted many services yet (still in the planning stages), I found it rather annoying typing in <ip_address>:port every time. The Homer dashboard makes it a little bit easier

as all I have to do is click on one of the menu options and it will take me there. Still thought it would be best to use a domain name rather then an ip address. So with this thought in mind I did some research and set out to learn NGINX. NGINX is a open source HTTP/Server and reverse proxy. Also has options for IMAP/POP3. To my understanding NGINX is used in the industry quite often especially when exposing services to the internet. This is because instead of exposing every port to th einternet, only one port will need to be exposed. This open port will be a direct lane to the reverse proxy. From there it will then take in the domain name and decide which way to route the transmission.

I first started with NGINX as a docker container, I did run into some problems (which I cant recall what it was) so I then decided to run it locally on the pi. Really all that is needed after installing NGINX is to head over to /etc/nginx directory. From there you will see a sites-available directory. Within sites-available you will create a directory such as pihole.local.com. Inside that file you would create what is called a “Server block”. This server block would describe the connection. Then you would link this new directory to the sites-enabled directory. Then you can run nginx -t to verify syntax and then restart server. I may have missed out a few things as it is a quick description of the overall process but that is for another day.

It seemed a little advanced at first but with some tutorials online I was up and going in no time. Although my configuration was bare bones and was not ready for a production environment it got what I needed. Then I did some reading and found some mentions of a NGINX proxy manager. I believe the GUI is what sold me on giving it a shot but I am happy I did! I thought to myself, maybe this would help me get a better grasp on the basics especially when I start introducing SSL certificates then later on I can transition back to the NGINX server itself and have a better foundation to work off of.

To get started we need two things, Docker and Docker-Compose.

A good reference to install docker is from the website itself. Found here. With the ubuntu server I was running I had a hard time installing docker and instead had to add a bionic repository and it worked flawlessly. This would probably not fly in a production environment but this was a work around I found to work and it fits the needs of my lab.

deb-src [arch=amd64] https://download.docker.com/linux/ubuntu/ bionic stable

I was then able to run apt-get install docker-ce docker-ce-cli containerd.io

After installing docker you can run a simple command to make sure it was installed properly.
sudo docker run hello-world

Next all we need to do is get docker-compose installed.

 sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Lastly we will just need to ensure that the binary for docker-compose is executable. We can do this with chmod command

 sudo chmod +x /usr/local/bin/docker-compose

Once we have docker-compose installed we can then create the config file or .yml for our NGINX proxy manager. This config is provided by the developer allowing for the latest install.

version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

After saving this file using nano (any directory you prefer) or vim whichever you prefer, you will run
docker-compose up -d

Be sure before running the docker-compose command that you are in the same directory as the .yml file. Thats it! We are now running a NGINX proxy manager container using docker-compose hosted on port 81 of our local host. Ports 80 and 443 are listening for incoming requests.

In order to manage our proxy manager we will head over to port 81.

http://127.0.0.1:81 on our local machine, or if we are on a different machine on our network we will use the ip address of the hosting machine. The default credentials will be:

Email:    [email protected]
Password: changeme

Now that we are logged in we will create a reverse proxy to direct us to a specified port based on the domain or subdomain entered. We are going to focus on a closed environment with no connection to any other DNS server other then our own. In another discussion we will go over how to host this on the WAN instead of the LAN.

For my lab I am using Pi Hole as my DNS server. Pi Hole allows me to create local DNS records.

On the left-side menu you will click on Local DNS > DNS Records.

Next you will create a domain name, for example homer.local along with the IP address of NGINX server we just configured. This is important. You must make sure you are pointing to the server running NGINX Proxy Manager, otherwise it will not work. For instance if you are running a docker container on a computer with IP address 10.10.10.1 and you wanted homer.local to connect, you will use 10.10.10.77 because that is your NGINX manager.

Next we will want to head over to NGINX proxy manager and click on Proxy Hosts. Followed by Add Proxy Host at the top right corner.

Fairly straight forward from here, no SSL today just a basic reverse proxy.
Domain name: the name we set on our local DNS server homer.local
Scheme: Varies based on what the service running requires
Forward Hostname/IP: the ip address of machine we are looking to forward to
Forward Port: The port we are looking to forward to

From here we can just click save and then we are good to go. This is not a DNS tutorial but because we talked about it I will add one last thing to make sure you are not missing anything. We need to ensure the computer we are on is using the Raspberry Pi as our local DNS server. Otherwise it will be automatically given a DNS server from router and will not be able to see our local DNS records. Later we can change this in our router to push to the entire network but that is for another day as well.

You want to make sure you select the option of “Use the following DNS server addresses”. The 192.168.1.16 is a local IP address on my network hosting Pi Hole. With this configuration we will then be able to navigate to http://homer.local and be redirected to the ip/port we specified in NGINX.

I understand most of this instructional discussion was based on other references. I would rather provide my own input on how to do it but in this particular case I felt it was best to reference the websites and add input where I saw fit. It was a lot of fun. I am looking to grow my home lab with more services eventually having a wildcard *.ssl certificate throughout my entire lab and even hosting some of it over the internet for me to access anywhere. Well that is it for today, I hope someone can take something away from this. As always, Never Stop Learning!