-
Notifications
You must be signed in to change notification settings - Fork 103
HTTP security
Frang is an internal Tempesta module for enforcing security limits to prevent Web attacks and mitigate HTTP(S) (D)DoS attacks. It uses static limiting and checking of ingress HTTP requests. The main portion of it's logic is at HTTP layer, so it's recommended that ip_block option (enabled by default) is used to block malicious users at IP layer.
Learn how to configure limits when migrating from NGINX.
Frang limits are split into two parts: connection level limits and message level limits. Connection level limits are applied at very early processing stages, when there is not enough data to determine target vhost. E.g. when client establish connections or until full set of request headers is received. Thus connection level limits are configured only globally.
Message level limits are accounted on later processing stages when target vhost and location are already known. Such request can be configured globally as defaults, per vhost and per location.
The limits are described inside section frang_limits
. The section may appear:
-
at top level - to configure connection level limits and to override default values for message level limits for vhosts below this directive section. May appear multiple times. Implicit
default
vhost will use the last effective set of the message level limits. -
inside
vhost
section - to override defaults for locations of the current vhost below this directive section. May appear multiple times. Implicitdefault
location of the vhost will use the last effective set of the limits. -
inside
location
section - to configure message level limits for the current location.
Even if section frang_limits
is not stated in the configuration file, the
whole Frang subsystem is enabled with defaults.
The global Frang limits must be specified before all vhosts, which must inherit the global limits.
See examples below how the limits can be configured and overridden.
The Frang limits are calculated inside sliding windows, mostly window size equals to 1 second, but some limits have configurable window size.
ip_block [off|on]
If disabled client connection(-s) are closed of security events. If enabled
client connections are closed and client will be blocked by it's IP address.
Defaults: off
- disabled.
request_rate [NUM]
Maximum number of requests per second from a single client across all it's
connections. 0
to disable the limit.
Defaults: 0
(disabled).
request_burst [NUM]
Maximum burst of request rate on short periods of time (125 ms). The option
can be used independedly from request_rate
limit. 0
to disable the limit.
Defaults: 0
(disabled).
connection_rate [NUM]
Maximum number of new connection openings per second from a single client.
0
to disable the limit.
Defaults: 0
(disabled).
connection_burst [NUM]
Maximum burst of new connection openings rate on short periods of time (125 ms) from a single client.
The option can be used independently from connection_rate
limit. 0
to disable
the limit.
Defaults: 0
(disabled).
concurrent_connections [NUM]
Maximum number of new concurrent connections from a single client.
0
to disable the limit.
Defaults: 0
(disabled).
client_header_timeout [TIME]
Maximum time in seconds to receive the whole HTTP headers set of incoming
request.0
to disable the limit.
Defaults: 0
(disabled).
client_body_timeout [TIME]
Maximum time in seconds to receive the whole HTTP body of incoming
request.0
to disable the limit.
Defaults: 0
(disabled).
http_header_chunk_cnt [NUM]
HTTP messages can be sent by parts. The option controls maximum number of parts
(chunks) in the request header part.0
to disable the limit.
Defaults: 0
(disabled).
http_body_chunk_cnt [NUM]
HTTP messages can be sent by parts. The option controls maximum number of parts
(chunks) in the request body part.0
to disable the limit.
Defaults: 0
(disabled).
tls_connection_rate [NUM]
Maximum number of new TLS sessions established with a single client per second.
Establishing a new TLS connection (handshake
processing) requires much more computations on server side than on resuming a
previous one. Malicious clients can DDoS server constantly establishing
thousands new TLS connection. With the option Tempesta blocks new connections
with a client, if it establishes new TLS connections too often.
Defaults: 0
(disabled).
tls_connection_burst [NUM]
disable the limit.
Maximum burst of new TLS sessions rate on short periods of time (125 ms) from a single client.
The option can be used independently from tls_connection_rate
limit. 0
to
Defaults: 0
(disabled).
tls_incomplete_connection_rate [NUM]
Block client if it fails more than NUM
TLS handshakes per second.
Defaults: 0
(disabled).
http_uri_len [NUM]
Maximum length of URI part in a request.0
to disable the limit.
Defaults: 0
(disabled).
http_field_len [NUM]
Maximum length of a single HTTP header field in an incoming request. This limit
is helpful to prevent
HTTP Response Splitting
and other attacks using arbitrary injections in HTTP headers.
0
to disable the limit.
Defaults: 0
(disabled).
http_body_len [NUM]
Maximum length of HTTP message body of incoming request. 0
to disable the limit.
Defaults: 1073741824
(1 Gb).
http_header_cnt [NUM]
Maximum number of HTTP headers in a HTTP message. 0
to disable the limit.
Defaults: 0
(disabled).
http_host_required [true|false]
A request has an explicit authority declaration. The authority must not be an IP
address. Host:
header is a mandatory for HTTP/1.1 requests, but if the URI
has a full form with authority provided, it must have the same value as Host:
header. In HTTP/2 requests at least one of headers :authority
or host:
must be provided, the headers must have the same values, if both are provided
simultaneously. Also when Forwarded:
header with host
parameter is provided,
it also must be the same as :authority
and host:
. In case of multiple Forwarded:
headers were provided, only first header need to match.
Port, requested in authority, must be equal to the TCP port, where request was
received. The only exception is the protocols below HTTP/1.1, since an authority is not
defined for them, they must not provide authority headers.
Defaults: true
.
Notice While mismatching of SNI and virtual host names is the common source of vhost confusion Tempesta FW does not validate SNI against virtual host name in run time. Instead, it validates Subject Alternative Names (SAN) on certificate loading for the vhost and later, in run time, validates SNI against the available SANs.
http_ct_required [true|false]
Require presence of Content-Type
header in a request.
Defaults: false
.
http_trailer_split_allowed [true|false]
Allow the same header appear in both request header part and chunked trailer
part.
Defaults: false
.
http_methods METHOD [METHOD]...
The list of accepted HTTP methods (see
OWASP recommendations).
Defaults: limit disabled (all methods are allowed).
Example: http_methods get post head;
http_ct_vals ["CONTENT_TYPE"]...
The list of accepted values for Content-Type
header. Note that the full types must
be specified, i.e. if you need to allow text/html
and text/plain
, then you
should specify http_ct_vals "text/plain" "text/html"
, http_ct_vals "text/*"
won't match the required values.
Defaults: limit disabled (all values are allowed).
Example: http_ct_vals "text/plain" "text/html";
http_resp_code_block RESPONSE_CODE [RESPONSE_CODE]... LIMIT TIME_FRAME_IN_SECONDS
Block client if it cause to many errors on backend server in the selected
time frame (responses from the Tempesta cache is not counted for this limit).
See Password crackers section.
RESPONSE_CODE
- status code in the response from backend server.
LIMIT
- responses count.
TIME_FRAME_IN_SECONDS
- size of sliding window to count the limit.
Defaults: limit disabled.
Example: http_resp_code_block 403 404 502 20 5;
http_method_override_allowed [true|false]
The option controls how the requests with method override headers
(X-Http-Method
, X-Method-Override
, X-Http-Method-Override
) are processed.
Defaults: false.
If the option is disabled (defaults) such requests are blocked. If the option
is enabled, the overridden method is used as primary request method inside
request processing logic. The overridden method must be allowed by http_methods
directive, otherwise it will be blocked. Keep in mind that in all cases unsafe
method cannot override safe method (GET, HEAD, OPTIONS, TRACE, PROPFIND).
Example 1. Configure all Frang limits globally for all vhosts.
frang_limits {
request_rate 20;
request_burst 15;
connection_rate 8;
connection_burst 6;
concurrent_connections 8;
client_header_timeout 20;
client_body_timeout 10;
http_uri_len 1024;
http_field_len 256;
http_ct_required false;
http_methods get post head;
http_ct_vals "text/plain" "text/html";
http_header_chunk_cnt 10;
http_body_chunk_cnt 0;
http_resp_code_block 403 404 502 20 5;
}
# The `frang_limits` section is listed before vhosts definitions, thus the
# vhosts and all their locations will be using the limits defined above.
vhost crm.example.com {
...
}
vhost example.com {
...
}
...
Example 2. Global/connection-level vs per-vhost/message limits.
listen 192.168.100.4:443 proto=https;
srv_group default {
server 127.0.0.1:8080 conns_n=4;
}
vhost default {
tls_certificate /root/tempesta/etc/tfw-root.crt;
tls_certificate_key /root/tempesta/etc/tfw-root.key;
resp_hdr_set Strict-Transport-Security "max-age=31536000; includeSubDomains";
frang_limits {
http_methods GET;
http_uri_len 512;
http_resp_code_block 400 403 404 3 10;
}
proxy_pass default;
}
cache 0;
frang_limits {
client_header_timeout 20;
client_body_timeout 10;
http_header_chunk_cnt 10;
http_body_chunk_cnt 0;
}
block_action attack reply;
http_chain {
-> default;
}
Example 3. Overriding Frang limits default values.
# Any limits can be overridden, update just one to keep the example short.
frang_limits {
http_uri_len 1024;
}
vhost crm.example.com {
# No `frang_limits` section in this vhost, effective Frang configuration is:
# http_uri_len 1024;
...
}
frang_limits {
http_uri_len 2048;
}
# Frang configuration was updated, current defaults is:
# http_uri_len 2048;
vhost example.com {
location prefix "/img/" {
frang_limits {
http_uri_len 3096;
}
# Frang configuration was updated inside location, current defaults is:
# http_uri_len 3096;
}
location prefix "/video/" {
# Frang configuration was not updated inside location, keep using
# global defaults. Effective configuration is:
# http_uri_len 2048;
}
frang_limits {
http_uri_len 1024;
}
# Frang configuration was updated, current defaults for other locations is:
# http_uri_len 1024;
location prefix "/docs/" {
# Frang configuration was not updated inside location, keep using
# global defaults. Effective configuration is:
# http_uri_len 1024;
}
# Frang limits for implicit default location is:
# http_uri_len 1024;
}
vhost test-net.com {
# Frang settings was updated multiple times in vhost `example.com` section,
# but that changes doesn't affect global defaults. Effective configuration
# is:
# http_uri_len 2048;
}
...
Following configuration options define allowed character sets in various HTTP fields:
-
http_uri_brange - URI path. Note that Accept and Referer headers are also verified by the characters set.
-
http_token_brange - each header field value defined with 'token' by RFC 7230, e.g. unknown for Tempesta FW HTTP methods and HTTP headers, Connection or Transfer-Encoding extension values, Cookie name (note that value is processed with its own alphabet
http_cookie_brange
), E-Tag value. -
http_qetoken_brange - 'token' with DQUOTE and '=', e.g. Cache-Control, Pragma, and Keep-Alive headers extension values.
-
http_nctl_brange - 'non-control characters' for generic filed values defined by RFC 7230 Apendix B and RFC 5234 Apendix B.1. Currently used for HTTP date headers, such as Expires, Date, Last-Modified, and If-Modified-Since, extension values only.
-
http_xff_brange - X-Forwarded-For Node ID defined by RFC 7239.
-
http_etag_brange - ETag accepted characters set (RFC 7232 2.3).
-
http_cookie_brange - Cookie header values.
-
http_ctext_vchar_brange - 'ctext | VCHAR' headers, e.g. User-Agent.
Syntax for the directives is:
http_XXX_brange RANGES
, where RANGES
is a list of space separated ranges (integers in range [0-255])
or integers for single characters. Hex and decimal encodings are accepted.
Example:
http_uri_brange 0x2f 0x61-0x7a 48 0x2A;
HTTP Strict Transport Security (HSTS)
is defined in (RFC 6797) and can be
implemented just by adding Strict-Transport-Security
header to a required
vhost or location:
resp_hdr_set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Let's see a simple example to understand Tempesta filtering.
Run Tempesta FW with Frang configured and put some load onto the system to make Frang generate a blocking rule:
$ dmesg | grep frang
[tempesta] Warning: frang: connections max num. exceeded for 192.168.0.1: 9 (lim=8)
Frang's rate limiting calls the filter module that stores the blocked IPs in Tempesta DB, so now we can run some queries on the database (you can read more about tdbq):
# ./tdbq -a info
Tempesta DB version: 0.1.14
Open tables: filter
INFO: records=1 status=OK zero-copy
The table filter
contains all blocked IP addresses.
- Home
- Requirements
- Installation
-
Configuration
- Migration from Nginx
- On-the-fly reconfiguration
- Handling clients
- Backend servers
- Load Balancing
- Caching Responses
- Non-Idempotent Requests
- Modify HTTP Messages
- Virtual hosts and locations
- HTTP Session Management
- HTTP Tables
- HTTP(S) Security
- Header Via
- Health monitor
- TLS
- Virtual host confusion
- Traffic Filtering by Fingerprints
- Run & Stop
- Application Performance Monitoring
- Use cases
- Performance
- Contributing