checker: read GLUE record, check HTTP and HTTPS accordingly to DNS records
This commit is contained in:
parent
f4ee5503ec
commit
1f47b01294
1 changed files with 126 additions and 24 deletions
|
@ -1,9 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -35,21 +37,73 @@ func check_ping(ip string, cb func(pkt *ping.Packet)) (err error) {
|
||||||
|
|
||||||
// PORT 53
|
// PORT 53
|
||||||
|
|
||||||
func check_dns(domain, ip string) (err error) {
|
func get_GLUE(domain string) (aaaa net.IP, err error) {
|
||||||
|
client := dns.Client{Net: "tcp", Timeout: time.Second * 5}
|
||||||
|
|
||||||
|
m := new(dns.Msg)
|
||||||
|
m.SetQuestion(domain, dns.TypeNS)
|
||||||
|
m.RecursionDesired = false
|
||||||
|
m.SetEdns0(4096, true)
|
||||||
|
|
||||||
|
var r *dns.Msg
|
||||||
|
r, _, err = client.Exchange(m, "[2a01:e0a:25a:9160::2]:53")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if r == nil {
|
||||||
|
return nil, errors.New("response is nil")
|
||||||
|
}
|
||||||
|
if r.Rcode != dns.RcodeSuccess {
|
||||||
|
return nil, errors.New("failed to get a valid answer")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, extra := range r.Extra {
|
||||||
|
if t, ok := extra.(*dns.AAAA); ok {
|
||||||
|
aaaa = t.AAAA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func check_dns(domain, ip string) (aaaa net.IP, err error) {
|
||||||
client := dns.Client{Timeout: time.Second * 5}
|
client := dns.Client{Timeout: time.Second * 5}
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetQuestion(domain, dns.TypeSOA)
|
m.SetQuestion(domain, dns.TypeAAAA)
|
||||||
|
|
||||||
|
var r *dns.Msg
|
||||||
|
r, _, err = client.Exchange(m, fmt.Sprintf("[%s]:53", ip))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if r == nil {
|
||||||
|
err = errors.New("response is nil")
|
||||||
|
}
|
||||||
|
if r.Rcode != dns.RcodeSuccess {
|
||||||
|
err = errors.New("failed to get a valid answer")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(r.Answer) > 0 {
|
||||||
|
aaaa = r.Answer[0].(*dns.AAAA).AAAA
|
||||||
|
}
|
||||||
|
|
||||||
_, _, err = client.Exchange(m, fmt.Sprintf("[%s]:53", ip))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// PORT 80
|
// PORT 80
|
||||||
|
|
||||||
func check_http(ip string) (err error) {
|
func check_http(ip string) (err error) {
|
||||||
|
client := &http.Client{
|
||||||
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||||
|
return http.ErrUseLastResponse
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
resp, err = http.Get(fmt.Sprintf("http://[%s]/", ip))
|
resp, err = client.Get(fmt.Sprintf("http://[%s]/", ip))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -118,32 +172,20 @@ func studentsChecker() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check HTTP
|
dnsIP := stdIP
|
||||||
if err := check_http(stdIP); err == nil {
|
// Is GLUE defined?
|
||||||
if verbose {
|
if glueIP, err := get_GLUE(std.MyDelegatedDomain()); glueIP != nil {
|
||||||
log.Printf("%s just unlocked HTTP challenge\n", std.Login)
|
dnsIP = glueIP.String()
|
||||||
}
|
|
||||||
if _, err := std.UnlockNewChallenge(100*(tunnel_version-1)+0, ""); err != nil {
|
|
||||||
if _, err := std.UpdateUnlockedChallenge(100*(tunnel_version-1)+0, ""); err != nil {
|
|
||||||
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check HTTPs
|
|
||||||
if err := check_https(std.MyAssociatedDomain(), stdIP); err == nil {
|
|
||||||
if verbose {
|
if verbose {
|
||||||
log.Printf("%s just unlocked HTTPS challenge\n", std.Login)
|
log.Printf("%s has defined GLUE: %s\n", std.Login, dnsIP)
|
||||||
}
|
|
||||||
if _, err := std.UnlockNewChallenge(100*(tunnel_version-1)+1, ""); err != nil {
|
|
||||||
if _, err := std.UpdateUnlockedChallenge(100*(tunnel_version-1)+1, ""); err != nil {
|
|
||||||
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
log.Printf("%s and GLUE: %s\n", std.Login, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check DNS
|
// Check DNS
|
||||||
if err := check_dns(std.MyDelegatedDomain(), stdIP); err == nil {
|
if addr, err := check_dns(std.MyDelegatedDomain(), dnsIP); err == nil {
|
||||||
if verbose {
|
if verbose {
|
||||||
log.Printf("%s just unlocked DNS challenge\n", std.Login)
|
log.Printf("%s just unlocked DNS challenge\n", std.Login)
|
||||||
}
|
}
|
||||||
|
@ -152,6 +194,66 @@ func studentsChecker() {
|
||||||
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check HTTP with DNS
|
||||||
|
if addr == nil {
|
||||||
|
log.Printf("%s and HTTP (with DNS ip=%s): skipped due to empty response\n", std.Login, addr.String())
|
||||||
|
} else if err := check_http(addr.String()); err == nil {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("%s just unlocked HTTP challenge\n", std.Login)
|
||||||
|
}
|
||||||
|
if _, err := std.UnlockNewChallenge(100*(tunnel_version-1)+0, ""); err != nil {
|
||||||
|
if _, err := std.UpdateUnlockedChallenge(100*(tunnel_version-1)+0, ""); err != nil {
|
||||||
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if verbose {
|
||||||
|
log.Printf("%s and HTTP (with DNS ip=%s): %s\n", std.Login, addr.String(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check HTTPs with DNS
|
||||||
|
if addr == nil {
|
||||||
|
log.Printf("%s and HTTPS (with DNS ip=%s): skipped due to empty response\n", std.Login, addr.String())
|
||||||
|
} else if err := check_https(std.MyDelegatedDomain(), addr.String()); err == nil {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("%s just unlocked HTTPS challenge\n", std.Login)
|
||||||
|
}
|
||||||
|
if _, err := std.UnlockNewChallenge(100*(tunnel_version-1)+1, ""); err != nil {
|
||||||
|
if _, err := std.UpdateUnlockedChallenge(100*(tunnel_version-1)+1, ""); err != nil {
|
||||||
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if verbose {
|
||||||
|
log.Printf("%s and HTTPS (with DNS ip=%s): %s\n", std.Login, addr.String(), err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Check HTTP without DNS
|
||||||
|
if err := check_http(stdIP); err == nil {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("%s just unlocked HTTP challenge\n", std.Login)
|
||||||
|
}
|
||||||
|
if _, err := std.UnlockNewChallenge(100*(tunnel_version-1)+0, ""); err != nil {
|
||||||
|
if _, err := std.UpdateUnlockedChallenge(100*(tunnel_version-1)+0, ""); err != nil {
|
||||||
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if verbose {
|
||||||
|
log.Printf("%s and HTTP (without DNS): %s\n", std.Login, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check HTTPs without DNS
|
||||||
|
if err := check_https(std.MyAssociatedDomain(), stdIP); err == nil {
|
||||||
|
if verbose {
|
||||||
|
log.Printf("%s just unlocked HTTPS challenge\n", std.Login)
|
||||||
|
}
|
||||||
|
if _, err := std.UnlockNewChallenge(100*(tunnel_version-1)+1, ""); err != nil {
|
||||||
|
if _, err := std.UpdateUnlockedChallenge(100*(tunnel_version-1)+1, ""); err != nil {
|
||||||
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if verbose {
|
||||||
|
log.Printf("%s and HTTPS (without DNS): %s\n", std.Login, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
Reference in a new issue