Netbox: Filter RFC 1918 & 4193 IPv4/6 addresses & prefixes via search

Created on 26 Jun 2018  路  12Comments  路  Source: netbox-community/netbox

Issue type

[X] Feature request
[ ] Bug report
[ ] Documentation

Environment

  • Python version: 3.4.8
  • NetBox version: 2.3.4

Description

I think it would be handy to be able to filter IPv4/6 addresses & prefixes via search based on whether they are a RFC 1918 address or not.
search

This would allow a quick way to see/not see public/private address space in use by the organization/tenant.

pending closure needs owner feature

All 12 comments

For documentation / presentation purposes if exposed in the UI 鈥斅燫FC1918 is specifically for IPv4, you'd want RFC4193 for IPv6

Right. It's updated.

Maybe a possibility to add your own 'predefined search filters' and define the contents of them to your own needs? These filters should refer to a (set of) container prefixes. You could use this to filter for example on 'only childs of your a container used for customer addressing'

This needs to be fleshed out before it can be considered for implementation. "Private" prefixes are not limited to those defined in RFCs 1918 and 4193. There's also RFC 3927, RFC 6598, 127/8, all multicast space, prefixes designated for use only in documentation...

RFC 6890 seems pretty inclusive of the oddball ranges. I'm okay with implementing a filter for this, so long as the qualifier for what constitutes a "private" prefix comes from an authority such as RFC 6890 and not a list we cobble together and have to maintain indefinitely.

Hope this is useful.
The ipaddress Python module has a boolean value is_private on IP addresses. It is based on the IANA IPv4 and IPv6 Special-Purpose Address Registries. Pretty exhaustive lists.
https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_private

https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml

>>> from ipaddress import IPv4Address
>>> ip = IPv4Address('10.1.0.1')
>>> ip.is_private
True
>>> ip2 = IPv4Address('8.8.8.8')
>>> ip2.is_private
False
>>>

I'm not sure how well this would work at the database level though. Seems like we've got two options.

Option1: Write the filter to match on an array of all "private" prefixes. Probably not very efficient.

Option 2: Record an is_private flag on the IPAddress and Prefix models when the object is saved. We already do this with address family for some reason, so this would probably work fine. Then we can just filter on is_private. It might make things difficult if the rules for what's considered private change, but that should be rare enough that we could handle it in a database migration.

What I do in practice is create an IP address object and check is_private, but I'm only ever doing this with a couple of IPs or netblocks at a time. I definitely agree that doing something like that or your Option 1 at display filter time would be very inefficient.

I also think the danger of the rules being changed is pretty slim. Even if a new small block for some fringe use case is added, it's inherently not an issue until someone expects it to be caught in the filter. At that time they can submit an issue, the updated rules can be checked, and the issue can be quickly and easily resolved. Option 2 sounds great.

Since the ipaddress module already is based on the IANA list, that module will be updated with any new blocks. Instead of reinventing the wheel we could simply create an object from the ipaddress module when adding a new IPAddress/Prefix, then copy is_private's value. I don't know how feasible it is to then perform the same action for every single IPAddress/Prefix during database migrations. That sounds expensive.

Another idea: allow filtering of addresses and prefixes by RIR. Then you just enter 192.168.0.0/16, 172.16.0.0/12 etc as aggregates under an RIR called e.g. "Private" or "RFC1918"

Issue: you might also want negative matching, i.e. show all addresses not within the selected RIR.

The RIR association approach would work well for prefixes but not for IP addresses, because there's no direct path from IPAddress to RIR. Our best bet is probably to introduce a discrete field or fields.

The netaddr IPNetwork and IPAddress objects provide is_private(), is_reserved(), and is_link_local() methods. We could replicate those individually, or perhaps add a single is_global field set to True so long as the other three are are False.

The RIR association approach would work well for prefixes but not for IP addresses, because there's no direct path from IPAddress to RIR.

(Aside: I believe there's no direct path from prefix to RIR either. It's prefix -> enclosing aggregate -> RIR, so you could just as well have ipaddress -> enclosing aggregate -> RIR)

Anwyay, I don't object ot having a hard-coded list of private address blocks.

These are listed in IANA registries (v4, v6) - but I think it would be fine to limit it to just the important blocks: v4 /16 or larger, v6 ULA and link-local. Things like 'documentation examples' don't belong on a live network anyway. This would limit the complexity of corresponding filters in postgres queries.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our contributing guide.

This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shugotek picture shugotek  路  3Comments

benjy44 picture benjy44  路  3Comments

robbagithub picture robbagithub  路  3Comments

bellwood picture bellwood  路  4Comments

mrfroggg picture mrfroggg  路  3Comments