Skip to content

Commit eb0d5d6

Browse files
committed
Swap mod_evasive with mod_shield
1 parent 0a53b80 commit eb0d5d6

File tree

3 files changed

+199
-1
lines changed

3 files changed

+199
-1
lines changed

docs/.vuepress/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ module.exports = {
180180
children: [
181181
"admin/Apache",
182182
"admin/PHP-FPM",
183-
"admin/Evasive",
183+
"admin/Shield",
184184
"admin/ModSecurity",
185185
"admin/Fortification",
186186
"admin/Audit"

docs/admin/Shield.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
title: Brute-force protection
3+
4+
---
5+
6+
**New in 3.2.48**
7+
8+
mod_shield is an advanced bean counter that tracks HTTP requests, status codes, and response times over a large window to discriminate against malicious actors. When an IP address exceeds the point threshold within the duration, a configurable response is immediately returned and information is emitted from syslog to fail2ban, which allows [Rampart](../FIREWALL.md) to respond to to the incident. Additionally a file named */tmp/dos-IP* is created marking the event.
9+
10+
Requests are tracked by two methods: same URI and same site. An IP which exceeds either limit is blocked in the same manner.
11+
12+
## Configuration
13+
14+
`apache.shield` [Scope](Scopes.md) manages mod_shield parameters. This Scope interacts with /etc/httpd/conf.d/shield.conf and adds a 2 minute delay to reloading HTTP configuration.
15+
16+
*Apache directives are parenthesized for each named directive.*
17+
18+
### Page tracking
19+
20+
Same URI tracks the full URI provided to Apache. When `canonical` (`DOSCanonical on|off`) is enabled (default), query strings are truncated from the request: */foo* is the same as */foo?bar=baz* and */foo?quu=qux&bar=baz*.
21+
22+
`page-count` (`DOSPageCount AMOUNT`) and `page-interval` (`DOSPageInterval SECONDS`) control hit count and window. Recommended settings are a low interval and count greater than interval.
23+
24+
```bash
25+
cpcmd scope:set apache.shield page-count 20
26+
cpcmd scope:set apache.shield page-interval 5
27+
```
28+
29+
Above triggers protection if more than a score of 20 is reached on the same URI within 5 seconds.
30+
31+
### Page deadlines
32+
33+
Scoring may be adjusted if a response takes longer than *n* seconds using `shield-deadline` (`DOSPageDeadline DURATION SCORE|off`). Score may be any whole number, positive or negative. Deadlines are additive. Each page request always generates 1 point. Setting `off` disables this feature.
34+
35+
```bash
36+
# Any page that loads below 250 ms receives a -2 score
37+
cpcmd scope:set apache.shield-deadline 0 -2
38+
# Ignore any page that loads under 500 ms
39+
cpcmd scope:set apache.shield-deadline 0.250 0
40+
# Any page that loads above 500 ms is scored 1 extra point
41+
cpcmd scope:set apache.shield-deadline 0.500 1
42+
# Alternative form
43+
cpcmd scope:set apache.shield-deadline '[0:-2, 0.250:0, 0.500:1]'
44+
45+
# Cancel 250 ms score
46+
cpcmd scope:set apache.shield-deadline 0.250 null
47+
# Reset scoring to default
48+
cpcmd scope:set apache.shield-deadline null
49+
# Disable all deadline scoring
50+
cpcmd scope:set apache.shield-deadline false
51+
# Accepted for interoperability
52+
cpcmd scope:set apache.shield-deadline off
53+
```
54+
55+
### Site tracking
56+
57+
Site tracking ignores URI distinctions and looks at all requests originating from an IP against a HTTP hostname. */foo* and */bar* both accumulate hits.
58+
59+
`site-count` (`DOSSiteCount AMOUNT`) and `site-interval` (`DOSSiteInterval SECONDS`) control hit count and window. This ratio *must* be higher than page-based accumulation. Setting a high interval or low count will trigger false positives at a much higher rate, especially in plugin-dependent Web Applications, such as WordPress.
60+
61+
```bash
62+
cpcmd scope:set apache.shield site-count 300
63+
cpcmd scope:set apache.shield site-interval 2
64+
```
65+
66+
Above triggers protection if more than 300 requests are made within 2 seconds.
67+
68+
### Status penalties
69+
70+
Scoring may be adjusted for any HTTP response code, such as a 304, 403, 404 or even a custom status like [418 I'm a teapot](https://en.wikipedia.org/wiki/Hyper_Text_Coffee_Pot_Control_Protocol) using `shield-status` (`DOSPageStatus STATUS SCORE|off`).. Status codes are evaluated from the *final* response in a processing pipeline.
71+
72+
```bash
73+
# Add 50 points if HTTP status code is 418
74+
cpcmd scope:set apache.shield-status 418 50
75+
# Remove penalty for 302, "0" works as well
76+
cpcmd scope:set apache.shield-status 302 false
77+
# Add a -5 point adjustment for 204, not modified
78+
cpcmd scope:set apache.shield-status 204 -5
79+
# Reset scoring to default
80+
cpcmd scope:set apache.shield-status null
81+
# Disable all deadline scoring
82+
cpcmd scope:set apache.shield-status false
83+
# Accepted for interoperability
84+
cpcmd scope:set apache.shield-status off
85+
```
86+
87+
### Status handler
88+
89+
A separate status handler named `shield-status` is available. Settings, active blocks, and individual counters for same-page and site resources are provided.
90+
91+
It may be activated with the following directives in `/etc/httpd/conf/httpd-custom.conf`:
92+
93+
```makefile
94+
<Location /shield>
95+
SetHandler shield-handler
96+
# It's a good idea to limit traffic to your IP.
97+
# Accepts CIDR-style
98+
Require ip your.ip.address
99+
</Location>
100+
```
101+
102+
![Shield sample handler](./images/shield-handler.png)
103+
104+
105+
### Empirical estimates
106+
107+
Running a site through webpagetest.org or using [DevTools](https://developers.google.com/web/tools/chrome-devtools) to see the average number of subrequests per page view can help you estimate a good baseline for your site. An ideal setting allows typical usage while disabling atypical extremes: bots don't adhere to netiquette when brute-forcing credentials. Some protection is necessary.
108+
109+
### Disabling per site
110+
111+
Shield may be disabled directly with `DOSEnabled off` or indirectly by setting *apache*,*shield*=0 for the site.
112+
113+
#### Direct disablement
114+
Create a file named `custom` in `/etc/httpd/conf/siteXX` where *siteXX* is the site ID for the domain. `get_site_id domain.com` from command-line will help you locate this value. Within `custom` add:
115+
116+
`DOSEnabled off`
117+
118+
Then rebuild and reload, `htrebuild && systemctl reload httpd`.
119+
120+
#### Indirect
121+
```bash
122+
EditDomain -c shield,shield=0 domain.com
123+
```
124+
125+
## Status handler
126+
127+
128+
## Filtering individual resources
129+
130+
mod_shield is context-aware using Apache directives. For example, Shield ships with a filter to restrict POST attempts to xmlrpc.php and wp-login.php. `cpcmd config:set apache.shield-wordpress-filter true` enables this filter with a very stringent post rate of 3 attempts in 2 seconds.
131+
132+
As an example, the following rule applies to files named "wp-login.php", *glob is quicker than regular expression patterns by a factor of 5-10x!* If the request method isn't a POST, disable bean counting. If more than 3 POST attempts to the same resource occur within a 2 second interval, then return a `DOSHTTPStatus` response (429 Too Many Requests) and log the message via syslog to /var/log/messages. fail2ban will pick up the request and place the IP address into the temporary ban list.
133+
134+
# Block wp-login brute-force attempts
135+
<Files "wp-login.php">
136+
<If "%{REQUEST_METHOD} != 'POST'">
137+
DOSEnabled off
138+
</If>
139+
DOSPageCount 3
140+
DOSPageInterval 2
141+
</Files>
142+
143+
### Customizing
144+
145+
Copy `resources/templates/rampart/shield/wordpress-filter.blade.php` to `config/custom/resources/templates/rampart/shield/wordpress-filter.blade.php` creating parent directory structure as necessary:
146+
147+
```bash
148+
cd /usr/local/apnscp
149+
install -D -m 644 resources/templates/rampart/shield/wordpress-filter.blade.php config/custom/resources/templates/rampart/shield/wordpress-filter.blade.php
150+
```
151+
152+
**First time** use requires regeneration of cache or restart of ApisCP,
153+
154+
```bash
155+
cd /usr/local/apnscp
156+
./artisan config:clear
157+
```
158+
159+
## Adjusting cache size
160+
161+
Shield implements a cyclic shared buffer - default 512 KB - for each tracking criteria (site, page, and blocks). Each record is 176 bytes allowing for 2,978 unique entries that covers approximately 25 unique requests/second over a 2 minute tracking window.
162+
163+
Cache backend and size are both modifiable. [Redis](https://httpd.apache.org/docs/2.4/mod/mod_socache_redis.html) and [Memcached](https://httpd.apache.org/docs/2.4/mod/mod_socache_memcache.html) may be used to share hit data across servers. Latency spikes during locking may occur with either backend.
164+
165+
`cpcmd config:set apache.shield cache-size N` will adjust the cache size. If no unit is specified, KB is assumed. If a cache provider other than shmcb is active, this setting has no effect.
166+
167+
Cache size can also be set directly in `httpd-custom.conf`.
168+
169+
```
170+
# Resize cache size to 1 MB
171+
DOSCache shmcb:none(1048576)
172+
```
173+
174+
175+
## Proxy Compatibility
176+
177+
Shield may pierce a downstream proxy applying the block directly against the client IP. IPs blocked in this manner cannot be blocked by firewall but will continue to report an error code without further request processing.
178+
179+
### Cloudflare
180+
181+
mod_cloudflare updates the IP address of a request in `ap_hook_post_read_request()` before `ap_hook_access_checker()`; thus, at evaluation `rec->useragent_ip` reflects the upstream IP.
182+
183+
184+
### Others
185+
186+
[mod_remoteip](https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html) defines a set of trusted downstream proxies for which the forwarded IP is truthful. Support may be added in [httpd-custom.conf](Customizing.md#Apache).
187+
188+
```
189+
LoadModule remoteip_module modules/mod_remoteip.so
190+
# Header downstream sends connecting IP
191+
RemoteIPHeader X-Client-IP
192+
RemoteIPTrustedProxy 4.4.4.4
193+
```
194+
195+
::: info Trusting internal network addresses
196+
`RemoteIPTrustedProxy` discards any internal network ranges (10/8, 172.16/12, 192.168/16, 169.254/16, 127/8 or outside IPv6 public 2000::/3 block). Specify [`RemoteIPInternalProxy`](https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html#remoteipinternalproxy) instead if your network topology includes internal networks also subject to filtering.
197+
:::
198+
551 KB
Loading

0 commit comments

Comments
 (0)