Skip to content

Linux Exercise 11 - Nginx Reverse Proxy

Lab: Reverse Proxy, Load Balancing & API Gateway Features with Nginx

Section titled “Lab: Reverse Proxy, Load Balancing & API Gateway Features with Nginx”

You will configure Nginx to:

  • Act as a reverse proxy
  • Load balance across two backend servers
  • Apply API gateway features:
    • Rate limiting
    • User-agent filtering
    • HTTP method restrictions
    • Security headers

Every step must be documented in your protocol.


  • Ubuntu Server VM
  • Nginx installed
  • Python 3 installed (for backend servers)
  • Host machine configured with hosts entries like:
    <VM_IP> loadbalance.local

Terminal window
mkdir -p ~/backend1
cd ~/backend1
cat > server.py << 'EOF'
from http.server import BaseHTTPRequestHandler, HTTPServer
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
self.wfile.write(b'{"backend":"1"}')
HTTPServer(("0.0.0.0", 8001), Handler).serve_forever()
EOF
python3 server.py
Terminal window
mkdir -p ~/backend2
cd ~/backend2
cat > server.py << 'EOF'
from http.server import BaseHTTPRequestHandler, HTTPServer
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
self.wfile.write(b'{"backend":"2"}')
HTTPServer(("0.0.0.0", 8002), Handler).serve_forever()
EOF
python3 server.py

4. Step 2 – Configure Nginx Load Balancer

Section titled “4. Step 2 – Configure Nginx Load Balancer”
Terminal window
sudo nano /etc/nginx/sites-available/loadbalance.local

Insert:

upstream backend_pool {
server 127.0.0.1:8001;
server 127.0.0.1:8002;
}
server {
listen 80;
server_name loadbalance.local;
location / {
proxy_pass http://backend_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Enable:

Terminal window
sudo ln -s /etc/nginx/sites-available/loadbalance.local /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Test:

Terminal window
curl http://loadbalance.local/

Repeated calls should alternate between backend 1 and 2.


Add to Nginx config:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
...
location / {
limit_req zone=mylimit burst=3;
proxy_pass http://backend_pool;
}
}

Test with:

Terminal window
for i in {1..10}; do curl -I http://loadbalance.local/; done

Some requests should return 503.


Add inside server block:

if ($http_user_agent ~* "bot|crawler|curl") {
return 403;
}

Test:

Terminal window
curl -A "Googlebot" http://loadbalance.local/

Should return 403.


if ($request_method !~ ^(GET|POST)$ ) {
return 405;
}

Test:

Terminal window
curl -X DELETE http://loadbalance.local/

Should return 405 Method Not Allowed.


add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";

Verify using:

Terminal window
curl -I http://loadbalance.local/

Your protocol must include:

  • Backend server creation
  • Nginx reverse proxy configuration
  • Test outputs (curl results)
  • Load balancing verification
  • Rate limit behavior
  • Security filtering tests
  • Explanations for each step