diff --git a/README.md b/README.md index efcb3f6..83bb43f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # sslip.io -| Test Type | Status | -|---|---| +| Test Type | Status | +|------------------------|----------------------------------------------------------------------------------------------------------------------------------------| | Production Nameservers | [![ci.nono.io](https://ci.nono.io/api/v1/pipelines/sslip.io/jobs/dns-servers/badge)](https://ci.nono.io/teams/main/pipelines/sslip.io) | -| DNS Server Unit Tests | [![ci.nono.io](https://ci.nono.io/api/v1/pipelines/sslip.io/jobs/unit/badge)](https://ci.nono.io/teams/main/pipelines/sslip.io) | +| DNS Server Unit Tests | [![ci.nono.io](https://ci.nono.io/api/v1/pipelines/sslip.io/jobs/unit/badge)](https://ci.nono.io/teams/main/pipelines/sslip.io) | *sslip.io* is a DNS server that maps specially-crafted DNS A records to IP addresses (e.g. "127-0-0-1.sslip.io" maps to 127.0.0.1). It is similar to, and @@ -24,6 +24,7 @@ sudo go run main.go ``` In another window: + ```bash dig @localhost 192.168.0.1.sslip.io +short # should return "192.168.0.1" @@ -117,36 +118,36 @@ as ARM64 (AWS Graviton, Apple M1/M2). ## Command-line Flags - `-port` overrides the default port, 53, which the server binds to. This can - be especially useful when running as a non-privileged user, unable to bind to - privileged ports (<1024) ("`listen udp :53: bind: permission denied`"). For - example, to run the server on port 9553: `go run main.go -port 9553`. To query, - `dig @localhost 127.0.0.1.sslip.io -p 9553` -- `-nameservers` overrides the default NS records `ns-aws.sslip.io`, - `ns-azure.sslip.io`, `ns-gce.sslip.io`, and `ns-ovh.sslip.io`; flag, e.g. `go -run main.go -nameservers ns1.example.com,ns2.example.com`). If you're running - your own nameservers, you probably want to set this. Don't forget to set - address records for the new name servers with the `-addresses` flag (see - below). Exception: `_acme-challenge` records are handled differently to - accommodate the procurement of Let's Encrypt wildcard certificates; you can - read more about that procedure [here](docs/wildcard.md) +be especially useful when running as a non-privileged user, unable to bind to +privileged ports (<1024) ("`listen udp :53: bind: permission denied`"). For +example, to run the server on port 9553: `go run main.go -port 9553`. To query, +`dig @localhost 127.0.0.1.sslip.io -p 9553` +- `-nameservers` overrides the default NS records `ns-azure.sslip.io`, +`ns-gce.sslip.io`, and `ns-ovh.sslip.io`; flag, e.g. `go run main.go +-nameservers ns1.example.com,ns2.example.com`). If you're running your own +nameservers, you probably want to set this. Don't forget to set address records +for the new name servers with the `-addresses` flag (see below). Exception: +`_acme-challenge` records are handled differently to accommodate the +procurement of Let's Encrypt wildcard certificates; you can read more about +that procedure [here](docs/wildcard.md) - `-addresses` overrides the default A/AAAA (IPv4/IPv6) address records. For - example, here's how we set the IPv4 record & IPv6 record for our nameserver (in - the `-nameservers` example above), ns1.example.com: `-addresses +example, here's how we set the IPv4 record & IPv6 record for our nameserver (in +the `-nameservers` example above), ns1.example.com: `-addresses ns1.example.com=10.8.8.8,ns1.example.com=fc::8888`. Note that you can set many - addresses for a single host, e.g. - `ns1.example.com=1.1.1.1,ns1.example.com=8.8.8.8,ns1.example.com=9.9.9.9` +addresses for a single host, e.g. +`ns1.example.com=1.1.1.1,ns1.example.com=8.8.8.8,ns1.example.com=9.9.9.9` - `-blocklistURL` overrides the default block list, - (). - It's not necessary to override this if you're in an internetless environment: - if the DNS server can't download the blocklist, it prints out a message and - continues to serve DNS queries +(). +It's not necessary to override this if you're in an internetless environment: +if the DNS server can't download the blocklist, it prints out a message and +continues to serve DNS queries ## DNS Server Miscellany - it binds to both UDP and TCP. - The SOA record is hard-coded except the _MNAME_ (primary master name server) record, which is set to the queried hostname (e.g. `dig big.apple.com - @ns-aws.nono.io` would return an SOA with an _MNAME_ record of + @ns-ovh.nono.io` would return an SOA with an _MNAME_ record of `big.apple.com.` - The MX records are hard-coded to the queried hostname with a preference of 0, except `sslip.io` itself, which has custom MX records to enable email @@ -157,7 +158,7 @@ ns1.example.com=10.8.8.8,ns1.example.com=fc::8888`. Note that you can set many - `ci/` contains the [Concourse](https://concourse.ci/) continuous integration (CI) pipeline and task -- `spec/` contains the tests for the production nameservers. To run +- `spec/` contains the tests for the production nameservers. To run the tests locally: ```bash DOMAIN=sslip.io rspec --format documentation --color spec/ diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md index b6f7758..cf10c65 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -48,7 +48,7 @@ dig +short 127.0.0.1.example.com @$DNS_SERVER_IP echo 127.0.0.1 # NS ordering might be rotated dig +short ns example.com @$DNS_SERVER_IP -printf "ns-aws.sslip.io.\nns-azure.sslip.io.\nns-gce.sslip.io.\nns-ovh.sslip.io.\n" +printf "ns-azure.sslip.io.\nns-gce.sslip.io.\nns-ovh.sslip.io.\n" dig +short mx example.com @$DNS_SERVER_IP echo "0 example.com." dig +short mx sslip.io @$DNS_SERVER_IP diff --git a/docs/logs.md b/docs/logs.md index 0b36dce..be0acb3 100644 --- a/docs/logs.md +++ b/docs/logs.md @@ -1,6 +1,6 @@ ### Tools for Exploring Log Files -To generate log files on, say, ns-aws: +To generate log files on, say, ns-ovh: ```zsh sudo journalctl -u sslip.io-dns -S yesterday > /tmp/sslip.io.log diff --git a/docs/wildcard.md b/docs/wildcard.md index d6ce5d7..e8c66c2 100644 --- a/docs/wildcard.md +++ b/docs/wildcard.md @@ -4,7 +4,7 @@ Let's say you have a domain that is hosted on Amazon Route53, lets call it `example.com`. You have a few DNS entries set up like `foo.example.com`, and then -you have `xip.example.com` which is an NS record to `ns-aws.sslip.io`. So you +you have `xip.example.com` which is an NS record to `ns-ovh.sslip.io`. So you are able to use both regular DNS records that are hardcoded, and then when you need to use sslip you simply use your xip subdomain. @@ -14,7 +14,7 @@ Let's Encrypt DNS-01 challenge process. Let's Encrypt will query your name servers for the TXT record `_acme-challenge.xip.example.com`, then your DNS server will respond with the TXT record _that should have been created on Route53 as part of the challenge_, -otherwise it'll return the delegated nameservers (ns-aws.sslip.io and so on). +otherwise it'll return the delegated nameservers (ns-azure.sslip.io and so on). ### Using the sslip.io domain diff --git a/integration_test.go b/integration_test.go index aac1332..7cab64d 100644 --- a/integration_test.go +++ b/integration_test.go @@ -236,20 +236,20 @@ var _ = Describe("sslip.io-dns-server", func() { digCmd = exec.Command("dig", strings.Split(digArgs, " ")...) digSession, err = Start(digCmd, GinkgoWriter, GinkgoWriter) Expect(err).ToNot(HaveOccurred()) - Eventually(digSession).Should(Say(`52.0.56.137`)) Eventually(digSession).Should(Say(`52.187.42.158`)) Eventually(digSession).Should(Say(`104.155.144.4`)) + Eventually(digSession).Should(Say(`51.75.53.19`)) Eventually(digSession, 1).Should(Exit(0)) - Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeA ns.sslip.io. \? 52.0.56.137, 52.187.42.158, 104.155.144.4\n`)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeA ns.sslip.io. \? 52.187.42.158, 104.155.144.4, 51.75.53.19\n`)) }) It("returns all the AAAA records", func() { digArgs = "@localhost aaaa ns.sslip.io +short -p " + strconv.Itoa(port) digCmd = exec.Command("dig", strings.Split(digArgs, " ")...) digSession, err = Start(digCmd, GinkgoWriter, GinkgoWriter) Expect(err).ToNot(HaveOccurred()) - Eventually(digSession).Should(Say(`2600:1f18:aaf:6900::a`)) + Eventually(digSession).Should(Say(`2001:41d0:602:2313::1`)) Eventually(digSession, 1).Should(Exit(0)) - Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeAAAA ns.sslip.io. \? 2600:1f18:aaf:6900::a, 2600:1900:4000:4d12::\n`)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeAAAA ns.sslip.io. \? 2600:1900:4000:4d12::, 2001:41d0:602:2313::1\n`)) }) }) When("there are multiple MX records returned (e.g. sslip.io)", func() { @@ -270,11 +270,9 @@ var _ = Describe("sslip.io-dns-server", func() { digCmd = exec.Command("dig", strings.Split(digArgs, " ")...) digSession, err = Start(digCmd, GinkgoWriter, GinkgoWriter) Expect(err).ToNot(HaveOccurred()) - Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 7`)) + Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 5`)) Eventually(digSession).Should(Say(`;; ANSWER SECTION:`)) Eventually(digSession).Should(Say(`;; ADDITIONAL SECTION:`)) - Eventually(digSession).Should(Say(`ns-aws.sslip.io..*52.0.56.137\n`)) - Eventually(digSession).Should(Say(`ns-aws.sslip.io..*2600:1f18:aaf:6900::a\n`)) Eventually(digSession).Should(Say(`ns-azure.sslip.io..*52.187.42.158\n`)) Eventually(digSession).Should(Say(`ns-gce.sslip.io..*104.155.144.4\n`)) Eventually(digSession).Should(Say(`ns-gce.sslip.io..*2600:1900:4000:4d12::\n`)) @@ -282,11 +280,10 @@ var _ = Describe("sslip.io-dns-server", func() { Eventually(digSession).Should(Say(`ns-ovh.sslip.io..*2001:41d0:602:2313::1\n`)) Eventually(digSession, 1).Should(Exit(0)) // the server names may appear out-of-order - Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-aws.sslip.io.\n`)) Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-azure.sslip.io.\n`)) Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-gce.sslip.io.\n`)) Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-ovh.sslip.io.\n`)) - Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS example.com. \? ns-aws.sslip.io., ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n`)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS example.com. \? ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n`)) }) }) When(`there are multiple TXT records returned (e.g. SPF for sslip.io)`, func() { @@ -408,8 +405,8 @@ var _ = Describe("sslip.io-dns-server", func() { // use regex to account for rotated nameserver order Entry("an NS record with acme_challenge with a forbidden string is not delegated", "@localhost _acme-challenge.raiffeisen.fe80--.sslip.io ns +short", - `\Ans-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\n\z`, - `TypeNS _acme-challenge.raiffeisen.fe80--.sslip.io. \? ns-aws.sslip.io., ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n$`), + `\Ans-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\n\z`, + `TypeNS _acme-challenge.raiffeisen.fe80--.sslip.io. \? ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n$`), Entry("an A record with a forbidden CIDR is redirected", "@localhost nf.43.134.66.67.sslip.io +short", `\A52.0.56.137\n\z`, diff --git a/k8s/document_root_sslip.io/index.html b/k8s/document_root_sslip.io/index.html index 31a2875..1e73f39 100644 --- a/k8s/document_root_sslip.io/index.html +++ b/k8s/document_root_sslip.io/index.html @@ -136,12 +136,6 @@ src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"> - - ns-aws.sslip.io. - 52.0.56.137
- 2600:1f18:aaf:6900::a - USA - ns-azure.sslip.io. 52.187.42.158 @@ -238,7 +232,7 @@ dig @ns.sslip.io txt ip.sslip.io +short -6 # forces IPv6 lookup; sample reply "2

A big advantage of using DNS queries instead of HTTP queries is bandwidth: querying - ns-aws.sslip.io requires a mere 592 bytes spread over 2 packets; Querying ns-azure.sslip.io requires a mere 594 bytes spread over 2 packets; Querying https://icanhazip.com/ requires 8692 bytes spread out over 34 packets—over 14 times as much! Admittedly bandwidth usage is a bigger concern for the one hosting the service than the one using the service.

@@ -256,7 +250,7 @@ dig @ns-gce.nono.io version.status.sslip.io txt +short

Server Metrics

You can retrieve metrics from a given server by querying the TXT records of metrics.status.sslip.io
-dig @ns-aws.sslip.io metrics.status.sslip.io txt +short
+dig @ns-azure.sslip.io metrics.status.sslip.io txt +short
   "Uptime: 165655"
   "Blocklist: 2023-10-04 07:37:50-07 3,6"
   "Queries: 14295231 (86.3/s)"
diff --git a/main.go b/main.go
index 6f67249..909b0a9 100644
--- a/main.go
+++ b/main.go
@@ -17,16 +17,16 @@ func main() {
 	var blocklistURL = flag.String("blocklistURL",
 		"https://raw.githubusercontent.com/cunnie/sslip.io/main/etc/blocklist.txt",
 		`URL containing a list of non-resolvable IPs/names/CIDRs, usually phishing or scamming sites. Example "file://etc/blocklist.txt"`)
-	var nameservers = flag.String("nameservers", "ns-aws.sslip.io.,ns-azure.sslip.io.,ns-gce.sslip.io.,ns-ovh.sslip.io.",
+	var nameservers = flag.String("nameservers", "ns-azure.sslip.io.,ns-gce.sslip.io.,ns-ovh.sslip.io.",
 		"comma-separated list of FQDNs of nameservers. If you're running your own sslip.io nameservers, set them here")
 	var addresses = flag.String("addresses",
 		"sslip.io=78.46.204.247,"+
 			"sslip.io=2a01:4f8:c17:b8f::2,"+
-			"ns.sslip.io=52.0.56.137,"+
 			"ns.sslip.io=52.187.42.158,"+
 			"ns.sslip.io=104.155.144.4,"+
-			"ns.sslip.io=2600:1f18:aaf:6900::a,"+
 			"ns.sslip.io=2600:1900:4000:4d12::,"+
+			"ns.sslip.io=51.75.53.19,"+
+			"ns.sslip.io=2001:41d0:602:2313::1,"+
 			"ns-aws.sslip.io=52.0.56.137,"+
 			"ns-aws.sslip.io=2600:1f18:aaf:6900::a,"+
 			"ns-azure.sslip.io=52.187.42.158,"+
diff --git a/xip/xip.go b/xip/xip.go
index c90550e..939b6dc 100644
--- a/xip/xip.go
+++ b/xip/xip.go
@@ -656,7 +656,7 @@ func (x *Xip) NSResponse(name dnsmessage.Name, response Response, logMessage str
 	var logMessages []string
 	if response.Header.Authoritative {
 		// we're authoritative, so we reply with the answers
-		// but we rotate the nameservers every second so ns-aws doesn't bear the brunt (64%) of the traffic
+		// but we rotate the nameservers every second so one server doesn't bear the brunt of the traffic
 		epoch := time.Now().UTC().Unix()
 		index := int(epoch) % len(x.NameServers)
 		rotatedNameservers := append(x.NameServers[index:], x.NameServers[0:index]...)
diff --git a/xip/xip_test.go b/xip/xip_test.go
index b4280aa..967e52a 100644
--- a/xip/xip_test.go
+++ b/xip/xip_test.go
@@ -79,15 +79,14 @@ var _ = Describe("Xip", func() {
 
 	Describe("NSResources()", func() {
 		When("we use the default nameservers", func() {
-			var x, _ = xip.NewXip("file:///", []string{"ns-aws.sslip.io.", "ns-azure.sslip.io.", "ns-gce.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{})
+			var x, _ = xip.NewXip("file:///", []string{"ns-azure.sslip.io.", "ns-gce.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{})
 			It("returns the name servers", func() {
 				randomDomain := testhelper.Random8ByteString() + ".com."
 				ns := x.NSResources(randomDomain)
-				Expect(len(ns)).To(Equal(4))
-				Expect(ns[0].NS.String()).To(Equal("ns-aws.sslip.io."))
-				Expect(ns[1].NS.String()).To(Equal("ns-azure.sslip.io."))
-				Expect(ns[2].NS.String()).To(Equal("ns-gce.sslip.io."))
-				Expect(ns[3].NS.String()).To(Equal("ns-ovh.sslip.io."))
+				Expect(len(ns)).To(Equal(3))
+				Expect(ns[0].NS.String()).To(Equal("ns-azure.sslip.io."))
+				Expect(ns[1].NS.String()).To(Equal("ns-gce.sslip.io."))
+				Expect(ns[2].NS.String()).To(Equal("ns-ovh.sslip.io."))
 			})
 			When(`the domain name contains "_acme-challenge."`, func() {
 				When("the domain name has an embedded IP", func() {
@@ -106,20 +105,20 @@ var _ = Describe("Xip", func() {
 					It("returns the default trinity of nameservers", func() {
 						randomDomain := "_acme-challenge." + testhelper.Random8ByteString() + ".com."
 						ns := x.NSResources(randomDomain)
-						Expect(len(ns)).To(Equal(4))
+						Expect(len(ns)).To(Equal(3))
 					})
 				})
 			})
 			When("we delegate domains to other nameservers", func() {
 				When(`we don't use the "=" in the arguments`, func() {
 					It("returns an informative log message", func() {
-						var _, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-aws.sslip.io.", "ns-azure.sslip.io.", "ns-gce.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{"noEquals"})
+						var _, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-azure.sslip.io.", "ns-gce.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{"noEquals"})
 						Expect(strings.Join(logs, "")).To(MatchRegexp(`"-delegates: arguments should be in the format "delegatedDomain=nameserver", not "noEquals"`))
 					})
 				})
 				When(`there's no "." at the end of the delegated domain or nameserver`, func() {
 					It(`helpfully adds the "."`, func() {
-						var x, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-aws.sslip.io.", "ns-azure.sslip.io.", "ns-gce.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{"a=b"})
+						var x, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-azure.sslip.io.", "ns-gce.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{"a=b"})
 						Expect(strings.Join(logs, "")).To(MatchRegexp(`Adding delegated NS record "a\.=b\."`))
 						ns := x.NSResources("a.")
 						Expect(len(ns)).To(Equal(1))
@@ -229,8 +228,8 @@ var _ = Describe("Xip", func() {
 			Entry("www", "www.sslip.io"),
 			Entry("a lone number", "538.sslip.io"),
 			Entry("too big", "256.254.253.252"),
-			Entry("NS but no dot", "ns-aws.sslip.io"),
-			Entry("NS + cruft at beginning", "p-ns-aws.sslip.io"),
+			Entry("NS but no dot", "ns-azure.sslip.io"),
+			Entry("NS + cruft at beginning", "p-ns-azure.sslip.io"),
 			Entry("test-net address with dots-and-dashes mixed", "www-192.0-2.3.example-me.com"),
 		)
 		When("There is more than one A record", func() {