New package: minichecker
This commit is contained in:
parent
5d8bcd55ce
commit
ae3b2e6f3b
9 changed files with 852 additions and 0 deletions
169
pkg/minichecker/cmd/checker.go
Normal file
169
pkg/minichecker/cmd/checker.go
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/sparrc/go-ping"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_RESOLVER = "2a01:e0a:2b:2250::1"
|
||||
)
|
||||
|
||||
var (
|
||||
verbose = false
|
||||
test_name = ""
|
||||
)
|
||||
|
||||
// ICMP
|
||||
|
||||
func check_ping(ip string, cb func(pkt *ping.Packet)) (err error) {
|
||||
var pinger *ping.Pinger
|
||||
pinger, err = ping.NewPinger(ip)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer pinger.Stop()
|
||||
|
||||
pinger.Timeout = time.Second * 5
|
||||
pinger.Count = 1
|
||||
pinger.OnRecv = cb
|
||||
pinger.SetPrivileged(true)
|
||||
pinger.Run()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func check_dns(domain, ip string) (aaaa net.IP, err error) {
|
||||
client := dns.Client{Timeout: time.Second * 5}
|
||||
|
||||
m := new(dns.Msg)
|
||||
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")
|
||||
return
|
||||
}
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
err = errors.New("failed to get a valid answer")
|
||||
return
|
||||
}
|
||||
|
||||
for _, answer := range r.Answer {
|
||||
if t, ok := answer.(*dns.AAAA); ok {
|
||||
aaaa = t.AAAA
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// PORT 80
|
||||
|
||||
func check_http(ip, dn string) (err error) {
|
||||
client := &http.Client{
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
|
||||
req, errr := http.NewRequest("GET", fmt.Sprintf("http://[%s]/", ip), nil)
|
||||
if errr != nil {
|
||||
return errr
|
||||
}
|
||||
|
||||
if dn != "" {
|
||||
req.Header.Add("Host", strings.TrimSuffix(dn, "."))
|
||||
}
|
||||
|
||||
var resp *http.Response
|
||||
resp, err = client.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if dn != "" && resp.StatusCode >= 400 {
|
||||
return fmt.Errorf("Bad status, got: %d (%s)", resp.StatusCode, resp.Status)
|
||||
}
|
||||
|
||||
_, err = ioutil.ReadAll(resp.Body)
|
||||
return
|
||||
}
|
||||
|
||||
// PORT 443
|
||||
|
||||
func check_https(domain, ip string) (err error) {
|
||||
var resp *http.Response
|
||||
resp, err = http.Get(fmt.Sprintf("https://%s/", strings.TrimSuffix(domain, ".")))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= 300 && resp.StatusCode < 400 {
|
||||
loc := resp.Header.Get("Location")
|
||||
if loc != "" && strings.HasSuffix(dns.Fqdn(loc), domain) {
|
||||
if dns.Fqdn(loc) == domain {
|
||||
return fmt.Errorf("Redirection loop %s redirect to %s", domain, loc)
|
||||
} else if err = check_https(dns.Fqdn(loc), ip); err != nil {
|
||||
return fmt.Errorf("Error after following redirection to %s: %w", loc, err)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if resp.StatusCode >= 300 {
|
||||
return fmt.Errorf("Bad status, got: %d (%s)", resp.StatusCode, resp.Status)
|
||||
}
|
||||
|
||||
_, err = ioutil.ReadAll(resp.Body)
|
||||
return
|
||||
}
|
||||
|
||||
func wksChecker() {
|
||||
if collectorpubkey == nil {
|
||||
var err error
|
||||
if collectorpubkey, err = getCollectorPublicKey(); err != nil {
|
||||
log.Println("Contact collector:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
data, err := encodeData(SendMeta{Login: Login}, map[string]*string{
|
||||
test_name: nil,
|
||||
})
|
||||
if err != nil {
|
||||
log.Println("Unable to encode message:", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = sendData(data)
|
||||
if err != nil {
|
||||
log.Println("Unable to send message:", err)
|
||||
return
|
||||
}
|
||||
|
||||
v, _ := json.Marshal(data)
|
||||
if verbose {
|
||||
log.Printf("sent %s", v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in a new issue