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.
01server {
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
002defaults
003  option  http-server-close
004  option  dontlognull
005  option  redispatch
006  option  contstats
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
017frontend 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
046backend 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
068frontend 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
080backend 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)
097backend 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 the http 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 is blocked 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 [error] 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 a static 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

Links


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值