diff --git a/integration_test.go b/integration_test.go index 19aed75..6769aa9 100644 --- a/integration_test.go +++ b/integration_test.go @@ -342,6 +342,27 @@ var _ = Describe("sslip.io-dns-server", func() { Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeTXT sslip.io. \? \["protonmail-verification=ce0ca3f5010aa7a2cf8bcc693778338ffde73e26"\], \["v=spf1 include:_spf.protonmail.ch mx -all"\]\n`)) }) }) + When(`the DMARC records are queried`, func() { + It(`returns the nip.io DMARC TXT record`, func() { + digArgs = "@localhost _dmarc.nip.io. txt +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(`"v=DMARC1; p=reject"`)) + Eventually(digSession, 1).Should(Exit(0)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeTXT _dmarc\.nip\.io\. \? \["v=DMARC1; p=reject"\]\n`)) + }) + It(`returns the sslip.io DMARC TXT record`, func() { + digArgs = "@localhost _dmarc.sslip.io. txt +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(`"v=DMARC1; p=reject"`)) + Eventually(digSession, 1).Should(Exit(0)) + Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeTXT _dmarc\.sslip\.io\. \? \["v=DMARC1; p=reject"\]\n`)) + }) + }) + When(`a record for an "_acme-challenge" domain is queried`, func() { When(`it's an NS record`, func() { It(`returns the NS record of the query with the "_acme-challenge." stripped`, func() { diff --git a/xip/xip.go b/xip/xip.go index e04b6c2..826f1f8 100644 --- a/xip/xip.go +++ b/xip/xip.go @@ -137,6 +137,12 @@ var ( }, TXT: TXTSslipIoSPF, }, + "_dmarc.nip.io.": { + TXT: TXTDmarc, + }, + "_dmarc.sslip.io.": { + TXT: TXTDmarc, + }, // nameserver addresses; we get queries for those every once in a while // CNAMEs for nip.io/sslip.io for DKIM signing "protonmail._domainkey.nip.io.": { @@ -1068,6 +1074,15 @@ func TXTSslipIoSPF(_ *Xip, _ net.IP) ([]dnsmessage.TXTResource, error) { }, nil // Sender Policy Framework } +// TXTDmarc DMARC record +// Tighten the screws to prevent spam, thanks @brakhane +// - p=reject -> reject all emails that don't meet SPF requirements, subdomains inherit +func TXTDmarc(_ *Xip, _ net.IP) ([]dnsmessage.TXTResource, error) { + return []dnsmessage.TXTResource{ + {TXT: []string{"v=DMARC1; p=reject"}}, + }, nil +} + // TXTIp when TXT for "ip.sslip.io" is queried, return the IP address of the querier func TXTIp(x *Xip, srcAddr net.IP) ([]dnsmessage.TXTResource, error) { x.Metrics.AnsweredTXTSrcIPQueries++