From 50e6d71ee48fca70ec83f7a94a4aca0c63cd7970 Mon Sep 17 00:00:00 2001 From: Brian Cunnie Date: Sun, 27 Apr 2025 06:04:39 -0700 Subject: [PATCH] ns-gce is dead! Long live ns-ovh-sg! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm worried the traffic to my GCP server will cost me a hundred dollars in bandwidth fees. It has a volume similar to my late AWS server which, in its last month, racked up ~$130 in bandwidth fees! I'm also trying to balance the servers more geographically: instead of having two servers in the US and none in Asia, I'll have one server in the US and one in Asia (Singapore). The OVH server in Asia is expensive — $60/month instead of $20/month for the OVH server in Warsaw. Also there's a monthly bandwidth cap in Singapore in addition to the 300 Mbps cap. I went with a dedicated server, similar to the one in Warsaw, but I took the opportunity to upgrade it (same price): - ns-ovh: KS-4: Intel Xeon-E3 1230 v6 - ns-ovh-sg: KS-5: Intel Xeon-E3 1270 v6 I'm hoping that by adding this server to Singapore, the traffic to the ns-ovh, the Warsaw server, will lessen, and I won't get thos "Anti-DDoS protection enabled for IP address 51.75.53.19" emails every few days. Current Queries per second: - 4,087 ns-gce - 1,131 ns-hetzner - 7,183 ns-ovh --- Docker/sslip.io-dns-server/Dockerfile | 2 +- README.md | 4 ++-- bin/make_all | 2 +- docs/DEVELOPER.md | 20 ++++++++++++-------- docs/wildcard.md | 2 +- integration_test.go | 21 +++++++++++---------- k8s/document_root_sslip.io/index.html | 21 +++++++++++---------- main.go | 12 ++++++------ spec/check-dns_spec.rb | 2 +- xip/xip_test.go | 12 ++++++------ 10 files changed, 52 insertions(+), 46 deletions(-) diff --git a/Docker/sslip.io-dns-server/Dockerfile b/Docker/sslip.io-dns-server/Dockerfile index 73f4f4b..66395d8 100644 --- a/Docker/sslip.io-dns-server/Dockerfile +++ b/Docker/sslip.io-dns-server/Dockerfile @@ -26,7 +26,7 @@ LABEL org.opencontainers.image.authors="Brian Cunnie " RUN dnf install -y bind-utils ARG TARGETARCH # amd64, arm64 (so I can run on AWS graviton2) -RUN curl -f -L https://github.com/cunnie/sslip.io/releases/download/3.2.6/sslip.io-dns-server-linux-$TARGETARCH \ +RUN curl -f -L https://github.com/cunnie/sslip.io/releases/download/3.2.7/sslip.io-dns-server-linux-$TARGETARCH \ -o /usr/sbin/sslip.io-dns-server; \ chmod 755 /usr/sbin/sslip.io-dns-server diff --git a/README.md b/README.md index 5c284b7..ed77913 100644 --- a/README.md +++ b/README.md @@ -121,8 +121,8 @@ as ARM64 (AWS Graviton, Apple M1/M2). 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-gce.sslip.io`, `ns-hetzner.sslip.io`, and `ns-ovh.sslip.io`; flag, e.g. `go run main.go +- `-nameservers` overrides the default NS records `ns-hetzner.sslip.io`, + `ns-ovh.sslip.io`, and `ns-ovh-sg.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: diff --git a/bin/make_all b/bin/make_all index 24f35b4..53fd122 100755 --- a/bin/make_all +++ b/bin/make_all @@ -4,7 +4,7 @@ # DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" cd $DIR/.. -ldflags="-X xip/xip.VersionSemantic=3.2.6 \ +ldflags="-X xip/xip.VersionSemantic=3.2.7 \ -X xip/xip.VersionDate=$(date +%Y/%m/%d-%H:%M:%S%z) \ -X xip/xip.VersionGitHash=$(git rev-parse --short HEAD)" export GOOS GOARCH diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md index e63f367..e5562b6 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -4,8 +4,8 @@ These instructions are meant primarily for me when deploying a new release; they might not make sense unless you're on my workstation. ```bash -export OLD_VERSION=3.2.5 -export VERSION=3.2.6 +export OLD_VERSION=3.2.6 +export VERSION=3.2.7 cd ~/workspace/sslip.io git pull -r --autostash # update the version number for the TXT record for version.status.sslip.io @@ -14,8 +14,7 @@ sed -i '' "s/$OLD_VERSION/$VERSION/g" \ spec/check-dns_spec.rb # update the download instructions on the website sed -i '' "s~/$OLD_VERSION/~/$VERSION/~g" \ - k8s/document_root_sslip.io/index.html \ - k8s/Dockerfile-sslip.io-dns-server + Docker/sslip.io-dns-server/Dockerfile ``` Optional: Update the version for the ns-gce, ns-hetzner, and ns-ovh install scripts @@ -23,7 +22,7 @@ Optional: Update the version for the ns-gce, ns-hetzner, and ns-ovh install scri ```bash pushd ~/bin sed -i '' "s~/$OLD_VERSION/~/$VERSION/~g" \ - ~/bin/install_ns-{gce,hetzner,ovh}.sh + ~/bin/install_ns-{gce,hetzner,ovh}.sh ~/bin/install_common.sh git add -p git ci -m"Update sslip.io DNS server $OLD_VERSION → $VERSION" git push @@ -42,13 +41,13 @@ Test from another window: ```bash export DNS_SERVER_IP=127.0.0.1 -export VERSION=3.2.6 +export VERSION=3.2.7 # quick sanity test 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-gce.sslip.io.\nns-hetzner.sslip.io.\nns-ovh.sslip.io.\n" +printf "ns-hetzner.sslip.io.\nns-ovh.sslip.io.\nns-ovh-sg.sslip.io.\n" dig +short mx example.com @$DNS_SERVER_IP echo "0 example.com." dig +short mx sslip.io @$DNS_SERVER_IP @@ -88,6 +87,7 @@ git push --tags scp bin/sslip.io-dns-server-linux-amd64 ns-gce: scp bin/sslip.io-dns-server-linux-amd64 ns-hetzner: scp bin/sslip.io-dns-server-linux-amd64 ns-ovh: +scp bin/sslip.io-dns-server-linux-amd64 ns-ovh-sg: ssh ns-gce sudo install sslip.io-dns-server-linux-amd64 /usr/bin/sslip.io-dns-server ssh ns-gce sudo shutdown -r now # check version number: @@ -100,6 +100,10 @@ ssh ns-ovh sudo install sslip.io-dns-server-linux-amd64 /usr/bin/sslip.io-dns-se ssh ns-ovh sudo shutdown -r now # check version number: sleep 10; while ! dig txt @ns-ovh.sslip.io version.status.sslip.io +short; do sleep 5; done +ssh ns-ovh-sg sudo install sslip.io-dns-server-linux-amd64 /usr/bin/sslip.io-dns-server +ssh ns-ovh-sg sudo shutdown -r now + # check version number: +sleep 10; while ! dig txt @ns-ovh-sg.sslip.io version.status.sslip.io +short; do sleep 5; done ``` - Browse to to draft a new release @@ -114,7 +118,7 @@ Update the webservers with the HTML with new versions: ```bash ssh nono.io curl -L -o /www/sslip.io/document_root/index.html https://raw.githubusercontent.com/cunnie/sslip.io/main/k8s/document_root_sslip.io/index.html -for HOST in {blocked,ns-gce,ns-hetzner,ns-ovh}.sslip.io; do +for HOST in {blocked,ns-gce,ns-hetzner,ns-ovh,ns-ovh-sg}.sslip.io; do ssh $HOST curl -L -o /var/nginx/sslip.io/index.html https://raw.githubusercontent.com/cunnie/sslip.io/main/k8s/document_root_sslip.io/index.html done ``` diff --git a/docs/wildcard.md b/docs/wildcard.md index 80ea4d3..bd0a591 100644 --- a/docs/wildcard.md +++ b/docs/wildcard.md @@ -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-gce.sslip.io and so on). +otherwise it'll return the delegated nameservers (ns-ovh.sslip.io and so on). ### Using the sslip.io domain diff --git a/integration_test.go b/integration_test.go index 10fa77c..5443db6 100644 --- a/integration_test.go +++ b/integration_test.go @@ -236,21 +236,22 @@ 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(`104.155.144.4`)) Eventually(digSession).Should(Say(`5.78.115.44`)) Eventually(digSession).Should(Say(`51.75.53.19`)) + Eventually(digSession).Should(Say(`51.79.178.89`)) Eventually(digSession, 1).Should(Exit(0)) - Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeA ns.sslip.io. \? 104.155.144.4, 5.78.115.44, 51.75.53.19\n`)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeA ns.sslip.io. \? 5.78.115.44, 51.75.53.19, 51.79.178.89\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:1900:4000:4d12::`)) + Eventually(digSession).Should(Say(`2a01:4ff:1f0:c920::`)) Eventually(digSession).Should(Say(`2001:41d0:602:2313::1`)) + Eventually(digSession).Should(Say(`2402:1f00:8001:d59::1`)) Eventually(digSession, 1).Should(Exit(0)) - Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeAAAA ns.sslip.io. \? 2600:1900:4000:4d12::, 2a01:4ff:1f0:c920::, 2001:41d0:602:2313::1\n`)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeAAAA ns.sslip.io. \? 2a01:4ff:1f0:c920::, 2001:41d0:602:2313::1, 2402:1f00:8001:d59::1\n`)) }) }) When("there are multiple MX records returned (e.g. sslip.io)", func() { @@ -274,18 +275,18 @@ var _ = Describe("sslip.io-dns-server", func() { Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 6`)) Eventually(digSession).Should(Say(`;; ANSWER SECTION:`)) Eventually(digSession).Should(Say(`;; ADDITIONAL SECTION:`)) - 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`)) Eventually(digSession).Should(Say(`ns-hetzner.sslip.io..*5.78.115.44\n`)) Eventually(digSession).Should(Say(`ns-hetzner.sslip.io..*2a01:4ff:1f0:c920::\n`)) Eventually(digSession).Should(Say(`ns-ovh.sslip.io..*51.75.53.19\n`)) Eventually(digSession).Should(Say(`ns-ovh.sslip.io..*2001:41d0:602:2313::1\n`)) + Eventually(digSession).Should(Say(`ns-ovh-sg.sslip.io..*51.79.178.89\n`)) + Eventually(digSession).Should(Say(`ns-ovh-sg.sslip.io..*2402:1f00:8001:d59::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-gce.sslip.io.\n`)) Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-hetzner.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-gce.sslip.io., ns-hetzner.sslip.io., ns-ovh.sslip.io.\n`)) + Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-ovh-sg.sslip.io.\n`)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS example.com. \? ns-hetzner.sslip.io., ns-ovh.sslip.io., ns-ovh-sg.sslip.io.\n`)) }) }) When(`there are multiple TXT records returned (e.g. SPF for sslip.io)`, func() { @@ -407,8 +408,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.\n\z`, - `TypeNS _acme-challenge.raiffeisen.fe80--.sslip.io. \? ns-gce.sslip.io., ns-hetzner.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-hetzner.sslip.io., ns-ovh.sslip.io., ns-ovh-sg.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 f65dff1..1ac8b75 100644 --- a/k8s/document_root_sslip.io/index.html +++ b/k8s/document_root_sslip.io/index.html @@ -141,26 +141,27 @@ src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"> - ns-gce.sslip.io. - 104.155.144.4 - USA - - ns-hetzner.sslip.io. 5.78.115.44
2a01:4ff:1f0:c920:: USA - + ns-ovh.sslip.io. 51.75.53.19
2001:41d0:602:2313::1 Poland + + ns-ovh-sg.sslip.io. + 51.79.178.89
+ 2402:1f00:8001:d59::1 + Singapore +

Let’s test it from the command line using dig:

-
dig @ns-gce.sslip.io. 169-254-169-254.xip.example.com +short
+
dig @ns-ovh.sslip.io. 169-254-169-254.xip.example.com +short

Yields, hopefully: [connection timed out]

169.254.169.254

But I Want My Own DNS Server!

@@ -171,7 +172,7 @@ src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"> our server within a docker container:

 docker run -it --rm fedora
-curl -L https://github.com/cunnie/sslip.io/releases/download/3.2.6/sslip.io-dns-server-linux-amd64 -o dns-server
+curl -L https://github.com/cunnie/sslip.io/releases/download/3.2.7/sslip.io-dns-server-linux-amd64 -o dns-server
 chmod +x dns-server
 ./dns-server 2> dns-server.log &
 dnf install -y bind-utils
@@ -250,7 +251,7 @@ dig @ns.sslip.io txt ip.sslip.io +short -6 # forces IPv6 lookup; sample reply "2
       

Determining The Server Version of Software

You can determine the server version of the sslip.io software by querying the TXT record of version.status.sslip.io:
-dig @ns-gce.nono.io version.status.sslip.io txt +short
+dig @ns-ovh.nono.io version.status.sslip.io txt +short
   "2.7.0"
   "2023/10/04-18:51:49-0700"
   "8f7f2df"
@@ -324,7 +325,7 @@ dig @ns-ovh.sslip.io metrics.status.sslip.io txt +short
         
The number of responses which included a delegation of the NS (name server) to satisfy a certificate authority's DNS-01 challenge. This lookup is used for generating wildcard certificates from Let's Encrypt and other certificate authority. Technically this is not a "successful" query in that we don't return a record in - the ANSWER section, but we do return an NS record in the AUTHORITY section. (e.g. "dig @ns-gce.sslip.io + the ANSWER section, but we do return an NS record in the AUTHORITY section. (e.g. "dig @ns-ovh.sslip.io _acme-challenge.192.168.0.1.sslip.io. soa")
diff --git a/main.go b/main.go index 91c551b..eaab9d0 100644 --- a/main.go +++ b/main.go @@ -17,25 +17,25 @@ 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-gce.sslip.io.,ns-hetzner.sslip.io.,ns-ovh.sslip.io.", + var nameservers = flag.String("nameservers", "ns-hetzner.sslip.io.,ns-ovh.sslip.io.,ns-ovh-sg.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=104.155.144.4,"+ - "ns.sslip.io=2600:1900:4000:4d12::,"+ "ns.sslip.io=5.78.115.44,"+ "ns.sslip.io=2a01:4ff:1f0:c920::,"+ "ns.sslip.io=51.75.53.19,"+ "ns.sslip.io=2001:41d0:602:2313::1,"+ + "ns.sslip.io=51.79.178.89,"+ + "ns.sslip.io=2402:1f00:8001:d59::1,"+ "blocked.sslip.io=52.0.56.137,"+ "blocked.sslip.io=2600:1f18:aaf:6900::a,"+ - "ns-gce.sslip.io=104.155.144.4,"+ - "ns-gce.sslip.io=2600:1900:4000:4d12::,"+ "ns-hetzner.sslip.io=5.78.115.44,"+ "ns-hetzner.sslip.io=2a01:4ff:1f0:c920::,"+ "ns-ovh.sslip.io=51.75.53.19,"+ - "ns-ovh.sslip.io=2001:41d0:602:2313::1", + "ns-ovh.sslip.io=2001:41d0:602:2313::1,"+ + "ns-ovh-sg.sslip.io=51.79.178.89,"+ + "ns-ovh-sg.sslip.io=2402:1f00:8001:d59::1", "comma-separated list of hosts and corresponding IPv4 and/or IPv6 address(es). If you're running your own sslip.io nameservers, add their hostnames and addresses here. If unsure, add to the list rather than replace") var delegates = flag.String("delegates", "", "comma-separated list of domains you own "+ "and nameservers you control to which to delegate, often used to acquire wildcard certificates from "+ diff --git a/spec/check-dns_spec.rb b/spec/check-dns_spec.rb index dee85f8..fb1a3db 100644 --- a/spec/check-dns_spec.rb +++ b/spec/check-dns_spec.rb @@ -18,7 +18,7 @@ def get_whois_nameservers(domain) end domain = ENV['DOMAIN'] || 'example.com' -sslip_version = '3.2.6' +sslip_version = '3.2.7' whois_nameservers = get_whois_nameservers(domain) describe domain do diff --git a/xip/xip_test.go b/xip/xip_test.go index 10783f5..22b45d9 100644 --- a/xip/xip_test.go +++ b/xip/xip_test.go @@ -79,14 +79,14 @@ var _ = Describe("Xip", func() { Describe("NSResources()", func() { When("we use the default nameservers", func() { - var x, _ = xip.NewXip("file:///", []string{"ns-gce.sslip.io.", "ns-hetzner.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{}) + var x, _ = xip.NewXip("file:///", []string{"ns-hetzner.sslip.io.", "ns-ovh.sslip.io.", "ns-ovh-sg.sslip.io."}, []string{}, []string{}) It("returns the name servers", func() { randomDomain := testhelper.Random8ByteString() + ".com." ns := x.NSResources(randomDomain) Expect(len(ns)).To(Equal(3)) - Expect(ns[0].NS.String()).To(Equal("ns-gce.sslip.io.")) - Expect(ns[1].NS.String()).To(Equal("ns-hetzner.sslip.io.")) - Expect(ns[2].NS.String()).To(Equal("ns-ovh.sslip.io.")) + Expect(ns[0].NS.String()).To(Equal("ns-hetzner.sslip.io.")) + Expect(ns[1].NS.String()).To(Equal("ns-ovh.sslip.io.")) + Expect(ns[2].NS.String()).To(Equal("ns-ovh-sg.sslip.io.")) }) When(`the domain name contains "_acme-challenge."`, func() { When("the domain name has an embedded IP", func() { @@ -112,13 +112,13 @@ var _ = Describe("Xip", func() { 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-gce.sslip.io.", "ns-hetzner.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{"noEquals"}) + var _, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-hetzner.sslip.io.", "ns-ovh.sslip.io.", "ns-ovh-sg.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-gce.sslip.io.", "ns-hetzner.sslip.io.", "ns-ovh.sslip.io."}, []string{}, []string{"a=b"}) + var x, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-hetzner.sslip.io.", "ns-ovh.sslip.io.", "ns-ovh-sg.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))