Commit Graph

600 Commits

Author SHA1 Message Date
Brian Cunnie
cb01b261ee Developer DOCs: tweak cutting a new release 2021-06-20 21:18:43 -07:00
Brian Cunnie
55e23e34a3 BOSH release: 2.2.0: TXT records return IP addrs 2.2.0 2021-06-20 20:52:10 -07:00
Brian Cunnie
a4aa6a8905 Website: add even more "what is my IP?" sites 2021-06-20 19:31:36 -07:00
Brian Cunnie
9bf4c72033 Website: include ns-aws's IPv6 address 2021-06-20 14:08:24 -07:00
Brian Cunnie
e89d8b5caf Website: DNS queries are 14x more efficient
...than HTTPS queries.
2021-06-20 13:45:05 -07:00
Brian Cunnie
bd9ad86ede 🐞 Docs: Use HTML not Markdown
- `TXT` → <code>TXT</code>
- Clarify wording about looking up your public IP address
2021-06-20 07:08:42 -07:00
Brian Cunnie
bc103c7964 Website: reorganize headings
- "Related Services" is at the bottom
- Recommend using ns-aws.nono.io for both IPv4 & IPv6 lookups
2021-06-19 20:40:39 -07:00
Brian Cunnie
69972df833 Document: TXT records return querier's IP address
I didn't mention <https://wtfismyip.com/> because I felt the _wtf_
portion wasn't what I wanted on my website.
2021-06-19 20:02:27 -07:00
Brian Cunnie
b066b8821c DNS Server: Bump Serial to today's date
Drive-by: remove `named.conf`, an artifact of when we were powered by
PowerDNS.
2021-06-19 14:25:28 -07:00
Brian Cunnie
d2b99704ec TXT records: return querier's IP address
If there are no custom records, then return the querier's IP address.
This is so that I can use it instead of Google'ing "what is my IP
address" or `curl ident.me` or `curl -s httpbin.org/ip` or `curl
checkip.amazonaws.com`.

`dig @ns-aws.nono.io txt . +short`

Inspired by Google's `dig txt o-o.myaddr.l.google.com @8.8.8.8 +short`
2021-06-19 13:26:12 -07:00
Brian Cunnie
925ce8c978 ns-aws.nono.io has IPv6 Addr: 2600:1f18:aaf:6900::a
...and the NS records should reflect that.

Drive-by: I removed a completely duplicated test
2021-06-18 16:17:44 -07:00
Brian Cunnie
63d306b750 k8s: DNS server is deployed on AWS 2021-04-04 16:18:39 -07:00
Brian Cunnie
e27d536947 README: acknowledge JetBrains _et alii_ 2021-03-16 08:06:02 -07:00
Brian Cunnie
406b81c340 Dockerfile, Binaries include ARM (arm64 / aarch64)
Dockerfile:
- We use `CMD` instead of `ENTRYPOINT` because it's marginally easier
  to debug.
- We include 64-bit ARM, but not 32-bit
- We had to re-order the steps so that `apk add bind-tools` came
  before copying the binary; that fixed a bug where the
  `sslip.io-dns-server` wasn't on the ARM container filesystem (but it
  was on the amd64 filesystem 🤔)

Binaries
- We now build arm64 (GOARCH) versions of FreeBSD, Linux, and macOS
  (GOOS), but not Windows. It apparently doesn't have arm64 support yet.
2021-03-08 20:29:31 -08:00
Brian Cunnie
5cd770bbbd k8s sslip.io.yml: Deployment + NodePort Service 2021-02-28 21:30:47 -08:00
Brian Cunnie
947b47c8c5 Dockerfile: sslip.io has dig to allow probes
It increases the size of the image from 8MB to 26MB, but in the grand
scheme of things that's not much space.
2021-02-28 19:57:38 -08:00
Brian Cunnie
4ed10c4408 Dockerfile needs ip, ifconfig, tcpdump...
...to troubleshoot k8s even more.
2021-02-22 21:56:25 -08:00
Brian Cunnie
56248bc87a Dockerfile needs ping...
...so that I can troubleshoot my cluster
2021-02-22 20:47:01 -08:00
Brian Cunnie
e9eea2334c Website: plea to report Let's Encrypt rate-limits
We want people to report rate-limiting so we know to request an
increase.

[#6]
2021-02-12 19:11:42 -08:00
Brian Cunnie
74aed2f5b1 HTML: better wording for wildcard subdomains
The previous version wasn't clear.
2021-02-10 13:12:55 -08:00
Brian Cunnie
e14d7f0571 Website Documentation: Expand TLS options
- Use HTTP-01 challenge for run-of-the-mill certificates
- White label domains can acquire their own wildcard certificates
- VMware employees have access to *.sslip.io wildcard
- Use DNS-01 challenge for *.w-x-y-z.sslip.io wildcards
2021-02-09 08:22:57 -08:00
Brian Cunnie
3fc089b7a7 wildcard-dns-http-server: better error-checking
- when DNS gets a permission error, it helpfully suggests using `sudo`
- when DNS can't bind to `INADDR_ANY`, it's probably because it's Fedora
running `systemd.resolved` on port 53 of 127.0.0.53, so we try to bind
to each address individually.
- we don't implement similar checks for the HTTP server:
  - if it's a permission problem, the DNS server has already warned the
  user.
  - if it's a binding problem, the user is probably running an HTTP
  server bound to `INADDR_ANY`, so we might as well exit.
- we ported this code from main `sslip.io` DNS server.
2021-02-09 06:49:00 -08:00
Brian Cunnie
7ad3f4a22f Log better messages for DNS/HTTP server
The `wildcard-dns-http-server` didn't clearly differentiate the DNS
subsystem log messages from the HTTP subsystem log messages. We now
prepend "DNS:" and "HTTP:" depending the source of the message.
2021-02-08 20:00:27 -08:00
Brian Cunnie
fe3d81f194 Wildcard instructions: formatting, typos 2021-02-08 09:10:58 -08:00
Brian Cunnie
73a735bf37 Wildcard instructions: incorporate Norman's suggestions
Drive-by: update version numbers in `DEVELOPER.md`.
2021-02-06 14:02:21 -08:00
Brian Cunnie
ff35a2c1d1 Dockerfile: cunnie/sslip.io-dns-server → 2.1.2 2021-01-30 20:02:40 -08:00
Brian Cunnie
d2ed920d20 Bump version number on download link on web page 2021-01-30 20:00:19 -08:00
Brian Cunnie
041744312f BOSH release: 2.1.2: case-insensitive custom records matching 2.1.2 2021-01-30 19:37:45 -08:00
Brian Cunnie
1614f574bc 🐞 Ignore case when comparing customized records
This fixes an error when procuring Let's Encrypt certs using HTTP-01
challenge--my server didn't recognize, when queried with `SsLiP.iO`,
that it's the same as `sslip.io`, and so it doesn't reply with the
correct A/AAAA records.

fixes:
```
sudo /usr/local/bin/certbot renew
  No valid IP addresses found for sslip.io
```

log messages from `/var/vcap/sys/log/sslip.io-dns-server/sslip.io-dns-server.stderr.log`:
```
2021/01/30 21:45:49 3.122.55.230.22713 TypeA SsliP.IO. ? nil, SOA SsliP.IO. briancunnie.gmail.com. 2021011400 900 900 1800 300
2021/01/30 21:45:49 54.187.227.254.16621 TypeAAAA SslIP.io. ? nil, SOA SslIP.io. briancunnie.gmail.com. 2021011400 900 900 1800 300
```
2021-01-30 13:47:50 -08:00
Brian Cunnie
64df830d91 Use Go 1.13's errors.As() wherever possible
Now I know how to use a `syscall.Errno` with `errors.As()`
2021-01-30 12:37:52 -08:00
Brian Cunnie
115973bc12 Binding to port 53: better messaging
The bulk of this commit is to address problems under Linux:

- The user needs to be root to bind to port 53 (or have the
`CAP_NET_BIND_SERVICE` capability), so if we have a permissions-problem,
we say, "try `sudo`".

- If we can't bind to `INADDR_ANY`, and we probably can't because
"`systemd-resolved` provides a local DNS stub listener on IP address
127.0.0.53" on port 53, which prevents us from binding, we fallback
to attempting to bind to every available address individually.

This commit bloats `main.go`, which I have mixed feelings about because
it's untested.
2021-01-25 06:36:07 -08:00
Brian Cunnie
0d5886120a Give users a hint when permissions fail
addresses:
```
listen udp :53: bind: permission denied
```
2021-01-23 12:41:39 -08:00
Brian Cunnie
c349b45ea6 Docs: Securing a wildcard cert from Let's Encrypt
We are pleased to announce that these instructions finally work.

[#6]
2021-01-20 16:45:01 -08:00
Brian Cunnie
0be7a8c7e6 Dockerfile: cunnie/sslip.io-dns-server → 2.1.1 2021-01-20 16:03:57 -08:00
Brian Cunnie
5429c71c87 BOSH release: 2.1.1: case-insensitive _acme-challenge matching 2.1.1 2021-01-20 15:51:00 -08:00
Brian Cunnie
1a9279ecc1 🐞 _acme-challenge. comparisons are case-insensitive
Our DNS-01 challenges were failing because we weren't prepared for
mixed-case queries. Now we properly recognize them.

```
2021/01/20 20:15:40 3.123.253.205.45368 TypeTXT _ACMe-cHalLeNGE.34-83-219-164.sSlip.Io. ? nil, SOA _ACMe-cHalLeNGE.34-83-219-164.sSlip.Io. briancunnie.gmail.com. 2021011400 900 900 1800 300
```
```
2021/01/20 20:15:40 18.219.85.19.35164 TypeTXT _acMe-chaLlENGe.34-83-219-164.ssliP.Io. ? nil, SOA _acMe-chaLlENGe.34-83-219-164.ssliP.Io. briancunnie.gmail.com. 2021011400 900 900 1800 300
```
```
2021/01/20 20:15:40 66.133.109.36.11107 TypeTXT _aCme-chaLleNGe.34-83-219-164.sSLip.Io. ? nil, SOA _aCme-chaLleNGe.34-83-219-164.sSLip.Io. briancunnie.gmail.com. 2021011400 900 900 1800 300
```
2021-01-20 13:00:42 -08:00
Brian Cunnie
a3de35fa45 Dockerfile: cunnie/sslip.io-dns-server → 2.1.0 2021-01-20 11:59:42 -08:00
Brian Cunnie
3025c8186d BOSH release: 2.1.0: moar _acme-challenge delegation 2.1.0 2021-01-20 08:54:00 -08:00
Brian Cunnie
f797605bba Delegate ALL "_acme-challenge." queries
The purpose of this commit is to enable Let's Encrypt DNS-01 challenges
for wildcard certificates.

To accomplish that, we'd like to delegate queries for ALL types (e.g.
NS, SOA, A, AAAA) to the IP address of that server. For example, any
query for `_acme-challenge.52-0-56-137.sslip.io` would be delegated to
the DNS server `52-0-56-137.sslip.io` (whose IP address 52.0.56.137
would be supplied as well).

Thanks @NormanR !

On a personal note, I feel the code is getting bloated again. Also, I'm
inconsistent with my parameters: `NSResponse()`, for example, has
arguments which it mutates (`response`), and which are returned
(`logMessage`). This offends my esthetics.

[#6]
2021-01-20 08:23:53 -08:00
Brian Cunnie
4816854d3f Response queries include NS IP addrs in Additionals
When querying for NS (name server) records, the responses include an
"Additionals" section which lists the IP addresses of the name server.
This is a courtesy & an optimization: by sending the IP address, we
avoid the client sending a second query for the IP address of the
nameserver.

With this change, the following command...

```
dig @ns-aws.nono.io sslip.io ns
```

...will yield these additional records:

```diff
+;; ADDITIONAL SECTION:
+ns-aws.nono.io.                604800  IN      A       52.0.56.137
+ns-azure.nono.io.              604800  IN      A       52.187.42.158
+ns-gce.nono.io.                604800  IN      A       104.155.144.4
```
2021-01-20 06:39:02 -08:00
Brian Cunnie
9691e1326d 🐞 Tests: Fix out-of-order matching on Linux
Our CI is failing, and it appears that the `Eventually` pointer is moved
ahead by one of the tests, skipping over the line that another test is
waiting for.

To fix, rather than relying on a pointer, we compare the entire contents
of the DNS server's stderr output. We also remove the `$` anchor from
the regex which was causing it to fail.

fixes <https://ci.nono.io/teams/main/pipelines/sslip.io/jobs/unit/builds/149>:
```
  Got stuck at:
      2021/01/19 15:34:28 127.0.0.1.60973 TypeNS example.com. ? ns-aws.nono.io., ns-azure.nono.io., ns-gce.nono.io.
      2021/01/19 15:34:28 127.0.0.1.46683 TypeMX sslip.io. ? 10 mail.protonmail.ch., 20 mailsec.protonmail.ch.

  Waiting for:
      TypeNS example.com. \? ns-aws.nono.io., ns-azure.nono.io., ns-gce.nono.io.\n$
```
2021-01-19 08:30:02 -08:00
Brian Cunnie
c44b8e6d94 🐞 ;; Warning: ID mismatch: expected ID x, got y
When I ran the following code, I would get at least one of the above
messages when run on the Linux CI container:

```bash
for i in $(seq 1 32); do
  dig @localhost asdf +short &
done
```

The error hasn't recurred after this change, in spite of running the
above code a dozen times.
2021-01-19 07:27:53 -08:00
Brian Cunnie
1b6d72cf49 🐞 dig: "any" type query works on macOS & Linux
The behavior of `dig` version **9.11.25-RedHat-9.11.25-2.fc32** differs
from macOS's `dig` version **9.10.6**. In other words, this test passes
on my mac but not until now on (Linux-based) CI.

I also took the opportunity to refactor our `dig` arguments to conform with
the suggested usage:

> Usage:  dig [@global-server] [domain] [q-type] [q-class] {q-opt}

fixes <https://ci.nono.io/teams/main/pipelines/sslip.io/jobs/unit/builds/145>:
```
  Expected
      <int>: 9
  to match exit code:
      <int>: 0
```

Note that for the `any` test I had to append an additional `+notcp`
argument to avoid an attempted TCP connection. I suspect a bug in `dig`:
```
dig any sslip.io @localhost
;; Connection to 127.0.0.1#53(127.0.0.1) for sslip.io failed: connection refused.
```
2021-01-19 07:05:17 -08:00
Brian Cunnie
b534bcd0cb Formatting only: goimports -w 2021-01-19 07:04:07 -08:00
Brian Cunnie
bdb0b08de8 🐞 wildcard-dns-http-server: multiple TXT records
- it appears that Let's Encrypt requires setting at least two TXT
records; before I only allowed one to be set; now you can set as many as
you want.

- our records had a TTL of 0 seconds; I bumped it to 60: long enough to
get a cert, short enough to refesh for a second attempt if the first one
failed.
2021-01-18 16:52:27 -08:00
Brian Cunnie
6d0d3b9be5 🐞 HTTP server returns body confirming change
Previously we weren't returning a response when `acme.sh` updated our
TXT record, but the acme-dns endpoint specifies a
[response](https://github.com/joohoi/acme-dns#response), and acme.sh
expects [a
response](b7a3fe05a4/dnsapi/dns_acmedns.sh (L38)).

fixes:
```
[Mon Jan 18 19:09:26 UTC 2021] invalid response of acme-dns
[Mon Jan 18 19:09:26 UTC 2021] Error add txt for domain:_acme-challenge.34-83-219-164.sslip.io
```
2021-01-18 14:19:06 -08:00
Brian Cunnie
a346b7d668 Dockerfile: cunnie/sslip.io-dns-server → 2.0.0 2021-01-18 11:01:05 -08:00
Brian Cunnie
b2396ff081 🐞 bin/make_all compiles in correct directory
We had moved the DNS server to a sub-directory to make room for a
sibling application, a small DNS server + small HTTP server.

fixes:
```
cannot find package "main.go" in any of:
	/usr/local/Cellar/go/1.15.6/libexec/src/main.go (from $GOROOT)
	/Users/cunnie/go/src/main.go (from $GOPATH)
```
2021-01-18 10:42:54 -08:00
Brian Cunnie
eb032a78d8 BOSH release: 2.0.0: 🐞 _acme-challenge. delegation 2.0.0 2021-01-18 10:21:09 -08:00
Brian Cunnie
e33c33269f 🐞 Respond to Let's Encrypt Challenges properly
When querying for a record with `_acme-challenge.` and an embedded IP
address, we mistakenly responded with an answer with the
**authoritative** flag set and the **SOA** record in the **Authorities**
section. But that was wrong: we should NOT have set the
**authoritative** flag, and we should have included the **NS** record,
not the **SOA** record, in the **Authorities** section.

Created much-needed integration-level tests. The existing unit tests
were difficult to set up, were too constricting when refactoring, and
were less meaningful than the integration tests.

Hygiene:

- Eliminated the `ErrNotFound` error; it was hack: it was a substitute
for returning an empty set, which I wasn't handling correctly. Now, when
a record isn't found (usually because it's not a customized domain), it
returns an empty set, not an error.

- Used the `dnsmessage` capitalization convention where applicable, e.g.
`SOAResource()` not `SOAResource()`

- Replaced painful low-level copying with the `dnsmessage`'s utility
functions, `NewName()` and `MustNewName()`

This change triggered a huge rewrite, for we had hard-coded the
**authoritative** flag. The newer code is more flexible, and lays the
groundwork for future changes such as including IP addresses in the
**Additionals** section.
2021-01-18 07:32:13 -08:00