NGINX reset_timedout_connection: Explained with examples

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

Introduction

NGINX, known for its high performance and low memory usage, is often used as a web server or reverse proxy. It provides powerful directive options, one of which is the reset_timedout_connection directive. This directive allows NGINX to abort connections if a timeout occurs, rather than waiting for a proper close. This behavior can be beneficial in environments where connections are often reset, or to mitigate certain types of Denial-of-Service attacks.

In this tutorial, we’ll fully explore the reset_timedout_connection directive, walking through its use cases and showing how to implement it with practical code examples. We’ll go from basic configurations to more advanced scenarios, breaking down each example to understand the impacts and behaviors induced by this setting.

Basic Example

The simplest use case for reset_timedout_connection is in the context of a basic NGINX server configuration. This setting can be added within the http, server, or location blocks.

# Basic usage within the http block
default_type  application/octet-stream;
reset_timedout_connection on;

# Inside server block
server {
    listen 80;
    server_name www.example.com;
    reset_timedout_connection on;
    ...
}

# Inside location block
location / {
    proxy_pass http://backend;
    reset_timedout_connection on;
}

By placing reset_timedout_connection on in these blocks, NGINX will reset connections as they time out in the specified scope.

Combining with timeout directives

NGINX allows for fine-tuning of various timeout settings, such as keepalive_timeout, send_timeout, and others. When used in conjunction with reset_timedout_connection, this can create a robust setup that handles slow connections elegantly.

# Advanced configuration with timeout directives
http {
    keepalive_timeout 15;
    send_timeout 10;

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

        reset_timedout_connection on;
        location / {
            proxy_pass http://backend;
            proxy_read_timeout 20;
            proxy_connect_timeout 10;
        }
    }
}

Note how the proxy_read_timeout dictates how long to wait for a response from the proxied server. When combined with reset_timedout_connection, any timed-out connections will be reset promptly, avoiding unnecessary resource consumption.

Handling Timeouts at Upstream Levels

Let’s say you’re using NGINX as a reverse proxy with an upstream configuration that defines a group of backend servers. You can specify how NGINX should handle connection timeouts to these backend servers with reset_timedout_connection. Below, see an example of how this works in an upstream block:

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

    server {
        reset_timedout_connection on;
        ...
    }
}

By including reset_timedout_connection within an upstream block, NGINX ensures that any idle or slow connections to your backend systems are terminated promptly, freeing up resources and improving overall system performance.

Utilizing Variables and Map Blocks

In more complex configurations, you might want the reset_timedout_connection feature to be conditionally applied based on certain criteria, like the client’s IP address or the requested URI. NGINX’s map block can help to achieve this. Here’s an example:

http {
    map $request_uri $reset_timeout {
        default off;
        ~^/api/ on;
    }

    server {
        listen 80;
        server_name www.example.com;
        reset_timedout_connection $reset_timeout;
    }
}

In this example, $reset_timeout will be dynamically set to on for URIs beginning with ‘/api/’, and to off for all others. This enables selective resetting of timed-out connections based on the request URI pattern.

Setting Timed Out Connections with SSL/TLS

NGINX’s reset capabilities are equally relevant when dealing with encrypted connections. Here we’ll specify reset_timedout_connection in conjunction with SSL/TLS settings to ensure secure connections are also terminated if they become unresponsive:

server {
    listen 443 ssl;
    ssl_certificate /path/to/certificate.pem;
    ssl_certificate_key /path/to/key.pem;
    ... 
    reset_timedout_connection on;
}

Even with the overhead of encryption and decryption, NGINX will proactively reset SSL/TLS connections that timeout, protecting the overhead from growing unnecessarily and potentially impacting server performance.

Debugging and Log Analysis

Understanding when connections are reset can be key to tuning your NGINX environment. By tweaking your log format, you can gain insights into behavior affected by the reset_timedout_connection directive. This small addition to your logging can be invaluable:

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      'connection_reset:$connection_reset';
    ...
}

The custom log_format includes the connection_reset variable, which indicates whether a connection was reset due to a timeout.

Conclusion

The reset_timedout_connection directive is a valuable tool in the NGINX configuration toolbox, providing you with the ability to keep your server responsive by quickly dropping unresponsive connections. Through the series of examples provided, you should now feel confident in implementing this directive to manage connection timeouts effectively, ensuring improved server reliability and performance.