Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multihomed ldap server #166

Open
f1-outsourcing opened this issue May 26, 2024 · 3 comments
Open

multihomed ldap server #166

f1-outsourcing opened this issue May 26, 2024 · 3 comments

Comments

@f1-outsourcing
Copy link

I hope it is ok to ask this here via an issue. I have a multi homed ldap server, dig returns something like this

[@-]$ dig +short ldap.dev.example.net
192.168.110.240
10.10.130.20

However my java application is only on the 10.10.x.x network, it currently only tries to connect to 192.168.110.240 instead of 10.10.130.20.

I know this can be resolved with sorting in dns, but I don't have this currently available. Can this be resolved in unboundid?

@dirmgr
Copy link
Collaborator

dirmgr commented May 27, 2024

The LDAP SDK doesn’t have anything that can do this by default. It typically relies on the operating system’s logic for routing requests to the appropriate destination. However, there are a couple of potential ways that you could address this by writing some custom code.

The easiest option would probably be to create a custom NameResolver implementation. Your implementation would probably just need to override the getByName method (and perhaps also the getAllByName method). They’d probably just use the InetAddress.getAllByName() method to get all addresses associated with a given name, and if one of the returned addresses is in the same network as an address on the local system, then you could prefer that one. You can use the LDAPConnectionOptions.setNameResolver method to set the name resolver to use for a set of connection options, and then create new connections (and connection pools) using that LDAPConnectionOptions object.

It may also be possible to accomplish with a custom ServerSet implementation. The RoundRobinDNSServerSet class provides some support for names that resolve to multiple addresses, but it’s designed more for cases in which all addresses are equally usable, which doesn’t sound like is the case in your environment. The DNSSRVRecordServerSet implementation provides even more in-depth DNS accesses for getting SRV records that allow for automatic discovery, but I don’t think you’d need anything as involved as that.

But really, I think that a custom NameResolver implementation is probably the easiest way to address the issue for your environment.

@f1-outsourcing
Copy link
Author

Hi Neil thanks for the detailed advise!

The LDAP SDK doesn’t have anything that can do this by default. It typically relies on the operating system’s logic for routing requests to the appropriate destination.

So in theory (I don't think my CO currently supports this) I could try and add sortlist to resolv.conf and then the application (java springboot) should resolve this correctly?

/etc/resolv.conf
sortlist 10.10.130.0/255.255.255.0

But really, I think that a custom NameResolver implementation is probably the easiest way to address the issue for your environment.

Is this being called at some point when the connection fails? Eg. if my ldap server moves to a different host and changes its ip addresses, is this being caught? Eg currently I have clamav/spamassassing milters that need to be restarted for them to learn an application has been moved and resolves to different ip address.

Or does this require me to make a custom NameResolver and start using ServerSet?

@dirmgr
Copy link
Collaborator

dirmgr commented May 28, 2024

Using a sortlist in resolv.conf might work, although I don’t have any experience with this particular kind of setup where DNS returns multiple addresses for a given name, but only some of them are reachable.

The LDAP SDK always uses a NameResolver instance when performing address lookups. If it needs to get the address for a given name, then it will use NameResolver.getByName instead of directly calling InetAddress.getByName, or instead of directly creating a socket with the provided name. If you have a NameResolver that always tries to choose an address in the same network as your local system, then that can ensure that the LDAP SDK uses that address when trying to establish a connection to a name that’s associated with multiple addresses in different networks.

If the LDAP server address changes (which generally isn’t a common thing), and if you need to be able to react to that immediately, then that’s something that could also be accomplished with a custom NameResolver, although it would need to forego the JVM’s default caching and trigger a name service lookup every time a given name is used (which you should be able to do by calling NameResolver.setJVMSuccessfulLookupCacheTTLSeconds(0), indicating that it should not perform any caching). Note, however, that this could be fragile and could cause your application to break if there’s a DNS outage. If you do that, you might want to have a custom NameResolver implementation that does its own caching, but only uses the cache if a lookup attempt fails. You can look at the CachingNameResolver implementation for a sample implementation that makes use of caching, but it isn’t suitable for your case because (A) it prefers using the cache whereas you only want to use the cache as a last resort, and (B) it doesn’t do what you want it to do for names that are associated with multiple IP addresses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants