Posted in

Nginx web and proxy server

Introduction to Nginx Server

Nginx is a high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Known for its stability, rich feature set, simple configuration, and low resource consumption, Nginx is widely used for serving web content and as a reverse proxy for handling client requests. It was created by Igor Sysoev and first released in 2004. Today, Nginx is a popular choice for many websites, ranging from small personal blogs to large-scale enterprise applications.

Installing Nginx Server

On Ubuntu/Debian
To install Nginx on an Ubuntu/Debian system, follow these steps:

Update your package list:

sudo apt update

Install Nginx:

sudo apt install nginx

Start Nginx:

sudo systemctl start nginx

On CentOS/RHEL

To install Nginx on a CentOS/RHEL system, follow these steps:

Add the EPEL repository:

sudo yum install epel-release

Install Nginx:

sudo yum install nginx

Start Nginx:

sudo systemctl start nginx
Basic Configuration

Nginx configuration files are located in /etc/nginx, and the main configuration file is nginx.conf. Here’s a basic configuration for serving static content:

server {
listen 80;
server_name example.com;

root /var/www/html;
index index.html;

location / {
try_files $uri $uri/ =404;
}
}

listen 80;: Nginx listens on port 80 for HTTP requests.
server_name example.com;: Specifies the domain name.
root /var/www/html;: Sets the root directory for the website files.
index index.html;: Specifies the default file to serve.
location / { try_files $uri $uri/ =404; }: Tries to serve the requested file, and if not found, returns a 404 error.

Advanced Configuration

Load Balancing set up a basic load balancer:

upstream backend {
server backend1.example.com;
server backend2.example.com;
}

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend;
}
}

upstream backend { … }: Defines a group of backend servers.
proxy_pass http://backend;: Forwards requests to the defined backend servers.

Gzip Compression enable the Gzip compression:

http {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

gzip on;: Enables Gzip compression.
gzip_types …;: Specifies the types of files to compress.
Serving a Single Website + Security with SSL Certbot
To serve a single website with SSL:

Install Certbot:

sudo apt install certbot python3-certbot-nginx

Obtain an SSL certificate:

sudo certbot --nginx -d example.com

Certbot will automatically configure your Nginx to use the SSL certificate.

Example Configuration with SSL:

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend;
}

listen 443 ssl; # HTTPS port
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

location / {
proxy_pass http://backend;
}
}

listen 443 ssl;: Listens on port 443 for HTTPS requests.
ssl_certificate and ssl_certificate_key: Paths to the SSL certificate and key files.
Serving Multiple Websites + Security with SSL Certbot

To serve multiple websites with SSL configure Nginx for each website:

server {
listen 80;
server_name example1.com;

root /var/www/example1;
index index.html;

location / {
try_files $uri $uri/ =404;
}
}

server {
listen 80;
server_name example2.com;

root /var/www/example2;
index index.html;

location / {
try_files $uri $uri/ =404;
}
}

Obtain SSL certificates for each domain:

sudo certbot --nginx -d example1.com
sudo certbot --nginx -d example2.com

Example Configuration with SSL:

server {
listen 80;
server_name example1.com;

root /var/www/example1;
index index.html;

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example1.com/privkey.pem;

location / {
try_files $uri $uri/ =404;
}
}

server {
listen 80;
server_name example2.com;

root /var/www/example2;
index index.html;

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example2.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example2.com/privkey.pem;

location / {
try_files $uri $uri/ =404;
}
}

Configuring Reverse Proxy + Security with SSL Certbot
Basic reverse proxy configuration:

server {
listen 80;
server_name proxy.example.com;

location / {
proxy_pass http://backend.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Obtain an SSL certificate:

sudo certbot --nginx -d proxy.example.com

Example Configuration with SSL:

server {
listen 80;
server_name proxy.example.com;

location / {
proxy_pass http://backend.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/proxy.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy.example.com/privkey.pem;

location / {
proxy_pass http://backend.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Configuring Reverse Proxy with Multiple Sites + Security with SSL Certbot
Configuration for multiple sites:

server {
listen 80;
server_name site1.example.com;

location / {
proxy_pass http://backend1.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

server {
listen 80;
server_name site2.example.com;

location / {
proxy_pass http://backend2.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Obtain SSL certificates for each domain:

sudo certbot --nginx -d site1.example.com
sudo certbot --nginx -d site2.example.com

Example Configuration with SSL:

server {
listen 80;
server_name site1.example.com;

location / {
proxy_pass http://backend1.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/site1.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site1.example.com/privkey.pem;

location / {
proxy_pass http://backend1.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

server {
listen 80;
server_name site2.example.com;

location / {
proxy_pass http://backend2.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/site2.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site2.example.com/privkey.pem;

location / {
proxy_pass http://backend2.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Configuring Forward Proxy + Security with SSL Certbot
Basic forward proxy configuration:

server {
listen 3128;

location / {
proxy_pass http://$http_host$request_uri;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Secure the forward proxy with SSL:

sudo certbot --nginx -d proxy.example.com

Example Configuration with SSL:

server {
listen 3128 ssl;
server_name proxy.example.com;

ssl_certificate /etc/letsencrypt/live/proxy.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy.example.com/privkey.pem;

location / {
proxy_pass http://$http_host$request_uri;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Security with SSL Certbot
SSL (Secure Sockets Layer) ensures the data transmitted between the server and clients is encrypted. Certbot, a tool from the Electronic Frontier Foundation, simplifies the process of obtaining and renewing SSL certificates from Let’s Encrypt. Using SSL with Certbot enhances security by providing HTTPS encryption for your websites.

Configuring Reverse Proxy for Multiple Sites
As shown earlier, configuring a reverse proxy for multiple sites involves setting up server blocks for each site and directing traffic to the appropriate backend services.

Advanced Configuration Options

To limit the rate of requests:

http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;

server {
location / {
limit_req zone=mylimit burst=5;
}
}
}

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;: Defines a rate limit of 1 request per second.
limit_req zone=mylimit burst=5;: Allows bursts of up to 5 requests.

To enable caching:

http {
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
location / {
proxy_cache my_cache;
proxy_pass http://backend;
}
}
}

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;: Configures the cache storage.
proxy_cache my_cache;: Enables caching for the specified location.

Security Considerations
Security is crucial when running a web server. Some key considerations include:

  • Keeping Nginx Updated: Regularly update Nginx to benefit from security patches.
  • Using SSL/TLS: Always use HTTPS to encrypt data.
  • Configuring Firewalls: Restrict access to necessary ports only.
  • Enabling Rate Limiting: Prevent DDoS attacks by limiting request rates.
  • Implementing Access Controls: Use authentication mechanisms to restrict access to sensitive areas.

Performance Tuning

To optimize Nginx for better performance: Adjust the number of worker processes based on your CPU cores.

worker_processes auto;

Worker Connections: Increase the worker connections limit.

events {
worker_connections 1024;
}

Enable Caching: Use caching to reduce load on backend servers.
Optimize Gzip: Compress responses to reduce bandwidth usage.
Use Content Delivery Networks (CDNs): Distribute load and improve content delivery speed.

Enabling Caching:

http {
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
location / {
proxy_cache my_cache;
proxy_pass http://backend;
}
}
}

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;: Configures the cache storage.
proxy_cache my_cache;: Enables caching for the specified location.

Optimizing Gzip Compression:

http {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
}

gzip on;: Enables Gzip compression.
gzip_types …;: Specifies the types of files to compress.
gzip_min_length 256;: Sets the minimum length of responses to be compressed.
gzip_proxied any;: Enables compression for proxied requests.
gzip_vary on;: Ensures that proxies cache both compressed and uncompressed versions.

Using Content Delivery Networks (CDNs):

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
proxy_pass http://cdn.example.com;
}
}

The location block for static files (like images, CSS, and JavaScript) proxies requests to the CDN.
expires 30d;: Sets an expiration date for static content, allowing the CDN to cache these files.
add_header Cache-Control “public, no-transform”;: Adds cache control headers to further optimize caching behavior.

Leave a Reply

Your email address will not be published. Required fields are marked *