mirror of
https://github.com/cmz0228/hysteria-dev.git
synced 2025-06-08 13:29:53 +00:00
Merge pull request #20 from tobyxdd/wip-logrus
Change the logging system to Logrus
This commit is contained in:
commit
7f45cb2ae4
1
build_windows.bat
Normal file
1
build_windows.bat
Normal file
@ -0,0 +1 @@
|
||||
go build -ldflags="-w -s" ./cmd
|
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@ -20,6 +21,14 @@ var modeMap = map[string]func(args []string){
|
||||
"proxy client": proxyClient,
|
||||
}
|
||||
|
||||
func init() {
|
||||
logrus.SetOutput(os.Stdout)
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetFormatter(&logrus.TextFormatter{
|
||||
ForceColors: true,
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) == 2 && strings.ToLower(strings.TrimSpace(os.Args[1])) == "version" {
|
||||
// Print version and quit
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"crypto/x509"
|
||||
"github.com/lucas-clemente/quic-go"
|
||||
"github.com/lucas-clemente/quic-go/congestion"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/tobyxdd/hysteria/pkg/acl"
|
||||
hyCongestion "github.com/tobyxdd/hysteria/pkg/congestion"
|
||||
"github.com/tobyxdd/hysteria/pkg/core"
|
||||
@ -12,7 +13,6 @@ import (
|
||||
"github.com/tobyxdd/hysteria/pkg/obfs"
|
||||
"github.com/tobyxdd/hysteria/pkg/socks5"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
@ -22,12 +22,12 @@ func proxyClient(args []string) {
|
||||
var config proxyClientConfig
|
||||
err := loadConfig(&config, args)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load configuration:", err)
|
||||
logrus.WithField("error", err).Fatal("Unable to load configuration")
|
||||
}
|
||||
if err := config.Check(); err != nil {
|
||||
log.Fatalln("Configuration error:", err)
|
||||
logrus.WithField("error", err).Fatal("Configuration error")
|
||||
}
|
||||
log.Printf("Configuration loaded: %+v\n", config)
|
||||
logrus.WithField("config", config.String()).Info("Configuration loaded")
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: config.Insecure,
|
||||
@ -38,11 +38,16 @@ func proxyClient(args []string) {
|
||||
if len(config.CustomCAFile) > 0 {
|
||||
bs, err := ioutil.ReadFile(config.CustomCAFile)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load CA file:", err)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"file": config.CustomCAFile,
|
||||
}).Fatal("Unable to load CA file")
|
||||
}
|
||||
cp := x509.NewCertPool()
|
||||
if !cp.AppendCertsFromPEM(bs) {
|
||||
log.Fatalln("Unable to parse CA file", config.CustomCAFile)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"file": config.CustomCAFile,
|
||||
}).Fatal("Unable to parse CA file")
|
||||
}
|
||||
tlsConfig.RootCAs = cp
|
||||
}
|
||||
@ -68,7 +73,10 @@ func proxyClient(args []string) {
|
||||
if len(config.ACLFile) > 0 {
|
||||
aclEngine, err = acl.LoadFromFile(config.ACLFile)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to parse ACL:", err)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"file": config.ACLFile,
|
||||
}).Fatal("Unable to parse ACL")
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,10 +86,10 @@ func proxyClient(args []string) {
|
||||
return hyCongestion.NewBrutalSender(congestion.ByteCount(refBPS))
|
||||
}, obfuscator)
|
||||
if err != nil {
|
||||
log.Fatalln("Client initialization failed:", err)
|
||||
logrus.WithField("error", err).Fatal("Client initialization failed")
|
||||
}
|
||||
defer client.Close()
|
||||
log.Println("Connected to", config.ServerAddr)
|
||||
logrus.WithField("addr", config.ServerAddr).Info("Connected")
|
||||
|
||||
errChan := make(chan error)
|
||||
|
||||
@ -90,27 +98,48 @@ func proxyClient(args []string) {
|
||||
socks5server, err := socks5.NewServer(client, config.SOCKS5Addr, nil, config.SOCKS5Timeout, aclEngine,
|
||||
config.SOCKS5DisableUDP,
|
||||
func(addr net.Addr, reqAddr string, action acl.Action, arg string) {
|
||||
log.Printf("[TCP] [%s] %s <-> %s\n", actionToString(action, arg), addr.String(), reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": actionToString(action, arg),
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("New SOCKS5 TCP request")
|
||||
},
|
||||
func(addr net.Addr, reqAddr string, err error) {
|
||||
log.Printf("Closed [TCP] %s <-> %s: %s\n", addr.String(), reqAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("SOCKS5 TCP request closed")
|
||||
},
|
||||
func(addr net.Addr) {
|
||||
log.Printf("[UDP] Associate %s\n", addr.String())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"src": addr.String(),
|
||||
}).Debug("New SOCKS5 UDP associate request")
|
||||
},
|
||||
func(addr net.Addr, err error) {
|
||||
log.Printf("Closed [UDP] Associate %s: %s\n", addr.String(), err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"src": addr.String(),
|
||||
}).Debug("SOCKS5 UDP associate request closed")
|
||||
},
|
||||
func(addr net.Addr, reqAddr string, action acl.Action, arg string) {
|
||||
log.Printf("[UDP] [%s] %s <-> %s\n", actionToString(action, arg), addr.String(), reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": actionToString(action, arg),
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("New SOCKS5 UDP tunnel")
|
||||
},
|
||||
func(addr net.Addr, reqAddr string, err error) {
|
||||
log.Printf("Closed [UDP] %s <-> %s: %s\n", addr.String(), reqAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("SOCKS5 UDP tunnel closed")
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalln("SOCKS5 server initialization failed:", err)
|
||||
logrus.WithField("error", err).Fatal("SOCKS5 server initialization failed")
|
||||
}
|
||||
log.Println("SOCKS5 server up and running on", config.SOCKS5Addr)
|
||||
logrus.WithField("addr", config.SOCKS5Addr).Info("SOCKS5 server up and running")
|
||||
errChan <- socks5server.ListenAndServe()
|
||||
}()
|
||||
}
|
||||
@ -119,18 +148,21 @@ func proxyClient(args []string) {
|
||||
go func() {
|
||||
proxy, err := hyHTTP.NewProxyHTTPServer(client, time.Duration(config.HTTPTimeout)*time.Second, aclEngine,
|
||||
func(reqAddr string, action acl.Action, arg string) {
|
||||
log.Printf("[HTTP] [%s] %s\n", actionToString(action, arg), reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": actionToString(action, arg),
|
||||
"dst": reqAddr,
|
||||
}).Debug("New HTTP request")
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalln("HTTP server initialization failed:", err)
|
||||
logrus.WithField("error", err).Fatal("HTTP server initialization failed")
|
||||
}
|
||||
log.Println("HTTP server up and running on", config.HTTPAddr)
|
||||
logrus.WithField("addr", config.HTTPAddr).Info("HTTP server up and running")
|
||||
errChan <- http.ListenAndServe(config.HTTPAddr, proxy)
|
||||
}()
|
||||
}
|
||||
|
||||
log.Fatalln(<-errChan)
|
||||
|
||||
err = <-errChan
|
||||
logrus.WithField("error", err).Fatal("Client shutdown")
|
||||
}
|
||||
|
||||
func actionToString(action acl.Action, arg string) string {
|
||||
|
@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const proxyTLSProtocol = "hysteria-proxy"
|
||||
|
||||
@ -46,6 +49,10 @@ func (c *proxyClientConfig) Check() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *proxyClientConfig) String() string {
|
||||
return fmt.Sprintf("%+v", *c)
|
||||
}
|
||||
|
||||
type proxyServerConfig struct {
|
||||
ListenAddr string `json:"listen" desc:"Server listen address"`
|
||||
DisableUDP bool `json:"disable_udp" desc:"Disable UDP support"`
|
||||
@ -80,3 +87,7 @@ func (c *proxyServerConfig) Check() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *proxyServerConfig) String() string {
|
||||
return fmt.Sprintf("%+v", *c)
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ import (
|
||||
"crypto/tls"
|
||||
"github.com/lucas-clemente/quic-go"
|
||||
"github.com/lucas-clemente/quic-go/congestion"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/tobyxdd/hysteria/pkg/acl"
|
||||
hyCongestion "github.com/tobyxdd/hysteria/pkg/congestion"
|
||||
"github.com/tobyxdd/hysteria/pkg/core"
|
||||
"github.com/tobyxdd/hysteria/pkg/obfs"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
@ -20,16 +20,20 @@ func proxyServer(args []string) {
|
||||
var config proxyServerConfig
|
||||
err := loadConfig(&config, args)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load configuration:", err)
|
||||
logrus.WithField("error", err).Fatal("Unable to load configuration")
|
||||
}
|
||||
if err := config.Check(); err != nil {
|
||||
log.Fatalln("Configuration error:", err.Error())
|
||||
logrus.WithField("error", err).Fatal("Configuration error")
|
||||
}
|
||||
log.Printf("Configuration loaded: %+v\n", config)
|
||||
logrus.WithField("config", config.String()).Info("Configuration loaded")
|
||||
// Load cert
|
||||
cert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load the certificate:", err)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"cert": config.CertFile,
|
||||
"key": config.KeyFile,
|
||||
}).Fatal("Unable to load the certificate")
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
@ -54,7 +58,7 @@ func proxyServer(args []string) {
|
||||
}
|
||||
|
||||
if len(config.AuthFile) == 0 {
|
||||
log.Println("WARNING: No authentication configured. This server can be used by anyone!")
|
||||
logrus.Warn("No authentication configured, this server can be used by anyone")
|
||||
}
|
||||
|
||||
var obfuscator core.Obfuscator
|
||||
@ -66,7 +70,10 @@ func proxyServer(args []string) {
|
||||
if len(config.ACLFile) > 0 {
|
||||
aclEngine, err = acl.LoadFromFile(config.ACLFile)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to parse ACL:", err)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"file": config.ACLFile,
|
||||
}).Fatal("Unable to parse ACL")
|
||||
}
|
||||
aclEngine.DefaultAction = acl.ActionDirect
|
||||
}
|
||||
@ -79,28 +86,49 @@ func proxyServer(args []string) {
|
||||
obfuscator,
|
||||
func(addr net.Addr, username string, password string, sSend uint64, sRecv uint64) (core.AuthResult, string) {
|
||||
if len(config.AuthFile) == 0 {
|
||||
log.Printf("%s (%s) connected, negotiated speed (Mbps): Up %d / Down %d\n",
|
||||
addr.String(), username, sSend/mbpsToBps, sRecv/mbpsToBps)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"addr": addr.String(),
|
||||
"username": username,
|
||||
"up": sSend / mbpsToBps,
|
||||
"down": sRecv / mbpsToBps,
|
||||
}).Info("Client connected")
|
||||
return core.AuthSuccess, ""
|
||||
} else {
|
||||
// Need auth
|
||||
ok, err := checkAuth(config.AuthFile, username, password)
|
||||
if err != nil {
|
||||
log.Printf("%s (%s) auth error: %s\n", addr.String(), username, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err.Error(),
|
||||
"addr": addr.String(),
|
||||
"username": username,
|
||||
}).Error("Client authentication error")
|
||||
return core.AuthInternalError, "Server auth error"
|
||||
}
|
||||
if ok {
|
||||
log.Printf("%s (%s) authenticated, negotiated speed (Mbps): Up %d / Down %d\n",
|
||||
addr.String(), username, sSend/mbpsToBps, sRecv/mbpsToBps)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"addr": addr.String(),
|
||||
"username": username,
|
||||
"up": sSend / mbpsToBps,
|
||||
"down": sRecv / mbpsToBps,
|
||||
}).Info("Client authenticated")
|
||||
return core.AuthSuccess, ""
|
||||
} else {
|
||||
log.Printf("%s (%s) auth failed (invalid credential)\n", addr.String(), username)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"addr": addr.String(),
|
||||
"username": username,
|
||||
"up": sSend / mbpsToBps,
|
||||
"down": sRecv / mbpsToBps,
|
||||
}).Info("Client rejected due to invalid credential")
|
||||
return core.AuthInvalidCred, "Invalid credential"
|
||||
}
|
||||
}
|
||||
},
|
||||
func(addr net.Addr, username string, err error) {
|
||||
log.Printf("%s (%s) disconnected: %s\n", addr.String(), username, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err.Error(),
|
||||
"addr": addr.String(),
|
||||
"username": username,
|
||||
}).Info("Client disconnected")
|
||||
},
|
||||
func(addr net.Addr, username string, id int, packet bool, reqAddr string) (core.ConnectResult, string, io.ReadWriteCloser) {
|
||||
if packet && config.DisableUDP {
|
||||
@ -123,19 +151,35 @@ func proxyServer(args []string) {
|
||||
case acl.ActionDirect, acl.ActionProxy: // Treat proxy as direct on server side
|
||||
if !packet {
|
||||
// TCP
|
||||
log.Printf("%s (%s): [TCP] [Direct] %s\n", addr.String(), username, reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": "direct",
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("New TCP request")
|
||||
conn, err := net.DialTimeout("tcp", reqAddr, dialTimeout)
|
||||
if err != nil {
|
||||
log.Printf("TCP error %s: %s\n", reqAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"dst": reqAddr,
|
||||
}).Error("TCP error")
|
||||
return core.ConnFailed, err.Error(), nil
|
||||
}
|
||||
return core.ConnSuccess, "", conn
|
||||
} else {
|
||||
// UDP
|
||||
log.Printf("%s (%s): [UDP] [Direct] %s\n", addr.String(), username, reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": "direct",
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("New UDP request")
|
||||
conn, err := net.Dial("udp", reqAddr)
|
||||
if err != nil {
|
||||
log.Printf("UDP error %s: %s\n", reqAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"dst": reqAddr,
|
||||
}).Error("UDP error")
|
||||
return core.ConnFailed, err.Error(), nil
|
||||
}
|
||||
return core.ConnSuccess, "", conn
|
||||
@ -143,30 +187,58 @@ func proxyServer(args []string) {
|
||||
case acl.ActionBlock:
|
||||
if !packet {
|
||||
// TCP
|
||||
log.Printf("%s (%s): [TCP] [Block] %s\n", addr.String(), username, reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": "block",
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("New TCP request")
|
||||
return core.ConnBlocked, "blocked by ACL", nil
|
||||
} else {
|
||||
// UDP
|
||||
log.Printf("%s (%s): [UDP] [Block] %s\n", addr.String(), username, reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": "block",
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("New UDP request")
|
||||
return core.ConnBlocked, "blocked by ACL", nil
|
||||
}
|
||||
case acl.ActionHijack:
|
||||
hijackAddr := net.JoinHostPort(arg, port)
|
||||
if !packet {
|
||||
// TCP
|
||||
log.Printf("%s (%s): [TCP] [Hijack to %s] %s\n", addr.String(), username, arg, reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": "hijack",
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
"rdst": arg,
|
||||
}).Debug("New TCP request")
|
||||
conn, err := net.DialTimeout("tcp", hijackAddr, dialTimeout)
|
||||
if err != nil {
|
||||
log.Printf("TCP error %s: %s\n", hijackAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"dst": hijackAddr,
|
||||
}).Error("TCP error")
|
||||
return core.ConnFailed, err.Error(), nil
|
||||
}
|
||||
return core.ConnSuccess, "", conn
|
||||
} else {
|
||||
// UDP
|
||||
log.Printf("%s (%s): [UDP] [Hijack to %s] %s\n", addr.String(), username, arg, reqAddr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"action": "hijack",
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
"rdst": arg,
|
||||
}).Debug("New UDP request")
|
||||
conn, err := net.Dial("udp", hijackAddr)
|
||||
if err != nil {
|
||||
log.Printf("UDP error %s: %s\n", hijackAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"dst": hijackAddr,
|
||||
}).Error("UDP error")
|
||||
return core.ConnFailed, err.Error(), nil
|
||||
}
|
||||
return core.ConnSuccess, "", conn
|
||||
@ -177,19 +249,30 @@ func proxyServer(args []string) {
|
||||
},
|
||||
func(addr net.Addr, username string, id int, packet bool, reqAddr string, err error) {
|
||||
if !packet {
|
||||
log.Printf("%s (%s): closed [TCP] %s: %s\n", addr.String(), username, reqAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("TCP request closed")
|
||||
} else {
|
||||
log.Printf("%s (%s): closed [UDP] %s: %s\n", addr.String(), username, reqAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"dst": reqAddr,
|
||||
}).Debug("UDP request closed")
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalln("Server initialization failed:", err)
|
||||
logrus.WithField("error", err).Fatal("Server initialization failed")
|
||||
}
|
||||
defer server.Close()
|
||||
log.Println("Up and running on", config.ListenAddr)
|
||||
logrus.WithField("addr", config.ListenAddr).Info("Server up and running")
|
||||
|
||||
log.Fatalln(server.Serve())
|
||||
err = server.Serve()
|
||||
logrus.WithField("error", err).Fatal("Server shutdown")
|
||||
}
|
||||
|
||||
func checkAuth(authFile, username, password string) (bool, error) {
|
||||
|
@ -5,12 +5,12 @@ import (
|
||||
"crypto/x509"
|
||||
"github.com/lucas-clemente/quic-go"
|
||||
"github.com/lucas-clemente/quic-go/congestion"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/tobyxdd/hysteria/internal/utils"
|
||||
hyCongestion "github.com/tobyxdd/hysteria/pkg/congestion"
|
||||
"github.com/tobyxdd/hysteria/pkg/core"
|
||||
"github.com/tobyxdd/hysteria/pkg/obfs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os/user"
|
||||
)
|
||||
@ -19,10 +19,10 @@ func relayClient(args []string) {
|
||||
var config relayClientConfig
|
||||
err := loadConfig(&config, args)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load configuration:", err)
|
||||
logrus.WithField("error", err).Fatal("Unable to load configuration")
|
||||
}
|
||||
if err := config.Check(); err != nil {
|
||||
log.Fatalln("Configuration error:", err)
|
||||
logrus.WithField("error", err).Fatal("Configuration error")
|
||||
}
|
||||
if len(config.Name) == 0 {
|
||||
usr, err := user.Current()
|
||||
@ -30,7 +30,7 @@ func relayClient(args []string) {
|
||||
config.Name = usr.Name
|
||||
}
|
||||
}
|
||||
log.Printf("Configuration loaded: %+v\n", config)
|
||||
logrus.WithField("config", config.String()).Info("Configuration loaded")
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: config.Insecure,
|
||||
@ -41,11 +41,16 @@ func relayClient(args []string) {
|
||||
if len(config.CustomCAFile) > 0 {
|
||||
bs, err := ioutil.ReadFile(config.CustomCAFile)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load CA file:", err)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"file": config.CustomCAFile,
|
||||
}).Fatal("Unable to load CA file")
|
||||
}
|
||||
cp := x509.NewCertPool()
|
||||
if !cp.AppendCertsFromPEM(bs) {
|
||||
log.Fatalln("Unable to parse CA file", config.CustomCAFile)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"file": config.CustomCAFile,
|
||||
}).Fatal("Unable to parse CA file")
|
||||
}
|
||||
tlsConfig.RootCAs = cp
|
||||
}
|
||||
@ -73,33 +78,36 @@ func relayClient(args []string) {
|
||||
return hyCongestion.NewBrutalSender(congestion.ByteCount(refBPS))
|
||||
}, obfuscator)
|
||||
if err != nil {
|
||||
log.Fatalln("Client initialization failed:", err)
|
||||
logrus.WithField("error", err).Fatal("Client initialization failed")
|
||||
}
|
||||
defer client.Close()
|
||||
log.Println("Connected to", config.ServerAddr)
|
||||
logrus.WithField("addr", config.ServerAddr).Info("Connected")
|
||||
|
||||
listener, err := net.Listen("tcp", config.ListenAddr)
|
||||
if err != nil {
|
||||
log.Fatalln("TCP listen failed:", err)
|
||||
logrus.WithField("error", err).Fatal("TCP listen failed")
|
||||
}
|
||||
defer listener.Close()
|
||||
log.Println("TCP listening on", listener.Addr().String())
|
||||
logrus.WithField("addr", listener.Addr().String()).Info("TCP server listening")
|
||||
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
log.Fatalln("TCP accept failed:", err)
|
||||
logrus.WithField("error", err).Fatal("TCP accept failed")
|
||||
}
|
||||
go relayClientHandleConn(conn, client)
|
||||
}
|
||||
}
|
||||
|
||||
func relayClientHandleConn(conn net.Conn, client core.Client) {
|
||||
log.Println("New connection", conn.RemoteAddr().String())
|
||||
logrus.WithField("src", conn.RemoteAddr().String()).Debug("New connection")
|
||||
var closeErr error
|
||||
defer func() {
|
||||
_ = conn.Close()
|
||||
log.Println("Connection", conn.RemoteAddr().String(), "closed", closeErr)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": closeErr,
|
||||
"src": conn.RemoteAddr().String(),
|
||||
}).Debug("Connection closed")
|
||||
}()
|
||||
rwc, err := client.Dial(false, "")
|
||||
if err != nil {
|
||||
|
@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const relayTLSProtocol = "hysteria-relay"
|
||||
|
||||
@ -34,6 +37,10 @@ func (c *relayClientConfig) Check() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *relayClientConfig) String() string {
|
||||
return fmt.Sprintf("%+v", *c)
|
||||
}
|
||||
|
||||
type relayServerConfig struct {
|
||||
ListenAddr string `json:"listen" desc:"Server listen address"`
|
||||
RemoteAddr string `json:"remote" desc:"Remote relay address"`
|
||||
@ -69,3 +76,7 @@ func (c *relayServerConfig) Check() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *relayServerConfig) String() string {
|
||||
return fmt.Sprintf("%+v", *c)
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ import (
|
||||
"crypto/tls"
|
||||
"github.com/lucas-clemente/quic-go"
|
||||
"github.com/lucas-clemente/quic-go/congestion"
|
||||
"github.com/sirupsen/logrus"
|
||||
hyCongestion "github.com/tobyxdd/hysteria/pkg/congestion"
|
||||
"github.com/tobyxdd/hysteria/pkg/core"
|
||||
"github.com/tobyxdd/hysteria/pkg/obfs"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
)
|
||||
|
||||
@ -16,16 +16,20 @@ func relayServer(args []string) {
|
||||
var config relayServerConfig
|
||||
err := loadConfig(&config, args)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load configuration:", err)
|
||||
logrus.WithField("error", err).Fatal("Unable to load configuration")
|
||||
}
|
||||
if err := config.Check(); err != nil {
|
||||
log.Fatalln("Configuration error:", err.Error())
|
||||
logrus.WithField("error", err).Fatal("Configuration error")
|
||||
}
|
||||
log.Printf("Configuration loaded: %+v\n", config)
|
||||
logrus.WithField("config", config.String()).Info("Configuration loaded")
|
||||
// Load cert
|
||||
cert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to load the certificate:", err)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"cert": config.CertFile,
|
||||
"key": config.KeyFile,
|
||||
}).Fatal("Unable to load the certificate")
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
@ -62,34 +66,55 @@ func relayServer(args []string) {
|
||||
obfuscator,
|
||||
func(addr net.Addr, username string, password string, sSend uint64, sRecv uint64) (core.AuthResult, string) {
|
||||
// No authentication logic in relay, just log username and speed
|
||||
log.Printf("%s (%s) connected, negotiated speed (Mbps): Up %d / Down %d\n",
|
||||
addr.String(), username, sSend/mbpsToBps, sRecv/mbpsToBps)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"addr": addr.String(),
|
||||
"username": username,
|
||||
"up": sSend / mbpsToBps,
|
||||
"down": sRecv / mbpsToBps,
|
||||
}).Info("Client connected")
|
||||
return core.AuthSuccess, ""
|
||||
},
|
||||
func(addr net.Addr, username string, err error) {
|
||||
log.Printf("%s (%s) disconnected: %s\n", addr.String(), username, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err.Error(),
|
||||
"addr": addr.String(),
|
||||
"username": username,
|
||||
}).Info("Client disconnected")
|
||||
},
|
||||
func(addr net.Addr, username string, id int, packet bool, reqAddr string) (core.ConnectResult, string, io.ReadWriteCloser) {
|
||||
log.Printf("%s (%s): new stream ID %d\n", addr.String(), username, id)
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"id": id,
|
||||
}).Debug("New stream")
|
||||
if packet {
|
||||
return core.ConnBlocked, "unsupported", nil
|
||||
}
|
||||
conn, err := net.DialTimeout("tcp", config.RemoteAddr, dialTimeout)
|
||||
if err != nil {
|
||||
log.Printf("TCP error %s: %s\n", config.RemoteAddr, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"dst": config.RemoteAddr,
|
||||
}).Error("TCP error")
|
||||
return core.ConnFailed, err.Error(), nil
|
||||
}
|
||||
return core.ConnSuccess, "", conn
|
||||
},
|
||||
func(addr net.Addr, username string, id int, packet bool, reqAddr string, err error) {
|
||||
log.Printf("%s (%s): closed stream ID %d: %s\n", addr.String(), username, id, err.Error())
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
"username": username,
|
||||
"src": addr.String(),
|
||||
"id": id,
|
||||
}).Debug("Stream closed")
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalln("Server initialization failed:", err)
|
||||
logrus.WithField("error", err).Fatal("Server initialization failed")
|
||||
}
|
||||
defer server.Close()
|
||||
log.Println("Up and running on", config.ListenAddr)
|
||||
logrus.WithField("addr", config.ListenAddr).Info("Server up and running")
|
||||
|
||||
log.Fatalln(server.Serve())
|
||||
err = server.Serve()
|
||||
logrus.WithField("error", err).Fatal("Server shutdown")
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/lucas-clemente/quic-go v0.16.1
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/txthinking/runnergroup v0.0.0-20200327135940-540a793bb997 // indirect
|
||||
github.com/txthinking/socks5 v0.0.0-20200327133705-caf148ab5e9d
|
||||
github.com/txthinking/x v0.0.0-20200330144832-5ad2416896a9 // indirect
|
||||
|
5
go.sum
5
go.sum
@ -70,6 +70,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
@ -127,6 +129,8 @@ github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1l
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
@ -184,6 +188,7 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
Loading…
x
Reference in New Issue
Block a user