|
| 1 | +--- |
| 2 | +id: haproxy_spoa |
| 3 | +title: HAProxy SPOA |
| 4 | +--- |
| 5 | + |
| 6 | +import Tabs from '@theme/Tabs'; |
| 7 | +import TabItem from '@theme/TabItem'; |
| 8 | +import useBaseUrl from '@docusaurus/useBaseUrl'; |
| 9 | +import RemediationSupportBadges from '@site/src/components/RemediationSupportBadges.tsx'; |
| 10 | + |
| 11 | +<p align="center"> |
| 12 | +<img src={useBaseUrl('/img/crowdsec_haproxy.svg')} alt="CrowdSec" title="CrowdSec" width="400" height="300" /> |
| 13 | +</p> |
| 14 | +<p align="center"> |
| 15 | +<img src="https://img.shields.io/badge/build-pass-green" /> |
| 16 | +<img src="https://img.shields.io/badge/tests-pass-green" /> |
| 17 | +</p> |
| 18 | +<p align="center"> |
| 19 | +📚 <a href="#installation/">Documentation</a> |
| 20 | +💠 <a href="https://hub.crowdsec.net">Hub</a> |
| 21 | +💬 <a href="https://discourse.crowdsec.net">Discourse </a> |
| 22 | +</p> |
| 23 | + |
| 24 | +<RemediationSupportBadges |
| 25 | + Appsec={false} |
| 26 | + Metrics |
| 27 | + Prometheus |
| 28 | +/> |
| 29 | + |
| 30 | + |
| 31 | +# A Remediation Component for haproxy. |
| 32 | + |
| 33 | + |
| 34 | +## How does it work ? |
| 35 | + |
| 36 | +The `cs-haproxy-spoa-bouncer` allows CrowdSec to enforce blocking, CAPTCHA, or |
| 37 | +allow actions directly within HAProxy using the [SPOE |
| 38 | +protocol](https://www.haproxy.com/blog/introduction-to-the-stream-processing-offload-engine-spoe/). |
| 39 | + |
| 40 | +It supports IP-based decisions, CAPTCHA challenges, GeoIP-based headers, and |
| 41 | +integrates cleanly with CrowdSec’s LAPI using the stream bouncer protocol. |
| 42 | + |
| 43 | +Supported features: |
| 44 | + |
| 45 | + - Stream mode (pull the local API for new/old decisions every X seconds) |
| 46 | + - Ban remediation (can ban an IP address by redirecting him or returning a custom HTML page) |
| 47 | + - Captcha remediation (can return a captcha) |
| 48 | + - Works with IPv4/IPv6 |
| 49 | + - Support IP ranges (can apply a remediation on an IP range) |
| 50 | + |
| 51 | + |
| 52 | +## Installation |
| 53 | + |
| 54 | +### Using packages |
| 55 | + |
| 56 | +First, [setup crowdsec repositories](/docs/next/getting_started/install_crowdsec#install-our-repositories). |
| 57 | + |
| 58 | +<Tabs |
| 59 | + defaultValue="haproxy_debian" |
| 60 | + values={[ |
| 61 | + { label: 'Debian/Ubuntu', value: 'haproxy_debian' ,}, |
| 62 | + { label: 'RHEL/Centos/Fedora', value: 'haproxy_rhel' ,}, |
| 63 | + ] |
| 64 | +}> |
| 65 | +<TabItem value="haproxy_debian"> |
| 66 | + |
| 67 | +```bash |
| 68 | +sudo apt install crowdsec-haproxy-bouncer |
| 69 | +``` |
| 70 | + |
| 71 | +</TabItem> |
| 72 | + |
| 73 | +<TabItem value="haproxy_rhel"> |
| 74 | + |
| 75 | +```bash |
| 76 | +sudo dnf install crowdsec-haproxy-spoa-bouncer |
| 77 | +``` |
| 78 | + |
| 79 | +</TabItem> |
| 80 | + |
| 81 | +</Tabs> |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | +### Manual installation |
| 86 | + |
| 87 | +TODO |
| 88 | + |
| 89 | + |
| 90 | +## Configuration |
| 91 | + |
| 92 | +Create or edit the configuration file at /etc/crowdsec/bouncer/crowdsec-spoa-bouncer.yaml: |
| 93 | +```yaml |
| 94 | +log_mode: file |
| 95 | +log_dir: /var/log/ |
| 96 | +log_level: info |
| 97 | + |
| 98 | +update_frequency: 10s |
| 99 | +api_url: http://127.0.0.1:8080/ |
| 100 | +api_key: ${API_KEY} |
| 101 | +insecure_skip_verify: false |
| 102 | + |
| 103 | +workers: |
| 104 | + - name: spoa1 |
| 105 | + listen_addr: 0.0.0.0:9000 |
| 106 | + listen_socket: /run/crowdsec-spoa/spoa-1.sock |
| 107 | + |
| 108 | +worker_user: crowdsec-spoa |
| 109 | +worker_group: crowdsec-spoa |
| 110 | + |
| 111 | +asn_database_path: /var/lib/crowdsec/data/GeoLite2-ASN.mmdb |
| 112 | +city_database_path: /var/lib/crowdsec/data/GeoLite2-City.mmdb |
| 113 | + |
| 114 | +admin_socket: /run/crowdsec-spoa-admin.sock |
| 115 | + |
| 116 | +prometheus: |
| 117 | + enabled: true |
| 118 | + listen_addr: 127.0.0.1 |
| 119 | + listen_port: 60601 |
| 120 | +``` |
| 121 | +
|
| 122 | +If you installed this bouncer through package, you should already have a working |
| 123 | +configuration file. |
| 124 | +
|
| 125 | +If not you can get an API key with cscli: |
| 126 | +```bash |
| 127 | +sudo cscli bouncers add mybouncer |
| 128 | +API key for 'bouncertest': |
| 129 | + |
| 130 | + JdVa7DKBM35gPDAR014pH/55l38fxLGt02NPPnZgLQI |
| 131 | + |
| 132 | +Please keep this key since you will not be able to retrieve it! |
| 133 | +``` |
| 134 | + |
| 135 | +## HAProxy Configuration |
| 136 | + |
| 137 | +### SPOE Filter |
| 138 | + |
| 139 | +Add a SPOE agent configuration to /etc/haproxy/crowdsec.cfg: |
| 140 | + |
| 141 | +``` |
| 142 | +spoe-agent crowdsec-agent |
| 143 | + messages crowdsec-ip crowdsec-http |
| 144 | + option var-prefix crowdsec |
| 145 | + option set-on-error error |
| 146 | + timeout hello 100ms |
| 147 | + timeout idle 30s |
| 148 | + timeout processing 500ms |
| 149 | + use-backend crowdsec-spoa |
| 150 | + log global |
| 151 | +
|
| 152 | +spoe-message crowdsec-ip |
| 153 | + args id=unique-id src-ip=src src-port=src_port |
| 154 | + event on-client-session |
| 155 | +
|
| 156 | +spoe-message crowdsec-http |
| 157 | + args remediation=var(txn.crowdsec.remediation) \ |
| 158 | + crowdsec_captcha_cookie=req.cook(crowdsec_captcha_cookie) \ |
| 159 | + id=unique-id host=hdr(Host) method=method path=path query=query \ |
| 160 | + version=req.ver headers=req.hdrs body=req.body url=url ssl=ssl_fc |
| 161 | + event on-frontend-http-request |
| 162 | +``` |
| 163 | + |
| 164 | +If you installed the haproxy spoe bouncer through package, you will find this |
| 165 | +configuration file in `/usr/share/docs/crowdsec-haproxy-spoa-bouncer/examples` |
| 166 | + |
| 167 | +This crowdsec spoe agent configuration is then referenced in the main haproxy configuration file. |
| 168 | + |
| 169 | +``` |
| 170 | +frontend http-in |
| 171 | + bind *:80 |
| 172 | + filter spoe engine crowdsec config /etc/haproxy/crowdsec.cfg |
| 173 | + http-request set-header X-CrowdSec-Remediation %[var(txn.crowdsec.remediation)] |
| 174 | + http-request lua.crowdsec_handle if { var(txn.crowdsec.remediation) -m found } |
| 175 | +
|
| 176 | +backend crowdsec-spoa |
| 177 | + mode tcp |
| 178 | + balance roundrobin |
| 179 | + server s1 127.0.0.1:9000 |
| 180 | +``` |
| 181 | +This snippet can also be found in `/usr/share/docs/crowdsec-haproxy-spoa-bouncer/examples/haproxy.cfg`. |
| 182 | + |
| 183 | +### Specific features |
| 184 | + |
| 185 | +#### To enable CAPTCHA for a domain: |
| 186 | + |
| 187 | +``` |
| 188 | +hosts: |
| 189 | + - host: "example.com" |
| 190 | + captcha: |
| 191 | + site_key: "<your-site-key>" |
| 192 | + secret_key: "<your-secret-key>" |
| 193 | + provider: "hcaptcha" |
| 194 | +``` |
| 195 | + |
| 196 | +The following captcha providers are supported: |
| 197 | +``` |
| 198 | +hcaptcha |
| 199 | +recaptcha |
| 200 | +turnstile |
| 201 | +``` |
| 202 | + |
| 203 | +### Prometheus Metrics |
| 204 | + |
| 205 | +Enable and expose metrics: |
| 206 | + |
| 207 | +``` |
| 208 | +prometheus: |
| 209 | + enabled: true |
| 210 | + listen_addr: 127.0.0.1 |
| 211 | + listen_port: 60601 |
| 212 | +``` |
| 213 | + |
| 214 | +Access them at http://127.0.0.1:60601/metrics. |
| 215 | + |
| 216 | +### Admin Socket (to be tested) |
| 217 | + |
| 218 | +You can query the bouncer runtime state using the admin socket: |
| 219 | + |
| 220 | +socat - UNIX-CONNECT:/run/crowdsec-spoa-admin.sock |
| 221 | + |
| 222 | +Commands: |
| 223 | + |
| 224 | + get hosts |
| 225 | + |
| 226 | + get host <host> session <uuid> <key> |
| 227 | + |
| 228 | + set host <host> session <uuid> <key> <value> |
| 229 | + |
| 230 | + get ip <ip> |
| 231 | + |
| 232 | + val host <host> cookie <cookie> |
| 233 | + |
| 234 | + val host <host> captcha <response> |
| 235 | + |
| 236 | + |
0 commit comments