(Slighly major edit - I realized the key difference isn’t the direction…)
In my homelab, I have a Cloudflare Tunnel, with Traefik being my reverse proxy and Nginx doing my HTTP services and Suricata is inspecting it all, and when an alert is generated with XFF enabled it alerts according to this config:
- eve-log:
enabled: yes
filetype: syslog
identity: "suricata"
facility: local5
level: Info
metadata: yes
pcap-file: false
community-id: true
community-id-seed: 0
xff:
enabled: yes
mode: extra-data
deployment: reverse
header: X-Forwarded-For
types:
- alert:
payload: yes
payload-buffer-size: 4kb
payload-printable: yes
packet: no
# metadata: no
metadata:
app-layer: true
flow: true
rule:
metadata: true
raw: true
reference: true
http-body: no
http-body-printable: no
websocket-payload: no
websocket-payload-printable: no
tagged-packets: yes
The notes about XFF Forward and Reverse are:
# Two proxy deployments are supported: "reverse" and "forward". In
# a "reverse" deployment the IP address used is the last one, in a
# "forward" deployment the first IP address is used.
In one alert looking for malicious incoming traffic to a web server the order of the Hosts is:
"xff": "1.2.3.4, 192.168.2.3",
1.2.3.4 == external host browsing my HTTP server
192.168.2.3 == cloudflare tunnel
The notes around XFF say, ‘reverse’ == last, and ‘forward’ == first - and I wanted to mention that it would appear I would have to ‘mis-configure’ my Suricata according to the notes to get the desired outcome for this alert with respect to the incoming nature of the traffic/alert. This is my only “dual XFFed” traffic, the other traffic that comes in the main/natural IP and also goes through Traefik gets the XFF of the Client if it exists, and so far I only ever see a list of one.
It appears that if an alert fires on the traffic coming from/after the Cloudflare Tunnel shows both values in the XFF and otherwise uses the Last entry as the Alert instead of the first that is the original source of the traffic.
Would be happy to dig into this further, I just happened to notice it recently, running Suricata 8.0.3.