DNS-OARC / dnsperf

DNS Performance Testing Tools
https://www.dns-oarc.net/tools/dnsperf
Apache License 2.0
404 stars 67 forks source link

dnsperf with GSS-TSIG signed DNS updates #229

Open ahmadharis4u opened 1 year ago

ahmadharis4u commented 1 year ago

Hi everyone,

We have been working on integrating gss-tsig method of sending dns updates into the dnsperf tool. Our code is complete and going through testing phase.

There is an issue when we try to load test and it fails randomly (more on Debian client than on Ubuntu client) with below cause: root@build-vm-buster:~/Packages# dnsperf -s [dnsperfserver.bcdnsperf.com](http://dnsperfserver.bcdnsperf.com/) -d add-rec_50000 -u -g -c 30 -W -t 15 DNS Performance Testing Tool Version 2.10.0 [Status] Command line: dnsperf -s [dnsperfserver.bcdnsperf.com](http://dnsperfserver.bcdnsperf.com/) -d add-rec_50000 -u -g -c 30 -W -t 15 [Status] Sending updates (to 10.244.105.233:53) [Status] Started at: Thu Feb 23 17:44:18 2023 [Status] Stopping after 1 run through file Warning: gss_init_sec_context error: major = 589824, minor = 100002 Error: GSSAPI error: Major = Invalid token was supplied, Minor = Unknown error. Error: Failed to initialize GSS context: sent = 12232

This error occurs while initializing security context using TKEY response from the server.

Note:

Different ways tried so far-

Let me know if anyone has any hint about this. Should I create a merge request so helpers can get a direct look into the code and provide better suggestions ?

jelu commented 1 year ago

You should in general not mix packages and systems like that. And the problem is not likely about compiler flags.

I would have to see the code, preferably in a branch somewhere.

ahmadharis4u commented 1 year ago

You should in general not mix packages and systems like that. And the problem is not likely about compiler flags.

I would have to see the code, preferably in a branch somewhere.

Thanks for the response. I will finalize my code and share for review.

jelu commented 1 year ago

Closing this in waiting for the pull request

ahmadharis4u commented 1 year ago

Here you go: https://github.com/DNS-OARC/dnsperf/pull/230

jelu commented 1 year ago

Can you explain why you want TSIG GSS-API support this performance testing tool?

Because I don't understand why you want to performance test an UPDATE this way, because your rather just testing the GSS-API key mechanic then the real UPDATE.

jelu commented 1 year ago

I was not familiar with the process of TSIG/TKEY and the usage of GSS-API for DNS UPDATE but now that I saw your code I can say that it's not compatible with the engine design of dnsperf.

If support for this was to be added it would need to be using some other library that can do all the GSS-API leg-work, hopefully with some caching or reusing of keys, and added in dns.c similar to the usage of LDNS for build_update().

ahmadharis4u commented 1 year ago

Can you explain why you want TSIG GSS-API support this performance testing tool?

Because I don't understand why you want to performance test an UPDATE this way, because your rather just testing the GSS-API key mechanic then the real UPDATE.

I got your point. The use of new security context for each update was done upon request from management. I will have this point discussed and make it closer to the real update scenario (if the keys are cached to be re-used for a batch of updates). We use the dnsperf tool to load test our dns solutions.

ahmadharis4u commented 1 year ago

I was not familiar with the process of TSIG/TKEY and the usage of GSS-API for DNS UPDATE but now that I saw your code I can say that it's not compatible with the engine design of dnsperf.

If support for this was to be added it would need to be using some other library that can do all the GSS-API leg-work, hopefully with some caching or reusing of keys, and added in dns.c similar to the usage of LDNS for build_update().

Thank you for the review. This is really helpful. As I understood, below steps are required to make the code compatible:

  1. Separate the gss-tsig code from dnsperf.c and move to a separate lib/file that handles gss-tsig security context creation.
  2. Use that lib/file from dns.c, similar to LDNS
  3. Add caching/reusing of the keys to focus more on measuring the UPDATE performance
jelu commented 1 year ago

As I understood, below steps are required to make the code compatible

Yes.

Have you looked around if there are any available libraries that already does this?

Also, do not use DNSPerf functions for sending DNS queries for TSIG/TKEY exchange. They are not meant for that. If you need to implement this yourself because of lack of available libraries then use a proper DNS resolver library! For example libunbound or getdns.

On point 3, I don't know how this mechanism works but I really hope you can somehow cache signing keys and not have to make an exchange for every DNS UPDATE that DNSPerf needs to send. Because otherwise you'll more be testing the key exchange then the UPDATE.

ahmadharis4u commented 1 year ago

I haven't found any supporting library other than https://github.com/bodgit/tsig which is a Golang library. I assumed it would be extra overhead, as it requires to first build using Go for being used with dnsperf.

I analyzed the changes required for key reuse and modified the code (locally) to assign 1 key per socket (acting as a client) which required the a new list in parallel to **socks within struct threadinfo_t.

But this change will not allow moving the tsig/tkey calling code out of dnsperf.c as threadinfo_t is a local structure. Looking for more ideas..

jelu commented 1 year ago

I haven't found any supporting library other than https://github.com/bodgit/tsig which is a Golang library. I assumed it would be extra overhead, as it requires to first build using Go for being used with dnsperf.

Any library should be widely available as package in the most common distributions (Debian/Fedora/FreeBSD etc).

I analyzed the changes required for key reuse and modified the code (locally) to assign 1 key per socket (acting as a client) which required the a new list in parallel to **socks within struct threadinfo_t.

No, you can do a separate program wide cache and use mutexes to protect it across threads.

Btw, have you looked at the option to pre-generate signed UPDATE queries?

dnsperf could be made to just read and send an already signed UPDATE. That would leave you free to use any tool/library to generate the UPDATE.

jelu commented 1 year ago

Btw, if you wanna hash out the approach for this maybe it's better that we talk about on our Mattermost?

You can find me here https://chat.dns-oarc.net/community/channels/oarc-software