Dragan Dosen | 59bb97a | 2017-06-02 12:03:16 +0200 | [diff] [blame] | 1 | -------------------------- |
| 2 | Mod Defender for HAProxy |
| 3 | -------------------------- |
| 4 | |
| 5 | |
| 6 | This is a service that talks SPOE protocol and uses the Mod Defender |
| 7 | (https://github.com/VultureProject/mod_defender) functionality to detect |
| 8 | HTTP attacks. It returns a HTTP status code to indicate whether the request |
| 9 | is suspicious or not, based on NAXSI rules. The value of the returned code |
| 10 | can be used in HAProxy rules to determine if the HTTP request should be |
| 11 | blocked/rejected. |
| 12 | |
| 13 | Unlike ModSecurity, Mod Defender is a whitelist based WAF (everything is |
| 14 | disallowed, unless there are rules saying otherwise). It's a partial |
| 15 | replication of NAXSI and it uses NAXSI compatible rules configuration |
| 16 | format. |
| 17 | |
| 18 | |
| 19 | 1) How to build it |
| 20 | ------------------ |
| 21 | |
| 22 | Required packages : |
| 23 | |
| 24 | * Mod Defender source (https://github.com/VultureProject/mod_defender) |
| 25 | * Asynchronous event notification library and headers (libevent) |
| 26 | * Apache 2 (>= 2.4) development headers |
| 27 | * APR library and headers |
| 28 | * GNU C (gcc) and C++ (g++) >= 4.9 |
| 29 | * GNU Standard C++ Library v3 (libstdc++) |
| 30 | * GNU Make |
| 31 | |
| 32 | |
| 33 | Compile the source : |
| 34 | |
| 35 | $ make MOD_DEFENDER_SRC=/path/to/mod_defender_src |
| 36 | |
| 37 | |
| 38 | 2) Configuration |
| 39 | ---------------- |
| 40 | |
| 41 | Download the Naxsi core rules file : |
| 42 | |
| 43 | $ wget -O /path/to/core.rules \ |
| 44 | https://raw.githubusercontent.com/nbs-system/naxsi/master/naxsi_config/naxsi_core.rules |
| 45 | |
| 46 | |
| 47 | Create the Mod Defender configuration file. For example : |
| 48 | |
| 49 | # Defender toggle |
| 50 | Defender On |
| 51 | # Match log path |
| 52 | MatchLog /path/to/defender_match.log |
| 53 | # JSON Match log path |
| 54 | JSONMatchLog /path/to/defender_json_match.log |
| 55 | # Request body limit |
| 56 | RequestBodyLimit 8388608 |
| 57 | # Learning mode toggle |
| 58 | LearningMode Off |
| 59 | # Extensive Learning log toggle |
| 60 | ExtensiveLog Off |
| 61 | # Libinjection SQL toggle |
| 62 | LibinjectionSQL On |
| 63 | # Libinjection XSS toggle |
| 64 | LibinjectionXSS On |
| 65 | |
| 66 | # Rules |
| 67 | Include /path/to/core.rules |
| 68 | |
| 69 | # Score action |
| 70 | CheckRule "$SQL >= 8" BLOCK |
| 71 | CheckRule "$RFI >= 8" BLOCK |
| 72 | CheckRule "$TRAVERSAL >= 4" BLOCK |
| 73 | CheckRule "$EVADE >= 4" BLOCK |
| 74 | CheckRule "$XSS >= 8" BLOCK |
| 75 | CheckRule "$UPLOAD >= 8" BLOCK |
| 76 | |
| 77 | # Whitelists |
| 78 | # .... |
| 79 | |
| 80 | |
| 81 | Next step is to configure the SPOE for use with the Mod Defender service. |
| 82 | Example configuration (args elements order is important) : |
| 83 | |
| 84 | [mod_defender] |
| 85 | |
| 86 | spoe-agent mod-defender-agent |
| 87 | messages check-request |
| 88 | option var-prefix defender |
| 89 | timeout hello 100ms |
| 90 | timeout idle 30s |
| 91 | timeout processing 15ms |
| 92 | use-backend spoe-mod-defender |
| 93 | |
| 94 | spoe-message check-request |
| 95 | args src unique-id method path query req.ver req.hdrs_bin req.body |
| 96 | event on-frontend-http-request |
| 97 | |
| 98 | |
| 99 | The engine is in the scope "mod_defender". To enable it, you must set the |
| 100 | following line in a frontend/listener section : |
| 101 | |
| 102 | frontend my_frontend |
| 103 | ... |
| 104 | filter spoe engine mod_defender config /path/to/spoe-mod-defender.conf |
| 105 | ... |
| 106 | |
| 107 | |
| 108 | Also, we must define the "spoe-mod-defender" backend in HAProxy configuration : |
| 109 | |
| 110 | backend spoe-mod-defender |
| 111 | mode tcp |
| 112 | balance roundrobin |
| 113 | timeout connect 5s |
| 114 | timeout server 3m |
| 115 | server defender1 127.0.0.1:12345 |
| 116 | |
| 117 | |
| 118 | The Mod Defender status is returned in a variable "sess.defender.status" -- |
| 119 | it contains the returned HTTP status code. The request is considered |
| 120 | malicious if the variable contains value greater than zero. |
| 121 | |
| 122 | The following rule can be used to reject all suspicious HTTP requests : |
| 123 | |
| 124 | http-request deny if { var(sess.defender.status) -m int gt 0 } |
| 125 | |
| 126 | |
| 127 | 3) Start the service |
| 128 | -------------------- |
| 129 | |
| 130 | To start the service, you need to use "defender" binary : |
| 131 | |
| 132 | $ ./defender -h |
| 133 | Usage : ./defender [OPTION]... |
| 134 | -h Print this message |
| 135 | -f <config-file> Mod Defender configuration file |
| 136 | -l <log-file> Mod Defender log file |
| 137 | -d Enable the debug mode |
| 138 | -m <max-frame-size> Specify the maximum frame size (default : 16384) |
| 139 | -p <port> Specify the port to listen on (default : 12345) |
| 140 | -n <num-workers> Specify the number of workers (default : 10) |
| 141 | -c <capability> Enable the support of the specified capability |
| 142 | -t <time> Set a delay to process a message (default: 0) |
| 143 | The value is specified in milliseconds by default, |
| 144 | but can be in any other unit if the number is suffixed |
| 145 | by a unit (us, ms, s) |
| 146 | |
| 147 | Supported capabilities: fragmentation, pipelining, async |
| 148 | |
| 149 | Example: |
| 150 | |
| 151 | $ ./defender -n 4 -f /path/to/mod_defender.conf -d -l /path/to/error.log |
| 152 | |
| 153 | |
| 154 | 4) Known bugs and limitations |
| 155 | ----------------------------- |
| 156 | |
| 157 | In its current state, the module is limited by haproxy to the analysis of |
| 158 | the first buffer. One workaround may consist in significantly increasing |
| 159 | haproxy's buffer size. |