Prior behavior was that the same trinity of NS records was returned for
every NS query:
- ns-aws.nono.io.
- ns-azure.nono.io.
- ns-gce.nono.io.
This commit introduces a change in that behavior: IF the NS query includes
the string `_acme-challenge.` AND the query has an embedded IP address
THEN the NS record returned is the query with the `_acme-challenge.`
stripped.
For example:
```
dig +short ns _acme-challenge.104.155.144.4.sslip.io
```
Would return:
```
104.155.144.4.sslip.io.
```
This is an attempt to enable
[DNS-01](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge)
challenge for wildcard certs from Let's Encrypt or other CAs
(Certificate Authorities).
Note that the embedded IP address would need to be routable (NOT 10.x
172.16-31.x, or 192.168.x).
Note that you would also need to run a DNS server such as
[acme-dns](https://github.com/joohoi/acme-dns) at that address.
Thanks @normanr !
[#6]
I try to use random domain names (`randomDomain`) in my tests wherever
possible, rather than `"example.com."` or such.
When domains have custom records, I use the variable name
`customizedDomain`.
I've bumped up the number of IPv6 fuzz tests 1,000 → 10,000 because the
tests are so cheap (quick).
`NXResources()` now takes an argument. I don't use it yet, but I plan
to.
This underscores a flaw in my code; log messages are difficult to
test, so I test them minimally.
I inlined the constant `hostmaster` ("brian.cunnie@gmail.com"). It was
was only used in one place, and we shave nanoseconds by not converting
it do a `dnsmessage.Name` every time we return an SOA record.
fixes
</var/vcap/sys/log/sslip.io-dns-server/sslip.io-dns-server.stderr.log>
(IP changed for anonymity):
```
2020/12/20 03:15:09 54.186.222.15.60886 TypeMX A8aB69E3e4D8.55.74.79.60.sslip.io. ? 0 A8aB69E3e4D8.55.74.79.60.sslip.io.^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
```
The DNS server now returns CNAME records. We have updated
`Customizations` to include `sslip.io`'s DKIM signing records.
We have renamed `MXResource()` → `MXResources()` (plural). Although
there can only be one CNAME, there can be multiple MX records. We have
also moved `MXResources` upwards to maintain a semblance of alphabetical
ordering.
We no longer have a trail of zeros at the end of our `[255]byte` arrays.
We let Golang populate the zeros for us. We also updated our Golang
Playground link to new code that doesn't produce the unnecessary zeros.
Rather than hard-coding domain names in our test, we try to use
`random8ByteString()` wherever possible.
Previously the DNS server only returned the first A record of a
customized domain; now it will return all the A records.
Documented in unit tests what happens when there are multiple matches
(spoiler: it only returns one IP address, not several):
- If there's a mix of dashed and dotted IP addresses, it returns the
dashed. (`127.0.0.1.192-168-0-1.sslip.io` → `192.168.0.1`)
- If there are more than one matched IP address, it returns the leftmost
match. (`127-0-0-1.192-168-0-1.sslip.io` → `127.0.0.1`)
Rather than using Docker Hub's automated build feature (which doesn't
seem to work when setting up new repositories), I've opted to manually
build & push the images.
There are workarounds which might allow me to use GitHub's automated
build feature, like creating an organization, moving the repos to the
new organization, and creating a 'bot' user to publish the images, but
that seems like a lot of work for little gain.
fixes:
> Fetch source repositories failed.
> Connect a GitHub account to cunnie to enable automated builds. If it is already connected, please re-link the source provider.
We use the Alpine image; it's a lean 5.6 MB, and our 3 MB server keeps
it lean at below 9 MB.
Though we include instructions to build the Dockerfile, we plan to use
Docker Hub's automated builds feature.
When we released our new Golang-based DNS server, we had a banner that
said to let us know if anything breaks, but we neglected to tell them
_how_ to let us know. Now we include a link that opens a GitHub issue.
Previously we were returning one TXT record with multiple strings for
_sslip.io_. That did not work for ProtonMail's domain verification.
It seems a convention that each TXT record has one string. _google.com_,
for example, has a separate TXT record for each string.
It turns out I had misunderstood the
[StackExchange](https://serverfault.com/questions/815841/multiple-txt-fields-for-same-subdomain)
thread.
fixes (from ProtonMail domain verification):
> Verification did not succeed, please try again in an hour.
In order to restore email service for the sslip.io domain, we need to
return custom TXT records.
The custom records are in the `xip.Customizations` variable. This lays
the groundwork for ACMEv2 wildcard DNS, which, IIRC, works via TXT
records.
Drive-by: removed an unused constant, `MxHost`. That information is
either in the `Customization` struct or generated on-the-fly.
fixes:
> Dear valued customer, We have disabled your domain sslip.io and all of its addresses. No emails will be received or sent for it.
[#6]
- 🐞 fix IPv6 resolution:
2601-41d0-2-e01e--56dB-3598.sSLIP.io. → 2601:41d0:2:e01e::56db (wrong)
→ 2601:41d0:2:e01e::56db:3598 (right)
- 🐞 fix IPv4 resolution:
minio-01.192-168-1-100.sslip.io → 1.192.168.1 (wrong)
→ 192.168.1.100 (right)
- MX records are customized
- sslip.io's records point to protonmail
- everyone else's point to themselves (whatever FQDN they queried)
- License switched to Apache because GNU is too burdensome
(trust me, I've been on the receiving end)
- include notes for myself to create BOSH releases
(DEVELOPER.md)
To avoid being caught with our pants down & having certain IPv6
addresses not resolve correctly, we introduce fuzz testing to catch any
errors. Each run tests 1k IPv6 addresses.
We haven't found any errors yet.
IPv6 resolution was truncated if there was more than one section after
the double-dash (`--`):
2601-41d0-2-e01e--56dB-3598.sSLIP.io. → 2601:41d0:2:e01e::56db (wrong)
→ 2601:41d0:2:e01e::56db:3598 (right)
The fix was to use `regexp.Longest()`
`git diff` makes it appear that I modified the IPv6 RE. I didn't. This
is merely a whitespace change caused by having forgotten to run `gofmt`
before committing the previous commit.
fixes (from the logs):
```
TypeAAAA 2601-41d0-2-e01e--56dB-3598.sSLIP.io. ? 2601:41d0:2:e01e::56db
```
Long-ago behavior (PowerDNS):
minio-01.192-168-1-100.sslip.io → 192.168.1.100
More-recent behavior (Golang):
minio-01.192-168-1-100.sslip.io → 1.192.168.1
This behavior is counter-intuitive & wrong. We now restore the long-ago
behavior by being much more strict--no more mixing of dots and dashes!
Thanks @pandaxin!
[fixes#9]
...and not the deprecated PowerDNS pipe backend shell script, which we
no longer use.
README now has the badge for the unit tests, and the placeholder is
gone.
fixes:
```
resources.6h: '6h' is not a valid identifier: must start with a lowercase letter^
```
The Golang DNS server is no longer experimental; the sslip.io
nameservers run the Golang DNS server.
- Include a placeholder for the `ginkgo` tests to run in CI.
- Include `src/` and `bosh-release/` in the list of directories.
- Mark the PowerDNS-related assets as deprecated; we no longer use
PowerDNS.
Previously I had nested `if` statements to test if a key existed and if
there were any records under that key. I squashed it so that it was no
longer nested.
Some may complain it's now harder to read, but for me it's easier to
read, and more logical, too, for the `if` statement says, "if there's an
override, then return the override."
...and everyone else's are themselves, e.g. `127.0.0.1.sslip.io`'s MX
record is `127.0.0.1.sslip.io` with a preference of 0. This allows me to
get email for sslip.io without worrying about email for every sslip.io
subdomain.
- Refactor: the global variable `NameServers` no longer holds the IP
addresses of the nameservers, merely their names. The addresses are now
held in the `Customizations` variable, the more appropriate place. We
only want one source of truth wherever possible.
- 🐞 The original Go Playground for creating `dnsmessage.Name`s was
wrong: it said to NOT put a dot at the end. You need the dot at the end.
The MX records for `sslip.io` now have dots at the end.
- The above bug caused `processQuestion()` to return an unexpected
error, but without the underlying error message. Now, when
`processQuestion()` errors in an unexpected manner, it logs the
underlying error message, which makes debugging much easier.
- Richer logging for MX queries: we now return the servers and
preferences rather than the terse `MX`.
- We use specific `fqdnString` rather than the generic `domain`
as a variable for consistency, which is the hobgoblin of small minds.
I wanted to add SPF and DKIM records (TXT records) to sslip.io, but I
couldn't because I'd have to add those records to _every_ query, and I
didn't want that.
This refactor now allows overrides for specific records for specific
domains. It's a more elegant solution.
sslip.io has the following custom records:
- A (which points to the Hetzner server)
- AAAA (same Hetzner server, but via IPv6)
- MX records (protonmail)
We describe how to run our pre-built executable within a docker
container. They can figure out the rest from there.
If they don't understand those instructions, they shouldn't be running
their own DNS server.
Now that I've worked on the other side of LGPL licensing, and the pain
of providing build instructions for a binary we download from Maven, I'm
a big fan of Apache 2.0 licensing.
The new webserver didn't have A and AAAA records for `sslip.io`, which
meant there was no website. We need a website. This commit fixes that.
The code is somewhat inflexible in that it assumes that there's exactly
oneA record and exactly one AAAA record.
I took the opportunity to bump SOA's serial and set the Hostmaster email
address to my primary email (brian.cunnie@gmail.com).
fixes:
```
curl: (6) Could not resolve host: sslip.io
```
- The impetus? I deployed a custom webserver but forgot to add the
A & AAAA records for sslip.io, so the website disappeared.
- I now check for the A & AAAA records (to be present, but not of any
particular value because that gives me the latitude to migrate to
other machines).
- I also check that the website is responsive.
- drive by: removed hard-coding of `sslip.io` in many tests; instead we
now query the domain that the env var `DOMAIN` is set to.
On macOS, `whois` returns _two_ results for the domain `sslip.io` from
two different whois servers:
- whois.nic.io
- whois.namecheap.com
This means that every nameservers is double-counted. To fix, we remove
the duplicates.
fixes:
```
Failure/Error: expect(dig_nameservers.sort).to eq(whois_nameservers.sort)
expected: ["ns-aws.nono.io.", "ns-aws.nono.io.", "ns-azure.nono.io.", "ns-azure.nono.io.", "ns-gce.nono.io.", "ns-gce.nono.io."]
got: ["ns-aws.nono.io.", "ns-azure.nono.io.", "ns-gce.nono.io."]
(compared using ==)
# ./spec/check-dns_spec.rb:44:in `block (3 levels) in <top (required)>'
```
DiG 9.10.6 no longer has the `+noidn` option, and `dig` will error if we
try to use it.
fixes:
```
dig +short +noidnin ns sslip.io @ns-azure.nono.io.
Invalid option: +noidnin
```
And this previously-invalid dig query now works, so we don't need the
option anyway:
```
dig +short AAAA api.--.sslip.io
::
```
This reverts commit a2564c12d3.
- Modified SOA:
- We're setting the SOA serial _backwards_; yes, even though there's no
impact, it feels gross. But the alternative, modifying the Golang code
and re-releasing, was too much work.
- I changed the SOA's refresh/retry/expire to match google.com's.
- I changed the mname (primary master) from `ns-he.nono.io` to
`sslip.io`. The change is cosmetic; those are the same machine.
- We emptied out the `pdns_named_conf`; we're not using the bind backend
anymore, so the bind configuration can be empty.
fixes <https://ci.nono.io/teams/main/pipelines/sslip.io/jobs/check-dns/builds/3813>:
```
expected: "ns-he.nono.io. briancunnie.gmail.com. 2020112800 300 300 300 300\n"
got: "sslip.io. yoyo.nono.io. 2020090400 900 900 1800 300\n"
```
fixes:
```
+ go build -o /var/vcap/packages/sslip.io-dns-server/bin/sslip.io-dns-server
main.go:7:2: package xip/xip is not in GOROOT (/var/vcap/data/packages/golang-1-linux/da1e0a99a1246edab92d9ffd0c4a2e7c3d5df83a/src/xip/xip)
```