Skip to content

Commit

Permalink
block errorfile-switch
Browse files Browse the repository at this point in the history
  • Loading branch information
ansibleguy committed May 4, 2024
1 parent 2a9e50b commit 485ce62
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 109 deletions.
2 changes: 1 addition & 1 deletion ExampleAcme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ root@test-ag-haproxy-acme:/# cat /etc/haproxy/haproxy.cfg
> ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
> ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
> tune.ssl.capture-buffer-size 96

>
> defaults
> log global
> mode http
Expand Down
7 changes: 5 additions & 2 deletions ExampleGeoIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ haproxy:
## Result
```bash
root@test-ag-haproxy-acme:/# cat /etc/haproxy/haproxy.cfg
root@test-ag-haproxy-geoip:/# journalctl -u haproxy.service -f
> May 04 18:58:57 test-ag-haproxy-geoip haproxy[84265]: ::ffff:140.82.115.47:33494 [04/May/2024:18:58:57.790] fe_web~ be_test2/srv2 0/0/26/26/52 200 1778 - - ---- 2/2/0/0/0 0/0 {US|36459|github-camo (4b76e509)} "GET /infra_haproxy.pylint.svg HTTP/1.1

root@test-ag-haproxy-geoip:/# cat /etc/haproxy/haproxy.cfg
> # Ansible managed: Do NOT edit this file manually!
> # ansibleguy.infra_haproxy
>
Expand All @@ -66,7 +69,7 @@ root@test-ag-haproxy-acme:/# cat /etc/haproxy/haproxy.cfg
> ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
> ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
> tune.ssl.capture-buffer-size 96

>
> defaults
> log global
> mode http
Expand Down
181 changes: 181 additions & 0 deletions ExampleWAF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Basic Example with GeoIP

There are still some basic WAF features to be implemented.

NOTE: The feature-set this role provides does not come lose to the one [available in HAProxy Enterprise by default](https://www.haproxy.com/solutions/web-application-firewall).

## Config

```yaml
haproxy:
waf: {}

frontends:
fe_web:
bind: ['[::]:80 v4v6']

security:
headers: true
fingerprint_ssl: true
restrict_methods: true
allow_only_methods: ['HEAD', 'GET', 'POST']
# deny_dangerous_methods: true
block_script_bots: true
block_bad_crawler_bots: true


routes:
be_test:
domains: ['app.test.ansibleguy.net']

default_backend: 'be_fallback'

backends:
be_test:
security:
restrict_methods: true
allow_only_methods: ['HEAD', 'GET', 'POST']
# deny_dangerous_methods: true
block_script_bots: true
block_bad_crawler_bots: true

servers:
- 'srv-1 192.168.10.11:80'
- 'srv-2 192.168.10.12:80'

be_fallback:
lines: 'http-request redirect code 301 location https://github.com/ansibleguy'
```
----
## Result
```bash
root@test-ag-haproxy-waf:/# cat /etc/haproxy/haproxy.cfg
> # Ansible managed: Do NOT edit this file manually!
> # ansibleguy.infra_haproxy
>
> global
> daemon
> user haproxy
> group haproxy
>
>
> log /dev/log local0
> log /dev/log local1 notice
> chroot /var/lib/haproxy
> stats socket /run/haproxy/admin.sock mode 660 level admin
> stats timeout 30s
> ca-base /etc/ssl/certs
> crt-base /etc/ssl/private
> ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
> ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
> ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
> tune.ssl.capture-buffer-size 96
>
> defaults
> log global
> mode http
> option httplog
> option dontlognull
> timeout connect 5000
> timeout client 50000
> timeout server 50000
> errorfile 400 /etc/haproxy/errors/400.http
> errorfile 403 /etc/haproxy/errors/403.http
> errorfile 408 /etc/haproxy/errors/408.http
> errorfile 500 /etc/haproxy/errors/500.http
> errorfile 502 /etc/haproxy/errors/502.http
> errorfile 503 /etc/haproxy/errors/503.http
> errorfile 504 /etc/haproxy/errors/504.http

root@test-ag-haproxy-waf:/# cat /etc/haproxy/conf.d/frontend.cfg
> # Ansible managed: Do NOT edit this file manually!
> # ansibleguy.infra_haproxy
>
> frontend fe_web
> mode http
> bind [::]:80 v4v6
>
> http-request deny status 405 default-errorfiles if !{ method HEAD GET POST }
>
> # block well-known script-bots
> http-request deny status 425 default-errorfiles if { req.fhdr(User-Agent) -m sub -i curl wget Apache-HttpClient nmap Metasploit headless cypress go-http-client zgrab python httpx httpcore aiohttp httputil urllib GuzzleHttp phpcrawl Zend_Http_Client Wordpress Symfony-HttpClient cpp-httplib java perl axios ruby }
> # block well-known bad-crawler-bots
> http-request deny status 425 default-errorfiles if { req.fhdr(User-Agent) -m sub -i spider test-bot tiny-bot fidget-spinner-bot download scrapy }
> # Security headers
> http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
> http-response set-header X-Frame-Options "DENY"
> http-response set-header X-Content-Type-Options "nosniff"
> http-response set-header X-Permitted-Cross-Domain-Policies "none"
> http-response set-header X-XSS-Protection "1; mode=block"
> # SSL fingerprint
> http-request set-var(txn.fp_ssl_p1) ssl_fc_cipherlist_bin(1),be2dec(-,2)
> http-request set-var(txn.fp_ssl_p2) ssl_fc_extlist_bin(1),be2dec(-,2)
> http-request set-var(txn.fp_ssl_p3) ssl_fc_eclist_bin(1),be2dec(-,2)
> http-request set-var(txn.fp_ssl_p4) ssl_fc_ecformats_bin,be2dec(-,1)
> http-request set-var(txn.fingerprint_ssl_raw) "ssl_fc_protocol_hello_id,concat(',',txn.fp_ssl_p1),concat(',',txn.fp_ssl_p2),concat(',',txn.fp_ssl_p3),concat(',',txn.fp_ssl_p4)"
> http-request set-var(txn.fingerprint_ssl) var(txn.fingerprint_ssl_raw),digest(md5),hex,lower
> http-request capture var(txn.fingerprint_ssl) len 32
>
> http-request capture req.fhdr(User-Agent) len 200
>
> # BACKEND be_test
> acl be_test_domains req.hdr(host) -m str -i app.test.ansibleguy.net
> acl be_test_filter_ip always_true
> acl be_test_filter_not_ip always_false
>
> use_backend be_test if be_test_domains be_test_filter_ip !be_test_filter_not_ip
>
> default_backend be_fallback

root@test-ag-haproxy-waf:/# cat /etc/haproxy/conf.d/backend.cfg
> # Ansible managed: Do NOT edit this file manually!
> # ansibleguy.infra_haproxy
>
> backend be_test
> mode http
> balance leastconn
>
> http-request deny status 405 default-errorfiles if !{ method HEAD GET POST }
>
> # block well-known script-bots
> http-request deny status 425 default-errorfiles if { req.fhdr(User-Agent) -m sub -i curl wget Apache-HttpClient nmap Metasploit headless cypress go-http-client zgrab python httpx httpcore aiohttp httputil urllib GuzzleHttp phpcrawl Zend_Http_Client Wordpress Symfony-HttpClient cpp-httplib java perl axios ruby }
> # block well-known bad-crawler-bots
> http-request deny status 425 default-errorfiles if { req.fhdr(User-Agent) -m sub -i spider test-bot tiny-bot fidget-spinner-bot download scrapy }
>
> server srv-1 192.168.10.11:80 check
> server srv-2 192.168.10.12:80 check
>
>
> backend be_fallback
> mode http
> balance leastconn
>
> # SECTION: default
> http-request redirect code 301 location https://github.com/ansibleguy
>

root@test-ag-haproxy-waf:/# systemctl status haproxy.service
> * haproxy.service - HAProxy Load Balancer
> Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; preset: enabled)
> Drop-In: /etc/systemd/system/haproxy.service.d
> `-override.conf
> Active: active (running) since Sat 2024-05-04 16:24:54 UTC; 4min 11s ago
> Docs: man:haproxy(1)
> file:/usr/share/doc/haproxy/configuration.txt.gz
> https://www.haproxy.com/documentation/haproxy-configuration-manual/latest/
> https://github.com/ansibleguy/infra_haproxy
> Process: 4574 ExecStartPre=/usr/sbin/haproxy -c -f $CONFIG -f /etc/haproxy/conf.d/ (code=exited, status=0/SUCCESS)
> Process: 4635 ExecReload=/usr/sbin/haproxy -c -f $CONFIG -f /etc/haproxy/conf.d/ (code=exited, status=0/SUCCESS)
> Process: 4637 ExecReload=/bin/kill -USR2 $MAINPID (code=exited, status=0/SUCCESS)
> Main PID: 4576 (haproxy)
> Status: "Ready."
> Tasks: 7 (limit: 1783)
> Memory: 132.2M
> CPU: 297ms
> CGroup: /system.slice/haproxy.service
> |-4576 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /run/haproxy.pid -S /run/haproxy-master.sock
> `-4639 /usr/sbin/haproxy -sf 4578 -x sockpair@4 -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /run/haproxy.pid -S /run/haproxy-master.sock
```
Loading

0 comments on commit 485ce62

Please sign in to comment.