From 59767dfaff9951f8732f9a2a700f17f7349eb88d Mon Sep 17 00:00:00 2001 From: Toby Date: Thu, 2 Jul 2020 17:24:25 -0700 Subject: [PATCH] Add disable UDP option for both proxy client & server --- README.md | 2 ++ README.zh.md | 2 ++ cmd/proxy_client.go | 6 ++++-- cmd/proxy_config.go | 2 ++ cmd/proxy_server.go | 3 +++ cmd/relay_client.go | 5 +++-- pkg/socks5/server.go | 21 ++++++++++++++------- 7 files changed, 30 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 765537e..bd58416 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ The command line program supports loading configurations from both JSON files an | Description | JSON config field | CLI argument | | --- | --- | --- | | Server listen address | listen | -listen | +| Disable UDP support | disable_udp | -disable-udp | | Access control list | acl | -acl | | TLS certificate file | cert | -cert | | TLS key file | key | -key | @@ -86,6 +87,7 @@ The command line program supports loading configurations from both JSON files an | --- | --- | --- | | SOCKS5 listen address | socks5_addr | -socks5-addr | | SOCKS5 connection timeout in seconds | socks5_timeout | -socks5-timeout | +| Disable SOCKS5 UDP support | socks5_disable_udp | -socks5-disable-udp | | HTTP listen address | http_addr | -http-addr | | HTTP connection timeout in seconds | http_timeout | -http-timeout | | Access control list | acl | -acl | diff --git a/README.zh.md b/README.zh.md index 7f29f5a..b0af1e6 100644 --- a/README.zh.md +++ b/README.zh.md @@ -67,6 +67,7 @@ Hysteria 是专门针对恶劣网络环境(常见于在中国访问海外服 | 描述 | JSON 字段 | 命令行参数 | | --- | --- | --- | | 服务端监听地址 | listen | -listen | +| 禁用 UDP 支持 | disable_udp | -disable-udp | | ACL 规则文件 | acl | -acl | | TLS 证书文件 | cert | -cert | | TLS 密钥文件 | key | -key | @@ -84,6 +85,7 @@ Hysteria 是专门针对恶劣网络环境(常见于在中国访问海外服 | --- | --- | --- | | SOCKS5 监听地址 | socks5_addr | -socks5-addr | | SOCKS5 超时时间(秒) | socks5_timeout | -socks5-timeout | +| 禁用 SOCKS5 UDP 支持 | socks5_disable_udp | -socks5-disable-udp | | HTTP 监听地址 | http_addr | -http-addr | | HTTP 超时时间(秒) | http_timeout | -http-timeout | | ACL 规则文件 | acl | -acl | diff --git a/cmd/proxy_client.go b/cmd/proxy_client.go index 0c98ef0..cc676d5 100644 --- a/cmd/proxy_client.go +++ b/cmd/proxy_client.go @@ -30,8 +30,9 @@ func proxyClient(args []string) { log.Printf("Configuration loaded: %+v\n", config) tlsConfig := &tls.Config{ - NextProtos: []string{proxyTLSProtocol}, - MinVersion: tls.VersionTLS13, + InsecureSkipVerify: config.Insecure, + NextProtos: []string{proxyTLSProtocol}, + MinVersion: tls.VersionTLS13, } // Load CA if len(config.CustomCAFile) > 0 { @@ -87,6 +88,7 @@ func proxyClient(args []string) { if len(config.SOCKS5Addr) > 0 { go func() { 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) }, diff --git a/cmd/proxy_config.go b/cmd/proxy_config.go index 2bb230f..033ab33 100644 --- a/cmd/proxy_config.go +++ b/cmd/proxy_config.go @@ -7,6 +7,7 @@ const proxyTLSProtocol = "hysteria-proxy" type proxyClientConfig struct { SOCKS5Addr string `json:"socks5_addr" desc:"SOCKS5 listen address"` SOCKS5Timeout int `json:"socks5_timeout" desc:"SOCKS5 connection timeout in seconds"` + SOCKS5DisableUDP bool `json:"socks5_disable_udp" desc:"Disable SOCKS5 UDP support"` HTTPAddr string `json:"http_addr" desc:"HTTP listen address"` HTTPTimeout int `json:"http_timeout" desc:"HTTP connection timeout in seconds"` ACLFile string `json:"acl" desc:"Access control list"` @@ -47,6 +48,7 @@ func (c *proxyClientConfig) Check() error { type proxyServerConfig struct { ListenAddr string `json:"listen" desc:"Server listen address"` + DisableUDP bool `json:"disable_udp" desc:"Disable UDP support"` ACLFile string `json:"acl" desc:"Access control list"` CertFile string `json:"cert" desc:"TLS certificate file"` KeyFile string `json:"key" desc:"TLS key file"` diff --git a/cmd/proxy_server.go b/cmd/proxy_server.go index 00ae58b..bdc5955 100644 --- a/cmd/proxy_server.go +++ b/cmd/proxy_server.go @@ -103,6 +103,9 @@ func proxyServer(args []string) { log.Printf("%s (%s) disconnected: %s\n", addr.String(), username, err.Error()) }, func(addr net.Addr, username string, id int, packet bool, reqAddr string) (core.ConnectResult, string, io.ReadWriteCloser) { + if packet && config.DisableUDP { + return core.ConnBlocked, "UDP disabled", nil + } host, port, err := net.SplitHostPort(reqAddr) if err != nil { return core.ConnFailed, err.Error(), nil diff --git a/cmd/relay_client.go b/cmd/relay_client.go index 1256fff..d511c58 100644 --- a/cmd/relay_client.go +++ b/cmd/relay_client.go @@ -33,8 +33,9 @@ func relayClient(args []string) { log.Printf("Configuration loaded: %+v\n", config) tlsConfig := &tls.Config{ - NextProtos: []string{relayTLSProtocol}, - MinVersion: tls.VersionTLS13, + InsecureSkipVerify: config.Insecure, + NextProtos: []string{relayTLSProtocol}, + MinVersion: tls.VersionTLS13, } // Load CA if len(config.CustomCAFile) > 0 { diff --git a/pkg/socks5/server.go b/pkg/socks5/server.go index 5e62d94..3729b83 100644 --- a/pkg/socks5/server.go +++ b/pkg/socks5/server.go @@ -29,6 +29,7 @@ type Server struct { TCPAddr *net.TCPAddr TCPDeadline int ACLEngine *acl.Engine + DisableUDP bool NewRequestFunc func(addr net.Addr, reqAddr string, action acl.Action, arg string) RequestClosedFunc func(addr net.Addr, reqAddr string, err error) @@ -41,7 +42,7 @@ type Server struct { } func NewServer(hyClient core.Client, addr string, authFunc func(username, password string) bool, tcpDeadline int, - aclEngine *acl.Engine, + aclEngine *acl.Engine, disableUDP bool, newReqFunc func(addr net.Addr, reqAddr string, action acl.Action, arg string), reqClosedFunc func(addr net.Addr, reqAddr string, err error), newUDPAssociateFunc func(addr net.Addr), @@ -64,6 +65,7 @@ func NewServer(hyClient core.Client, addr string, authFunc func(username, passwo TCPAddr: taddr, TCPDeadline: tcpDeadline, ACLEngine: aclEngine, + DisableUDP: disableUDP, NewRequestFunc: newReqFunc, RequestClosedFunc: reqClosedFunc, NewUDPAssociateFunc: newUDPAssociateFunc, @@ -154,7 +156,12 @@ func (s *Server) handle(c *net.TCPConn, r *socks5.Request) error { return s.handleTCP(c, r) } else if r.Cmd == socks5.CmdUDP { // UDP - return s.handleUDP(c, r) + if !s.DisableUDP { + return s.handleUDP(c, r) + } else { + _ = sendReply(c, socks5.RepCommandNotSupported) + return ErrUnsupportedCmd + } } else { _ = sendReply(c, socks5.RepCommandNotSupported) return ErrUnsupportedCmd @@ -297,7 +304,7 @@ func (s *Server) udpServer(c *net.UDPConn) { case acl.ActionDirect: rc, err = net.Dial("udp", addr) if err != nil { - // Failed to establish a connection, silently ignore + s.UDPTunnelClosedFunc(clientAddr, addr, err) continue } // The other direction @@ -306,26 +313,26 @@ func (s *Server) udpServer(c *net.UDPConn) { case acl.ActionProxy: rc, err = s.HyClient.Dial(true, addr) if err != nil { - // Failed to establish a connection, silently ignore + s.UDPTunnelClosedFunc(clientAddr, addr, err) continue } // The other direction go udpReversePipe(clientAddr, c, rc) remoteMap[addr] = rc case acl.ActionBlock: - // Silently ignore + s.UDPTunnelClosedFunc(clientAddr, addr, errors.New("blocked in ACL")) continue case acl.ActionHijack: rc, err = net.Dial("udp", net.JoinHostPort(arg, port)) if err != nil { - // Failed to establish a connection, silently ignore + s.UDPTunnelClosedFunc(clientAddr, addr, err) continue } // The other direction go udpReversePipe(clientAddr, c, rc) remoteMap[addr] = rc default: - // Silently ignore + s.UDPTunnelClosedFunc(clientAddr, addr, fmt.Errorf("unknown action %d", action)) continue } }