yunvnadmin 发表于 2015-11-20 13:46:18

high performance WAF platform with Naxsi and HAProxy

http://blog.exceliance.fr/2012/10/16/high-performance-waf-platform-with-naxsi-and-haproxy/



Synopsis
  I’ve already described WAF in a previous article, where I spoke about
WAF scalability with apache and modsecurity.

One of the main issue with Apache and modsecurity is the performance. To address this issue, an alternative exists:naxsi, a Web Application Firewall
module fornginx.
  So using Naxsi and HAProxy as a load-balancer, we’re able to build a platform which meets the following requirements:


[*]Web Application Firewall: achieved by Apache andmodsecurity
[*]High-availability: application server and WAF monitoring, achieved byHAProxy
[*]Scalability: ability to adapt capacity to the upcoming volume of traffic, achieved byHAProxy
[*]DDOS protection: blind and brutal attacks protection, slowloris protection, achieved byHAProxy
[*]Content-Switching: ability to route only dynamic requests to the WAF, achieved byHAProxy
[*]Reliability: ability to detect capacity overusage, this is achieved byHAProxy
[*]Performance: deliver response as fast as possible, achieved by the whole platform
  The picture below provides a better overview:


  The LAB platform is composed by 6 boxes:


[*]2 ALOHA Load-Balancers (could be replaced by HAProxy 1.5-dev)
[*]2 WAF servers: CentOS 6.0, nginx and Naxsi
[*]2 Web servers: Debian + apache + PHP + dokuwiki

Nginx and Naxsi installation on CentOS 6
  Purpose of this article is not to provide such procedue. So please read this wiki article which summarizeshow to install nginx
and naxsi on CentOS 6.0.

Diagram
  The diagram below shows the platform with HAProxy frontends (prefixed byft_) and backends (prefixed by
bk_). Each farm is composed by 2 servers.



Configuration

Nginx and Naxsi



Configure nginx as a reverse-proxy which listen in bk_waf and forward traffic to ft_web. In the mean time,naxsi is there to analyze the requests.


01
server {


02
proxy_set_header Proxy-Connection "";


03
listen       192.168.10.15:81;


04
access_log/var/log/nginx/naxsi_access.log;


05
error_log/var/log/nginx/naxsi_error.log debug;


06


07
location / {


08
include    /etc/nginx/test.rules;


09
proxy_pass
http://192.168.10.2:81/;


10
}


11


12
error_page 403 /403.html;


13
location = /403.html {


14
root /opt/nginx/html;


15
internal;


16
}


17


18
location /RequestDenied {


19
return 403;


20
}


21
}

HAProxy Load-Balancer configuration



The configuration below allows the following advanced features:

[*]DDOS protection on the frontend
[*]abuser or attacker detection in bk_waf and blocking on the public interface (ft_waf)
[*]Bypassing WAF when overusage or unavailable


001
######## Default values for all entries till next defaults section


002
defaults


003
optionhttp-server-close


004
optiondontlognull


005
optionredispatch


006
optioncontstats


007
retries 3


008
timeout connect 5s


009
timeout http-keep-alive 1s


010
# Slowloris protection


011
timeout http-request 15s


012
timeout queue 30s


013
timeout tarpit 1m          # tarpit hold tim


014
backlog 10000


015


016
# public frontend where users get connected to


017
frontend ft_waf


018
bind 192.168.10.2:80 name http


019
mode http


020
log global


021
option httplog


022
timeout client 25s


023
maxconn 10000


024


025
# DDOS protection


026
# Use General Purpose Couter (gpc) 0 in SC1 as a global abuse counter


027
# Monitors the number of request sent by an IP over a period of 10 seconds


028
stick-table type ip size 1m expire 1m store gpc0,http_req_rate(10s),http_err_rate(10s)


029
tcp-request connection track-sc1 src


030
tcp-request connection reject if { sc1_get_gpc0 gt 0 }


031
# Abuser means more than 100reqs/10s


032
acl abuse sc1_http_req_rate(ft_web) ge 100


033
acl flag_abuser sc1_inc_gpc0(ft_web)


034
tcp-request content reject if abuse flag_abuser


035


036
acl static path_beg /static/ /dokuwiki/images/


037
acl no_waf nbsrv(bk_waf) eq 0


038
acl waf_max_capacity queue(bk_waf) ge 1


039
# bypass WAF farm if no WAF available


040
use_backend bk_web if no_waf


041
# bypass WAF farm if it reaches its capacity


042
use_backend bk_web if static waf_max_capacity


043
default_backend bk_waf


044


045
# WAF farm where users' traffic is routed first


046
backend bk_waf


047
balance roundrobin


048
mode http


049
log global


050
option httplog


051
option forwardfor header X-Client-IP


052
option httpchk HEAD /waf_health_check HTTP/1.0


053


054
# If the source IP generated 10 or more http request over the defined period,


055
# flag the IP as abuser on the frontend


056
acl abuse sc1_http_err_rate(ft_waf) ge 10


057
acl flag_abuser sc1_inc_gpc0(ft_waf)


058
tcp-request content reject if abuse flag_abuser


059


060
# Specific WAF checking: a DENY means everything is OK


061
http-check expect status 403


062
timeout server 25s


063
default-server inter 3s rise 2 fall 3


064
server waf1 192.168.10.15:81 maxconn 100 weight 10 check


065
server waf2 192.168.10.16:81 maxconn 100 weight 10 check


066


067
# Traffic secured by the WAF arrives here


068
frontend ft_web


069
bind 192.168.10.2:81 name http


070
mode http


071
log global


072
option httplog


073
timeout client 25s


074
maxconn 1000


075
# route health check requests to a specific backend to avoid graph pollution in ALOHA GUI


076
use_backend bk_waf_health_check if { path /waf_health_check }


077
default_backend bk_web


078


079
# application server farm


080
backend bk_web


081
balance roundrobin


082
mode http


083
log global


084
option httplog


085
option forwardfor


086
cookie SERVERID insert indirect nocache


087
default-server inter 3s rise 2 fall 3


088
option httpchk HEAD /


089
# get connected on the application server using the user ip


090
# provided in the X-Client-IP header setup by ft_waf frontend


091
source 0.0.0.0 usesrc hdr_ip(X-Client-IP)


092
timeout server 25s


093
server server1 192.168.10.11:80 maxconn 100 weight 10 cookie server1 check


094
server server2 192.168.10.12:80 maxconn 100 weight 10 cookie server2 check


095


096
# backend dedicated to WAF checking (to avoid graph pollution)


097
backend bk_waf_health_check


098
balance roundrobin


099
mode http


100
log global


101
option httplog


102
option forwardfor


103
default-server inter 3s rise 2 fall 3


104
timeout server 25s


105
server server1 192.168.10.11:80 maxconn 100 weight 10 check


106
server server2 192.168.10.12:80 maxconn 100 weight 10 check

Detecting attacks



On the load-balancer



The ft_waf frontend stick table tracks two information:
http_req_rate and http_err_rate which are respectively thehttp request rate and the
http error rate generated by a single IP address.

HAProxy would automatically block an IP which has generated more than 100 requests over a period of 10s or 10 errors (WAF detection 403 responses included) in 10s. The user isblocked for 1 minute as long as he keeps on abusing.

Of course, you can setup above values to whatever you need: it is fully flexible.  To know the status of IPs in your load-balancer, just run the command below:

echo show table ft_waf | socat /var/run/haproxy.stat -
# table: ft_waf, type: ip, size:1048576, used:1
0xc33304: key=192.168.10.254 use=0 exp=4555 gpc0=0 http_req_rate(10000)=1 http_err_rate(10000)=1
  Note: The ALOHA Load-balancer does not provide watch tool, but you can monitor the content of the table in live with the command below:

while true ; do echo show table ft_waf | socat /var/run/haproxy.stat - ; sleep 2 ; clear ; done
On the Waf



Every Naxsi error log appears in /var/log/nginx/naxsi_error.log. IE:
2012/10/16 13:40:13 10556#0: *10293 NAXSI_FMT: ip=192.168.10.254&server=192.168.10.15&uri=/testphp.vulnweb.com/artists.php&total_processed=3195&total_blocked=2&zone0=ARGS&id0=1000&var_name0=artist, client: 192.168.10.254, server: , request: "GET /testphp.vulnweb.com/artists.php?artist=0+div+1+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user HTTP/1.1", host: "192.168.10.15:81"
  Naxsi log line is less obvious than modsecurity one. The rule which matched os provided by the argumentidX=abcde.

No false positive during the test, I had to build a request to make Naxsi match it .

conclusion



Today, we saw it’s easy to build a scalable and performing WAF platform in front of any web application.

The WAF is able to communicate to HAProxy which IPs to automatically blacklist (throuth error rate monitoring), which is convenient since the attacker won’t bother the WAF for a certain amount of time

The platform allows to detect WAF farm availability and to bypass it in case of total failure, we even saw it is possible to bypass the WAF for static content if the farm is running out of capacity. Purpose is to deliver a good end-user experience without dropping
too much the security.

Note that it is possible to route all the static content to the web servers (or astatic farm) directly,
whatever the status of the WAF farm.

This make me say that the platform is fully scallable and flexible.

Thanks to HAProxy, the architecture is very flexible: I could switch my apache + modexurity to nginx + naxsi with no issues at all This could be done
as well for any third party waf appliances.

Note that I did not try any naxsi advanced features like learning mode and the UI as well.
Related links


[*]naxsi
[*]HTTP request flood mitigation
[*]Use a load-balancer as a first row of defense against DDOS

Links


[*]Exceliance
[*]Aloha load balancer: HAProxy based LB appliance
[*]HAPee: HAProxy Enterprise Edition
页: [1]
查看完整版本: high performance WAF platform with Naxsi and HAProxy