Welcome to all from a Nginx proxied web-server!
I've been using Cloudflare Tunnel since the day I started hosting stuff on my own server and it's been great since then. But the problem was Cloudflare Tunnel was proxying the traffic over servers that's far away from the server and since they had access to my https certs for validating the traffic, it was a privacy concern for me and people visits the webpages I host.
Before doing that I didn't had any idea about how reverse proxies worked or even a setup like mine was even possible or not. And at that point I started to do some research. I read tons of articles about that and in the end I asked to the GPT-4 about how Nginx reverse proxies works in a detailed way and here is the answers he gaved to me:
- Can you explain me how reverse proxies like Cloudflare Tunnel and Nginx works?(gpt.cybah.me)
- Can you explain me how Nginx reverse proxies works in a detailed way with some reverse proxy setup config examples (gpt.cybah.me)
After reading those answers and doing more research I decided to try out Nginx setup. Here is how I did that.
Getting VPS ready
Before starting out, I needed to get some stuff ready for it on my VPS including some security imrpovements and server monitoring software. I installed Cockpit for monitoring the network activity and Uptime Kuma for monitoring the connection to my sites. After that I added an DNS A record for v.thebatuhansnetwork.xyz subdomain.
Configuring Nginx
I installed Nginx with the command below
sudo dnf install nginx
After that I created a config file named reverse.conf
under the /etc/nginx/conf.d/
with the example config that ChatGPT gave me.
server {
listen 80;
server_name domain1.com;
location / {
proxy_pass http://backend1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
}
}
server {
listen 80;
server_name domain2.com;
location / {
proxy_pass http://backend2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
}
}
# Define backend servers
upstream backend1 {
server backend1_ip:backend1_port;
}
upstream backend2 {
server backend2_ip:backend2_port;
}
In this example config file, we have 2 different services that runs on the same port which is 80. At this point the thing that seperates our services is the server_name
which is the domain we're connecting from. How it's gonna work you may ask and it's actually very simple.
Remember the time we routed the v subdomain to our VPS, it's becouse we're gonna use CNAME records for our subdomains and we'll route them to our VPS and rest of the magic will happen on our server. With CNAME records our server can see which hostname our connection is coming from and route that connection to the right source.
![/images/Screenshot-2023-12-28-at-22.45.45.png]
As you can see from the image above. It's really that simple. Now after understanding how this works. We can change the example config for our needs and now it should look like this:
server {
listen 80;
server_name server1_domain;
location / {
proxy_pass http://backend1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name server2_domain;
location ~ {
proxy_pass http://backend2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# Define backend servers
upstream backend1 {
server server1_ip:server1_port
}
upstream backend2 {
server server2_ip:server2_port
}
After saving our config we can start our Nginx server using Systemd.
sudo systemctl enable --now nginx.service
Now you should be able to visit your websites over Nginx. But the problem is it's only possible over the unsecure http connection becouse we don't have our certificates yet.
Activating Https connections
What we're gonna use for generating our certificates is Certbot.
Certbot is a free and open source program that generates public SSL certificates using Let's encrypt and renews them when needed. Unlike Cloudflare those generated certs are being stored in our own server.
Installing Certbot
To install Certbot on Almalinux use the command
sudo dnf install certbot python3-certbot-nginx
and after installing Certbot we can generate our certificates easly using the command
sudo certbot certonly --nginx -d server1_domain -d server2_domain
and after that go to your reverse.conf
file and add your certificates and redirects for http connections.
server {
listen 80;
server_name server1_domain;
return 301 https://$host$request_uri; # Redirecting http connection to https.
}
server {
listen 443 ssl;
server_name server1_domain;
ssl_certificate /etc/letsencrypt/live/server1_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/server1_domain/privkey.pem;
location / {
proxy_pass http://backend1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name server2_domain;
return 301 https://$host$request_uri; # Redirecting http connection to https.
}
server {
listen 443 ssl;
server_name server2_domain;
ssl_certificate /etc/letsencrypt/live/server2_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/server2_domain/privkey.pem;
location ~ {
proxy_pass http://backend2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# Define backend servers
upstream backend1 {
server server1_ip:server1_port
}
upstream backend2 {
server server2_ip:server2_port
}
After that restart your Nginx server using the command
sudo systemctl restart nginx.service
and we're done!
On my case switching from Cloudflare Tunnel has improved the connection speeds and latency. According to Uptime Kuma, the connections to this site had an avarage of 600ms ping before that but now it has an avarage of 250ms. Which is an %50 improvement!
Thanks for reading! If you encounter a problem with your setup, you can always come to our Discord Server and ask for help or reach me via E-mail from end of this post. See you in the next time!
Reply via E-Mail
Thank You!
Batuhan Yılmaz - 30.12.2023 - 37/100