In this tutorial, we will be discussing how we can leverage the power of Nginx to create a reverse proxy for our PostgreSQL server. This will allow us to access our PostgreSQL database from remote servers. So for example, let’s say you have an app hosted in a vps and you would like to access the app db from your local computer. Then if you setup the nginx reverse proxy on your vps server, you will be able to connect to postgres db directly from your local computer’s Pgadmin4 app by using your vps ip address and port!

Why Nginx?

Nginx will act as an intermediary service to process the client requests. It is also known for better performance since it uses an event-driven architecture to deal with the client requests asynchronously. Nginx can parse and analyze website URLs fast and serve static content. An Nginx reverse proxy also acts as a line of defense for our PostgreSQL server. Configuring a reverse proxy ensures that the identity of our PostgreSQL server remains unknown, so the PostgreSQL server will be safe from port-scanning and enumeration attacks.

How?

You can follow the step by step guide below on how to install the necessary dependencies and get up and running. We are assuming you already have postgresql installed, if you don’t have it. You can easily install it

Install Nginx

Run the following commands to install nginx in ubuntu:

apt update
apt install nginx

For other distro or operating system, please see the nginx installation documentation.

By default, nginx will create a record in the sites-enabled for a virtual host. We can safely unlink it:

unlink /etc/nginx/sites-enabled/default

Add Nginx Server Configuration

Now, let’s update the nginx configuration. First we will create a new folder webapp in the sites-available folder of nginx. Inside this folder we will keep the server config in a file named: db. Of course, you can name them the way you want. So go ahead open up your text editor e.g. vim, nano, emacs, etc. and create the file. In my case, I’m going to use vim:

vim /etc/nginx/sites-available/webapp/db

in the db file, we will write the following server block:

server {
        listen   5431 so_keepalive=on;
        
        allow <ip_address>;
        deny all;
	
        proxy_connect_timeout 60s;
        proxy_socket_keepalive on;
	    proxy_pass localhost:5432;
}

Notice, we told nginx to listen to port 5431. using the allow we can tell nginx, only the ip address mentioned in the configuration can use the reverse proxy to connect & communicate with our postgresql server. So, if you want to connect from your local computer you can put your own ip address here: allow <your_ip_address>; You can allow multiple ip addresses as well using multiple allow

We also tell nginx to deny all. This makes sure, Nginx will deny all the requests coming from any other ip addresses.
Later, we set a timeout of 60s and finally pass/forward the request to postgresql server hosted in the localhost port 5432. Depending on your installation you may have to change these address to match yours. Once, the config file is created we can link it to sites-enabled by using symbolic link:

ln -s /etc/nginx/sites-available/webapp/db /etc/nginx/sites-enabled/webapp/db

Update nginx.conf

Now, we will have to edit the nginx.conf file. So, open the nginx.conf file in a text editor:

vim /etc/nginx/nginx.conf 

Append the following block of code in the existing nginx.conf

stream {
       access_log  /var/log/nginx/db.access.log;
       error_log  /var/log/nginx/db.error.log;
       include /etc/nginx/sites-enabled/webapp/db;
}

The above stream block tells nginx to include the server block from the mentioned file: /etc/nginx/sites-enabled/webapp/db TCP is the default protocol for the stream context, so we don’t have to mention it.

Test & reload Nginx

Now, we will test the nginx configuration file using the command:

nginx -t

If we don’t get any error and the configuration files are ok. Then we can reload nginx to start serving:

service nginx reload

That’s it! Now, you should be able to access the postgres database from the ip address mentioned in the nginx configuration. If it doesn’t work, make sure you have the 5431 port open (Our nginx server was configured to listen for the tcp network requests in the port 5431)

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.