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

HTTP tables #731

Closed
krizhanovsky opened this issue May 13, 2017 · 2 comments
Closed

HTTP tables #731

krizhanovsky opened this issue May 13, 2017 · 2 comments

Comments

@krizhanovsky
Copy link
Contributor

krizhanovsky commented May 13, 2017

Current HTTP scheduler must be reworked to more generic HTTP tables (just like IPtables or Nftables) and work with lower TCP/IP filtering logic using nftables mark. An example for the new HTTP tables (based on example from https://github.com/tempesta-tech/tempesta/wiki/Scheduling-and-Load-Balancing#http-scheduler-for-server-groups) :

# Server groups, just the same as previously.
srv_group waf { ... }
srv_group static { ... }
srv_group foo_app { ... }
srv_group foo_app_backup { ... }

# Logical HTTP tables are defined before their usage and have names.
# This requirement enforces absense of loops.
http_chain resource_chain {
        uri == "*.php" -> static;
        host == "static.*" -> static;
        host == "foo.example.com" -> foo_app backup=foo_app_backup;
        hdr_raw == "X-Custom-Bar-Hdr: *" -> static;
}

# WAF redirection rules from issue #760.
http_chain waf_chain {
        # 4. ...the mark should be used to forward the request to backend.
        mark == 2 -> resource_chain;
        # 2. Tempesta must forward it to WAF by some scheduling policy.
        # Set mark to send an information for nftables.
        -> mark = 3;
        -> waf;
}

# The main HTTP table w/o name. Always the last one.
http_chain {
        # Block DDoS requests early using nftables mark.
        # Process value of skb->mark set by nftables
        mark != 1 -> waf_chain;
        referer != "*hacked.com" -> waf_chain;
        # Default rule instead of "match <SRV_GROUP> * * *:
        -> block;
}       

Note rule referer != "*hacked.com" -> waf_chain - this is essentially L7 filtering rule. It's expected to have many of such rules produced in run-time, so all the rules must be dynamically reconfigurable in sense of #51.

There are several aspects for reworking described at the below.

Extend http_match headers set

Currently not all special headers are handled in tfw_http_match_fld_t, e.g. it doesn't handle X-Forwarded-For, User-Agent or Cookie. Also Refer header must be made special and properly handled by http_match. The last one is important to properly handle iFrame attacks. Update https://github.com/tempesta-tech/tempesta/wiki/DDoS-mitigation#iframes-on-a-busy-site .

Syntax changes

  1. There is no sense for long prefix and suffix: prefix and suffix must be changed to * prefix or suffix correspondingly of a pattern as in usual wildcards.
  2. eq is replaced by ==.
  3. No more senseless match at begin of the scheduler rules.
  4. Introduce new keywords and operators: ->, ==, !=, =, mark, block, referer, user_agent, cookie and maybe other forgotten special headers.
  5. sched_http_rules is renamed to http_table with optional name.

Rules processing

All current functions in tfw_sched_http.c as well as the file itself must be renamed to prefixes tfw_http_tbl. Basically, the corner logictfw_http_match_req() remains the same: the list of rules in http_table are processed one after another. However, do_match() now must be renamed to something like do_eval() and reworked correspondingly since now it must be able to (1) set skb->mark for all skbs inside msg and (2) handle != as well as == (eq), In case of -> mark = 3 rule do_eval() just can return false to move to the next rule in the table.

The new keyword block must block current request according to specified block_action and the chain processing for the request finishes, just the same as for chosen server group now. Probably, if block requires tighter integration with http code, it has sense to more the module from /sched directory and build it within main Tempesta FW module.

mark keyword works in two modes: reading skb->mark as in #844 and setting it for all skbs in current msg.

-> operator is just a syntax sugar for now to separate rule condition from rule action. Further it allow us to develop the rule language by more complex expressions (e.g. ... -> mark = 3, waf instead of 2 lines in the example above).

Documentation & testing

Please revise following docs:

I created issue #883 for the test. Please add other interesting cases to the task.

@krizhanovsky
Copy link
Contributor Author

krizhanovsky commented Feb 10, 2018

A use case (please document it in Wiki) for protection (by Tempesta FW only without introducing a third-party WAF, issue #907 addresses the case with the third-party WAF) of many backend servers with different IP addresses can be configured in efficient way using mark (integer values provided by nftables from destination IP addresses) scheduling instead of Host values string matching:

http_chain {
        mark == 2 -> backend_0;
        mark == 3 -> backend_1;
        mark == 4 -> backend_2;
        mark == 5 -> backend_3;
        ....
}

The scheduling (routing) method can also be useful to correctly route HTTP/1.0 requests without Host header.

While Tempesta FW is able to operate with marks and routing table directly, the problem with the scenario is that Tempesta FW is a full TCP proxy having different TCP connections between a client and a server, so we can't just pass a packet to the right server and have to resend it to a server socket.

Note that it's also expected to work in busy environments with large, and constantly varying, number backend servers, so these rules also must be dynamically reconfigurable in sense of #51.

@krizhanovsky
Copy link
Contributor Author

Since #688 depends on the issue and #471 which change the how server groups are handled, the configuration example at the above with #471 in mind would look like:

# Server groups, just the same as previously.
srv_group waf { ... }
srv_group static { ... }
srv_group foo_app { ... }
srv_group foo_app_backup { ... }

vhost natsys {
        proxy_pass static;
}

vhost tempesta-tech {
        location "?" {
                proxy_pass foo_app backup=foo_app_backup;
                cache_fulfill; # cache all proxied data
        }
}

http_chain resource_chain {
        uri == "*.php" -> natsys;
        host == "static.*" -> natsys;
        # The right side of '->' operator can have server group or vhost
        host == "foo.example.com" -> tempesta-tech;
        hdr_raw == "X-Custom-Bar-Hdr: *" -> natsys;
}

# WAF redirection rules from issue #760.
http_chain waf_chain {
        # 4. ...the mark should be used to forward the request to backend.
        mark == 2 -> resource_chain;
        # 2. Tempesta must forward it to WAF by some scheduling policy.
        # Set mark to send an information for nftables.
        -> mark = 3;
        -> waf;
}

# The main HTTP table w/o name. Always the last one.
http_chain {
        # Block DDoS requests early using nftables mark.
        # Process value of skb->mark set by nftables
        mark != 1 -> waf_chain;
        referer != "*hacked.com" -> waf_chain;
        # Default rule instead of "match <SRV_GROUP> * * *:
        -> block;
}       

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

2 participants