ipn/ipnlocal, net/dns*, util/cloudenv: add AWS DNS support

And remove the GCP special-casing from ipn/ipnlocal; do it only in the
forwarder for *.internal.

Fixes #4980
Fixes #4981

Change-Id: I5c481e96d91f3d51d274a80fbd37c38f16dfa5cb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2022-06-29 19:32:41 -07:00
committed by Brad Fitzpatrick
parent 88c2afd1e3
commit aa37aece9c
7 changed files with 103 additions and 82 deletions

View File

@ -6,6 +6,9 @@
package cloudenv
import (
"os"
"runtime"
"strings"
"sync/atomic"
gcpmetadata "cloud.google.com/go/compute/metadata"
@ -15,14 +18,41 @@ import (
// It's also the *.internal DNS server, and proxies to 8.8.8.8.
const GoogleMetadataAndDNSIP = "169.254.169.254"
// AWSResolverIP is the IP address of the AWS DNS server.
// See https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html
const AWSResolverIP = "169.254.169.253"
// Cloud is a recognize cloud environment with properties that
// Tailscale can specialize for in places.
type Cloud string
const (
GCP = Cloud("gcp") // Google Cloud
AWS = Cloud("aws") // Amazon Web Services (EC2 in particular)
)
// ResolverIP returns the cloud host's recursive DNS server or the
// empty string if not available.
func (c Cloud) ResolverIP() string {
switch c {
case GCP:
return GoogleMetadataAndDNSIP
case AWS:
return AWSResolverIP
}
return ""
}
// HasInternalTLD reports whether c is a cloud environment
// whose ResolverIP serves *.internal records.
func (c Cloud) HasInternalTLD() bool {
switch c {
case GCP, AWS:
return true
}
return false
}
var cloudAtomic atomic.Value // of Cloud
// Get returns the current cloud, or the empty string if unknown.
@ -37,6 +67,16 @@ func Get() Cloud {
}
func getCloud() Cloud {
// TODO(bradfitz): also detect AWS on Windows, etc. Just try to hit the metadata server
// and see if it's there? But it might be turned off. Do some small-timeout DNS request
// to 169.254.169.253 and see if it replies? But which DNS request?
if runtime.GOOS == "linux" {
biosVendorB, _ := os.ReadFile("/sys/class/dmi/id/bios_vendor")
biosVendor := strings.TrimSpace(string(biosVendorB))
if biosVendor == "Amazon EC2" || strings.HasSuffix(biosVendor, ".amazon") {
return AWS
}
}
if gcpmetadata.OnGCE() {
return GCP
}