153 lines
3.4 KiB
Go
153 lines
3.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"crypto/ed25519"
|
||
|
"crypto/sha512"
|
||
|
"flag"
|
||
|
"io/ioutil"
|
||
|
"log"
|
||
|
"math/rand"
|
||
|
"os"
|
||
|
"os/signal"
|
||
|
"path"
|
||
|
"syscall"
|
||
|
"time"
|
||
|
|
||
|
"gopkg.in/fsnotify.v1"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
myprivkey ed25519.PrivateKey
|
||
|
collectorpubkey ed25519.PublicKey
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
var tokenfile = flag.String("token-file", "/etc/wireguard/adlin.token", "Path to your token file")
|
||
|
var wgfile = flag.String("wg-file", "/etc/wireguard/adlin.conf", "Path to your wireguard configuration file")
|
||
|
var interval = flag.Duration("check-interval", 30*time.Second, "Interval between two checks")
|
||
|
flag.StringVar(&test_name, "test-name", "", "Name of the test to report")
|
||
|
flag.StringVar(&target, "target", "https://adlin.nemunai.re", "HTTP server to contact")
|
||
|
flag.BoolVar(&verbose, "verbose", verbose, "Enable verbose mode")
|
||
|
flag.Parse()
|
||
|
|
||
|
if test_name == "" {
|
||
|
test_name, _ = os.Hostname()
|
||
|
}
|
||
|
|
||
|
// First load token if it exists
|
||
|
if _, err := os.Stat(*tokenfile); !os.IsNotExist(err) {
|
||
|
if err := loadToken(*tokenfile); err != nil {
|
||
|
log.Fatal("ERROR: Unable to read token file:", err)
|
||
|
}
|
||
|
} else {
|
||
|
log.Fatal("Unable to find token file:", err)
|
||
|
}
|
||
|
|
||
|
// Load of configuration if it exists
|
||
|
if _, err := os.Stat(*wgfile); !os.IsNotExist(err) {
|
||
|
if err := loadSettings(*wgfile); err != nil {
|
||
|
log.Println("ERROR: Unable to read wg settings:", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Register SIGHUP
|
||
|
c := make(chan os.Signal, 1)
|
||
|
signal.Notify(c, syscall.SIGHUP)
|
||
|
go func() {
|
||
|
for range c {
|
||
|
log.Println("SIGHUP received, reloading settings...")
|
||
|
if err := loadSettings(*wgfile); err != nil {
|
||
|
log.Println("ERROR: Unable to read wg settings:", err)
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
// Watch the configuration file
|
||
|
if watcher, err := fsnotify.NewWatcher(); err != nil {
|
||
|
log.Fatal(err)
|
||
|
} else {
|
||
|
if err := watcher.Add(path.Dir(*wgfile)); err != nil {
|
||
|
log.Fatal("Unable to watch: ", path.Dir(*wgfile), ": ", err)
|
||
|
}
|
||
|
|
||
|
go func() {
|
||
|
defer watcher.Close()
|
||
|
for {
|
||
|
select {
|
||
|
case ev := <-watcher.Events:
|
||
|
if path.Base(ev.Name) == *wgfile && ev.Op&(fsnotify.Write|fsnotify.Create) != 0 {
|
||
|
log.Println("Settings file changes, reloading it!")
|
||
|
if err := loadSettings(*wgfile); err != nil {
|
||
|
log.Println("ERROR: Unable to read wg settings:", err)
|
||
|
}
|
||
|
}
|
||
|
case err := <-watcher.Errors:
|
||
|
log.Println("watcher error:", err)
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
}
|
||
|
|
||
|
// Prepare graceful shutdown
|
||
|
interrupt := make(chan os.Signal, 1)
|
||
|
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
|
||
|
|
||
|
// Delay first check randomly
|
||
|
rand.Seed(time.Now().UnixNano())
|
||
|
n := rand.Intn(10)
|
||
|
time.Sleep(time.Duration(n) * time.Second)
|
||
|
|
||
|
ticker := time.NewTicker(*interval)
|
||
|
defer ticker.Stop()
|
||
|
|
||
|
// Launch checker
|
||
|
//wksChecker()
|
||
|
loop:
|
||
|
for {
|
||
|
select {
|
||
|
case <-interrupt:
|
||
|
break loop
|
||
|
case <-ticker.C:
|
||
|
wksChecker()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
func loadToken(filename string) error {
|
||
|
if fd, err := os.Open(filename); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
defer fd.Close()
|
||
|
|
||
|
if b, err := ioutil.ReadAll(fd); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
seed := sha512.Sum512(bytes.TrimSpace(b))
|
||
|
myprivkey = ed25519.NewKeyFromSeed(seed[:ed25519.SeedSize])
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func loadSettings(filename string) error {
|
||
|
if fd, err := os.Open(filename); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
defer fd.Close()
|
||
|
|
||
|
if b, err := ioutil.ReadAll(fd); err != nil {
|
||
|
return err
|
||
|
} else if wgConf, err := FromWgQuick(string(b), "wg0"); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
Login = wgConf.Interface.MyLogin
|
||
|
KeySign = wgConf.Interface.KeySign
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
}
|