NGINX stream core module: The Complete Guide

Updated: January 20, 2024 By: Guest Contributor Post a comment

Introduction

The NGINX stream core module is an essential tool for handling TCP and UDP traffic, providing load balancing, SSL/TLS termination, and more, all while maintaining high performance and reliability. This guide explores the module’s offerings, providing code examples from basic to advanced setups. By the end, you’ll gain comprehensive insights into NGINX’s abilities to manage non-HTTP network traffic.

Getting Started with NGINX Stream Core Module

NGINX is a web server known for its high performance, simplicity, and resource efficiency. Apart from handling HTTP requests, it can also manage other types of network traffic using its stream core module. This module processes TCP and UDP streams, performing load balancing across multiple backends and enabling the use of SSL/TLS for encrypted communication.

The first step in using the stream module is to ensure it is included in your NGINX build. You can check module availability by running:

nginx -V 2>&1 | grep --color -- 'stream'

If the module is included, you’ll see --with-stream in the output.

Basic Configuration

Before delving into advanced configurations, it’s important to understand the basics. The following demonstrates setting up a simple TCP proxy for an SSH server running on port 22:

stream {
    upstream ssh_backend {
        server 192.168.1.10:22;
    }

    server {
        listen 2345;
        proxy_pass ssh_backend;
    }
}

In this example, NGINX listens on port 2345 and forwards any TCP traffic it receives to the IP address 192.168.1.10 on port 22.

Load Balancing

NGINX can distribute traffic across multiple servers to enhance performance and reliability. Here’s an example for a TCP-based application:

stream {
    upstream myapp_backend {
        server server1.example.com:1234;
        server server2.example.com:1234;
        server server3.example.com:1234;
    }

    server {
        listen 5678;
        proxy_pass myapp_backend;
    }
}

Traffic arriving at port 5678 will be load-balanced across the three specified servers. By default, NGINX uses a round-robin approach.

SSL/TLS Termination

The stream module allows for SSL/TLS termination. Here’s how to configure NGINX to handle encrypted traffic for a MySQL database:

stream {
    upstream db_backend {
        server db1.example.com:3306;
    }

    server {
        listen 1234 ssl;
        ssl_certificate /etc/nginx/ssl/my-cert.pem;
        ssl_certificate_key /etc/nginx/ssl/my-key.pem;
        proxy_pass db_backend;
    }
}

With these configurations, NGINX terminates the SSL/TLS connection and forwards the plaintext traffic to the backend database server.

Advanced Load Balancing

The module supports more sophisticated load-balancing techniques, such as least connections and IP hash:

stream {
    upstream myapp_backend {
        least_conn;
        server server1.example.com:1234;
        server server2.example.com:1234;
        server server3.example.com:1234;
    }

    server {
        listen 5678;
        proxy_pass myapp_backend;
    }
}

With least_conn, NGINX directs traffic to the server with the fewest active connections.

Access Control

NGINX stream core module offers access control features, such as allowing or denying access to specific IPs:

stream {
    server {
        listen 2345;
        allow 203.0.113.0/24;
        deny all;
        proxy_pass ssh_backend;
    }
}

In this example, only IPs from the subnet 203.0.113.0/24 are permitted to access your service on port 2345. All other IP addresses are denied.

Health Checks

With NGINX Plus, you can perform health checks on your backend servers to ensure traffic is only sent to healthy nodes:

stream {
    upstream myapp_backend {
        zone myapp 64k;
        server server1.example.com:1234 max_fails=3 fail_timeout=30s;
        server server2.example.com:1234 max_fails=3 fail_timeout=30s;
        server server3.example.com:1234 max_fails=3 fail_timeout=30s;
        health_check;
    }

    server {
        listen 5678;
        proxy_pass myapp_backend;
    }
}

Here, the health_check directive instructs NGINX to regularly check the health of the backend servers. If a server fails a specified number of times within a period, it will temporarily be removed from the pool.

UDP Load Balancing

Similar to TCP, NGINX can balance UDP traffic across multiple servers:

stream {
    upstream dns_backend {
        server dns1.example.com:53;
        server dns2.example.com:53;
    }

    server {
        listen 53 udp;
        proxy_pass dns_backend;
        proxy_responses 1;
        error_log /var/log/nginx/dns_error.log;
    }
}

In this configuration, NGINX operates as a DNS server that can handle UDP traffic, forwarding queries to two upstream DNS servers.

Conclusion

The NGINX stream core module offers a versatile set of features that make it an excellent tool for handling TCP and UDP based network traffic. Its ability to load balance, perform SSL/TLS termination, and provide access control showcases its power and flexibility. With this guide, you are now ready to leverage these attributes in your own network infrastructure.