feature request, wildcard host resolution from hostfile
titpetric opened this issue · 5 comments
I'd like to request a feature, a bit of an extension of the hosts file. I'd like to add support for a wildcard domain. I would suggest implementing it as:
IP1 *.server.lan server.lan
IP2 mail.server.lan
I would want it to work similar to nginx server_name directive. Meaning:
resolve server.lan to IP1 (exact match, as now)
resolve mail.server.lan to IP2 (exact match, as now)
resolve www.server.lan to IP1 (wildcard match, new)
My main use is running a VM guest locally on the laptop, using it for a DNS to avoid modifying hosts file on the host. Several projects have a catch-all domain entry point, where it wouldn't be feasible for me to create many hosts file entries, and bind* or other dns servers take too much of configuration / maintenance.
If you're willing to accept a pull request from a newbie, I can also work on implementing the above in Go. I guess I could swing it, even if Go is not my default language :)
Best,
Tit
I think we can do that.
Also let's keep it simple and cheap so just one level of wildcard lookup.
Given a hosts file of:
192.168.0.1 www.server.lan
192.168.0.2 *.server.lan
Query www.server.lan
resolves to 192.168.0.1
Query www2.server.lan
resolves to 192.168.0.2
Query www.subdomain.server.lan
will not be resolved
Should be easy to implement. hostname
struct gets an additional field. When we do wildcard lookup check for a hostname with matching hostname.domain
and hostname.wildcard
set to true
.
type hostname struct {
domain string
ip net.IP
ipv6 bool
wildcard bool
}
PR is welcome! 😄
I've made some modifications, and even extended tests with new wildcard functionality. I figured out how to build dnsmasq with scripts/build, but I'm quite unfamiliar with golang dev/build/test steps. How can I run the tests inside hostsfile_test.go? I don't want to leave the hard parts to you :)
Just leaving some information here for posterity before I submit a PR:
I figured out that the test are not updated, so I updated them. Most notable change since the tests were written, is that parseLine rejects link-local definitions (ipv4 and ipv6) with IsGlobalUnicast + ParseIP("fe00::"). I didn't try to change this behavior, but I did update the tests to use some valid IPv6 and IPv4 IPs. Tests are updated with wildcard matches, and I added an Equal method to hostname to check equality - tests wanted it, but was missing.
I'm running the test with the following command:
# docker run --rm=true -it -v `pwd`:/go golang go test -v
=== RUN TestEquality
--- PASS: TestEquality (0.00s)
=== RUN TestParseLine
--- PASS: TestParseLine (0.00s)
=== RUN TestHostname
--- PASS: TestHostname (0.00s)
PASS
ok _/go 0.002s
I moved some code around, just to make it accessible for testing. Most notably, I put FindHost and FindHosts method in hostlist struct, and did some other restructuring as well.
I tested that running scripts/build
works for me, but I didn't test if the output / dnsmasq works as expected after the change. I hope the unit test is enough and that I didn't break any behavior here.
Verified the modifications work as expected:
> server 127.0.0.1
Default server: 127.0.0.1
Address: 127.0.0.1#53
> test.my.lan
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
Name: test.my.lan
Address: 49.1.1.1
> anything.my.lan
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
Name: anything.my.lan
Address: 49.1.1.1
> my.anything.my.lan
Server: 127.0.0.1
Address: 127.0.0.1#53
** server can't find my.anything.my.lan: NXDOMAIN
With hosts file:
49.1.1.1 *.my.lan
Thanks for the opportunity to write some golang :) I hope I didn't step on any toes while restructuring FindHosts a bit. Let me know if some corrections are needed on your side.
Feature has been released: https://github.com/janeczku/go-dnsmasq/releases/tag/1.0.2