implement metric endpoint

This commit is contained in:
pufferffish 2024-04-10 02:46:29 +01:00
parent bbde9cd266
commit 4cf68c94dd
3 changed files with 55 additions and 2 deletions

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"log" "log"
"net/http"
"os" "os"
"os/exec" "os/exec"
"os/signal" "os/signal"
@ -78,6 +79,7 @@ func main() {
config := parser.String("c", "config", &argparse.Options{Help: "Path of configuration file"}) config := parser.String("c", "config", &argparse.Options{Help: "Path of configuration file"})
silent := parser.Flag("s", "silent", &argparse.Options{Help: "Silent mode"}) silent := parser.Flag("s", "silent", &argparse.Options{Help: "Silent mode"})
daemon := parser.Flag("d", "daemon", &argparse.Options{Help: "Make wireproxy run in background"}) daemon := parser.Flag("d", "daemon", &argparse.Options{Help: "Make wireproxy run in background"})
info := parser.String("i", "info", &argparse.Options{Help: "Specify the address and port for exposing health status"})
printVerison := parser.Flag("v", "version", &argparse.Options{Help: "Print version"}) printVerison := parser.Flag("v", "version", &argparse.Options{Help: "Print version"})
configTest := parser.Flag("n", "configtest", &argparse.Options{Help: "Configtest mode. Only check the configuration file for validity."}) configTest := parser.Flag("n", "configtest", &argparse.Options{Help: "Configtest mode. Only check the configuration file for validity."})
@ -140,13 +142,22 @@ func main() {
// no file access is allowed from now on, only networking // no file access is allowed from now on, only networking
pledgeOrPanic("stdio inet dns") pledgeOrPanic("stdio inet dns")
tnet, err := wireproxy.StartWireguard(conf.Device, logLevel) tun, err := wireproxy.StartWireguard(conf.Device, logLevel)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
for _, spawner := range conf.Routines { for _, spawner := range conf.Routines {
go spawner.SpawnRoutine(tnet) go spawner.SpawnRoutine(tun)
}
if *info != "" {
go func() {
err := http.ListenAndServe(*info, tun)
if err != nil {
panic(err)
}
}()
} }
<-ctx.Done() <-ctx.Done()

View file

@ -1,15 +1,20 @@
package wireproxy package wireproxy
import ( import (
"bytes"
"context" "context"
"crypto/subtle" "crypto/subtle"
"errors" "errors"
"golang.zx2c4.com/wireguard/device"
"io" "io"
"log" "log"
"math/rand" "math/rand"
"net" "net"
"net/http"
"os" "os"
"path"
"strconv" "strconv"
"strings"
"github.com/sourcegraph/conc" "github.com/sourcegraph/conc"
"github.com/things-go/go-socks5" "github.com/things-go/go-socks5"
@ -32,6 +37,7 @@ type CredentialValidator struct {
// VirtualTun stores a reference to netstack network and DNS configuration // VirtualTun stores a reference to netstack network and DNS configuration
type VirtualTun struct { type VirtualTun struct {
Tnet *netstack.Net Tnet *netstack.Net
Dev *device.Device
SystemDNS bool SystemDNS bool
} }
@ -330,3 +336,38 @@ func (conf *TCPServerTunnelConfig) SpawnRoutine(vt *VirtualTun) {
go tcpServerForward(vt, raddr, conn) go tcpServerForward(vt, raddr, conn)
} }
} }
func (d VirtualTun) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Printf("Health metric request: %s\n", r.URL.Path)
switch path.Clean(r.URL.Path) {
case "/readyz":
w.WriteHeader(http.StatusOK)
case "/metrics":
get, err := d.Dev.IpcGet()
if err != nil {
errorLogger.Printf("Failed to get device metrics: %s\n", err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
var buf bytes.Buffer
for _, peer := range strings.Split(get, "\n") {
pair := strings.SplitN(peer, "=", 2)
if len(pair) != 2 {
buf.WriteString(peer)
continue
}
if pair[0] == "private_key" || pair[0] == "preshared_key" {
pair[1] = "REDACTED"
}
buf.WriteString(pair[0])
buf.WriteString("=")
buf.WriteString(pair[1])
buf.WriteString("\n")
}
w.WriteHeader(http.StatusOK)
_, _ = w.Write(buf.Bytes())
default:
w.WriteHeader(http.StatusNotFound)
}
}

View file

@ -82,6 +82,7 @@ func StartWireguard(conf *DeviceConfig, logLevel int) (*VirtualTun, error) {
return &VirtualTun{ return &VirtualTun{
Tnet: tnet, Tnet: tnet,
Dev: dev,
SystemDNS: len(setting.dns) == 0, SystemDNS: len(setting.dns) == 0,
}, nil }, nil
} }