plugins icon indicating copy to clipboard operation
plugins copied to clipboard

os-acme-client: Add support for Dnsmasq DNS

Open karelkryda opened this issue 5 months ago • 1 comments

Important notices Before you add a new report, we ask you kindly to acknowledge the following:

  • [x] I have read the contributing guide lines at https://github.com/opnsense/plugins/blob/master/CONTRIBUTING.md
  • [x] I have searched the existing issues, open and closed, and I'm convinced that mine is new.
  • [x] When the request is meant for an existing plugin, I've added its name to the title.

Is your feature request related to a problem? Please describe. OPNsense ACME client does not support DNS challenges using local DNS services (Unbound, Dnsmasq, etc.).

Describe the solution you'd like It would be nice to be able to use local DNS services running on an OPNsense machine for DNS challenges. For example, Dnsmasq supports TXT records and could be used for this use case. Currently, only the BIND plugin (os-bind) is supported.

Describe alternatives you've considered An alternative would be to add the option to create custom DNS APIs and reference them in the GUI in some way. For example, write the API name - as with Cloudflare, it is dns_cf.

Additional context I wrote a relatively simple shell script that adds a TXT record to Dnsmasq and then removes it again. Unfortunately, adding custom DNS APIs is not possible because the GUI strictly offers only the options available in the MVC model. For this reason, I was forced to "replace" the existing API code - in my case, I rewrote the ACME DNS API. This solution is not ideal because I assume that the original code will be restored when the plugin is updated.

I believe that the upstream acme.sh project would not be interested in adding this API, because its use case is quite specific - it can only be used if request is performed using the acme.sh client on an OPNsense machine with Dnsmasq. However, if you believe that I should create a PR for the upstream project, I will be happy to do so.

#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_acmedns_info='OPNsense Dnsmasq DNS Server'

dnsmasq_config_dir='/usr/local/etc/dnsmasq.conf.d'

# Add DNS record to Dnsmasq
dns_acmedns_add() {
  fulldomain=$1
  txtvalue=$2

  # Log that we are using Dnsmasq as replacement for ACME DNS server
  _info "Using Dnsmasq as replacement for ACME DNS server!"

  # Create file with TXT DNS record
  record_file="${dnsmasq_config_dir}/acme_${fulldomain}.conf"
  _info "Creating DNS record file: ${record_file}"
  echo "txt-record=${fulldomain},\"${txtvalue}\"" > "${record_file}"

  # Restart Dnsmasq to apply changes
  _info "Restarting Dnsmasq to apply changes"
  service dnsmasq onerestart

  return 0
}

# Remove DNS record from Dnsmasq
dns_acmedns_rm() {
  fulldomain=$1
  txtvalue=$2

  # Log that we are using Dnsmasq as replacement for ACME DNS server
  _info "Using Dnsmasq as replacement for ACME DNS server!"

  # Remove file with TXT DNS record
  record_file="${dnsmasq_config_dir}/acme_${fulldomain}.conf"
  _info "Removing DNS record file: ${record_file}"
  rm -f "${record_file}"

  # Restart Dnsmasq to apply changes
  _info "Restarting Dnsmasq to apply changes"
  service dnsmasq onerestart
}

karelkryda avatar Aug 12 '25 16:08 karelkryda

A TXT record requires an authoritative nameserver (if you want to be compliant).

Check out the dnsmasq man page, the article for: AUTHORITATIVE CONFIGURATION https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html

Dnsmasq is mostly a forwarder, and it should not be configured as authoritative nameserver like e.g. BIND.

Monviech avatar Aug 12 '25 16:08 Monviech