mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-13 19:34:51 +08:00
🐞 wildcard-dns-http-server: multiple TXT records
- it appears that Let's Encrypt requires setting at least two TXT records; before I only allowed one to be set; now you can set as many as you want. - our records had a TTL of 0 seconds; I bumped it to 60: long enough to get a cert, short enough to refesh for a second attempt if the first one failed.
This commit is contained in:
@@ -13,7 +13,7 @@ import (
|
|||||||
"golang.org/x/net/dns/dnsmessage"
|
"golang.org/x/net/dns/dnsmessage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var txt = `Set this TXT record: curl -X POST http://localhost/update -d '{"txt":"Certificate Authority validation token"}'`
|
var txts = []string{`Set this TXT record: curl -X POST http://localhost/update -d '{"txt":"Certificate Authority validation token"}'`}
|
||||||
|
|
||||||
// Txt is for parsing the JSON POST to set the DNS TXT record
|
// Txt is for parsing the JSON POST to set the DNS TXT record
|
||||||
type Txt struct {
|
type Txt struct {
|
||||||
@@ -61,6 +61,18 @@ func dnsServer(conn *net.UDPConn, group *sync.WaitGroup) {
|
|||||||
log.Println("I expected a question for a TypeTXT record but got a question for a " + query.Questions[0].Type.String() + " record.")
|
log.Println("I expected a question for a TypeTXT record but got a question for a " + query.Questions[0].Type.String() + " record.")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
var txtAnswers = []dnsmessage.Resource{}
|
||||||
|
for _, txt := range txts {
|
||||||
|
txtAnswers = append(txtAnswers, dnsmessage.Resource{
|
||||||
|
Header: dnsmessage.ResourceHeader{
|
||||||
|
Name: query.Questions[0].Name,
|
||||||
|
Type: dnsmessage.TypeTXT,
|
||||||
|
Class: dnsmessage.ClassINET,
|
||||||
|
TTL: 60,
|
||||||
|
},
|
||||||
|
Body: &dnsmessage.TXTResource{TXT: []string{txt}},
|
||||||
|
})
|
||||||
|
}
|
||||||
reply := dnsmessage.Message{
|
reply := dnsmessage.Message{
|
||||||
Header: dnsmessage.Header{
|
Header: dnsmessage.Header{
|
||||||
ID: query.ID,
|
ID: query.ID,
|
||||||
@@ -69,16 +81,7 @@ func dnsServer(conn *net.UDPConn, group *sync.WaitGroup) {
|
|||||||
RecursionDesired: query.RecursionDesired,
|
RecursionDesired: query.RecursionDesired,
|
||||||
},
|
},
|
||||||
Questions: query.Questions,
|
Questions: query.Questions,
|
||||||
Answers: []dnsmessage.Resource{
|
Answers: txtAnswers,
|
||||||
{
|
|
||||||
Header: dnsmessage.ResourceHeader{
|
|
||||||
Name: query.Questions[0].Name,
|
|
||||||
Type: dnsmessage.TypeTXT,
|
|
||||||
Class: dnsmessage.ClassINET,
|
|
||||||
},
|
|
||||||
Body: &dnsmessage.TXTResource{TXT: []string{txt}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
replyRaw, err := reply.Pack()
|
replyRaw, err := reply.Pack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -90,7 +93,7 @@ func dnsServer(conn *net.UDPConn, group *sync.WaitGroup) {
|
|||||||
log.Println(err.Error())
|
log.Println(err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Printf("%v.%d %s → \"%s\"\n", addr.IP, addr.Port, query.Questions[0].Type.String(), txt)
|
log.Printf("%v.%d %s → \"%v\"\n", addr.IP, addr.Port, query.Questions[0].Type.String(), txts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +143,7 @@ func updateTxtHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Println(err.Error())
|
log.Println(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Println("Updating TXT record from \"" + txt + "\" → \"" + updateTxt.Txt + "\".")
|
log.Println("Creating new TXT record \"" + updateTxt.Txt + "\".")
|
||||||
// this is the money shot, where we update the DNS TXT record to what was in the POST request
|
// this is the money shot, where we create a new DNS TXT record to what was in the POST request
|
||||||
txt = updateTxt.Txt
|
txts = append(txts, updateTxt.Txt)
|
||||||
}
|
}
|
||||||
|
@@ -66,7 +66,38 @@ docker run --rm -it \
|
|||||||
```
|
```
|
||||||
|
|
||||||
Clean-up:
|
Clean-up:
|
||||||
|
|
||||||
```
|
```
|
||||||
gcloud compute firewall-rules delete sslip-io-allow-dns
|
gcloud compute firewall-rules delete sslip-io-allow-dns
|
||||||
gcloud compute instances delete sslip
|
gcloud compute instances delete sslip
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Troubleshooting / Debugging
|
||||||
|
|
||||||
|
Run the server in one window so you can see the output, and then ssh into another window
|
||||||
|
and watch the output in realtime.
|
||||||
|
|
||||||
|
```
|
||||||
|
gcloud compute ssh sslip -- -A
|
||||||
|
docker run -it --rm --name wildcard \
|
||||||
|
-p 53:53/udp \
|
||||||
|
-p 80:80 \
|
||||||
|
cunnie/wildcard-dns-http-server
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `acme.sh`'s `--staging` flag to make sure it works (so you don't run into Let's Encrypt's [rate limits](https://letsencrypt.org/docs/rate-limits/) with failed attempts).
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run --rm -it \
|
||||||
|
-v $PWD/tls:/acme.sh \
|
||||||
|
-e ACMEDNS_UPDATE_URL \
|
||||||
|
--net=host \
|
||||||
|
neilpang/acme.sh \
|
||||||
|
--issue \
|
||||||
|
--staging \
|
||||||
|
--debug \
|
||||||
|
-d $FQDN \
|
||||||
|
-d *.$FQDN \
|
||||||
|
--dns dns_acmedns
|
||||||
|
|
||||||
|
```
|
Reference in New Issue
Block a user