diff --git a/component/outbound/dialer/dialer.go b/component/outbound/dialer/dialer.go index a2c610f..d42b8c9 100644 --- a/component/outbound/dialer/dialer.go +++ b/component/outbound/dialer/dialer.go @@ -39,6 +39,8 @@ type GlobalOption struct { CheckTolerance time.Duration CheckDnsTcp bool AllowInsecure bool + TlsImplementation string + UtlsImitate string } type InstanceOption struct { diff --git a/component/outbound/dialer/trojan/trojan.go b/component/outbound/dialer/trojan/trojan.go index 4a5c53e..f53c6d6 100644 --- a/component/outbound/dialer/trojan/trojan.go +++ b/component/outbound/dialer/trojan/trojan.go @@ -48,11 +48,12 @@ func NewTrojan(option *dialer.GlobalOption, iOption dialer.InstanceOption, link func (s *Trojan) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOption) (*dialer.Dialer, error) { d := direct.FullconeDirect // Trojan Proxy supports full-cone. u := url.URL{ - Scheme: "tls", + Scheme: option.TlsImplementation, Host: net.JoinHostPort(s.Server, strconv.Itoa(s.Port)), RawQuery: url.Values{ "sni": []string{s.Sni}, "allowInsecure": []string{common.BoolToString(s.AllowInsecure)}, + "utlsImitate": []string{option.UtlsImitate}, }.Encode(), } var err error diff --git a/component/outbound/dialer/v2ray/v2ray.go b/component/outbound/dialer/v2ray/v2ray.go index a3d4914..00b4f2a 100644 --- a/component/outbound/dialer/v2ray/v2ray.go +++ b/component/outbound/dialer/v2ray/v2ray.go @@ -110,11 +110,12 @@ func (s *V2Ray) Dialer(option *dialer.GlobalOption, iOption dialer.InstanceOptio sni = s.Host } u := url.URL{ - Scheme: "tls", + Scheme: option.TlsImplementation, Host: net.JoinHostPort(s.Add, s.Port), RawQuery: url.Values{ "sni": []string{sni}, "allowInsecure": []string{common.BoolToString(s.AllowInsecure)}, + "utlsImitate": []string{option.UtlsImitate}, }.Encode(), } d, err = tls.NewTls(u.String(), d) diff --git a/component/outbound/transport/tls/tls.go b/component/outbound/transport/tls/tls.go index d8055ca..7546688 100644 --- a/component/outbound/transport/tls/tls.go +++ b/component/outbound/transport/tls/tls.go @@ -3,17 +3,22 @@ package tls import ( "crypto/tls" "fmt" - "github.com/mzz2017/softwind/netproxy" "net/url" + + "github.com/mzz2017/softwind/netproxy" + utls "github.com/refraction-networking/utls" ) // Tls is a base Tls struct type Tls struct { - dialer netproxy.Dialer - addr string - serverName string - skipVerify bool - tlsConfig *tls.Config + dialer netproxy.Dialer + addr string + serverName string + skipVerify bool + tlsImplentation string + utlsImitate string + + tlsConfig *tls.Config } // NewTls returns a Tls infra. @@ -24,12 +29,14 @@ func NewTls(s string, d netproxy.Dialer) (*Tls, error) { } t := &Tls{ - dialer: d, - addr: u.Host, + dialer: d, + addr: u.Host, + tlsImplentation: u.Scheme, } query := u.Query() t.serverName = query.Get("sni") + t.utlsImitate = query.Get("utlsImitate") // skipVerify if query.Get("allowInsecure") == "true" || query.Get("allowInsecure") == "1" || @@ -72,11 +79,35 @@ func (s *Tls) DialTcp(addr string) (conn netproxy.Conn, err error) { return nil, fmt.Errorf("[Tls]: dial to %s: %w", s.addr, err) } - tlsConn := tls.Client(&netproxy.FakeNetConn{ - Conn: rc, - LAddr: nil, - RAddr: nil, - }, s.tlsConfig) + var tlsConn interface { + netproxy.Conn + Handshake() error + } + + switch s.tlsImplentation { + case "tls": + tlsConn = tls.Client(&netproxy.FakeNetConn{ + Conn: rc, + LAddr: nil, + RAddr: nil, + }, s.tlsConfig) + + case "utls": + clientHelloID, err := nameToUtlsClientHelloID(s.utlsImitate) + if err != nil { + return nil, err + } + + tlsConn = utls.UClient(&netproxy.FakeNetConn{ + Conn: rc, + LAddr: nil, + RAddr: nil, + }, uTLSConfigFromTLSConfig(s.tlsConfig), *clientHelloID) + + default: + return nil, fmt.Errorf("unknown tls implementation: %v", s.tlsImplentation) + } + if err := tlsConn.Handshake(); err != nil { return nil, err } diff --git a/component/outbound/transport/tls/utls.go b/component/outbound/transport/tls/utls.go new file mode 100644 index 0000000..76d8542 --- /dev/null +++ b/component/outbound/transport/tls/utls.go @@ -0,0 +1,63 @@ +package tls + +import ( + "crypto/tls" + "fmt" + + utls "github.com/refraction-networking/utls" +) + +func uTLSConfigFromTLSConfig(config *tls.Config) *utls.Config { + return &utls.Config{ + ServerName: config.ServerName, + InsecureSkipVerify: config.InsecureSkipVerify, + } +} + +var clientHelloIDMap = map[string]*utls.ClientHelloID{ + "randomized": &utls.HelloRandomized, + "randomizedalpn": &utls.HelloRandomizedALPN, + "randomizednoalpn": &utls.HelloRandomizedNoALPN, + "firefox_auto": &utls.HelloFirefox_Auto, + "firefox_55": &utls.HelloFirefox_55, + "firefox_56": &utls.HelloFirefox_56, + "firefox_63": &utls.HelloFirefox_63, + "firefox_65": &utls.HelloFirefox_65, + "firefox_99": &utls.HelloFirefox_99, + "firefox_102": &utls.HelloFirefox_102, + "firefox_105": &utls.HelloFirefox_105, + "chrome_auto": &utls.HelloChrome_Auto, + "chrome_58": &utls.HelloChrome_58, + "chrome_62": &utls.HelloChrome_62, + "chrome_70": &utls.HelloChrome_70, + "chrome_72": &utls.HelloChrome_72, + "chrome_83": &utls.HelloChrome_83, + "chrome_87": &utls.HelloChrome_87, + "chrome_96": &utls.HelloChrome_96, + "chrome_100": &utls.HelloChrome_100, + "chrome_102": &utls.HelloChrome_102, + "ios_auto": &utls.HelloIOS_Auto, + "ios_11_1": &utls.HelloIOS_11_1, + "ios_12_1": &utls.HelloIOS_12_1, + "ios_13": &utls.HelloIOS_13, + "ios_14": &utls.HelloIOS_14, + "android_11_okhttp": &utls.HelloAndroid_11_OkHttp, + "edge_auto": &utls.HelloEdge_Auto, + "edge_85": &utls.HelloEdge_85, + "edge_106": &utls.HelloEdge_106, + "safari_auto": &utls.HelloSafari_Auto, + "safari_16_0": &utls.HelloSafari_16_0, + "360_auto": &utls.Hello360_Auto, + "360_7_5": &utls.Hello360_7_5, + "360_11_0": &utls.Hello360_11_0, + "qq_auto": &utls.HelloQQ_Auto, + "qq_11_1": &utls.HelloQQ_11_1, +} + +func nameToUtlsClientHelloID(name string) (*utls.ClientHelloID, error) { + clientHelloID, ok := clientHelloIDMap[name] + if !ok { + return nil, fmt.Errorf("unknown uTLS Client Hello ID: %s", name) + } + return clientHelloID, nil +} diff --git a/config/config.go b/config/config.go index eb29f17..8ef635d 100644 --- a/config/config.go +++ b/config/config.go @@ -30,6 +30,12 @@ type Global struct { DisableWaitingNetwork bool `mapstructure:"disable_waiting_network" default:"false"` AutoConfigKernelParameter bool `mapstructure:"auto_config_kernel_parameter" default:"false"` SniffingTimeout time.Duration `mapstructure:"sniffing_timeout" default:"100ms"` + TlsImplementation string `mapstructure:"tls_implementation" default:"tls"` + UtlsImitate string `mapstructure:"utls_imitate" default:"chrome_auto"` +} + +type Utls struct { + Imitate string `mapstructure:"imitate"` } type FunctionOrString interface{} diff --git a/config/desc.go b/config/desc.go index 7e55bd1..e6b2594 100644 --- a/config/desc.go +++ b/config/desc.go @@ -53,6 +53,8 @@ var GlobalDesc = Desc{ "disable_waiting_network": "Disable waiting for network before pulling subscriptions.", "auto_config_kernel_parameter": "Automatically configure Linux kernel parameters like ip_forward and send_redirects. Check out https://github.com/daeuniverse/dae/blob/main/docs/getting-started/kernel-parameters.md to see what will dae do.", "sniffing_timeout": "Timeout to waiting for first data sending for sniffing. It is always 0 if dial_mode is ip. Set it higher is useful in high latency LAN network.", + "tls_implementation": "TLS implementation. \"tls\" is to use Go's crypto/tls. \"utls\" is to use uTLS, which can imitate browser's Client Hello.", + "utls_imitate": "The Client Hello ID for uTLS to imitate. This takes effect only if tls_implementation is utls. See more: https://github.com/daeuniverse/dae/blob/331fa23c16/component/outbound/transport/tls/utls.go#L17", } var DnsDesc = Desc{ diff --git a/control/control_plane.go b/control/control_plane.go index 28b6652..f8d05e0 100644 --- a/control/control_plane.go +++ b/control/control_plane.go @@ -233,6 +233,8 @@ func NewControlPlane( CheckTolerance: global.CheckTolerance, CheckDnsTcp: true, AllowInsecure: global.AllowInsecure, + TlsImplementation: global.TlsImplementation, + UtlsImitate: global.UtlsImitate, } outbounds := []*outbound.DialerGroup{ outbound.NewDialerGroup(option, consts.OutboundDirect.String(), diff --git a/example.dae b/example.dae index 58ec207..26f1525 100644 --- a/example.dae +++ b/example.dae @@ -1,4 +1,7 @@ global { + ##### Software options. + ### + # tproxy port to listen on. It is NOT a HTTP/SOCKS port, and is just used by eBPF program. # In normal case, you do not need to use it. tproxy_port: 12345 @@ -6,7 +9,29 @@ global { # Log level: error, warn, info, debug, trace. log_level: info - # Node connectivity check. + # Disable waiting for network before pulling subscriptions. + disable_waiting_network: false + + + ##### Interface and kernel options. + ### + + # The LAN interface to bind. Use it if you want to proxy LAN. + # Multiple interfaces split by ",". + #lan_interface: docker0 + + # The WAN interface to bind. Use it if you want to proxy localhost. + # Multiple interfaces split by ",". Use "auto" to auto detect. + wan_interface: auto + + # Automatically configure Linux kernel parameters like ip_forward and send_redirects. Check out + # https://github.com/daeuniverse/dae/blob/main/docs/getting-started/kernel-parameters.md to see what will dae do. + auto_config_kernel_parameter: true + + + ##### Node connectivity check. + ### + # Host of URL should have both IPv4 and IPv6 if you have double stack in local. # First is URL, others are IP addresses if given. # Considering traffic consumption, it is recommended to choose a site with anycast IP and less response. @@ -29,16 +54,9 @@ global { # Group will switch node only when new_latency <= old_latency - tolerance. check_tolerance: 50ms - # The LAN interface to bind. Use it if you want to proxy LAN. - # Multiple interfaces split by ",". - #lan_interface: docker0 - # The WAN interface to bind. Use it if you want to proxy localhost. - # Multiple interfaces split by ",". Use "auto" to auto detect. - wan_interface: auto - - # Allow insecure TLS certificates. It is not recommended to turn it on unless you have to. - allow_insecure: false + ##### Connecting options. + ### # Optional values of dial_mode are: # 1. "ip". Dial proxy using the IP from DNS directly. This allows your ipv4, ipv6 to choose the optimal path @@ -57,16 +75,19 @@ global { # domain based traffic split ability. It doesn't work for direct traffic and consumes more CPU resources. dial_mode: domain - # Disable waiting for network before pulling subscriptions. - disable_waiting_network: false - - # Automatically configure Linux kernel parameters like ip_forward and send_redirects. Check out - # https://github.com/daeuniverse/dae/blob/main/docs/getting-started/kernel-parameters.md to see what will dae do. - auto_config_kernel_parameter: true + # Allow insecure TLS certificates. It is not recommended to turn it on unless you have to. + allow_insecure: false # Timeout to waiting for first data sending for sniffing. It is always 0 if dial_mode is ip. Set it higher is useful # in high latency LAN network. sniffing_timeout: 100ms + + # TLS implementation. tls is to use Go's crypto/tls. utls is to use uTLS, which can imitate browser's Client Hello. + tls_implementation: tls + + # The Client Hello ID for uTLS to imitate. This takes effect only if tls_implementation is utls. + # See more: https://github.com/daeuniverse/dae/blob/331fa23c16/component/outbound/transport/tls/utls.go#L17 + utls_imitate: chrome_auto } # Subscriptions defined here will be resolved as nodes and merged as a part of the global node pool. diff --git a/go.mod b/go.mod index 7772cb7..551590f 100644 --- a/go.mod +++ b/go.mod @@ -19,13 +19,19 @@ require ( github.com/v2rayA/ahocorasick-domain v0.0.0-20230218160829-122a074c48c8 github.com/vishvananda/netlink v1.1.0 github.com/x-cray/logrus-prefixed-formatter v0.5.2 - golang.org/x/crypto v0.5.0 + golang.org/x/crypto v0.9.0 golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 - golang.org/x/net v0.5.0 - golang.org/x/sys v0.4.0 + golang.org/x/net v0.10.0 + golang.org/x/sys v0.8.0 google.golang.org/protobuf v1.28.1 ) +require ( + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/gaukas/godicttls v0.0.3 // indirect + github.com/klauspost/compress v1.15.15 // indirect +) + require ( github.com/bits-and-blooms/bitset v1.3.1 // indirect github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d // indirect @@ -44,13 +50,14 @@ require ( github.com/mzz2017/disk-bloom v1.0.1 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/gomega v1.26.0 // indirect + github.com/refraction-networking/utls v1.3.2 github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.1 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect - gitlab.com/yawning/chacha20.git v0.0.0-20190903091407-6d1cb28dc72c // indirect - golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + gitlab.com/yawning/chacha20.git v0.0.0-20230427033715-7877545b1b37 // indirect + golang.org/x/term v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect google.golang.org/grpc v1.52.0 // indirect ) diff --git a/go.sum b/go.sum index 4e307f7..3b48cec 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/bits-and-blooms/bitset v1.3.1 h1:y+qrlmq3XsWi+xZqSaueaE8ry8Y127iMxlMfqcK8p0g= @@ -29,6 +31,8 @@ github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0X github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk= +github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -55,6 +59,8 @@ github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7P github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -89,6 +95,8 @@ github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8= +github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/safchain/ethtool v0.0.0-20230116090318-67cc41908669 h1:2uB3lH1zhL5dQflRl7+qLNKdZhiLAg+McePwsnJcBw8= @@ -125,13 +133,13 @@ github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1 github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -gitlab.com/yawning/chacha20.git v0.0.0-20190903091407-6d1cb28dc72c h1:yrfrd1u7MWIwWIulet2TZPEkeNQhQ/GcPLdPXgiEEr0= -gitlab.com/yawning/chacha20.git v0.0.0-20190903091407-6d1cb28dc72c/go.mod h1:3x6b94nWCP/a2XB/joOPMiGYUBvqbLfeY/BkHLeDs6s= +gitlab.com/yawning/chacha20.git v0.0.0-20230427033715-7877545b1b37 h1:ZrWBE3u/o9cHU2mySXf1687MaK09JOeZt1A+fHnCjmU= +gitlab.com/yawning/chacha20.git v0.0.0-20230427033715-7877545b1b37/go.mod h1:3x6b94nWCP/a2XB/joOPMiGYUBvqbLfeY/BkHLeDs6s= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +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-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -140,8 +148,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -160,14 +168,15 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/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.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +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.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=