Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L7 IP blocking #934

Open
krizhanovsky opened this issue Mar 4, 2018 · 4 comments
Open

L7 IP blocking #934

krizhanovsky opened this issue Mar 4, 2018 · 4 comments

Comments

@krizhanovsky
Copy link
Contributor

krizhanovsky commented Mar 4, 2018

Currently filter module just filters IPs loaded by tfw_filter_block_ip() and this is duplication of nftables functionality. However, we need this to quickly load up to 1M IP filtering rules, managing them and provide persistency on reboot (i.e. if we dynamically load 1M rules and then reboot the server, all the rules must be reloaded on the server startup). nftables and IPset partially address these issues, so need to replace filter module by an interface to nftables and probably patch nftables to provide them quick index and persistency. The final filter data set must have quick index for the rules and be preferably NUMA-aware.

Action interface for different filtration strategies

Actually, nftables isn't the only and most efficient way to filter DDoS attacks. Instead of generating nftable rule. it has sense to generate/modify an XDP program. The other frequent way to defeat DDoS is to announce blocked IPs via BGP to a router. So the filter must implement a configuration option (the exact syntax is to be discussed):

filter <filter_name> <action>

, so HTTP tables plus block action (blocking traffic on application layer) can use filter_name (this must be implemented) to run custom action and block traffic on L3 and lower layers. <filter_name> is just a string identifier. <action> should define exact nftable, XDP or user space script call (this is also TBD).

@krizhanovsky krizhanovsky added this to the 0.9 Web server milestone Mar 4, 2018
@krizhanovsky krizhanovsky changed the title Filter unification with {ip,nf}tables Filter unification with {ip,nf}tables and/or XDP Jul 20, 2018
@krizhanovsky
Copy link
Contributor Author

Aggregate the issue with #1042 - filtering IP on XDP:

Recent research shows that filtering single IP address can be ten times more efficient with XDP than with iptables. That can be handy to mitigate DDoS attacks.

@krizhanovsky krizhanovsky changed the title Filter unification with {ip,nf}tables and/or XDP Filter unification with nftables and/or XDP Jul 20, 2018
@krizhanovsky krizhanovsky modified the milestones: 1.3 Web server, 1.2 TDB v0.2 Aug 8, 2018
@i-rinat
Copy link
Contributor

i-rinat commented Oct 19, 2018

Currently (1617736), tfw_filter_block_ip() uses simple hashing tfw_ipv6_hash():

static unsigned long
tfw_ipv6_hash(const struct in6_addr *addr)
{
        return ((unsigned long)addr->s6_addr32[0] << 32)
               ^ ((unsigned long)addr->s6_addr32[1] << 24)
               ^ ((unsigned long)addr->s6_addr32[2] << 8)
               ^ addr->s6_addr32[3];
}

which is fine for IPv4 addresses, but dangerous for IPv6. Clients with IPv6 usually have /64 (or in rare cases, /48) subnet at their disposal, which gives them control over at least 64 bits of the address.

Such clients can (1) circumvent address blocking, or (2) poison storage for IPs by overloading particular buckets. We need to prevent that.

One of the solutions is to always discard last 64 bits of IPv6 address. In other words, always block whole /64 subnets.

@krizhanovsky krizhanovsky modified the milestones: 1.2 TDB v0.3, 1.1 QUIC Feb 2, 2019
@krizhanovsky krizhanovsky changed the title Filter unification with nftables and/or XDP L7 IP blocking Sep 19, 2019
@krizhanovsky
Copy link
Contributor Author

krizhanovsky commented Sep 19, 2019

Introduction

The initial task statement is wrong for Tempesta design: we're L7 firewall and we should be able to filter IP addresses came through L7 proxies. So instead of current logic mimic L3 firewall we must use real client IP from X-Forwarded-For, X-Real-IP or Forwarded: for headers. So depends on #1350 (Forwarded HTTP header by RFC 7239).

We need to implement real IP definition taking into account trusted sources. Also an attacker could cause a confusion e.g. by setting all the headers at the same time to different values. Such and similar cases must handled.

The task is partially a bug since we can not correctly filter traffic if Tempesta FW there is a proxy between a client and Tempesta FW.

Both the initial (from skb) and resolved (from all the headers) client IPs must be written to access log.

New config options

All the variables must be global and should be reconfigurable on the fly.

We have #1350 parsing standard headers, so we don't need to support Nginx's real_ip_header option. Client IP resolving must be recursive (i.e. stop on first untrusted IP) and the search always must scan HTTP headers in the same order.

Need to implement a new trusted_ip_from config option mimicing http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from . Only IP (e.g. 1.1.1.1) or subnets (e.g. 1.1.1.0/24) in IPv4 and IPv6 must be supported.

Use 4-bit per level Linux radix tree or TDB HTtrie with a modification to keep 8 layers instead of current constant 16 (subnets just use zeroes on last levels).

The new filter logic

Now filter.c must use the resolved client IP for blocking. The filter.c and http_limit.c logic must be called after IP resolving, so if there is no trusted_ip_from, then the whole logic is just equivalent for the current one.

Documentation

The image https://github.com/tempesta-tech/tempesta/wiki/DDoS-mitigation obviously becomes false and must be updated.

The new config option must be described in https://github.com/tempesta-tech/tempesta/wiki/Handling-clients

If reconfiguration on the fly is implemented, then https://github.com/tempesta-tech/tempesta/wiki/On-the-fly-Reconfiguration must also be updated.

Testing

Test for the issue tempesta-tech/tempesta-test#216

const-t added a commit that referenced this issue Mar 6, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Mar 7, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Mar 8, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Mar 8, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Mar 8, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Mar 15, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Apr 13, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue May 20, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Jun 28, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Jun 28, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Jul 1, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
kingluo pushed a commit that referenced this issue Aug 2, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Aug 6, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
EvgeniiMekhanik pushed a commit that referenced this issue Aug 7, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Oct 25, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
const-t added a commit that referenced this issue Oct 29, 2024
This logic might be used and should be revisioned
only after implementation #934 issue.
@krizhanovsky krizhanovsky modified the milestones: 1.1: TBD, 1.0 - GA Nov 2, 2024
@krizhanovsky
Copy link
Contributor Author

#2074 disables the client User-Agent logic and relies on IP addresses only, so multi-CDN and other proxying in front of Tempesta FW cause identification problems. So move to earlier milestone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants