Closed aim0r closed 1 year ago
coraza-spoa
? HAProxy?config.yaml
, coraza.conf
, crs-setup.conf
? Thank you for the prompt response. Requested info below.
1.Version of coraza-spoa: git rev-parse --short HEAD dd5eb86, HAProxy version is 2.4.22-0 on Ubuntu 22.10
2. config.yml is a straight from here: github. Note I had to remove the pipe right behind the "directives:" for it to work and be valid not sure why the pipe is in there in the first place.
haproxy/coraza.cfg is a straight copy from here: github. Only changed the bind to 127.0.0.1 since I don't need it to listen on all ips and changed the log location.
coraza.conf is a straight copy from here: github
crs-setup.conf is a straight copy from here: github. I have also taken the crs-setup directly from coreruleset and the rules from coreruleset with no success.
I have not tried to run it in docker and wasn't planning to. Already running it in a container on Proxmox and don't need the overhead of docker.
wasn't planning to. Already running it in a container on Proxmox and don't need the overhead of docker.
That's OK of course, but I meant something different.
I have not tried to run it in docker
I've checked again by running example in docker and haven't got error you described. Works as intended.
Try to run docker example. If it works, try to find difference between docker setup and your standalone.
I just actually did compare the docker example and the haproxy conf is significantly different from the one in the git for the non docker version. So I copied it over and not getting the Argument missing message anymore but still not blocking.
Do I need to tell it to turn on blocking explicitly or is it on by default? Does it silently drop or does it show the drop in the logs? When it blocks does it also ban subsequent requests for a period of time?
Is the test example outdated maybe and HAProxy already escapes it?
I am using the example from the docs to test.
curl http://localhost:4000/\?x\=/etc/passwd
This request results in:
Jul 12 08:56:19 test haproxy[2691]: 192.168.1.10:50526 [12/Jul/2023:08:56:19.013] test test/<NOSRV> 0/0/3/3/-1/-1/-1/3 403 72 - - PR-- 1/1/0/0/0 0/0 "GET /?x=/etc/passwd HTTP/1.1" 2a3af7ac-ffbd-49b0-9274-5e8870bc3bce spoa-error: - waf-hit: -
Just doing curl http://localhost
results in
Jul 12 08:56:14 test haproxy[2691]: 192.168.1.10:56796 [12/Jul/2023:08:56:14.481] test test_backend/<NOSRV> 0/0/2/2/-1/-1/-1/2 200 80 - - LR-- 1/1/0/0/3 0/0 "GET / HTTP/1.1" 7b1d9997-a188-4f50-a852-214e3f77c3e0 spoa-error: - waf-hit: 0
waf-hit -
on first request and waf-hit 0
on second
Obviously changed ip and port.
Update:
Log statement is wrong:
log-format "%ci:%cp\ [%t]\ %ft\ %b/%s\ %Th/%Ti/%TR/%Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r\ %ID\ spoa-error:\ %[var(txn.coraza.error)]\ waf-hit:\ %[var(txn.coraza.fail)]"
txn.coraza.fail is always 0 or -
txn.coraza.action is the correct variable to see if denied or passed
changed it and now can see requests being blocked.
This can be closed. The documentation is all over the place about this. Hopefully this will be updated at some point to help others.
Thank you for your help.
Do I need to tell it to turn on blocking explicitly or is it on by default?
Sets up by SecRuleEngine
Does it silently drop or does it show the drop in the logs?
In Docker example it shows
When it blocks does it also ban subsequent requests for a period of time?
I don't know, TBH. Look at underlying library. @jcchavezs I'm curious too.
Is the test example outdated maybe and HAProxy already escapes it?
What example? In the docs?
Hopefully this will be updated at some point to help others.
PR is welcome ;)
When it blocks does it also ban subsequent requests for a period of time?
nope, that would be a whole different thing but achievable with current APIs. is this something you need?
All the other answers are right.
I do not, I was just curious. But it would be cool ;-). I have been running it in DetectionOnly mode now for a few hours and capturing logs to see what I need to tweak in terms of rules. Very excited about this, so far it's working great.
I do have a few more questions:
Log statement is wrong txn.coraza.action is the correct variable to see if denied or passed
@aim0r, thanks for report, fixed in #74.
I think we should also update the example configs with an updated haproxy config, which incorporates the new variables. Just for reference, this is whats in use for the Docker & e2e tests:
# Currently haproxy cannot use variables to set the code or deny_status, so this needs to be manually configured here
http-request redirect code 302 location %[var(txn.coraza.data)] if { var(txn.coraza.action) -m str redirect }
http-response redirect code 302 location %[var(txn.coraza.data)] if { var(txn.coraza.action) -m str redirect }
http-request deny deny_status 403 hdr waf-block "request" if { var(txn.coraza.action) -m str deny }
http-response deny deny_status 403 hdr waf-block "response" if { var(txn.coraza.action) -m str deny }
http-request silent-drop if { var(txn.coraza.action) -m str drop }
http-response silent-drop if { var(txn.coraza.action) -m str drop }
# Deny in case of an error, when processing with the Coraza SPOA
http-request deny deny_status 504 if { var(txn.coraza.error) -m int gt 0 }
http-response deny deny_status 504 if { var(txn.coraza.error) -m int gt 0 }
^ Addressed by #76.
@jcchavezs mark this as a bug
, please.
Hey there, thank you for aiming to replace Trustwave ModSecurity. I have been following the instruction to setup coraza-spoa with haproxy and finally got it running. I am not seeing it block however.
The agent reports the below on every single request:
INFO[0000] spoe: listening on 127.0.0.1:9000 Argument 'version' not found Argument 'headers' not found
Haproxy log shows the following:
Jul 11 13:15:41 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-frontend-http-request> sid=17 st=0 0/0/0/0/1 1/1 0/0 0/27 Jul 11 13:15:41 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-frontend-http-request> sid=17 st=0 0/0/0/0/1 1/1 0/0 0/27 Jul 11 13:15:41 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-http-response> sid=17 st=0 0/0/0/0/0 1/1 0/0 0/28 Jul 11 13:15:41 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-http-response> sid=17 st=0 0/0/0/0/0 1/1 0/0 0/28 Jul 11 13:15:41 test haproxy[222]: 192.168.1.10:64257 [11/Jul/2023:13:15:41.954] test test_backend/s1 0/0/1/1/0/1/3/6 200 3383 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" 1ec2bbea-a85f-44da-8e21-d7f382b7bc7b spoa-error: - waf-hit: 0 Jul 11 13:15:42 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-frontend-http-request> sid=19 st=0 0/0/0/0/0 1/1 0/0 0/29 Jul 11 13:15:42 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-frontend-http-request> sid=19 st=0 0/0/0/0/0 1/1 0/0 0/29 Jul 11 13:15:42 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-http-response> sid=19 st=0 0/0/0/0/0 1/1 0/0 0/30 Jul 11 13:15:42 test haproxy[222]: SPOE: [coraza-agent] <EVENT:on-http-response> sid=19 st=0 0/0/0/0/0 1/1 0/0 0/30 Jul 11 13:15:42 test haproxy[222]: 192.168.1.10:64257 [11/Jul/2023:13:15:41.961] test test_backend/s1 0/63/0/63/0/0/1/64 404 433 - - ---- 1/1/0/0/0 0/0 "GET /favicon.ico HTTP/1.1" 5bd81c35-f252-4c44-9ac1-22f17983b228 spoa-error: - waf-hit: 0
The haproxy config is defined as in the sample from the git project.
filter spoe engine coraza config /etc/coraza-spoa/coraza.cfg
and
http-request deny if { var(txn.coraza.fail) -m int eq 1 }
http-response deny if { var(txn.coraza.fail) -m int eq 1 }
http-request deny deny_status 504 if { var(txn.coraza.error) -m int gt 0 }
http-response deny deny_status 504 if { var(txn.coraza.error) -m int gt 0 }
use_backend test_backend
backend is:
backend test_backend
mode http
server s1 127.0.0.1:8080
backend coraza-spoa
mode tcp
server s1 127.0.0.1:9000
This:
curl http://serverip/\?x\=/etc/passwd
Results in the request being passed to apache which is listening on port 8080 same server. Browsing to the url results in the same.
Corerules are loaded and configured as per example in docs.