Bug 61310 - mod_reqtimeout does not timeout during SSL handshakes
Summary: mod_reqtimeout does not timeout during SSL handshakes
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_reqtimeout (show other bugs)
Version: 2.4.26
Hardware: PC FreeBSD
: P2 enhancement (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Keywords: FixedInTrunk
Depends on:
Reported: 2017-07-16 22:00 UTC by apache.bugs
Modified: 2019-03-27 21:54 UTC (History)
1 user (show)

Allow to configure TLS handshake timeout(s) (10.12 KB, patch)
2019-02-15 23:38 UTC, Yann Ylavic
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description apache.bugs 2017-07-16 22:00:19 UTC
It seems that `mod_reqtimeout` timeout only starts when the SSL handshake has been fulfilled.

Here is a simple configuration to show the issue:

    # Ensure that accept filters do not interfere
    AcceptFilter http none
    AcceptFilter https none
    # Apache core timeout
    Timeout 30
    # mod_reqtimeout timeout
    RequestReadTimeout header=5 body=5

A connection made with `openssl s_client` correctly times out after 5 seconds as expected:

    user@host:~$ time openssl s_client -quiet -host www.mydomain.test -port 443
    depth=0 CN = default.invalid
    verify error:num=18:self signed certificate
    verify return:1
    depth=0 CN = default.invalid
    verify return:1
    real  0m5.082s
    user  0m0.006s
    sys   0m0.016s

However a connection made using `telnet` remains during 30 seconds, until Apache core global `Timeout` value expires:

    user@host:~$ time telnet www.mydomain.test 443
    Connected to mydomain.test.
    Escape character is '^]'.
    Connection closed by foreign host.
    real  0m30.028s
    user  0m0.003s
    sys   0m0.012s

The expected behavior is for this connection to be interrupted after 5 seconds too, as defined in the `RequestReadTimeout` setting.

For reference, `mod_reqtimeout` documentation[1] seems to imply that its timeout should cover the SSL handshake ("If a common configuration is used for http and https virtual hosts, the timeouts should not be set too low") which does not seem to the be case here, hence the bug report.

Moreover, `mod_reqtimeout` is cited by Wikipedia[2] as the "the official solution supported by the developers" to mitigate Slowloris class of attacks. The fact that it does not impose any timeout on the SSL handshake strongly limits its effectiveness for such use.

[1]: https://httpd.apache.org/docs/2.4/mod/mod_reqtimeout.html
[2]: https://en.wikipedia.org/wiki/Slowloris_(computer_security)#Mitigating_the_Slowloris_attack
Comment 1 dferradal 2019-02-15 18:05:10 UTC
as replied in #httpd in irc:

mod_reqtimeout deals with HTTP attacks, checks the timing for HTTP requests, including headers, body.

HTTP communication does no happen until SSL negotiation has been established correctly.

So it is normal openssl timesout with mod_reqtimeout because SSL negotiation has been stablished already.

And it is normal telnet timesout with global server config timeout instead of mod_reqtimeout, because SSL negotiation has not been made and thus we are not in http communication yet.

I'd declare this INVALID.
Comment 2 Yann Ylavic 2019-02-15 22:26:30 UTC
Right, switching to "enhancement" though, maybe we can have a new handshake=timeout[-maxtimeout][,MinRate=rate] setting which would act at the TLS handhake level. Will look into this, unless one beats me to it :)
Comment 3 Yann Ylavic 2019-02-15 23:38:21 UTC
Created attachment 36438 [details]
Allow to configure TLS handshake timeout(s)

Something like this.
Comment 4 Yann Ylavic 2019-02-19 18:25:50 UTC
Committed to trunk (r1853906, with first preparation commit in r1853901)
Comment 5 Yann Ylavic 2019-03-27 21:54:37 UTC
Backported to 2.4.39 (r1855409).