[GH-ISSUE #1871] Support TSIG/SIG(0) for trust-dns-util #801

Open
opened 2026-03-16 00:18:00 +03:00 by kerem · 6 comments
Owner

Originally created by @jcgruenhage on GitHub (Jan 5, 2023).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1871

Is your feature request related to a problem? Please describe.
I'm looking to write a hook script for https://github.com/breard-r/acmed, setting TXT records for a DNS-01 challenge in ACME via RFC2136, with authentication handled by TSIG.

Describe the solution you'd like
Extend dns --nameserver <NAMESERVER> create <NAME> <TYPE> <TTL> <RDATA>... to support setting TSIG/SIG(0) signing information via CLI arguments, or maybe environment variables.

Describe alternatives you've considered

  • Use a different tool
  • Use a VPN to restrict access to the DNS server instead of signing requests

Additional context
None really.

Originally created by @jcgruenhage on GitHub (Jan 5, 2023). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1871 **Is your feature request related to a problem? Please describe.** I'm looking to write a hook script for https://github.com/breard-r/acmed, setting TXT records for a DNS-01 challenge in ACME via RFC2136, with authentication handled by TSIG. **Describe the solution you'd like** Extend `dns --nameserver <NAMESERVER> create <NAME> <TYPE> <TTL> <RDATA>...` to support setting TSIG/SIG(0) signing information via CLI arguments, or maybe environment variables. **Describe alternatives you've considered** - Use a different tool - Use a VPN to restrict access to the DNS server instead of signing requests **Additional context** None really.
Author
Owner

@bluejekyll commented on GitHub (Jan 6, 2023):

Oh, this is a bit of an oversight. we should definitely make this work.

<!-- gh-comment-id:1373092205 --> @bluejekyll commented on GitHub (Jan 6, 2023): Oh, this is a bit of an oversight. we should definitely make this work.
Author
Owner

@jcgruenhage commented on GitHub (Jan 6, 2023):

With the library already supporting that, it should be fairly easy to add that,although it might require some refactoring of initializing the client. Would you be interested in a PR for this?

<!-- gh-comment-id:1373381100 --> @jcgruenhage commented on GitHub (Jan 6, 2023): With the library already supporting that, it should be fairly easy to add that,although it might require some refactoring of initializing the client. Would you be interested in a PR for this?
Author
Owner

@Darkspirit commented on GitHub (Jan 6, 2023):

Back then I found it easy to integrate trustdns (0.16.0) into my acme client which only supports DNS challenges and TLSA:
https://docs.rs/crate/trust-acme/latest/source/src/dns.rs
(I wrote it when I had such headaches I couldn't think clearly. I find it so horribly incomplete that I depublished it from Github. But I haven't touched it since then because it works.)

<!-- gh-comment-id:1373440433 --> @Darkspirit commented on GitHub (Jan 6, 2023): Back then I found it easy to integrate trustdns (0.16.0) into my acme client which only supports DNS challenges and TLSA: https://docs.rs/crate/trust-acme/latest/source/src/dns.rs (I wrote it when I had such headaches I couldn't think clearly. I find it so horribly incomplete that I depublished it from Github. But I haven't touched it since then because it works.)
Author
Owner

@jcgruenhage commented on GitHub (Jan 6, 2023):

@Darkspirit this issue is about the CLI utility. acmed relies on hooks that call other commands for completing the challenges.

<!-- gh-comment-id:1373450357 --> @jcgruenhage commented on GitHub (Jan 6, 2023): @Darkspirit this issue is about the CLI utility. acmed relies on hooks that call other commands for completing the challenges.
Author
Owner

@bluejekyll commented on GitHub (Jan 7, 2023):

Thanks, @Darkspirit . I think there are a few things to consider here. When I wrote the dns cli, I recognized that we need to refactor the client library API. It's very complicated and probably doesn't need to be. I think it could benefit from some of the work that was done on the Resolver, probably push some of those things up for the Client to benefit from, like the Runtime and such.

@jcgruenhage, I'd definitely be open to a PR, but this could be a bit more work than you may anticipate. First, I don't recommend the refactoring the Client API, that should be a separate PR. That being said, the current Client API doesn't make this straightforward to implement generically, which I ran into when writing dns originally. I did take a quick look at this. I think there are a few things I identified that need to happen here.

  1. We need a means to pass the key material into the Client. There is quite a bit, so I'm not sure we want a CLI param for each. Basically, we need a signing key for both tsig and sig0 algorithms. The keys at the moment are slightly different, it makes me wonder if we can consolidate them into a single type? Here's the key material needed for sig0 (shared with dnskey/rrsig signing): https://github.com/bluejekyll/trust-dns/blob/main/crates/client/src/rr/dnssec/signer.rs#L288 . And then here's the tsig signing material we need: https://github.com/bluejekyll/trust-dns/blob/main/crates/client/src/rr/dnssec/tsig.rs#L34-L39 . There are a few common components and a few not, but we need those parameters. see 2 & 3.

The next 2 are decisions:

  1. BIND has a key file format it uses, I have a tool I wrote a while ago to extract key material from the BIND format here: https://github.com/bluejekyll/trust-dns/blob/main/util/src/bind_dnskey_to_pem.rs . I think an option we should consider if we'd want to adopt that format to simplify the CLI arguments? Of course the alternative would be to use a more common format of from openssl, like pkcs8 (though I don't think that has all the key info like hashing algorithm, I'd have to double check). Adopting that file format would give us a simple way to store the key material in a file, and then load with a single param to the dns cli. I think we should decide on this one first.

  2. Do we want to support passing all the parameters from the CLI, name, key material, etc. I think if we do that, we'll need the encoded key in something like base64. So even if we don't do 2, there is still a bit of overhead to making the CLI work. The advantage to doing 3 is that we can then support env-var based loading of the key material, which might have benefits in docker/k8s environments where the key material wouldn't have to live on disk in a file in the docker env.

Those are at least my early thoughts here.

<!-- gh-comment-id:1374584626 --> @bluejekyll commented on GitHub (Jan 7, 2023): Thanks, @Darkspirit . I think there are a few things to consider here. When I wrote the `dns` cli, I recognized that we need to refactor the client library API. It's very complicated and probably doesn't need to be. I think it could benefit from some of the work that was done on the Resolver, probably push some of those things up for the Client to benefit from, like the Runtime and such. @jcgruenhage, I'd definitely be open to a PR, but this could be a bit more work than you may anticipate. First, I don't recommend the refactoring the Client API, that should be a separate PR. That being said, the current Client API doesn't make this straightforward to implement generically, which I ran into when writing `dns` originally. I did take a quick look at this. I think there are a few things I identified that need to happen here. 1) We need a means to pass the key material into the Client. There is quite a bit, so I'm not sure we want a CLI param for each. Basically, we need a signing key for both `tsig` and `sig0` algorithms. The keys at the moment are slightly different, it makes me wonder if we can consolidate them into a single type? Here's the key material needed for sig0 (shared with dnskey/rrsig signing): https://github.com/bluejekyll/trust-dns/blob/main/crates/client/src/rr/dnssec/signer.rs#L288 . And then here's the tsig signing material we need: https://github.com/bluejekyll/trust-dns/blob/main/crates/client/src/rr/dnssec/tsig.rs#L34-L39 . There are a few common components and a few not, but we need those parameters. see 2 & 3. The next 2 are decisions: 2) BIND has a key file format it uses, I have a tool I wrote a while ago to extract key material from the BIND format here: https://github.com/bluejekyll/trust-dns/blob/main/util/src/bind_dnskey_to_pem.rs . I think an option we should consider if we'd want to adopt that format to simplify the CLI arguments? Of course the alternative would be to use a more common format of from openssl, like pkcs8 (though I don't think that has all the key info like hashing algorithm, I'd have to double check). Adopting that file format would give us a simple way to store the key material in a file, and then load with a single param to the `dns` cli. I think we should decide on this one first. 3) Do we want to support passing all the parameters from the CLI, name, key material, etc. I think if we do that, we'll need the encoded key in something like base64. So even if we don't do 2, there is still a bit of overhead to making the CLI work. The advantage to doing 3 is that we can then support env-var based loading of the key material, which might have benefits in docker/k8s environments where the key material wouldn't have to live on disk in a file in the docker env. Those are at least my early thoughts here.
Author
Owner

@jcgruenhage commented on GitHub (Jan 16, 2023):

@jcgruenhage, I'd definitely be open to a PR, but this could be a bit more work than you may anticipate.

I have looked through the code for both the sig0 and tsig signers roughly and what the API looks like to get a client object that has these capabilities, and that didn't look too bad IMO. Definitely not straight forward, but my plan would have been to go with an MVP here first anyway, which only supports TSIG and only on UDP, which is enough to see how the rest could work, and would mean that it can happen before any major refactoring, as migrating that to a new Client API shouldn't be to much work there.

Regarding the remaining points: Using CLI args is probably not appropriate, having thought about it a bit more. CLI args end up in shell histories, and worse, they are exposed world-readable to everyone on the system as long as they are running. Every unprivileged anything can query that and steal key material. Environment variables on the other hand are protected. So, any key material should be passed to dns via env var or file content.

<!-- gh-comment-id:1384635075 --> @jcgruenhage commented on GitHub (Jan 16, 2023): > @jcgruenhage, I'd definitely be open to a PR, but this could be a bit more work than you may anticipate. I have looked through the code for both the sig0 and tsig signers roughly and what the API looks like to get a client object that has these capabilities, and that didn't look too bad IMO. Definitely not straight forward, but my plan would have been to go with an MVP here first anyway, which only supports TSIG and only on UDP, which is enough to see how the rest could work, and would mean that it can happen before any major refactoring, as migrating that to a new Client API shouldn't be to much work there. Regarding the remaining points: Using CLI args is probably not appropriate, having thought about it a bit more. CLI args end up in shell histories, and worse, they are exposed world-readable to everyone on the system as long as they are running. Every unprivileged anything can query that and steal key material. Environment variables on the other hand are protected. So, any key material should be passed to `dns` via env var or file content.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#801
No description provided.