Ever had the issue where the source IP is not the source IP?

With Suricata and Sourcefire you can view the true client source IP and filter out or alert on it. For example, if there’s some known legit scanner hiding in X-Forwarded-For –generating mountains of false positives– it’s much easier to whitelist after some simple mods. An eStreamer client can also be configured to pull in the extra data from Sourcefire for analysis.

My setup is like so:

Client —> Proxy port 8080 —-IDS—> Server port 80

For Suricata, enable xff and set a few options in suricata.yaml.

 enabled: yes
 # Two operation modes are available, "extra-data" and "overwrite". Note
 # that in the "overwrite" mode, if the reported IP address in the HTTP
 # X-Forwarded-For header is of a different version of the packet
 # received, it will fall-back to "extra-data" mode.
 mode: overwrite
 # 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.
 deployment: reverse
 # Header name where the actual IP address will be reported, if more
 # than one IP address is present, the last IP address will be the
 # one taken into consideration.
 header: X-Forwarded-For

I created a simple rule for testing:

alert tcp any any -> 80 (msg:"test XFF"; flow:established,to_server; 
content:"X-Forwarded-For|3a|"; http_header; fast_pattern:only; sid:1000003; rev:1;)

And browsed to which forwards to port 80 on the webserver.

Eve log shows the following alert which contains the XFF IP extracted and overwritten as Source. The Proxy IP address is under hostname.


To filter out sources and destinations in Suricata you can use bpf, pass rules, or thresholds.

For BPF create a file called suri.bpf or something under /etc/suricata or wherever you set the configs and then call it when you start Suri with -F /etc/suricata/suri.bpf.

For pass rules, create a rule in local.rules or pass.rules or something; just be sure to reference it in suricata.yaml.

pass ip X.X.X.X any <> any any (msg:"pass all traffic from X.X.X.X"; sid:123123123;)

To threshold,  add this in threshold.config to keep it from firing for all rules.

suppress gen_id 0, sig_id 0, track by_src, ip X.X.X.X

But, none of that will work for X-Forwarded-For as far as I can tell.  I was able to whitelist by creating a pass rule with the Proxy IP as the source TO any host on port 80, and X-Forwarded-For regex to match the true host in the HTTP header. You don’t need any of the above for this.

pass tcp any -> any 80 (msg:"Pass/Whitelist XFF"; flow:to_server,established; content:"X-Forwarded-For|3a|";
fast_pattern:only; http_header; pcre:"/X-Forwarded-For\x3a\s+10\.1\.40\.66/"; sid:321321321; rev:1;)

You can whitelist an entire subnet like for Qualys.

pass tcp any any -> $HOME_NET $HTTP_PORTS (msg:"Don't alert on Qualys in XFF"; flow:to_server,established; 
content:"X-Forwarded-For|3a 20|64.39."; fast_pattern:only; http_header; pcre:"/X-Forwarded-For\x3a\x2064\.39\.(9[6-9]|1[0-1][0-9])\./i"; sid:51321321; rev:1;)



For Sourcefire, go to Intrusion policy/Network Access Policy/HTTP Configuration and set the following options.

-“Detect HTTP Proxy Servers” Should be checked.

-Under servers click + and add the IP of the proxy or a comma separated list of proxies under networks.

-Check “Extract Original Client IP address” and “Allow HTTP Proxy Use”

-Make sure the XFF Header prioity is 1. X-Forwarded-For and 2. True-Client-IP

Same rule as before.

alert tcp any any -> 80 (msg:"test XFF"; flow:established,to_server;
content:"X-Forwarded-For|3a|"; http_header; fast_pattern:only; sid:1000003; rev:1;)

You can view the actual source host in Sourcefire by drilling down into the event, and enabling the column for “Original Client IP.”

To filter true client IPs out, first create an object for the originating source IP(s) that you want to exclude.

Objects/Object Management/Network/Add Network

In this case I created one called “whitelist_proxy_true_ip” and added the client IP of

Then go into your Access Control policy and add a new rule at the top. I called mine “No Inspect”.

Set it to “Action: Trust” and under Networks add “whitelist_proxy_true_ip” under the Original Client tab.

And Voila! No more alerts from that IP through the load balancer.


For eStreamer, I usually just check all the boxes, set the IP of the client, and gen the cert.

The client needs to be able to pull “extra data.” You would then see something similar to this in logs:

More info: https://www.cisco.com/c/en/us/td/docs/security/firesight/540/api/estreamer/EventStreamerIntegrationGuide/Protocol.html

Categories: Security


Leave a Reply

Your email address will not be published. Required fields are marked *