Add disable UDP option for both proxy client & server

This commit is contained in:
Toby 2020-07-02 17:24:25 -07:00
parent 55e029f8ad
commit 59767dfaff
7 changed files with 30 additions and 11 deletions

View File

@ -69,6 +69,7 @@ The command line program supports loading configurations from both JSON files an
| Description | JSON config field | CLI argument | | Description | JSON config field | CLI argument |
| --- | --- | --- | | --- | --- | --- |
| Server listen address | listen | -listen | | Server listen address | listen | -listen |
| Disable UDP support | disable_udp | -disable-udp |
| Access control list | acl | -acl | | Access control list | acl | -acl |
| TLS certificate file | cert | -cert | | TLS certificate file | cert | -cert |
| TLS key file | key | -key | | 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 listen address | socks5_addr | -socks5-addr |
| SOCKS5 connection timeout in seconds | socks5_timeout | -socks5-timeout | | 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 listen address | http_addr | -http-addr |
| HTTP connection timeout in seconds | http_timeout | -http-timeout | | HTTP connection timeout in seconds | http_timeout | -http-timeout |
| Access control list | acl | -acl | | Access control list | acl | -acl |

View File

@ -67,6 +67,7 @@ Hysteria 是专门针对恶劣网络环境(常见于在中国访问海外服
| 描述 | JSON 字段 | 命令行参数 | | 描述 | JSON 字段 | 命令行参数 |
| --- | --- | --- | | --- | --- | --- |
| 服务端监听地址 | listen | -listen | | 服务端监听地址 | listen | -listen |
| 禁用 UDP 支持 | disable_udp | -disable-udp |
| ACL 规则文件 | acl | -acl | | ACL 规则文件 | acl | -acl |
| TLS 证书文件 | cert | -cert | | TLS 证书文件 | cert | -cert |
| TLS 密钥文件 | key | -key | | TLS 密钥文件 | key | -key |
@ -84,6 +85,7 @@ Hysteria 是专门针对恶劣网络环境(常见于在中国访问海外服
| --- | --- | --- | | --- | --- | --- |
| SOCKS5 监听地址 | socks5_addr | -socks5-addr | | SOCKS5 监听地址 | socks5_addr | -socks5-addr |
| SOCKS5 超时时间(秒) | socks5_timeout | -socks5-timeout | | SOCKS5 超时时间(秒) | socks5_timeout | -socks5-timeout |
| 禁用 SOCKS5 UDP 支持 | socks5_disable_udp | -socks5-disable-udp |
| HTTP 监听地址 | http_addr | -http-addr | | HTTP 监听地址 | http_addr | -http-addr |
| HTTP 超时时间(秒) | http_timeout | -http-timeout | | HTTP 超时时间(秒) | http_timeout | -http-timeout |
| ACL 规则文件 | acl | -acl | | ACL 规则文件 | acl | -acl |

View File

@ -30,8 +30,9 @@ func proxyClient(args []string) {
log.Printf("Configuration loaded: %+v\n", config) log.Printf("Configuration loaded: %+v\n", config)
tlsConfig := &tls.Config{ tlsConfig := &tls.Config{
NextProtos: []string{proxyTLSProtocol}, InsecureSkipVerify: config.Insecure,
MinVersion: tls.VersionTLS13, NextProtos: []string{proxyTLSProtocol},
MinVersion: tls.VersionTLS13,
} }
// Load CA // Load CA
if len(config.CustomCAFile) > 0 { if len(config.CustomCAFile) > 0 {
@ -87,6 +88,7 @@ func proxyClient(args []string) {
if len(config.SOCKS5Addr) > 0 { if len(config.SOCKS5Addr) > 0 {
go func() { go func() {
socks5server, err := socks5.NewServer(client, config.SOCKS5Addr, nil, config.SOCKS5Timeout, aclEngine, socks5server, err := socks5.NewServer(client, config.SOCKS5Addr, nil, config.SOCKS5Timeout, aclEngine,
config.SOCKS5DisableUDP,
func(addr net.Addr, reqAddr string, action acl.Action, arg string) { func(addr net.Addr, reqAddr string, action acl.Action, arg string) {
log.Printf("[TCP] [%s] %s <-> %s\n", actionToString(action, arg), addr.String(), reqAddr) log.Printf("[TCP] [%s] %s <-> %s\n", actionToString(action, arg), addr.String(), reqAddr)
}, },

View File

@ -7,6 +7,7 @@ const proxyTLSProtocol = "hysteria-proxy"
type proxyClientConfig struct { type proxyClientConfig struct {
SOCKS5Addr string `json:"socks5_addr" desc:"SOCKS5 listen address"` SOCKS5Addr string `json:"socks5_addr" desc:"SOCKS5 listen address"`
SOCKS5Timeout int `json:"socks5_timeout" desc:"SOCKS5 connection timeout in seconds"` 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"` HTTPAddr string `json:"http_addr" desc:"HTTP listen address"`
HTTPTimeout int `json:"http_timeout" desc:"HTTP connection timeout in seconds"` HTTPTimeout int `json:"http_timeout" desc:"HTTP connection timeout in seconds"`
ACLFile string `json:"acl" desc:"Access control list"` ACLFile string `json:"acl" desc:"Access control list"`
@ -47,6 +48,7 @@ func (c *proxyClientConfig) Check() error {
type proxyServerConfig struct { type proxyServerConfig struct {
ListenAddr string `json:"listen" desc:"Server listen address"` 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"` ACLFile string `json:"acl" desc:"Access control list"`
CertFile string `json:"cert" desc:"TLS certificate file"` CertFile string `json:"cert" desc:"TLS certificate file"`
KeyFile string `json:"key" desc:"TLS key file"` KeyFile string `json:"key" desc:"TLS key file"`

View File

@ -103,6 +103,9 @@ func proxyServer(args []string) {
log.Printf("%s (%s) disconnected: %s\n", addr.String(), username, err.Error()) 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) { 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) host, port, err := net.SplitHostPort(reqAddr)
if err != nil { if err != nil {
return core.ConnFailed, err.Error(), nil return core.ConnFailed, err.Error(), nil

View File

@ -33,8 +33,9 @@ func relayClient(args []string) {
log.Printf("Configuration loaded: %+v\n", config) log.Printf("Configuration loaded: %+v\n", config)
tlsConfig := &tls.Config{ tlsConfig := &tls.Config{
NextProtos: []string{relayTLSProtocol}, InsecureSkipVerify: config.Insecure,
MinVersion: tls.VersionTLS13, NextProtos: []string{relayTLSProtocol},
MinVersion: tls.VersionTLS13,
} }
// Load CA // Load CA
if len(config.CustomCAFile) > 0 { if len(config.CustomCAFile) > 0 {

View File

@ -29,6 +29,7 @@ type Server struct {
TCPAddr *net.TCPAddr TCPAddr *net.TCPAddr
TCPDeadline int TCPDeadline int
ACLEngine *acl.Engine ACLEngine *acl.Engine
DisableUDP bool
NewRequestFunc func(addr net.Addr, reqAddr string, action acl.Action, arg string) NewRequestFunc func(addr net.Addr, reqAddr string, action acl.Action, arg string)
RequestClosedFunc func(addr net.Addr, reqAddr string, err error) 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, 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), newReqFunc func(addr net.Addr, reqAddr string, action acl.Action, arg string),
reqClosedFunc func(addr net.Addr, reqAddr string, err error), reqClosedFunc func(addr net.Addr, reqAddr string, err error),
newUDPAssociateFunc func(addr net.Addr), newUDPAssociateFunc func(addr net.Addr),
@ -64,6 +65,7 @@ func NewServer(hyClient core.Client, addr string, authFunc func(username, passwo
TCPAddr: taddr, TCPAddr: taddr,
TCPDeadline: tcpDeadline, TCPDeadline: tcpDeadline,
ACLEngine: aclEngine, ACLEngine: aclEngine,
DisableUDP: disableUDP,
NewRequestFunc: newReqFunc, NewRequestFunc: newReqFunc,
RequestClosedFunc: reqClosedFunc, RequestClosedFunc: reqClosedFunc,
NewUDPAssociateFunc: newUDPAssociateFunc, NewUDPAssociateFunc: newUDPAssociateFunc,
@ -154,7 +156,12 @@ func (s *Server) handle(c *net.TCPConn, r *socks5.Request) error {
return s.handleTCP(c, r) return s.handleTCP(c, r)
} else if r.Cmd == socks5.CmdUDP { } else if r.Cmd == socks5.CmdUDP {
// UDP // UDP
return s.handleUDP(c, r) if !s.DisableUDP {
return s.handleUDP(c, r)
} else {
_ = sendReply(c, socks5.RepCommandNotSupported)
return ErrUnsupportedCmd
}
} else { } else {
_ = sendReply(c, socks5.RepCommandNotSupported) _ = sendReply(c, socks5.RepCommandNotSupported)
return ErrUnsupportedCmd return ErrUnsupportedCmd
@ -297,7 +304,7 @@ func (s *Server) udpServer(c *net.UDPConn) {
case acl.ActionDirect: case acl.ActionDirect:
rc, err = net.Dial("udp", addr) rc, err = net.Dial("udp", addr)
if err != nil { if err != nil {
// Failed to establish a connection, silently ignore s.UDPTunnelClosedFunc(clientAddr, addr, err)
continue continue
} }
// The other direction // The other direction
@ -306,26 +313,26 @@ func (s *Server) udpServer(c *net.UDPConn) {
case acl.ActionProxy: case acl.ActionProxy:
rc, err = s.HyClient.Dial(true, addr) rc, err = s.HyClient.Dial(true, addr)
if err != nil { if err != nil {
// Failed to establish a connection, silently ignore s.UDPTunnelClosedFunc(clientAddr, addr, err)
continue continue
} }
// The other direction // The other direction
go udpReversePipe(clientAddr, c, rc) go udpReversePipe(clientAddr, c, rc)
remoteMap[addr] = rc remoteMap[addr] = rc
case acl.ActionBlock: case acl.ActionBlock:
// Silently ignore s.UDPTunnelClosedFunc(clientAddr, addr, errors.New("blocked in ACL"))
continue continue
case acl.ActionHijack: case acl.ActionHijack:
rc, err = net.Dial("udp", net.JoinHostPort(arg, port)) rc, err = net.Dial("udp", net.JoinHostPort(arg, port))
if err != nil { if err != nil {
// Failed to establish a connection, silently ignore s.UDPTunnelClosedFunc(clientAddr, addr, err)
continue continue
} }
// The other direction // The other direction
go udpReversePipe(clientAddr, c, rc) go udpReversePipe(clientAddr, c, rc)
remoteMap[addr] = rc remoteMap[addr] = rc
default: default:
// Silently ignore s.UDPTunnelClosedFunc(clientAddr, addr, fmt.Errorf("unknown action %d", action))
continue continue
} }
} }