Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Nginx Virtual Hosts and Core Configuration Directives

Tech Sep 17 1

Nginx Virtual Hosts

Overview

Virtual host technology allows a single physical server to host multiple websites. Each virtual host can provide independent web services, and they are isolated from each other.

Classification of Virtual Hosts

Virtual Host Types

Nginx supports three types of virtual host configurations:

  • IP-based virtual hosts IP-based
  • Port-based virtual hosts Port-based
  • Name-based virtual hosts Name-based

IP-based Virtual Host Configuraton (Single NIC, Multiple IPs)

IP-based configuration

This method distinguishes virtual hosts by different IP addresses. It is rarely used in enterprise environments; typically, VIP binding on load balancers is preferred over binding IPs on web servers.

Requirement:

  • A Linux server with two IPs: 192.168.66.100 and 192.168.66.101.
  • Accessing http://192.168.66.100 serves content from the html100 directory.
  • Accessing http://192.168.66.101 serves content from the html101 directory.

Binding Multiple IPs on Linux:

Linux allows binding multiple IP addresses on a single physical NIC. To do this, change the dynamic IP assignment to static configuration.

Change dynamic IP to static:

[root@node1 ~]# cd /etc/sysconfig/network-scripts
[root@node1 network-scripts]# ls
ifcfg-ens33
[root@node1 network-scripts]# vim ifcfg-ens33
BOOTPROTO="static"
IPADDR0=192.168.66.100
IPADDR1=192.168.66.101
[root@node1 network-scripts]# systemctl restart network   # CentOS 7
# For CentOS 8: nmcli c reload ens33
# Alternatively, reboot

Configure Nginx for IP-based virtual hosts:

Edit /usr/local/nginx/conf/nginx.conf:

# First virtual host
server {
    listen       80;
    server_name  192.168.66.100;

    location / {
        root   html100;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

# Second virtual host
server {
    listen       80;
    server_name  192.168.66.101;

    location / {
        root   html101;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

Name-based Virtual Host Configuration

Name-based configuration

Requirement:

  • Two domains pointing to the same Nginx server, each serving different content.
  • www.example.com for frontend, www.admin.example.com for backend.

Modify Windows hosts file:

192.168.66.100 www.example.com
192.168.66.100 www.admin.example.com

Configure Nginx:

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

    location / {
        root   example;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

server {
    listen       80;
    server_name  www.admin.example.com;

    location / {
        root   admin;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

Prepare directories and HTML files:

mkdir example admin
cd example
echo "this is example" > index.html
cd ../admin
echo "this is admin" > index.html

Reload Nginx:

./nginx -s reload

Port-based Virtual Host Configuration

Port-based configuration

This method uses different ports to distinguish virtual hosts and is common used for internal company websites.

Requirement:

  • Nginx listens on ports 8888 and 9999.
  • Requests to port 8888 serve content from html8888 directory.
  • Requests to port 9999 serve content from html9999 directory.

Restore single IP:

vim /etc/sysconfig/network-scripts/ifcfg-ens33
# Change:
IPADDR0=192.168.66.100
IPADDR1=192.168.66.101
# To:
IPADDR=192.168.66.100
systemctl restart network

Configure Nginx:

server {
    listen       8888;
    server_name  192.168.66.100;

    location / {
        root   html8888;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

server {
    listen       9999;
    server_name  192.168.66.100;

    location / {
        root   html9999;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

Prepare directories and HTML files:

mkdir html8888 html9999
cd html8888
echo "this is html8888" > index.html
cd ../html9999
echo "this is html9999" > index.html

Nginx Core Directives

Root vs. Alias Directive

  • Commonality: Both specify the mapping between URI and file system path.
  • Difference: root concatenates the defined path with the URI; alias replaces the URI path with the defined path.

Example with root: Client requests www.test.com/images/1.jpg -> actual path: /opt/nginx/html/images/images/1.jpg

location /images {
    root /opt/nginx/html/images;
    index index.html index.htm;
}

Example with alias: Client requests www.test.com/images/1.jpg -> actual path: /opt/nginx/html/images/1.jpg

location /images {
    alias /opt/nginx/html/images/;   # must end with '/'
    index index.html index.htm;
}

Return Directive

The return directive stops processing and returns a response code or redirects.

Syntax:

  • return code [text]; (text meaningful only for 2xx)
  • return code URL; (e.g., redirect)
  • return URL; (must start with http or https)

Common status codes: 200, 301, 404, 500.

Context: server | location | if

Examples:

# Code + text
location / {
    return 200 'success';
}

# Code + URL (temporary redirect)
location / {
    return 302 /bbs;
}

# Direct URL redirect
location / {
    return http://baidu.com;
}

Rewrite Directive

URL Rewriting vs. Forwarding:

  • Rewriting: Changes the URL in the client's browser (usually two requests).
  • Forwarding: Internal server-side redirect, URL unchanged (single request).

Common rewrite variables:

Variable Description
$args Query string
$document_root Root directory from config
$document_uri Current URI without query string
$host Hostname
$http_user_agent Client browser
$remote_addr Client IP
$request_method GET, POST, etc.
$scheme http, https
$server_name Server name
$uri Same as $document_uri

Syntax:

rewrite regex replacement [flag];

Flags:

  • last: Continue matching new location after rewrite.
  • break: Stop matching after rewrite.
  • redirect: Return 302 temporary redirect.
  • permanent: Return 301 permanent redirect.

Examples:

# Permanent redirect to Baidu
location /search {
    rewrite ^/(.*) http://baidu.com permanent;
}

# Rewrite /images/1.html to /pics/1.html
location /images {
    rewrite /images/(.*) /pics/$1;
}

# Using break to prevent further matching
location /images {
    rewrite /images/(.*) /pics/$1 break;
}

# Using last to re-enter server block
location /images {
    rewrite /images/(.*) /pics/$1 last;
}

Practical domain redirect:

server {
    listen 80;
    server_name old-domain.com;
    rewrite ^/(.*) http://new-domain.com/$1 permanent;
}

If Directive

The if directive performs conditional checks and can be used in server or location blocks.

Syntax:

if (condition) { ... }

Condition examples:

  • Varible: $slow -> true if not empty or not '0'.
  • String comparison: $request_method = POST.
  • Regex: $http_user_agent ~ MSIE (case-sensitive), ~* for case-insensitive.

Examples:

# Block POST requests
if ($request_method = POST) {
    return 405;
}

# Block Google Chrome
if ($http_user_agent ~ Chrome) {
    return 500;
}

# Check client IP
location /search {
    if ($remote_addr = "192.168.66.10") {
        return 200 "test if ok";
    }
}

Set and Break Directives

Set: Create a variable.

set $variable value;

Break: Stop processing further directives in the current scope.

Example:

location / {
    if ($slow) {
        set $id $1;          # executes before break
        break;
        limit_rate 10k;      # ignored after break
    }
}

Gzip Compression Directive

Gzip compression reduces file sizes (CSS, JS, XML, HTML) for faster transfers.

Common configuration:

http {
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
    gzip_disable "MSIE [1-6]\.";
    gzip_vary on;
}

Notes:

  • Avoid compressing image and video files as they are already compressed.
  • Avoid compressing very large files due to CPU overhead.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.