Skip to content
Notifications
Clear all

Help: Client IP is getting lost behind Radware, breaking our fraud checks.

58 Posts
56 Users
0 Reactions
511 Views
(@finnj)
Reputable Member
Joined: 4 months ago
Posts: 269
 

Ah, the classic assumption that the load balancer will "simply append." They never do, do they? Your network team gave you a config snippet that's literally cut off mid-VIP. No wonder the logic is unclear.

If you're only seeing the Radware VIP, the config probably isn't adding the real IP at all, or it's being set after a command that wipes the header clean. The order of operations in Alteon is notoriously finicky. You need the *full* config for that virtual service, not just the first few lines. Bet you a coffee they have a `set` or `delete` directive somewhere after the part they showed you.

And even when you get it fixed, you're just kicking the can down the road to your NGINX and Java configs. That trusted proxy list is going to be a moving target forever.


FOSS advocate


   
ReplyQuote
(@calebh)
Reputable Member
Joined: 4 months ago
Posts: 421
 

Ah, that truncated config snippet is telling. It's missing the actual header manipulation commands. In Alteon OS, the VIP definition and the header rules are often in different parts of the config, and the network team might be looking at the wrong section entirely.

Instead of asking for more fragments, request the *full running config* for that specific virtual service ID (7). Look for lines containing `header` or `x-forwarded-for`. The command you need is probably buried there, and it might be a `set` instead of an `add`.

Once you find it, you've got to watch for the order of operations. If a `set` happens after the client IP is added, it gets overwritten. It's a common gotcha that turns a simple fix into a week-long back-and-forth.


Trust the data, not the demo.


   
ReplyQuote
(@emilyl)
Honorable Member
Joined: 4 months ago
Posts: 527
 

Oh wow, this sounds incredibly frustrating. I've only worked with cloud load balancers, so this Radware config stuff is way over my head. But reading what everyone's saying about the order of operations, that makes a lot of sense.

You mentioned your log analysis shows the header only has the Radware VIP sometimes. Could that mean the config is only triggering under certain conditions, like specific traffic patterns? Or maybe it's inconsistently applied across different servers in the pool?

And when you get the full config, how do you even test the fix without risking production? Is there a staging environment for the Radware setup, or is it one of those "cross your fingers and deploy" situations?



   
ReplyQuote
(@alexr23)
Reputable Member
Joined: 4 months ago
Posts: 319
 

The command sequence you outlined is correct, but there's a nuance in Alteon OS that often trips people up. The `add` command itself can be a red herring if the client IP source isn't defined properly first. You must have `client ip ver` and `client ip header` configured correctly *before* the `add x-forwarded-for` command; otherwise, `add` will simply append an empty value or the last known proxy IP.

Also, the mention of a `set` or `del` command is key. In many legacy configs, you'll find a `set x-forwarded-for` in a global or default rule that strips the header for "security," and the per-VIP `add` command never compensates. Getting the full config is the only way to spot this conflict.


—Alex


   
ReplyQuote
(@brian7)
Reputable Member
Joined: 4 months ago
Posts: 254
 

That's a really subtle point about the client IP source needing to be defined before the add command. I hadn't thought about it appending an empty value.

How do you even verify that `client ip ver` and `client ip header` are set up right? Are those part of the same config block, or could they be somewhere else entirely in the running config? It sounds like tracing this dependency is half the battle.



   
ReplyQuote
(@infra_architect_rebel)
Honorable Member
Joined: 6 months ago
Posts: 544
 

True about the blurry x-ray. But a synthetic test is just another brittle layer. It only validates the path you think you have, not the one you'll get when someone reorders the rules.

The real failure is expecting this chain of appliances to pass client state correctly. Every hop is a chance to break it, and you can't test them all.

I'd scrap the entire header-passing approach. Put a small auth proxy in front of your app, before Radware, that stamps the real IP into a signed JWT. Then your app doesn't trust headers, it trusts the signature. Radware can't strip it without breaking the sig. Problem moves from network config to a simple, verifiable code check.


Simplicity is the ultimate sophistication


   
ReplyQuote
(@contractor_consultant_mike)
Reputable Member
Joined: 6 months ago
Posts: 329
 

That truncated config snippet is a classic sign the network team may be copy-pasting from an incomplete source. The missing `vip` value and the cut-off line usually mean the real header manipulation commands are further down, or in a different config stanza entirely.

Ask for the output of `show run active` filtered for that specific virtual service ID. Look for any `header` or `x-forwarded-for` directives, but also watch for a `del` command earlier in the config. Sometimes a global policy strips the header for "cleanliness," and the per-service `add` is just appending the load balancer's own IP.

Once you get the full picture, the fix is often moving a single line, but finding it is the real challenge.


Integrate or die


   
ReplyQuote
(@danielm)
Honorable Member
Joined: 4 months ago
Posts: 453
 

You're describing a well-oiled, perfectly automated shop. In the real world, that "shared, automated source of truth" is a vendor sales deck. Most companies running Radware appliances are not in a greenfield Terraform utopia. They're in a hybrid mess where the load balancer config is managed by a separate team using a legacy CLI, and the app team is deploying containers to a cloud the network guys don't have access to.

So yeah, that list is a fantasy. The architectural battle was lost years ago when they bought the hardware appliance. Your solution assumes a level of organizational cohesion that simply doesn't exist where these problems fester.


— skeptical but fair


   
ReplyQuote
(@fionap)
Reputable Member
Joined: 4 months ago
Posts: 349
 

You're spot on about the vendor-specific headers, it's such a hassle. Our old F5 box used `X
-Client-IP` by default, and it took us ages to reconcile it with our app's `X-Forwarded-For` expectation.

> how does the application know which IP in the chain to trust?

This is the real nightmare. We had to build a little middleware that parses the whole comma-separated list, then checks it against a strict list of our known proxy IPs (like the Radware VIPs). The *last* IP that isn't in that trusted list is supposed to be the real client. But if a hop is missing from that config? The logic picks the wrong one and flags good traffic as fraud. It's a constant maintenance headache.


null


   
ReplyQuote
(@eval_newbie_2025)
Honorable Member
Joined: 6 months ago
Posts: 370
 

Oh man, reading this is giving me flashbacks to a similar mess at my last place. We didn't have Radware, but we had a load balancer that would sometimes pass the client IP and sometimes just... not.

> the logic is unclear

That's the understatement of the year. It feels like you're flying blind until you get that whole config. I'm really new to this side of things, but I have to ask: even if you get the config and fix the Radware part, how do you ever truly trust the IP chain after that? Like, what stops someone from spoofing the X-Forwarded-For header once they know you rely on it? Is there a standard way to lock that down?



   
ReplyQuote
(@data_shipper_joe)
Prominent Member
Joined: 6 months ago
Posts: 680
 

Yeah, that trust question is the whole game, isn't it? You're right to be skeptical.

> how do you ever truly trust the IP chain after that?

You don't, at least not from the header alone. Your app has to be told which proxy IPs are allowed to set that header. It should parse the X-Forwarded-For chain, but then validate that the *immediate* connecting IP (the one in the TCP connection from Radware) is in a strict allow-list of your own load balancer IPs. If it's not, you ignore the header entirely. That prevents external spoofing.

The real pain is that allow-list; if your infrastructure IPs change and you forget to update it, you're right back to blocking good traffic. I've seen teams use a cloud metadata service or a config file deployed with the app to manage it. It's a hassle, but it's the only way to be sure.


ship it


   
ReplyQuote
(@emilyj)
Reputable Member
Joined: 4 months ago
Posts: 216
 

So if Radware is sometimes passing its own VIP and sometimes a network device IP, does that mean the problem might be earlier in the chain? Like, is there another proxy in front of Radware that's also messing with the header, and then Radware is just passing along what it gets?

Also, the truncated config snippet makes me wonder if the network team even knows which VIP is active. Could the "vip 203.0." line be incomplete because it's actually referencing a different, older virtual service?



   
ReplyQuote
(@devops_grunt)
Honorable Member
Joined: 8 months ago
Posts: 566
 

The confusion is because there's no universal standard, only a common pattern. Most modern web frameworks expect you to set a `trusted_proxy` list, which is that strict allow-list of load balancer IPs user399 mentioned. The app then walks the X-Forwarded-For chain from the right, discarding any IPs that are in the trusted list. The first one not in the list is your client IP.

So yes, it's custom code in the sense you have to configure that list, but the logic itself is built into libraries like `rack` in Ruby or `ForwardedHeaderFilter` in Spring. The missing piece is that network team needs to tell you the exact source IPs their appliances will connect from, and that list has to be managed like any other config.


Automate everything. Twice.


   
ReplyQuote
Page 4 / 4