From 46de3a0101c4974afd6ea861c1246004151babd8 Mon Sep 17 00:00:00 2001 From: Alireza Mosajjal Date: Thu, 11 May 2023 12:35:40 +1200 Subject: [PATCH] moved back to zerolog and pretty logging --- acl/acl.go | 13 ++++---- acl/cidr.go | 24 +++++++-------- acl/domain.go | 26 ++++++++-------- acl/geoip.go | 28 ++++++++--------- acl/override.go | 16 +++++----- dns.go | 37 +++++++++++------------ go.mod | 21 +++++++------ go.sum | 41 +++++++++++++++++++++++-- httpproxy.go | 18 +++++------ https.go | 31 ++++++++----------- main.go | 80 ++++++++++++++++++++++++------------------------- 11 files changed, 180 insertions(+), 155 deletions(-) diff --git a/acl/acl.go b/acl/acl.go index 6a142d6..779d5af 100644 --- a/acl/acl.go +++ b/acl/acl.go @@ -6,7 +6,7 @@ import ( "sort" "github.com/knadh/koanf" - "golang.org/x/exp/slog" + "github.com/rs/zerolog" ) // Decision is the type of decision that an ACL can make for each connection info @@ -45,11 +45,11 @@ type ACL interface { Decide(*ConnInfo) error Name() string Priority() uint - ConfigAndStart(*slog.Logger, *koanf.Koanf) error + ConfigAndStart(zerolog.Logger, *koanf.Koanf) error } // StartACLs starts all the ACLs that have been configured and registered -func StartACLs(log *slog.Logger, k *koanf.Koanf) ([]ACL, error) { +func StartACLs(log zerolog.Logger, k *koanf.Koanf) ([]ACL, error) { var a []ACL aclK := k.Cut("acl") for _, acl := range availableACLs { @@ -58,16 +58,15 @@ func StartACLs(log *slog.Logger, k *koanf.Koanf) ([]ACL, error) { if !aclK.Bool(fmt.Sprintf("%s.enabled", (acl).Name())) { continue } - l := slog.New(log.Handler().WithAttrs([]slog.Attr{{Key: "service", Value: slog.StringValue((acl).Name())}})) + var l = log.With().Str("acl", (acl).Name()).Logger() // we pass the full config to each ACL so that they can cut it themselves. it's needed for some ACLs that need // to read the config of other ACLs or the global config if err := acl.ConfigAndStart(l, k); err != nil { - log.Warn("failed to start ACL", "name", (acl).Name(), "err", err) + log.Warn().Msgf("failed to start ACL %s with error %s", (acl).Name(), err) return a, err } a = append(a, acl) - log.Info("started ACL", "name", (acl).Name()) - fmt.Printf("%+v\n", a) + log.Info().Msgf("started ACL: '%s'", (acl).Name()) } return a, nil diff --git a/acl/cidr.go b/acl/cidr.go index 3daeef7..3af444a 100644 --- a/acl/cidr.go +++ b/acl/cidr.go @@ -10,8 +10,8 @@ import ( "time" "github.com/knadh/koanf" + "github.com/rs/zerolog" "github.com/yl2chen/cidranger" - "golang.org/x/exp/slog" ) // CIDR acl allows sniproxy to use a list of CIDR to allow or reject connections @@ -23,7 +23,7 @@ type cidr struct { RefreshInterval time.Duration `yaml:"refresh_interval"` AllowRanger cidranger.Ranger RejectRanger cidranger.Ranger - logger *slog.Logger + logger zerolog.Logger priority uint } @@ -31,10 +31,10 @@ func (d *cidr) LoadCIDRCSV(path string) error { d.AllowRanger = cidranger.NewPCTrieRanger() d.RejectRanger = cidranger.NewPCTrieRanger() - d.logger.Info("Loading the CIDR from file/url") + d.logger.Info().Msg("Loading the CIDR from file/url") var scanner *bufio.Scanner if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { - d.logger.Info("CIDR list is a URL, trying to fetch") + d.logger.Info().Msg("CIDR list is a URL, trying to fetch") client := http.Client{ CheckRedirect: func(r *http.Request, via []*http.Request) error { r.URL.Opaque = r.URL.Path @@ -43,10 +43,10 @@ func (d *cidr) LoadCIDRCSV(path string) error { } resp, err := client.Get(path) if err != nil { - d.logger.Error(err.Error()) + d.logger.Err(err) return err } - d.logger.Info("(re)fetching URL", "path", path) + d.logger.Info().Msgf("(re)fetching URL: ", path) defer resp.Body.Close() scanner = bufio.NewScanner(resp.Body) @@ -55,7 +55,7 @@ func (d *cidr) LoadCIDRCSV(path string) error { if err != nil { return err } - d.logger.Info("(re)loading File", "path", path) + d.logger.Info().Msgf("(re)loading file: ", path) defer file.Close() scanner = bufio.NewScanner(file) } @@ -65,7 +65,7 @@ func (d *cidr) LoadCIDRCSV(path string) error { // cut the line at the first comma cidr, policy, found := strings.Cut(row, ",") if !found { - d.logger.Info(cidr + " is not a valid csv line, assuming reject") + d.logger.Info().Msg(cidr + " is not a valid csv line, assuming reject") } if policy == "allow" { if _, netw, err := net.ParseCIDR(cidr); err == nil { @@ -74,7 +74,7 @@ func (d *cidr) LoadCIDRCSV(path string) error { if _, netw, err := net.ParseCIDR(cidr + "/32"); err == nil { _ = d.AllowRanger.Insert(cidranger.NewBasicRangerEntry(*netw)) } else { - d.logger.Error(err.Error()) + d.logger.Err(err) } } } else { @@ -84,12 +84,12 @@ func (d *cidr) LoadCIDRCSV(path string) error { if _, netw, err := net.ParseCIDR(cidr + "/32"); err == nil { _ = d.RejectRanger.Insert(cidranger.NewBasicRangerEntry(*netw)) } else { - d.logger.Error(err.Error()) + d.logger.Err(err) } } } } - d.logger.Info("cidrs loaded", "len", d.AllowRanger.Len()) + d.logger.Info().Msgf("%d cidr(s) loaded", d.AllowRanger.Len()) return nil } @@ -128,7 +128,7 @@ func (d cidr) Priority() uint { } // Config function is what starts the ACL -func (d *cidr) ConfigAndStart(logger *slog.Logger, c *koanf.Koanf) error { +func (d *cidr) ConfigAndStart(logger zerolog.Logger, c *koanf.Koanf) error { c = c.Cut(fmt.Sprintf("acl.%s", d.Name())) d.logger = logger d.Path = c.String("path") diff --git a/acl/domain.go b/acl/domain.go index 4cb74a7..2b3454d 100644 --- a/acl/domain.go +++ b/acl/domain.go @@ -11,7 +11,7 @@ import ( "github.com/golang-collections/collections/tst" "github.com/knadh/koanf" - "golang.org/x/exp/slog" + "github.com/rs/zerolog" ) // domain ACL makes a decision on a connection based on the domain name derived @@ -22,7 +22,7 @@ type domain struct { routePrefixes *tst.TernarySearchTree routeSuffixes *tst.TernarySearchTree routeFQDNs map[string]uint8 - logger *slog.Logger + logger zerolog.Logger priority uint } @@ -72,10 +72,10 @@ func reverse(s string) string { // 2. a TST for all the suffixes (type 2) // 3. a hashtable for all the full match fqdn (type 3) func (d *domain) LoadDomainsCsv(Filename string) error { - d.logger.Info("Loading the domain from file/url") + d.logger.Info().Msg("Loading the domain from file/url") var scanner *bufio.Scanner if strings.HasPrefix(Filename, "http://") || strings.HasPrefix(Filename, "https://") { - d.logger.Info("domain list is a URL, trying to fetch") + d.logger.Info().Msg("domain list is a URL, trying to fetch") client := http.Client{ CheckRedirect: func(r *http.Request, via []*http.Request) error { r.URL.Opaque = r.URL.Path @@ -84,10 +84,10 @@ func (d *domain) LoadDomainsCsv(Filename string) error { } resp, err := client.Get(Filename) if err != nil { - d.logger.Error(err.Error()) + d.logger.Err(err) return err } - d.logger.Info("(re)fetching URL", "url", Filename) + d.logger.Info().Msgf("(re)fetching URL: %s", Filename) defer resp.Body.Close() scanner = bufio.NewScanner(resp.Body) @@ -96,7 +96,7 @@ func (d *domain) LoadDomainsCsv(Filename string) error { if err != nil { return err } - d.logger.Info("(re)loading File", "file", Filename) + d.logger.Info().Msgf("(re)loading file: %s", Filename) defer file.Close() scanner = bufio.NewScanner(file) } @@ -105,7 +105,7 @@ func (d *domain) LoadDomainsCsv(Filename string) error { // split the line by comma to understand thed.logger.c fqdn := strings.Split(lowerCaseLine, ",") if len(fqdn) != 2 { - d.logger.Info(lowerCaseLine + " is not a valid line, assuming FQDN") + d.logger.Info().Msg(lowerCaseLine + " is not a valid line, assuming FQDN") fqdn = []string{lowerCaseLine, "fqdn"} } // add the fqdn to the hashtable with its type @@ -121,11 +121,11 @@ func (d *domain) LoadDomainsCsv(Filename string) error { d.routeFQDNs[fqdn[0]] = matchFQDN default: //d.logger.Warnf("%s is not a valid line, assuming fqdn", lowerCaseLine) - d.logger.Info(lowerCaseLine + " is not a valid line, assuming FQDN") + d.logger.Info().Msg(lowerCaseLine + " is not a valid line, assuming FQDN") d.routeFQDNs[fqdn[0]] = matchFQDN } } - d.logger.Info(fmt.Sprintf("%s loaded with %d prefix, %d suffix and %d fqdn", Filename, d.routePrefixes.Len(), d.routeSuffixes.Len(), len(d.routeFQDNs)-d.routePrefixes.Len()-d.routeSuffixes.Len())) + d.logger.Info().Msgf("%s loaded with %d prefix, %d suffix and %d fqdn", Filename, d.routePrefixes.Len(), d.routeSuffixes.Len(), len(d.routeFQDNs)-d.routePrefixes.Len()-d.routeSuffixes.Len()) return nil } @@ -145,10 +145,10 @@ func (d domain) Decide(c *ConnInfo) error { return nil } if d.inDomainList(c.Domain) { - d.logger.Debug("domain not going through proxy", "domain", c.Domain) + d.logger.Debug().Msgf("domain not going through proxy: %s", c.Domain) c.Decision = OriginIP } else { - d.logger.Debug("domain going through proxy", "domain", c.Domain) + d.logger.Debug().Msgf("domain going through proxy: %s", c.Domain) c.Decision = ProxyIP } return nil @@ -160,7 +160,7 @@ func (d domain) Priority() uint { return d.priority } -func (d *domain) ConfigAndStart(logger *slog.Logger, c *koanf.Koanf) error { +func (d *domain) ConfigAndStart(logger zerolog.Logger, c *koanf.Koanf) error { c = c.Cut(fmt.Sprintf("acl.%s", d.Name())) d.logger = logger d.routePrefixes = tst.New() diff --git a/acl/geoip.go b/acl/geoip.go index 0945da3..fdf6f8a 100644 --- a/acl/geoip.go +++ b/acl/geoip.go @@ -11,8 +11,8 @@ import ( "github.com/knadh/koanf" "github.com/oschwald/maxminddb-golang" + "github.com/rs/zerolog" "golang.org/x/exp/slices" - "golang.org/x/exp/slog" ) // geoIP is an ACL that checks the geolocation of incoming connections and @@ -29,7 +29,7 @@ type geoIP struct { BlockedCountries []string Refresh time.Duration mmdb *maxminddb.Reader - logger *slog.Logger + logger zerolog.Logger priority uint } @@ -59,15 +59,15 @@ func (g geoIP) getCountry(ipAddr string) (string, error) { // initializeGeoIP loads the geolocation database from the specified g.Path. func (g *geoIP) initializeGeoIP() error { - g.logger.Info("Loading the domain from file/url") + g.logger.Info().Msg("Loading the domain from file/url") var scanner []byte if strings.HasPrefix(g.Path, "http://") || strings.HasPrefix(g.Path, "https://") { - g.logger.Info("domain list is a URL, trying to fetch") + g.logger.Info().Msg("domain list is a URL, trying to fetch") resp, err := http.Get(g.Path) if err != nil { return err } - g.logger.Info("(re)fetching", "Path", g.Path) + g.logger.Info().Msgf("(re)fetching %s", g.Path) defer resp.Body.Close() scanner, err = io.ReadAll(resp.Body) if err != nil { @@ -79,13 +79,13 @@ func (g *geoIP) initializeGeoIP() error { if err != nil { return err } - g.logger.Info("(re)loading File: ", g.Path) + g.logger.Info().Msgf("(re)loading File: %s", g.Path) defer file.Close() n, err := file.Read(scanner) if err != nil { return err } - g.logger.Info("geolocation database loaded", n) + g.logger.Info().Msgf("geolocation database with %d bytes loaded", n) } var err error @@ -93,13 +93,13 @@ func (g *geoIP) initializeGeoIP() error { //g.logger.Warn("%d bytes read, %s", len(scanner), err) return err } - g.logger.Info("Loaded MMDB") + g.logger.Info().Msg("Loaded MMDB") for range time.NewTicker(g.Refresh).C { if g.mmdb, err = maxminddb.FromBytes(scanner); err != nil { //g.logger.Warn("%d bytes read, %s", len(scanner), err) return err } - g.logger.Info("Loaded MMDB %v", g.mmdb) + g.logger.Info().Msgf("Loaded MMDB %v", g.mmdb) } return nil } @@ -127,10 +127,10 @@ func (g geoIP) checkGeoIPSkip(addr net.Addr) bool { var country string country, err := g.getCountry(ip) country = strings.ToLower(country) - g.logger.Debug("incoming tcp connection", "ip", ip, "country", country) + g.logger.Debug().Msgf("incoming tcp connection from ip %s and country %s", ip, country) if err != nil { - g.logger.Info("Failed to get the geolocation", "ip", ip, "country", country) + g.logger.Info().Msgf("Failed to get the geolocation of ip %s", ip) return false } if slices.Contains(g.BlockedCountries, country) { @@ -153,10 +153,10 @@ func (g geoIP) checkGeoIPSkip(addr net.Addr) bool { func (g geoIP) Decide(c *ConnInfo) error { // in checkGeoIPSkip, false is reject if !g.checkGeoIPSkip(c.SrcIP) { - g.logger.Info("Rejecting connection from", "ip", c.SrcIP) + g.logger.Info().Msgf("rejecting connection from ip %s", c.SrcIP) c.Decision = Reject } - g.logger.Debug("GeoIP decision", "ip", c.SrcIP, "decision", c.Decision) + g.logger.Debug().Msgf("GeoIP decision for ip %s is %#v", c.SrcIP, c.Decision) return nil } func (g geoIP) Name() string { @@ -166,7 +166,7 @@ func (g geoIP) Priority() uint { return g.priority } -func (g *geoIP) ConfigAndStart(logger *slog.Logger, c *koanf.Koanf) error { +func (g *geoIP) ConfigAndStart(logger zerolog.Logger, c *koanf.Koanf) error { c = c.Cut(fmt.Sprintf("acl.%s", g.Name())) g.logger = logger g.Path = c.String("path") diff --git a/acl/override.go b/acl/override.go index 5729e92..96f156a 100644 --- a/acl/override.go +++ b/acl/override.go @@ -10,7 +10,7 @@ import ( "github.com/knadh/koanf" doh "github.com/mosajjal/sniproxy/dohserver" dohserver "github.com/mosajjal/sniproxy/dohserver" - "golang.org/x/exp/slog" + "github.com/rs/zerolog" "inet.af/tcpproxy" ) @@ -25,7 +25,7 @@ type override struct { tcpproxyport int tlsCert string tlsKey string - logger *slog.Logger + logger zerolog.Logger } // GetFreePort returns a random open port @@ -49,15 +49,15 @@ func (o *override) startProxy() { var err error o.tcpproxyport, err = GetFreePort() if err != nil { - o.logger.Error("failed to get a free port for tcpproxy: %s", err) + o.logger.Error().Msgf("failed to get a free port for tcpproxy: %s", err) return } for k, v := range o.rules { - o.logger.Info("adding overide rule", k, v) + o.logger.Info().Msgf("adding overide rule %s -> %s", k, v) // TODO: create a regex matcher for SNIRoute o.tcpproxy.AddSNIRoute(fmt.Sprintf("127.0.0.1:%d", o.tcpproxyport), k, tcpproxy.To(v)) } - o.logger.Info("starting tcpproxy", "port", o.tcpproxyport) + o.logger.Info().Msgf("starting tcpproxy on port %d", o.tcpproxyport) o.tcpproxy.Run() } @@ -81,7 +81,7 @@ func (o override) Priority() uint { return o.priority } -func (o *override) ConfigAndStart(logger *slog.Logger, c *koanf.Koanf) error { +func (o *override) ConfigAndStart(logger zerolog.Logger, c *koanf.Koanf) error { DNSBind := c.String("general.bind_dns_over_udp") c = c.Cut(fmt.Sprintf("acl.%s", o.Name())) tmpRules := c.StringMap("rules") @@ -100,9 +100,9 @@ func (o *override) ConfigAndStart(logger *slog.Logger, c *koanf.Koanf) error { dohConfig.Listen = []string{fmt.Sprintf("127.0.0.1:%d", o.dohPort)} if o.tlsCert == "" || o.tlsKey == "" { _, _, err := doh.GenerateSelfSignedCertKey(dohSNI, nil, nil, os.TempDir()) - o.logger.Info("certificate was not provided, generating a self signed cert in temp directory") + o.logger.Info().Msg("certificate was not provided, generating a self signed cert in temp directory") if err != nil { - o.logger.Error("error while generating self-signed cert: ", "error", err) + o.logger.Error().Msgf("error while generating self-signed cert: %s", err) } o.tlsCert = filepath.Join(os.TempDir(), dohSNI+".crt") o.tlsKey = filepath.Join(os.TempDir(), dohSNI+".key") diff --git a/dns.go b/dns.go index e07fe6f..bdab415 100644 --- a/dns.go +++ b/dns.go @@ -12,7 +12,6 @@ import ( "github.com/mosajjal/dnsclient" doqserver "github.com/mosajjal/doqd/pkg/server" "github.com/mosajjal/sniproxy/acl" - "golang.org/x/exp/slog" "github.com/miekg/dns" ) @@ -24,7 +23,7 @@ type DNSClient struct { var dnsLock sync.RWMutex -var dnslog = slog.New(log.Handler().WithAttrs([]slog.Attr{{Key: "service", Value: slog.StringValue("dns")}})) +var dnslog = logger.With().Str("service", "dns").Logger() func (dnsc *DNSClient) performExternalAQuery(fqdn string, QType uint16) ([]dns.RR, time.Duration, error) { if !strings.HasSuffix(fqdn, ".") { @@ -42,7 +41,7 @@ func (dnsc *DNSClient) performExternalAQuery(fqdn string, QType uint16) ([]dns.R res, trr, err := dnsc.Query(context.Background(), &msg) if err != nil { if err.Error() == "EOF" { - dnslog.Info("reconnecting DNS...") + dnslog.Info().Msg("reconnecting DNS...") // dnsc.C.Close() // dnsc.C, err = dnsclient.New(c.UpstreamDNS, true) err = c.dnsClient.Reconnect() @@ -58,7 +57,7 @@ func processQuestion(q dns.Question, decision acl.Decision) ([]dns.RR, error) { if decision == acl.ProxyIP || decision == acl.Override { // Return the public IP. c.proxiedDNS.Inc(1) - dnslog.Info("returned sniproxy address for domain", "fqdn", q.Name) + dnslog.Info().Msgf("returned sniproxy address for domain %s", q.Name) if q.Qtype == dns.TypeA { rr, err := dns.NewRR(fmt.Sprintf("%s A %s", q.Name, c.PublicIPv4)) @@ -80,7 +79,7 @@ func processQuestion(q dns.Question, decision acl.Decision) ([]dns.RR, error) { return nil, err } - dnslog.Info("returned origin address", "fqdn", q.Name, "rtt", rtt) + dnslog.Info().Msgf("returned origin address for fqdn %s and rtt %s", q.Name, rtt) return resp, nil } @@ -125,7 +124,7 @@ func handleDNS(w dns.ResponseWriter, r *dns.Msg) { acl.MakeDecision(&connInfo, c.acl) answers, err := processQuestion(q, connInfo.Decision) if err != nil { - dnslog.Error(err.Error()) + dnslog.Error().Msg(err.Error()) continue } m.Answer = append(m.Answer, answers...) @@ -140,12 +139,12 @@ func runDNS() { if c.BindDNSOverUDP != "" { go func() { serverUDP := &dns.Server{Addr: c.BindDNSOverUDP, Net: "udp"} - dnslog.Info("started udp dns", "bind", c.BindDNSOverUDP) + dnslog.Info().Msgf("started udp dns on %s", c.BindDNSOverUDP) err := serverUDP.ListenAndServe() defer serverUDP.Shutdown() if err != nil { - dnslog.Error("error starting udp dns server", "details", err) - dnslog.Info(fmt.Sprintf("failed to start server: %s\nyou can run the following command to pinpoint which process is listening on your bind\nsudo ss -pltun", c.BindDNSOverUDP)) + dnslog.Error().Msgf("error starting udp dns server: %s", err) + dnslog.Info().Msgf("failed to start server: %s\nyou can run the following command to pinpoint which process is listening on your bind\nsudo ss -pltun", c.BindDNSOverUDP) panic(2) } }() @@ -154,12 +153,12 @@ func runDNS() { if c.BindDNSOverTCP != "" { go func() { serverTCP := &dns.Server{Addr: c.BindDNSOverTCP, Net: "tcp"} - dnslog.Info("started tcp dns", "bind", c.BindDNSOverTCP) + dnslog.Info().Msgf("started tcp dns on %s", c.BindDNSOverTCP) err := serverTCP.ListenAndServe() defer serverTCP.Shutdown() if err != nil { - dnslog.Error("failed to start server", err) - dnslog.Info(fmt.Sprintf("failed to start server: %s\nyou can run the following command to pinpoint which process is listening on your bind\nsudo ss -pltun", c.BindDNSOverTCP)) + dnslog.Error().Msgf("failed to start server %s", err) + dnslog.Info().Msgf("failed to start server: %s\nyou can run the following command to pinpoint which process is listening on your bind\nsudo ss -pltun", c.BindDNSOverUDP) } }() } @@ -169,7 +168,7 @@ func runDNS() { go func() { crt, err := tls.LoadX509KeyPair(c.TLSCert, c.TLSKey) if err != nil { - dnslog.Error(err.Error()) + dnslog.Error().Msg(err.Error()) panic(2) } @@ -177,11 +176,11 @@ func runDNS() { tlsConfig.Certificates = []tls.Certificate{crt} serverTLS := &dns.Server{Addr: c.BindDNSOverTLS, Net: "tcp-tls", TLSConfig: tlsConfig} - dnslog.Info("started dot dns", "bind", c.BindDNSOverTLS) + dnslog.Info().Msgf("started dot dns on %s", c.BindDNSOverTLS) err = serverTLS.ListenAndServe() defer serverTLS.Shutdown() if err != nil { - dnslog.Error(err.Error()) + dnslog.Error().Msg(err.Error()) } }() } @@ -190,21 +189,19 @@ func runDNS() { crt, err := tls.LoadX509KeyPair(c.TLSCert, c.TLSKey) if err != nil { - dnslog.Error(err.Error()) + dnslog.Error().Msg(err.Error()) } tlsConfig := &tls.Config{} tlsConfig.Certificates = []tls.Certificate{crt} // Create the QUIC listener - // BUG: DoQ always uses localhost:53 as upstream. if Dns Over UDP is disabled or - // using a different port, DoQ won't work properly. doqServer, err := doqserver.New(c.BindDNSOverQuic, crt, c.BindDNSOverUDP, true) if err != nil { - dnslog.Error(err.Error()) + dnslog.Error().Msg(err.Error()) } // Accept QUIC connections - dnslog.Info("starting quic listener", "bind", c.BindDNSOverQuic) + dnslog.Info().Msgf("starting quic listener %s", c.BindDNSOverQuic) go doqServer.Listen() } diff --git a/go.mod b/go.mod index c7e10b3..4d16b0c 100644 --- a/go.mod +++ b/go.mod @@ -12,12 +12,13 @@ require ( github.com/mosajjal/dnsclient v0.1.1-0.20230206011533-99fa18d84393 github.com/mosajjal/doqd v0.0.0-20230201205103-19d9a309dc6a github.com/oschwald/maxminddb-golang v1.10.0 - github.com/prometheus/client_golang v1.15.0 + github.com/prometheus/client_golang v1.15.1 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 + github.com/rs/zerolog v1.29.1 github.com/spf13/cobra v1.7.0 github.com/yl2chen/cidranger v1.0.2 - golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 - golang.org/x/net v0.9.0 + golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea + golang.org/x/net v0.10.0 inet.af/tcpproxy v0.0.0-20221017015627-91f861402626 ) @@ -29,17 +30,19 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/pprof v0.0.0-20230429030804-905365eefe3e // indirect + github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc // indirect github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/onsi/ginkgo/v2 v2.9.2 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect + github.com/onsi/ginkgo/v2 v2.9.4 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.43.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect @@ -48,11 +51,11 @@ require ( github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.1 // indirect - golang.org/x/crypto v0.8.0 // indirect + golang.org/x/crypto v0.9.0 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.8.0 // indirect + golang.org/x/tools v0.9.1 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0dc0b3a..7a848d1 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -52,7 +53,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -68,6 +68,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -113,6 +114,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20230429030804-905365eefe3e h1:yuPVjc55Y343adYwQLA29DR8KrA0yuLJLlN5LxqlsgQ= github.com/google/pprof v0.0.0-20230429030804-905365eefe3e/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 h1:2XF1Vzq06X+inNqgJ9tRnGuw+ZVCB3FazXODD6JE1R8= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= @@ -188,11 +191,20 @@ github.com/m13253/dns-over-https/v2 v2.3.3/go.mod h1:9X63wUDr5eHQUfL7H+fX5VC3B2y github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -230,7 +242,10 @@ github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnu github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -252,18 +267,24 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us= +github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= @@ -284,6 +305,9 @@ github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8d github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= +github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -330,9 +354,13 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea h1:vLCWI/yYrdEHyN2JzIzPO3aaQJHQdp89IZBA/+azVC4= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -362,6 +390,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -375,6 +405,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -406,10 +437,12 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -436,6 +469,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/httpproxy.go b/httpproxy.go index 9a4c598..1fd5f47 100644 --- a/httpproxy.go +++ b/httpproxy.go @@ -8,10 +8,9 @@ import ( "time" "github.com/mosajjal/sniproxy/acl" - "golang.org/x/exp/slog" ) -var httplog = slog.New(log.Handler().WithAttrs([]slog.Attr{{Key: "service", Value: slog.StringValue("http")}})) +var httplog = logger.With().Str("service", "http").Logger() var passthruRequestHeaderKeys = [...]string{ "Accept", @@ -51,7 +50,7 @@ func runHTTP() { } if err := s.ListenAndServe(); err != nil { - httplog.Error(err.Error()) + httplog.Error().Msg(err.Error()) panic(-1) } } @@ -67,18 +66,18 @@ func handle80(w http.ResponseWriter, r *http.Request) { } acl.MakeDecision(&connInfo, c.acl) if connInfo.Decision == acl.Reject || connInfo.Decision == acl.ProxyIP || err != nil { - httplog.Info("rejected request", "ip", r.RemoteAddr) + httplog.Info().Msgf("rejected request from ip: %s", r.RemoteAddr) http.Error(w, "Could not reach origin server", 403) return } // if the URL starts with the public IP, it needs to be skipped to avoid loops if strings.HasPrefix(r.Host, c.PublicIPv4) { - httplog.Warn("someone is requesting HTTP to sniproxy itself, ignoring...") + httplog.Warn().Msg("someone is requesting HTTP to sniproxy itself, ignoring...") http.Error(w, "Could not reach origin server", 404) return } - httplog.Info("REQ", "method", r.Method, "host", r.Host, "url", r.URL) + httplog.Info().Msgf("REQ method %s, host: %s, url: %s", r.Method, r.Host, r.URL) // Construct filtered header to send to origin server hh := http.Header{} @@ -105,7 +104,7 @@ func handle80(w http.ResponseWriter, r *http.Request) { // check to see if this host is listed to be processed, otherwise RESET // if !c.AllDomains && inDomainList(r.Host+".") { // http.Error(w, "Could not reach origin server", 403) - // httplog.Warn("a client requested connection to " + r.Host + ", but it's not allowed as per configuration.. sending 403") + // httplog.Warn().Msg("a client requested connection to " + r.Host + ", but it's not allowed as per configuration.. sending 403") // return // } @@ -117,13 +116,12 @@ func handle80(w http.ResponseWriter, r *http.Request) { resp, err := transport.RoundTrip(&rr) if err != nil { // TODO: Passthru more error information - http.Error(w, "Could not reach origin server", 500) - httplog.Error(err.Error()) + httplog.Error().Msg(err.Error()) return } defer resp.Body.Close() - httplog.Info("http response", "status_code", resp.Status) + httplog.Info().Msgf("http response with status_code %s", resp.Status) // Transfer filtered header from origin server -> client respH := w.Header() diff --git a/https.go b/https.go index 4345a0e..8094bc3 100644 --- a/https.go +++ b/https.go @@ -5,11 +5,10 @@ import ( "net" "github.com/mosajjal/sniproxy/acl" - "golang.org/x/exp/slog" "golang.org/x/net/proxy" ) -var httpslog = slog.New(log.Handler().WithAttrs([]slog.Attr{{Key: "service", Value: slog.StringValue("https")}})) +var httpslog = logger.With().Str("service", "https").Logger() func handle443(conn net.Conn) error { c.recievedHTTPS.Inc(1) @@ -18,12 +17,12 @@ func handle443(conn net.Conn) error { incoming := make([]byte, 2048) n, err := conn.Read(incoming) if err != nil { - httpslog.Error(err.Error()) + httpslog.Err(err) return err } sni, err := GetHostname(incoming) if err != nil { - httpslog.Error(err.Error()) + httpslog.Err(err) return err } connInfo := acl.ConnInfo{ @@ -33,40 +32,36 @@ func handle443(conn net.Conn) error { acl.MakeDecision(&connInfo, c.acl) if connInfo.Decision == acl.Reject { - httpslog.Warn("ACL rejection", "ip", conn.RemoteAddr().String()) + httpslog.Warn().Msgf("ACL rejection for ip %s", conn.RemoteAddr().String()) conn.Close() return nil } // check SNI against domainlist for an extra layer of security if connInfo.Decision == acl.OriginIP { - httpslog.Warn("a client requested connection to " + sni + ", but it's not allowed as per configuration.. resetting TCP") + httpslog.Warn().Msg("a client requested connection to " + sni + ", but it's not allowed as per configuration.. resetting TCP") conn.Close() return nil } rPort := 443 var rAddr net.IP if connInfo.Decision == acl.Override { - httpslog.Debug("overriding destination IP", "ip", rAddr.String(), "newip", connInfo.DstIP.String()) + httpslog.Debug().Msgf("overriding destination IP %s with %s", rAddr.String(), connInfo.DstIP.String()) rAddr = connInfo.DstIP.IP rPort = connInfo.DstIP.Port } else { rAddr, err = c.dnsClient.lookupDomain4(sni) if err != nil || rAddr == nil { - httpslog.Warn(err.Error()) + httpslog.Warn().Msg(err.Error()) return err } // TODO: handle timeout and context here if rAddr.IsLoopback() || rAddr.IsPrivate() || rAddr.Equal(net.IPv4(0, 0, 0, 0)) || rAddr.Equal(net.IP(c.PublicIPv4)) || rAddr.Equal(net.IP(c.sourceAddr)) || rAddr.Equal(net.IP(c.PublicIPv6)) { - httpslog.Info("connection to private IP or self ignored") + httpslog.Info().Msg("connection to private IP or self ignored") return nil } } - httpslog.Info("establishing connection", - "remote", fmt.Sprintf("%s:%d", rAddr.String(), rPort), - "source", conn.RemoteAddr().String(), - "host", sni, - ) + httpslog.Info().Msgf("establishing connection to %s:%d from %s with SNI %s", rAddr.String(), rPort, conn.RemoteAddr().String(), sni) var target *net.TCPConn if c.dialer == proxy.Direct { // with the manipulation of the soruce address, we can set the outbound interface @@ -76,14 +71,14 @@ func handle443(conn net.Conn) error { } target, err = net.DialTCP("tcp", &srcAddr, &net.TCPAddr{IP: rAddr, Port: rPort}) if err != nil { - httpslog.Error("could not connect to target", "detail", err) + httpslog.Info().Msgf("could not connect to target with error: %s", err) conn.Close() return err } } else { tmp, err := c.dialer.Dial("tcp", fmt.Sprintf("%s:%d", rAddr, rPort)) if err != nil { - httpslog.Error("could not connect to target", "detail", err) + httpslog.Info().Msgf("could not connect to target with error: %s", err) conn.Close() return err } @@ -100,14 +95,14 @@ func runHTTPS() { l, err := net.Listen("tcp", c.BindHTTPS) if err != nil { - httpslog.Error(err.Error()) + httpslog.Err(err) panic(-1) } defer l.Close() for { c, err := l.Accept() if err != nil { - httpslog.Error(err.Error()) + httpslog.Err(err) } go func() { go handle443(c) diff --git a/main.go b/main.go index 1e3af33..4df5044 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( "github.com/knadh/koanf/parsers/yaml" "github.com/knadh/koanf/providers/file" "github.com/knadh/koanf/providers/rawbytes" + "github.com/rs/zerolog" prometheusmetrics "github.com/deathowl/go-metrics-prometheus" "github.com/mosajjal/dnsclient" @@ -25,7 +26,6 @@ import ( "github.com/spf13/cobra" "github.com/miekg/dns" - "golang.org/x/exp/slog" "golang.org/x/net/proxy" _ "embed" @@ -75,8 +75,7 @@ var ( //go:embed config.defaults.yaml var defaultConfig []byte -var logLevel = new(slog.LevelVar) -var log = slog.New(slog.HandlerOptions{Level: logLevel}.NewTextHandler(os.Stderr)) +var logger = zerolog.New(os.Stderr).With().Timestamp().Logger().Output(zerolog.ConsoleWriter{Out: os.Stderr}) func pipe(conn1 net.Conn, conn2 net.Conn) { chan1 := getChannel(conn1) @@ -153,7 +152,7 @@ func getPublicIPv4() (string, error) { return externalIP, nil } - log.Error("Could not automatically find the public IPv4 address. Please specify it in the configuration.", nil) + logger.Error().Msg("Could not automatically find the public IPv4 address. Please specify it in the configuration.") } return "", nil @@ -201,7 +200,7 @@ func getPublicIPv6() (string, error) { return cleanIPv6(externalIP), nil } - log.Error("Could not automatically find the public IPv6 address. Please specify it in the configuration.", nil) + logger.Error().Msg("Could not automatically find the public IPv6 address. Please specify it in the configuration.") } return "", nil @@ -221,7 +220,7 @@ func main() { _ = flags.Bool("defaultconfig", false, "write the default config yaml file to path") _ = flags.BoolP("version", "v", false, "show version info and exit") if err := cmd.Execute(); err != nil { - log.Error("failed to execute command", "error", err) + logger.Error().Msgf("failed to execute command: %s", err) return } if flags.Changed("help") { @@ -247,24 +246,24 @@ func main() { } } - switch k.String("log_level") { + logger.Info().Msgf("starting sniproxy. version %s, commit %s", version, commit) + + // verify and load config + generalConfig := k.Cut("general") + + switch l := generalConfig.String("log_level"); l { case "debug": - logLevel.Set(slog.LevelDebug) + zerolog.SetGlobalLevel(zerolog.DebugLevel) case "info": - logLevel.Set(slog.LevelInfo) + zerolog.SetGlobalLevel(zerolog.InfoLevel) case "warn": - logLevel.Set(slog.LevelWarn) + zerolog.SetGlobalLevel(zerolog.WarnLevel) case "error": - logLevel.Set(slog.LevelError) + zerolog.SetGlobalLevel(zerolog.ErrorLevel) default: - logLevel.Set(slog.LevelInfo) + zerolog.SetGlobalLevel(zerolog.InfoLevel) } - log.Info("starting sniproxy", "version", version, "commit", commit) - - // verify and load config - generalConfig := k.Cut("general") - c.UpstreamDNS = generalConfig.String("upstream_dns") c.UpstreamSOCKS5 = generalConfig.String("upstream_socks5") c.BindDNSOverUDP = generalConfig.String("bind_dns_over_udp") @@ -287,9 +286,9 @@ func main() { c.BindPrometheus = generalConfig.String("prometheus") var err error - c.acl, err = acl.StartACLs(log, k) + c.acl, err = acl.StartACLs(logger, k) if err != nil { - log.Error("failed to start ACLs", "error", err) + logger.Error().Msgf("failed to start ACLs: %s", err) return } @@ -306,37 +305,37 @@ func main() { go p.UpdatePrometheusMetrics() go func() { http.Handle("/metrics", promhttp.Handler()) - log.Info("starting metrics server", + logger.Info().Str( "address", c.BindPrometheus, - ) + ).Msg("starting metrics server") if err := http.ListenAndServe(c.BindPrometheus, promhttp.Handler()); err != nil { - log.Error(err.Error()) + logger.Error().Msgf("%s", err) } }() } // if c.DomainListPath == "" { - // log.Warn("Domain list (--domainListPath) is not specified, routing ALL domains through the SNI proxy") + // log.Warn().Msg("Domain list (--domainListPath) is not specified, routing ALL domains through the SNI proxy") // c.AllDomains = true // } if c.PublicIPv4 != "" { - log.Info("server info", "public_ip", c.PublicIPv4) + logger.Info().Str("public_ip", c.PublicIPv4).Msg("server info") } else { - log.Error("Could not automatically determine public IPv4. you should provide it manually using --publicIPv4") + logger.Error().Msg("Could not automatically determine public IPv4. you should provide it manually using --publicIPv4") } if c.PublicIPv6 != "" { - log.Info("server info", "public_ip", c.PublicIPv6) + logger.Info().Str("public_ip", c.PublicIPv6).Msg("server info") } else { - log.Error("Could not automatically determine public IPv6. you should provide it manually using --publicIPv6") + logger.Error().Msg("Could not automatically determine public IPv6. you should provide it manually using --publicIPv6") } // generate self-signed certificate if not provided if c.TLSCert == "" && c.TLSKey == "" { _, _, err := doh.GenerateSelfSignedCertKey(c.PublicIPv4, nil, nil, os.TempDir()) - log.Info("certificate was not provided, generating a self signed cert in temp directory") + logger.Info().Msg("certificate was not provided, generating a self signed cert in temp directory") if err != nil { - log.Error("error while generating self-signed cert: ", "error", err) + logger.Error().Msgf("error while generating self-signed cert: %s", err) } c.TLSCert = filepath.Join(os.TempDir(), c.PublicIPv4+".crt") c.TLSKey = filepath.Join(os.TempDir(), c.PublicIPv4+".key") @@ -344,29 +343,28 @@ func main() { // throw an error if geoip include or exclude is present, but geoippath is not // if c.GeoIPPath == "" && (len(c.GeoIPInclude)+len(c.GeoIPExclude) >= 1) { - // log.Error("GeoIP include or exclude is present, but GeoIPPath is not") + // log.Error().Msg("GeoIP include or exclude is present, but GeoIPPath is not") // } // // // load mmdb if provided // if c.GeoIPPath != "" { // go initializeGeoIP(c.GeoIPPath) // c.GeoIPExclude = toLowerSlice(c.GeoIPExclude) - // log.Info("GeoIP", "exclude", c.GeoIPExclude) + // log.Info().Msg("GeoIP", "exclude", c.GeoIPExclude) // c.GeoIPInclude = toLowerSlice(c.GeoIPInclude) - // log.Info("GeoIP", "include", c.GeoIPInclude) + // log.Info().Msg("GeoIP", "include", c.GeoIPInclude) // } // Finds source addr for outbound connections if interface is not empty if c.Interface != "" { - log.Info("Using", "interface", c.Interface) + logger.Info().Msgf("Using interface %s", c.Interface) ief, err := net.InterfaceByName(c.Interface) if err != nil { - log.Error(err.Error()) + logger.Err(err) } addrs, err := ief.Addrs() if err != nil { - log.Error(err.Error()) - + logger.Err(err) } c.sourceAddr = net.ParseIP(addrs[0].String()) @@ -375,20 +373,20 @@ func main() { if c.UpstreamSOCKS5 != "" { uri, err := url.Parse(c.UpstreamSOCKS5) if err != nil { - log.Error(err.Error()) + logger.Err(err) } if uri.Scheme != "socks5" { - log.Error("only SOCKS5 is supported") + logger.Error().Msg("only SOCKS5 is supported") return } - log.Info("Using an upstream SOCKS5 proxy", "address", uri.Host) + logger.Info().Msgf("Using an upstream SOCKS5 proxy: %s", uri.Host) u := uri.User.Username() p, _ := uri.User.Password() socksAuth := proxy.Auth{User: u, Password: p} c.dialer, err = proxy.SOCKS5("tcp", uri.Host, &socksAuth, proxy.Direct) if err != nil { - log.Error("can't connect to proxy", "error", err.Error()) + logger.Error().Msgf("can't connect to proxy: %s", err.Error()) os.Exit(1) } } else { @@ -397,7 +395,7 @@ func main() { tmp, err := dnsclient.New(c.UpstreamDNS, true, c.UpstreamSOCKS5) if err != nil { - log.Error(err.Error()) + logger.Err(err) } c.dnsClient = DNSClient{tmp} defer c.dnsClient.Close()