diff --git a/cmd/client.go b/cmd/client.go index 89f2924..a835058 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -175,38 +175,38 @@ func client(config *clientConfig) { func(addr net.Addr, reqAddr string, action acl.Action, arg string) { logrus.WithFields(logrus.Fields{ "action": actionToString(action, arg), - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Debug("SOCKS5 TCP request") }, func(addr net.Addr, reqAddr string, err error) { if err != io.EOF { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Info("SOCKS5 TCP error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Debug("SOCKS5 TCP EOF") } }, func(addr net.Addr) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Debug("SOCKS5 UDP associate") }, func(addr net.Addr, err error) { if err != io.EOF { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Info("SOCKS5 UDP error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Debug("SOCKS5 UDP EOF") } }) @@ -231,7 +231,7 @@ func client(config *clientConfig) { func(reqAddr string, action acl.Action, arg string) { logrus.WithFields(logrus.Fields{ "action": actionToString(action, arg), - "dst": reqAddr, + "dst": defaultIPMasker.Mask(reqAddr), }).Debug("HTTP request") }, authFunc) @@ -267,18 +267,18 @@ func client(config *clientConfig) { time.Duration(tcpr.Timeout)*time.Second, func(addr net.Addr) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Debug("TCP relay request") }, func(addr net.Addr, err error) { if err != io.EOF { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Info("TCP relay error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Debug("TCP relay EOF") } }) @@ -306,18 +306,18 @@ func client(config *clientConfig) { time.Duration(udpr.Timeout)*time.Second, func(addr net.Addr) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Debug("UDP relay request") }, func(addr net.Addr, err error) { if err != relay.ErrTimeout { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Info("UDP relay error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), }).Debug("UDP relay session closed") } }) @@ -336,21 +336,21 @@ func client(config *clientConfig) { time.Duration(config.TCPTProxy.Timeout)*time.Second, func(addr, reqAddr net.Addr) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Debug("TCP TProxy request") }, func(addr, reqAddr net.Addr, err error) { if err != io.EOF { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Info("TCP TProxy error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Debug("TCP TProxy EOF") } }) @@ -368,21 +368,21 @@ func client(config *clientConfig) { time.Duration(config.UDPTProxy.Timeout)*time.Second, func(addr, reqAddr net.Addr) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Debug("UDP TProxy request") }, func(addr, reqAddr net.Addr, err error) { if !errors.Is(err, os.ErrDeadlineExceeded) { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Info("UDP TProxy error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Debug("UDP TProxy session closed") } }) @@ -400,21 +400,21 @@ func client(config *clientConfig) { time.Duration(config.TCPRedirect.Timeout)*time.Second, func(addr, reqAddr net.Addr) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Debug("TCP Redirect request") }, func(addr, reqAddr net.Addr, err error) { if err != io.EOF { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Info("TCP Redirect error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr.String(), + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr.String()), }).Debug("TCP Redirect EOF") } }) diff --git a/cmd/client_gpl.go b/cmd/client_gpl.go index 5b633ff..2b4b182 100644 --- a/cmd/client_gpl.go +++ b/cmd/client_gpl.go @@ -42,32 +42,32 @@ func startTUN(config *clientConfig, client *core.Client, errChan chan error) { } tunServer.RequestFunc = func(addr net.Addr, reqAddr string) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Debugf("TUN %s request", strings.ToUpper(addr.Network())) } tunServer.ErrorFunc = func(addr net.Addr, reqAddr string, err error) { if err != nil { if err == io.EOF { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Debugf("TUN %s EOF", strings.ToUpper(addr.Network())) } else if err == core.ErrClosed && strings.HasPrefix(addr.Network(), "udp") { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Debugf("TUN %s closed for timeout", strings.ToUpper(addr.Network())) } else if nErr, ok := err.(net.Error); ok && nErr.Timeout() && strings.HasPrefix(addr.Network(), "tcp") { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Debugf("TUN %s closed for timeout", strings.ToUpper(addr.Network())) } else { logrus.WithFields(logrus.Fields{ "error": err, - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Infof("TUN %s error", strings.ToUpper(addr.Network())) } } diff --git a/cmd/ipmasker.go b/cmd/ipmasker.go new file mode 100644 index 0000000..97a1d13 --- /dev/null +++ b/cmd/ipmasker.go @@ -0,0 +1,43 @@ +package main + +import ( + "net" +) + +type ipMasker struct { + IPv4Mask net.IPMask + IPv6Mask net.IPMask +} + +// Mask masks an address with the configured CIDR. +// addr can be "host:port" or just host. +func (m *ipMasker) Mask(addr string) string { + if m.IPv4Mask == nil && m.IPv6Mask == nil { + return addr + } + + host, port, err := net.SplitHostPort(addr) + if err != nil { + // just host + host, port = addr, "" + } + ip := net.ParseIP(host) + if ip == nil { + // not an IP address, return as is + return addr + } + if ip4 := ip.To4(); ip4 != nil && m.IPv4Mask != nil { + // IPv4 + host = ip4.Mask(m.IPv4Mask).String() + } else if ip6 := ip.To16(); ip6 != nil && m.IPv6Mask != nil { + // IPv6 + host = ip6.Mask(m.IPv6Mask).String() + } + if port != "" { + return net.JoinHostPort(host, port) + } else { + return host + } +} + +var defaultIPMasker = &ipMasker{} diff --git a/cmd/main.go b/cmd/main.go index abc3e4f..ab0c0c6 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "math/rand" + "net" "os" "regexp" "strings" @@ -71,6 +72,16 @@ var rootCmd = &cobra.Command{ os.Exit(0) } + // ip mask config + v4m := viper.GetUint("log-ipv4-mask") + if v4m > 0 && v4m < 32 { + defaultIPMasker.IPv4Mask = net.CIDRMask(int(v4m), 32) + } + v6m := viper.GetUint("log-ipv6-mask") + if v6m > 0 && v6m < 128 { + defaultIPMasker.IPv6Mask = net.CIDRMask(int(v6m), 128) + } + // check update if !viper.GetBool("no-check") { go checkUpdate() @@ -158,7 +169,9 @@ func init() { rootCmd.PersistentFlags().String("mmdb-url", "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb", "mmdb download url") rootCmd.PersistentFlags().String("log-level", "debug", "log level") rootCmd.PersistentFlags().String("log-timestamp", time.RFC3339, "log timestamp format") - rootCmd.PersistentFlags().String("log-format", "txt", "log output format(txt/json)") + rootCmd.PersistentFlags().String("log-format", "txt", "log output format (txt/json)") + rootCmd.PersistentFlags().Uint("log-ipv4-mask", 0, "mask IPv4 addresses in log using a CIDR mask") + rootCmd.PersistentFlags().Uint("log-ipv6-mask", 0, "mask IPv6 addresses in log using a CIDR mask") rootCmd.PersistentFlags().Bool("no-check", false, "disable update check") rootCmd.PersistentFlags().Bool("license", false, "show license and exit") @@ -171,6 +184,8 @@ func init() { _ = viper.BindPFlag("log-level", rootCmd.PersistentFlags().Lookup("log-level")) _ = viper.BindPFlag("log-timestamp", rootCmd.PersistentFlags().Lookup("log-timestamp")) _ = viper.BindPFlag("log-format", rootCmd.PersistentFlags().Lookup("log-format")) + _ = viper.BindPFlag("log-ipv4-mask", rootCmd.PersistentFlags().Lookup("log-ipv4-mask")) + _ = viper.BindPFlag("log-ipv6-mask", rootCmd.PersistentFlags().Lookup("log-ipv6-mask")) _ = viper.BindPFlag("no-check", rootCmd.PersistentFlags().Lookup("no-check")) _ = viper.BindPFlag("license", rootCmd.PersistentFlags().Lookup("license")) @@ -180,6 +195,8 @@ func init() { _ = viper.BindEnv("log-level", "HYSTERIA_LOG_LEVEL", "LOGGING_LEVEL") _ = viper.BindEnv("log-timestamp", "HYSTERIA_LOG_TIMESTAMP", "LOGGING_TIMESTAMP_FORMAT") _ = viper.BindEnv("log-format", "HYSTERIA_LOG_FORMAT", "LOGGING_FORMATTER") + _ = viper.BindEnv("log-ipv4-mask", "HYSTERIA_LOG_IPV4_MASK", "LOGGING_IPV4_MASK") + _ = viper.BindEnv("log-ipv6-mask", "HYSTERIA_LOG_IPV6_MASK", "LOGGING_IPV6_MASK") _ = viper.BindEnv("no-check", "HYSTERIA_NO_CHECK", "HYSTERIA_NO_CHECK_UPDATE") viper.AutomaticEnv() } diff --git a/cmd/server.go b/cmd/server.go index 3a83a3e..7e79115 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -131,12 +131,12 @@ func server(config *serverConfig) { ok, msg := authFunc(addr, auth, sSend, sRecv) if !ok { logrus.WithFields(logrus.Fields{ - "src": addr, + "src": defaultIPMasker.Mask(addr.String()), "msg": msg, }).Info("Authentication failed, client rejected") } else { logrus.WithFields(logrus.Fields{ - "src": addr, + "src": defaultIPMasker.Mask(addr.String()), }).Info("Client connected") } return ok, msg @@ -287,15 +287,15 @@ func externalAuthFunc(rawMsg json5.RawMessage) (core.ConnectFunc, error) { func disconnectFunc(addr net.Addr, auth []byte, err error) { logrus.WithFields(logrus.Fields{ - "src": addr, + "src": defaultIPMasker.Mask(addr.String()), "error": err, }).Info("Client disconnected") } func tcpRequestFunc(addr net.Addr, auth []byte, reqAddr string, action acl.Action, arg string) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), "action": actionToString(action, arg), }).Debug("TCP request") } @@ -303,21 +303,21 @@ func tcpRequestFunc(addr net.Addr, auth []byte, reqAddr string, action acl.Actio func tcpErrorFunc(addr net.Addr, auth []byte, reqAddr string, err error) { if err != io.EOF { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), "error": err, }).Info("TCP error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), - "dst": reqAddr, + "src": defaultIPMasker.Mask(addr.String()), + "dst": defaultIPMasker.Mask(reqAddr), }).Debug("TCP EOF") } } func udpRequestFunc(addr net.Addr, auth []byte, sessionID uint32) { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), "session": sessionID, }).Debug("UDP request") } @@ -325,13 +325,13 @@ func udpRequestFunc(addr net.Addr, auth []byte, sessionID uint32) { func udpErrorFunc(addr net.Addr, auth []byte, sessionID uint32, err error) { if err != io.EOF { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), "session": sessionID, "error": err, }).Info("UDP error") } else { logrus.WithFields(logrus.Fields{ - "src": addr.String(), + "src": defaultIPMasker.Mask(addr.String()), "session": sessionID, }).Debug("UDP EOF") }