mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-07 00:23:44 +08:00
k-v.io: protect against scammers seeking wildcards
Prohibit setting DNS-01 challenge TXT record `_acme-challenge.k-v.io` Although it may appear the TXT record can be set or deleted, it's hardcoded to the string, "Please don't try to procure a k-v.io cert via DNS-01 challenge". Setting a custom value was easier than writing a special code path. Special thanks to [Alan Liang](http://symb.olic.link/): > ... one could easily add (and modify) a TXT record at _acme-challenge.k-v.io, which I believe is used for verifying domain ownership at various cert providers, so anyone could in theory obtain valid SSL certs for k-v.io and *.k-v.io
This commit is contained in:
@@ -157,6 +157,14 @@ var _ = Describe("sslip.io-dns-server", func() {
|
|||||||
"@127.0.0.1 my-key.k-v.io txt +short",
|
"@127.0.0.1 my-key.k-v.io txt +short",
|
||||||
`\A\z`,
|
`\A\z`,
|
||||||
`TypeTXT my-key.k-v.io. \? nil, SOA my-key.k-v.io. briancunnie.gmail.com. 2022020800 900 900 1800 180\n$`),
|
`TypeTXT my-key.k-v.io. \? nil, SOA my-key.k-v.io. briancunnie.gmail.com. 2022020800 900 900 1800 180\n$`),
|
||||||
|
Entry(`setting a TXT for _acme-challenge.k-v.io appears to work (spoiler: it doesn't)'"`,
|
||||||
|
"@127.0.0.1 put.sneaky-boy._acme-challenge.k-v.io txt +short",
|
||||||
|
`sneaky-boy`,
|
||||||
|
`TypeTXT put.sneaky-boy._acme-challenge.k-v.io. \? \["sneaky-boy"\]`),
|
||||||
|
Entry(`get a TXT for _acme-challenge.k-v.io is blocked to foil Let's Encrypt ACME DNS-01 challenge"`,
|
||||||
|
"@127.0.0.1 _acme-challenge.k-v.io txt +short",
|
||||||
|
`Please don't try to procure a k-v.io cert via DNS-01 challenge`,
|
||||||
|
`TypeTXT _acme-challenge.k-v.io. \? \["Please don't try to procure a k-v.io cert via DNS-01 challenge"\]`),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
Describe("for more complex assertions", func() {
|
Describe("for more complex assertions", func() {
|
||||||
|
@@ -93,7 +93,7 @@ var (
|
|||||||
ipv4REDashes = regexp.MustCompile(`(^|[.-])(((25[0-5]|(2[0-4]|1?[0-9])?[0-9])-){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))($|[.-])`)
|
ipv4REDashes = regexp.MustCompile(`(^|[.-])(((25[0-5]|(2[0-4]|1?[0-9])?[0-9])-){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))($|[.-])`)
|
||||||
// https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
|
// https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
|
||||||
ipv6RE = regexp.MustCompile(`(^|[.-])(([0-9a-fA-F]{1,4}-){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,7}-|([0-9a-fA-F]{1,4}-){1,6}-[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,5}(-[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}-){1,4}(-[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}-){1,3}(-[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}-){1,2}(-[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}-((-[0-9a-fA-F]{1,4}){1,6})|-((-[0-9a-fA-F]{1,4}){1,7}|-)|fe80-(-[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|--(ffff(-0{1,4})?-)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}-){1,4}-((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))($|[.-])`)
|
ipv6RE = regexp.MustCompile(`(^|[.-])(([0-9a-fA-F]{1,4}-){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,7}-|([0-9a-fA-F]{1,4}-){1,6}-[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,5}(-[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}-){1,4}(-[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}-){1,3}(-[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}-){1,2}(-[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}-((-[0-9a-fA-F]{1,4}){1,6})|-((-[0-9a-fA-F]{1,4}){1,7}|-)|fe80-(-[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|--(ffff(-0{1,4})?-)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}-){1,4}-((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))($|[.-])`)
|
||||||
dns01ChallengeRE = regexp.MustCompile(`(?i)_acme-challenge\.`)
|
dns01ChallengeRE = regexp.MustCompile(`(?i)_acme-challenge\.`) // (?i) → non-capturing case insensitive
|
||||||
kvRE = regexp.MustCompile(`\.k-v\.io\.$`)
|
kvRE = regexp.MustCompile(`\.k-v\.io\.$`)
|
||||||
nsAwsSslip, _ = dnsmessage.NewName("ns-aws.sslip.io.")
|
nsAwsSslip, _ = dnsmessage.NewName("ns-aws.sslip.io.")
|
||||||
nsAzureSslip, _ = dnsmessage.NewName("ns-azure.sslip.io.")
|
nsAzureSslip, _ = dnsmessage.NewName("ns-azure.sslip.io.")
|
||||||
@@ -159,6 +159,12 @@ var (
|
|||||||
{A: [4]byte{104, 155, 144, 4}},
|
{A: [4]byte{104, 155, 144, 4}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// don't let people procure *.k-v.io TLS certs via ACME DNS-01 challenge
|
||||||
|
"_acme-challenge.k-v.io.": {
|
||||||
|
TXT: func(_ *Xip, _ net.IP) ([]dnsmessage.TXTResource, error) {
|
||||||
|
return []dnsmessage.TXTResource{{TXT: []string{"Please don't try to procure a k-v.io cert via DNS-01 challenge"}}}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
// a global nameserver for sslip.io, a conglomeration of ns-{aws,azure,gce}.sslip.io
|
// a global nameserver for sslip.io, a conglomeration of ns-{aws,azure,gce}.sslip.io
|
||||||
"ns.sslip.io.": {
|
"ns.sslip.io.": {
|
||||||
A: []dnsmessage.AResource{
|
A: []dnsmessage.AResource{
|
||||||
@@ -756,9 +762,6 @@ func (x *Xip) NSResources(fqdnString string) []dnsmessage.NSResource {
|
|||||||
|
|
||||||
// TXTResources returns TXT records from Customizations or KvCustomizations
|
// TXTResources returns TXT records from Customizations or KvCustomizations
|
||||||
func (x *Xip) TXTResources(fqdn string, ip net.IP) ([]dnsmessage.TXTResource, error) {
|
func (x *Xip) TXTResources(fqdn string, ip net.IP) ([]dnsmessage.TXTResource, error) {
|
||||||
if kvRE.MatchString(fqdn) {
|
|
||||||
return x.kvTXTResources(fqdn)
|
|
||||||
}
|
|
||||||
if domain, ok := Customizations[strings.ToLower(fqdn)]; ok {
|
if domain, ok := Customizations[strings.ToLower(fqdn)]; ok {
|
||||||
// Customizations[strings.ToLower(fqdn)] returns a _function_,
|
// Customizations[strings.ToLower(fqdn)] returns a _function_,
|
||||||
// we call that function, which has the same return signature as this method
|
// we call that function, which has the same return signature as this method
|
||||||
@@ -766,6 +769,9 @@ func (x *Xip) TXTResources(fqdn string, ip net.IP) ([]dnsmessage.TXTResource, er
|
|||||||
return domain.TXT(x, ip)
|
return domain.TXT(x, ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if kvRE.MatchString(fqdn) {
|
||||||
|
return x.kvTXTResources(fqdn)
|
||||||
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user