Implementing the Apache RequestReadTimeout directive via mod_reqtimeout is a critical defensive measure for hardening web infrastructure against application layer Denial of Service (DoS) attacks. In high availability sectors such as energy grid management, municipal water control systems, or cloud-based financial networks; service uptime is the primary performance indicator. The core threat addressed by this module is the “Slowloris” or “slow body” attack; an exploit that consumes server resources by opening numerous connections and sending data at an infinitesimally slow pace. This strategy exploits the standard behavior of the Apache HTTP Server, which, by default, waits for a complete request before handing the process to a worker. If thousands of requests are kept in a semi-open state, the server exhausts its concurrency limits, leading to a total blackout for legitimate traffic. By enforcing strict yet dynamic timeouts for the request header and body, architects can ensure that worker threads are recycled efficiently; maintaining system throughput even under sustained malicious pressure.
TECHNICAL SPECIFICATIONS
| Requirement | Specification |
| :— | :— |
| Software Version | Apache HTTP Server 2.2.15 or 2.4.x (Recommended) |
| Operating System | Linux (RHEL/Ubuntu/Debian), Unix, or Windows Server |
| Default Port Range | Port 80 (HTTP) and Port 443 (HTTPS) |
| Protocol Standard | RFC 7230 (HTTP/1.1 Message Syntax and Routing) |
| Impact Level | 9/10 (Mitigates Critical Availability Risks) |
| Resource Overhead | Minimal: < 1% CPU and Negligible RAM utilization |
| Communication Logic | Asynchronous Header and Body Monitoring |
THE CONFIGURATION PROTOCOL
Environment Prerequisites:
Before proceeding with the deployment, ensure that the Apache environment is current. The system requires Apache 2.4.x for the most robust feature set within mod_reqtimeout. You must have sudo or root level permissions on the target host to modify configuration files and restart the service. It is also recommended to have a diagnostic tool like curl or a specialized slow-traffic simulator to verify the configuration post-implementation. Verify that your network firewall allows bidirectional traffic on the necessary ports and that any upstream load balancers are configured to pass the original client IP through the X-Forwarded-For header.
Section A: Implementation Logic:
The engineering rationale for using RequestReadTimeout centers on the preservation of the worker thread pool. In a standard Apache architecture, each incoming TCP connection maps to a thread or process. When an attacker sends a payload at a rate of one byte every few seconds, the server keeps that thread active, awaiting the completion of the HTTP encapsulation. This results in high latency for legitimate users as they wait for an available slot in the concurrency queue.
To be effective, the timeout must be idempotent; it should produce the same defensive result regardless of how many times the service is reloaded. We utilize dynamic timeouts rather than fixed ones. A fixed timeout of 20 seconds might be too aggressive for users experiencing high signal-attenuation or packet-loss on remote satellite links. Therefore, we implement a “Minimum Rate” logic. This tells Apache: “Start with a 20-second window, but as long as the client sends data at a rate of 500 bytes per second, extend that window.” This ensures that slow, legitimate connections (like a low-bandwidth mobile user) are not terminated, while malicious scripts that send data at 1 byte per second are purged immediately.
Step-By-Step Execution
1. Verify and Enable mod_reqtimeout
Run the command: sudo a2enmod reqtimeout
System Note: This command creates a symbolic link from the available modules directory to the enabled modules directory. It instructs the Apache binary to include the mod_reqtimeout.so shared object during the next initialization cycle. Without this, the RequestReadTimeout directive will be flagrantly ignored as an invalid command.
2. Locate the Configuration File
Access the configuration path: cd /etc/apache2/mods-enabled/ or cd /etc/httpd/conf.d/
System Note: On Debian-based systems, you will find a dedicated reqtimeout.conf file. On RHEL/CentOS systems, you may need to append the configuration to the primary httpd.conf. Navigating to this directory ensures you are modifying the active configuration state rather than a dormant template.
3. Configure Header Timeouts
Edit the file to include: RequestReadTimeout header=20-40,MinRate=500
System Note: This instruction sets a dual-stage limit for the HTTP header. The system grants an initial 20-second window. If the client sends data, the timer extends up to 40 seconds, provided the throughput stays above 500 bytes per second. This prevents attackers from holding a connection open indefinitely just by slowly trickling header fields.
4. Configure Body Timeouts
Edit the file to include: RequestReadTimeout body=20,MinRate=500
System Note: This directive targets the POST or PUT payload. Unlike the header, which has a hard cap of 40 seconds in the previous step, the body timeout here is entirely dependent on the MinRate. As long as the client maintains a throughput of 500 bytes per second, the connection remains open. This is essential for large file uploads over high-latency networks where signal-attenuation is a factor.
5. Validate Configuration Syntax
Run the command: sudo apachectl configtest
System Note: This utility parses the configuration files without actually applying them to the running process. It identifies typos, missing modules, or illogical variables. Performing this check is vital to prevent service downtime caused by a failed restart.
6. Commit Changes and Restart Service
Run the command: sudo systemctl restart apache2 or sudo systemctl restart httpd
System Note: This sends a SIGHUP or SIGTERM followed by a start command to the parent Apache process. The kernel flushes old worker threads and spawns new ones that adhere to the newly defined timeout logic. At this point, the defensive perimeter is active.
Section B: Dependency Fault-Lines:
Implementation failure often occurs when upstream proxies (like Nginx or HAProxy) are not synchronized with the Apache timeouts. If an upstream load balancer has a shorter timeout than Apache, it may drop connections prematurely, leading to 502 Bad Gateway errors. Furthermore, if the server is under extreme load, the CPU’s thermal-inertia may increase as it struggles with context switching; this can lead to delayed processing of the timeout logic itself. Always ensure the mod_reqtimeout settings are slightly more generous than your most restrictive upstream proxy to facilitate a graceful handover of connection management.
THE TROUBLESHOOTING MATRIX
Section C: Logs & Debugging:
When a connection is terminated by mod_reqtimeout, Apache logs a specific error string. Monitor your logs using: tail -f /var/log/apache2/error.log | grep reqtimeout.
Look for the following patterns:
1. “Request header read timeout”: This confirms that a client failed to send the full HTTP header within the allocated 20-40 second window.
2. “Request body read timeout”: This indicates the client failed to maintain the MinRate during the payload transfer.
3. Status Code 408: The server will return an HTTP 408 (Request Timeout) to the client. If legitimate users report seeing 408 errors frequently, your MinRate is too high or your initial timer is too short.
In environments with significant packet-loss, you might see these errors frequently for mobile users. To debug, use tcpdump -i eth0 port 80 to observe the actual arrival of packets. If packets are arriving but the server is still timing out, check the server’s internal clock and CPU load; high overhead can delay the module’s internal timer execution.
OPTIMIZATION & HARDENING
– Performance Tuning: In high-concurrency environments, reduce the header timeout to header=10-20,MinRate=500. This forces faster negotiation and frees up worker slots for the next payload. However, do not set the MinRate below 250 bytes per second, as this effectively disables the protection against modern, sophisticated slow-scripts.
– Security Hardening: Combine mod_reqtimeout with mod_evasive or a local firewall rule (iptables/nftables). While mod_reqtimeout handles the “slow” part of the attack, it does not stop an attacker from launching a “fast” attack (flooding). Use iptables to limit the number of concurrent connections from a single IP address to 20 or 50, depending on your application’s needs.
– Scaling Logic: As you scale horizontally across multiple web nodes, use a configuration management tool like Ansible or Chef to ensure the RequestReadTimeout settings are identical across the cluster. This consistency is vital for maintaining an idempotent security posture. If your infrastructure spans global regions, consider adjusting the MinRate based on the regional average latency; for instance, nodes in regions with poor infrastructure may require a lower MinRate to accommodate legitimate signal-attenuation.
THE ADMIN DESK
How do I check if the module is actually loaded?
Execute apachectl -M | grep reqtimeout. If the terminal returns reqtimeout_module (shared), the module is successfully initialized in the current runtime. If no output appears, return to the activation step and ensure the module is installed.
Will this interfere with large file uploads?
Not if configured correctly. By using the MinRate parameter, the timeout only triggers if the upload speed drops below a specific threshold. For large payloads, ensure your body timeout relies on throughput rather than a hard time limit.
What is the best MinRate for a standard application?
A MinRate of 500 bytes per second is the industry standard for general-purpose web servers. This is slow enough to support most mobile users on 3G networks but fast enough to kill malicious Slowloris scripts.
Can I set different timeouts for different VirtualHosts?
Yes. You can place the RequestReadTimeout directive inside a VirtualHost container to apply specific rules to different domains. This is useful if one site handles small API calls while another handles large media uploads.



