blob: df1fa73238d23f2a2a5245e60e1a4e8654cbb767 [file] [log] [blame] [view]
# Proposal: DNS Based Vanity Imports
Author(s): Sam Whited <sam@samwhited.com>
Last updated: 2018-06-30
Discussion at https://golang.org/issue/26160
## Abstract
A new mechanism for performing vanity imports using DNS TXT records.
## Background
Vanity imports allow the servers behind Go import paths to delegate hosting of
a packages source code to another host.
This is done using the HTTP protocol over TLS which means that expired
certificates, problems with bespoke servers, timeouts contacting the server, and
any number of other problems can cause looking up the source to fail.
Running an HTTP server also adds unnecessary overhead and expense that may be
difficult for hobbyists that create popular packages.
To avoid these problems, a new mechanism for looking up vanity imports is
needed.
## Proposal
To create a vanity import using DNS a separate TXT record is created for each
package with the name `go-import.example.net` where `example.net` is the domain
from the package import path.
The record data is the same format that would appear in an HTTP based vanity
imports "content" attribute.
This allows us to easily list all packages with vanity imports under a given
apex domain:
$ dig +short go-import.golang.org TXT
"golang.org/x/vgo git https://go.googlesource.com/vgo"
"golang.org/x/text git https://go.googlesource.com/text"
Because the current system for vanity import paths requires TLS unless the
`-insecure` flag is provided to `go get`, it is desirable to provide similar
security guarantees with DNS.
To this end `go get` should only accept TXT records with a verified DNSSEC
signature unless the `-insecure` flag has been passed.
To determine which package to import the Go tool would search each TXT record
returned for one that starts with the same fully qualified import path that
triggered the lookup.
TXT records for a given domain should be fetched only once when the first
package with a given domain in its import path is found and reused when parsing
other import lines in the same build.
## Rationale
Before we can make an HTTP request (as the current vanity import mechanism
does), or even establish a TLS connection, we must already have performed a DNS
lookup.
Because this happens anyways, it would be ideal to cut out other steps (HTTP,
TLS, etc.) altogether (and the extra problems they bring with them) and store
the information in the DNS record.
Even if vanity imports are deprecated in the near future for ZIP based package
servers ala vgo, backwards compatibility will be needed for some time and any
experience gained here may apply to pointing domains at package servers
(eg. via DNS SRV).
TXT records were chosen instead of a [custom resource record] to simplify
deployment and avoid the overhead of dealing with the IETF.
Because TXT records are limited to 255 characters but the apex domain used by a
package may be significantly longer than this, it is possible that some packages
may not fit in the record.
Since fully qualified package names must be typed in import statements this does
not seem practical or a cause for concern, so it is not addressed here.
[custom resource record]: https://tools.ietf.org/html/rfc6195
## Compatibility
If no TXT records are found for a given domain `go get` should fall back to
using the HTTP-based mechanism.
Having DNS TXT record lookup also lays the groundwork for discovering package
servers in a vgo-based future.
## Implementation
The author of this proposal has started looking into implementing it in the Go
tool, but cannot yet commit to a timeframe for an implementation.
## Open issues
- Does a DNSSEC implementation exist that could be vendored into the Go tool?