os-dynamic-homenet: Suricata HOME_NET follows IPv6 prefix and IPv4 address

Started by TBK, Today at 04:05:41 PM

Previous topic - Next topic
Hi all,

I run OPNsense with Suricata in IPS mode on a residential ISP that hands out a delegated IPv6 prefix that changes. When it changes, the Home networks entry in Suricata goes stale, and I found it caused the same problem described in core#6503.

I wrote a small plugin for this, os-dynamic-homenet. It hooks the WAN address events (newwanip and updateip), updates only the Home networks entry it owns with the current delegated prefix and the WAN IPv4 /32, and then reloads Suricata's rules without restarting the engine. Settings are under Services > Intrusion Detection > Dynamic Home Network. There's an Enable box, an interface choice, and checkboxes to follow the IPv6 prefix and/or the IPv4 address.

It has been running on my router for over two weeks, through multiple natural prefix changes. The plugin updated HOME_NET and reloaded Suricata on its own each time. I first saw it on a live change on Oct 17. It's been on 26.7.6 through 26.7.8 with Suricata 8.0.7 and 8.0.8.

The repo is here: https://github.com/TBK27/os-dynamic-homenet
I've also opened a proposal for it upstream: https://github.com/opnsense/plugins/issues/5794

I'm hoping a maintainer can take a look at the proposal and tell me whether it fits as an official plugin. Feedback is welcome too if anyone has thoughts.

Maybe start with an issue in opnsense/core describing the issue. A plugin that works around a core component isn't the best design choice.
Hardware:
DEC740

Thanks Cedrik. There have already been issues in core about this exact problem (core#6503 and core#3489), and both are closed. #6503 was closed by the bot for inactivity, and #3489 was closed over concerns about restarts and dependencies between the DHCP client and Suricata.

My plugin is meant as the remedy for those concerns, which is why I went this route instead of opening another core issue. It only reloads the rules and never restarts Suricata. #6503 was also tagged "help wanted" when the bot closed it, so I linked my plugin there.

Maybe you could offer a PR without a plugin that has a very small proof of concept whats needed for this.

If its very short, I'm sure it will be looked at eventually.

Maybe you could even reuse this to get normalized prefixes, also if a prefix is missing with safe fallbacks:

https://github.com/opnsense/core/blob/master/src/opnsense/mvc/app/library/OPNsense/Interface/Idassoc.php

I didnt look at the whole problem domain but a solution could be rather short I think.
Hardware:
DEC740

Thanks, that's a useful pointer on Idassoc. A core version would need the same address-change hooks the plugin already uses, so it would be the same logic moved into core rather than a different approach. If it were in core, I think it should be opt-in, since it automatically changes what ends up in Home networks. The earlier core issues (core#6503 and core#3489) were closed, and the older one over concerns about service dependencies and restarts, so I went with an optional plugin that only reloads the rules.

Before I open a PR against core, I'd like to know whether a core maintainer would want this there as an opt-in option, or whether the plugin is the better home for it.

Well I am a maintainer, but I also dont know the full picture.

What I would probably investigate is using an interface selectpicker in which you can select interfaces that additionally get added to the home net, and then reload suricata on the newwanip event. Look at how kea currently handles this.

Using interfaces removes and guesswork, the idassoc library will always return you what users actually configured.

If you have a PR just ping me on github. Of course no promises, but we can always discuss something small.

I reopened one of the issues.
Hardware:
DEC740

Thanks for reopening it, and for the pointers. The plugin is already close to what you describe: it has an interface setting and reloads Suricata on the newwanip event, and it covers both the IPv6 prefix and the WAN IPv4 /32. I'd rather not cut the IPv4 half, since rules that depend on Home networks need an accurate address, and it changes whenever the ISP changes it.

One question on the interface picker: do you mean a multi-select of internal interfaces whose prefixes get added?

If you or other maintainers would rather have this in core, I'm happy to answer questions or turn the plugin logic into a core PR.

I dont understand, EXTERNAL is !HOME_NET which already includes all public IPs, so the IPv4 half sounds redundant to me cause NAT is used anyway. If you use NAT you inspect after the NAT has happened.

For IPv6 the challenge is that you use dynamic GUAs internally, but that could also be circumvented by using ULAs (or a "borrowed" GUA) and NPTv6.

The scope if this is very tight around dynamic IPv6 in my opinion. Am I missing something?
Hardware:
DEC740

Fair question. The reason is the one in core#3489. With Suricata on WAN, outbound traffic is seen after NAT, so the source is the WAN IPv4 address, and inbound traffic to a port forward is seen before NAT, so the destination is the WAN IPv4 address. EXTERNAL_NET is !HOME_NET, so unless that address is in HOME_NET it counts as external, and rules written HOME_NET -> EXTERNAL_NET (or the reverse) don't match that traffic. Adding the WAN /32 fixes that, and it has to be kept current because the ISP changes it.

So the IPv4 half is the same kind of problem as the IPv6 prefix: both are dynamic addresses a user can't hard-code. I agree the scope is tight around dynamic addresses, and that is the idea.

But why arent you just inspecting on the internal interfaces which always have the invariants for the existing home net implementation.

Inspecting WAN and then building around that because it doesnt work in your environment sounds counter intuitive.

I can still understand it for v6, but not for v4.

The current (HOME_NET) implementations invariant is "There are no dynamic public addresses on internal interfaces"
Hardware:
DEC740