diff --git a/README.md b/README.md index 7153496f..02e3faf2 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ Table of Contents * [connect](#connect) * [relay](#relay) * [dnsserver](#dnsserver) + * [dnsclient](#dnsclient) + * [dohserver](#dohserver) + * [dohclient](#dohclient) * [dhcpserver](#dhcpserver) * [socks5](#socks5) * [socks5tohttp](#socks5tohttp) @@ -120,8 +123,11 @@ Brook - A cross-platform network tool designed for developers Brook ``` +[--dialWithDNSPrefer]=[value] +[--dialWithDNS]=[value] [--dialWithIP4]=[value] [--dialWithIP6]=[value] +[--dialWithNIC]=[value] [--dialWithSocks5Password]=[value] [--dialWithSocks5TCPTimeout]=[value] [--dialWithSocks5UDPTimeout]=[value] @@ -144,10 +150,16 @@ Brook [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] # GLOBAL OPTIONS +**--dialWithDNS**="": When a domain name needs to be resolved, use the specified DNS. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required. Note that for client-side commands, this does not affect the client passing the domain address to the server + +**--dialWithDNSPrefer**="": This is used with the dialWithDNS parameter. Prefer A record or AAAA record. Value is A or AAAA + **--dialWithIP4**="": When the current machine establishes a network connection to the outside IPv4, both TCP and UDP, it is used to specify the IPv4 used **--dialWithIP6**="": When the current machine establishes a network connection to the outside IPv6, both TCP and UDP, it is used to specify the IPv6 used +**--dialWithNIC**="": When the current machine establishes a network connection to the outside, both TCP and UDP, it is used to specify the NIC used + **--dialWithSocks5**="": When the current machine establishes a network connection to the outside, both TCP and UDP, with your socks5 proxy, such as 127.0.0.1:1081 **--dialWithSocks5Password**="": If there is @@ -315,6 +327,8 @@ Run as brook wssclient, both TCP and UDP, to start a socks5 proxy, [src <-> sock **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpTimeout**="": time (s) (default: 60) **--withoutBrookProtocol**: The data will not be encrypted with brook protocol @@ -393,6 +407,8 @@ Run as relay over brook, both TCP and UDP, this means access [from address] is e **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--to, -t**="": Address which relay to, like: 1.2.3.4:9999 **--udpTimeout**="": time (s) (default: 60) @@ -419,7 +435,7 @@ Run as dns server over brook, both TCP and UDP, [src <-> $ brook dnserversoverbr **--dns**="": DNS server for resolving domains NOT in list (default: 8.8.8.8:53) -**--dnsForBypass**="": DNS server for resolving domains in bypass list (default: 223.5.5.5:53) +**--dnsForBypass**="": DNS server for resolving domains in bypass list. Such as 223.5.5.5:53 or https://dns.alidns.com/dns-query?address=223.5.5.5:443, the address is required (default: 223.5.5.5:53) **--insecure**: When server is brook wssserver or brook quicserver, client do not verify the server's certificate chain and host name @@ -431,6 +447,8 @@ Run as dns server over brook, both TCP and UDP, [src <-> $ brook dnserversoverbr **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpTimeout**="": time (s) (default: 60) **--udpovertcp**: When server is brook server, UDP over TCP @@ -459,7 +477,7 @@ Run as transparent proxy, a router gateway, both TCP and UDP, only works on Linu **--disableAAAA**: Disable AAAA query -**--dnsForBypass**="": DNS server for resolving domains in bypass list (default: 223.5.5.5:53) +**--dnsForBypass**="": DNS server for resolving domains in bypass list. Such as 223.5.5.5:53 or https://dns.alidns.com/dns-query?address=223.5.5.5:443, the address is required (default: 223.5.5.5:53) **--dnsForDefault**="": DNS server for resolving domains NOT in list (default: 8.8.8.8:53) @@ -481,6 +499,8 @@ Run as transparent proxy, a router gateway, both TCP and UDP, only works on Linu **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpTimeout**="": time (s) (default: 60) **--udpovertcp**: When server is brook server, UDP over TCP @@ -505,6 +525,8 @@ Generate brook link **--server, -s**="": Support brook server, brook wsserver, brook wssserver, socks5 server, brook quicserver. Like: 1.2.3.4:9999, ws://1.2.3.4:9999, wss://google.com:443/ws, socks5://1.2.3.4:1080, quic://google.com:443 +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpovertcp**: When server is brook server, UDP over TCP **--username, -u**="": Username, when server is socks5 server @@ -541,7 +563,7 @@ Run as standalone relay, both TCP and UDP, this means access [from address] is e ## dnsserver -Run as standalone dns server, both TCP and UDP +Run as standalone dns server **--blockDomainList**="": One domain per line, suffix match mode. https://, http:// or local absolute file path. Like: https://txthinking.github.io/bypass/example_domain.txt @@ -549,7 +571,7 @@ Run as standalone dns server, both TCP and UDP **--disableAAAA**: Disable AAAA query -**--dns**="": DNS server which forward to (default: 8.8.8.8:53) +**--dns**="": DNS server which forward to. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required (default: 8.8.8.8:53) **--listen, -l**="": Listen address, like: 127.0.0.1:53 @@ -557,6 +579,56 @@ Run as standalone dns server, both TCP and UDP **--udpTimeout**="": time (s) (default: 60) +## dnsclient + +Send a dns query + +**--dns, -s**="": DNS server, such as 8.8.8.8:53 (default: 8.8.8.8:53) + +**--domain, -d**="": Domain + +**--short**: Short for A/AAAA + +**--type, -t**="": Type, such as A (default: A) + +## dohserver + +Run as standalone doh server + +**--blockDomainList**="": One domain per line, suffix match mode. https://, http:// or local absolute file path. Like: https://txthinking.github.io/bypass/example_domain.txt + +**--cert**="": The cert file absolute path for the domain, such as /path/to/cert.pem. If cert or certkey is empty, a certificate will be issued automatically + +**--certkey**="": The cert key file absolute path for the domain, such as /path/to/certkey.pem. If cert or certkey is empty, a certificate will be issued automatically + +**--disableA**: Disable A query + +**--disableAAAA**: Disable AAAA query + +**--dns**="": DNS server which forward to. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required (default: 8.8.8.8:53) + +**--domainaddress**="": Such as: domain.com:443, if you want to create a https server. If you choose to automatically issue certificates, the domain must have been resolved to the server IP and 80 port also will be used + +**--listen**="": listen address, if you want to create a http server behind nico + +**--path**="": URL path (default: /dns-query) + +**--tcpTimeout**="": time (s) (default: 0) + +**--udpTimeout**="": time (s) (default: 60) + +## dohclient + +Send a dns query + +**--doh, -s**="": DOH server, the address is required (default: https://dns.google/dns-query?address=8.8.8.8%3A443) + +**--domain, -d**="": Domain + +**--short**: Short for A/AAAA + +**--type, -t**="": Type, such as A (default: A) + ## dhcpserver Run as standalone dhcp server. Note that you need to stop other dhcp servers, if there are. @@ -569,6 +641,8 @@ Run as standalone dhcp server. Note that you need to stop other dhcp servers, if **--gateway**="": The router gateway which you want to assign to clients, such as: 192.168.1.1 +**--interface**="": Select interface on multi interface device. Linux only + **--netmask**="": Subnet netmask which you want to assign to clients (default: 255.255.255.0) **--serverip**="": DHCP server IP, the IP of the this machine, you shoud set a static IP to this machine before doing this, such as: 192.168.1.10 @@ -725,12 +799,12 @@ The so-called Internet connection is IP to IP connection, not domain name connec | -------------- | --------------------------------- | ----------------------------------------------------------------------------------- | --- | | Import Servers | iOS,Android,Mac,Windows,Linux | / | brook link list | | System DNS | iOS,Android,Mac,Windows,Linux | / | System DNS. **Do not bypass this IP** | -| Fake DNS | iOS, Android, Mac, Windows, Linux | Turn off the security DNS that comes with the system/browser, see below for details | The domain name is resolved to Fake IP, which will be converted to a domain name when a connection is initiated, and then the domain name address will be sent to the server, and the server is responsible for domain name resolution | +| Fake DNS | iOS,Android,Mac,Windows,Linux | **Turn off or block the security DNS that comes with the system/browser/etc, see below for details** | The domain name is resolved to Fake IP, which will be converted to a domain name when a connection is initiated, and then the domain name address will be sent to the server, and the server is responsible for domain name resolution | | Block | iOS,Android,Mac,Windows,Linux | / | Block switch | | Block Domain | iOS,Android,Mac,Windows,Linux | Fake DNS: On | Domain name list, matching domain names will be blocked. **Domain name is suffix matching mode** | | Bypass | iOS,Android,Mac,Windows,Linux | / | Bypass switch | | Bypass IP | iOS,Android,Mac,Windows,Linux | / | CIDR list, matched IP will be bypassed | -| Bypass Geo IP | iOS,Android | / | The matched IP will be bypassed. Note: Global IP changes frequently, so the Geo library is time-sensitive | +| Bypass Geo IP | iOS,Android,Mac,Windows,Linux | / | The matched IP will be bypassed. Note: Global IP changes frequently, so the Geo library is time-sensitive | | Bypass Apps | Android | / | These apps will be bypassed | | Bypass DNS | iOS,Android,Mac,Windows,Linux | / | Support normal DNS, such as `223.5.5.5:53`, support DoH, but need to specify the address of DoH through the parameter address, such as `https://dns. alidns.com/dns-query?address=223.5.5.5%3A443` is used to resolve Bypass Domain. **The IP of this DNS will automatically Bypass** | | Bypass Domain | iOS,Android,Mac,Windows,Linux | Fake DNS: On | List of domain names, matching domain names will use Bypass DNS resolution to get IP, **whether the final connection will be bypassed depends on the Bypass IP** . **The domain name is a suffix matching pattern** | @@ -742,8 +816,12 @@ The so-called Internet connection is IP to IP connection, not domain name connec | Log View | iOS,Android,Mac,Windows,Linux | / | Log List | | Log View Plus | iOS,Android,Mac,Windows,Linux | / | Log list, easier to read, filter conditions, etc. | | MITM Log View | iOS,Android,Mac,Windows,Linux | / | MITM log list, such as https request response, hexadecimal, JSON, image, etc. | -| TUN | Mac,Windows,Linux | / | Choose proxy mode or tun mode | +| TUN | iOS,Android,Mac,Windows,Linux | / | Choose proxy mode or tun. iOS and Android force TUN mode mode | | Capture Me | iOS,Android,Mac,Windows,Linux | / | Test your packet capture or proxy software is working as a system proxy or TUN | +| DNS Client | iOS,Android,Mac,Windows,Linux | / | DNS client | +| DOH Client | iOS,Android,Mac,Windows,Linux | / | DOH client | +| Echo Client | iOS,Android,Mac,Windows,Linux | / | Echo client | +| Test Socks5 | iOS,Android,Mac,Linux | / | Test socks5 server | | Dark Mode | iOS,Android,Mac,Windows,Linux | / | System / Light / Dark | | | Shortcut | iOS,Android,Mac,Windows,Linux | / | Quickly control the functions in the menu on the home page | | System Tray | Windows | / | Open as systray, then open dashboard from the systray | @@ -828,7 +906,7 @@ Take full control of your own network | block | bool | Whether Block, default `false` | false | | ipaddress | string | IP type address, rewrite destination | 1.2.3.4:443 | | ipaddressfrombypassdns | string | Use Bypass DNS to obtain `A` or `AAAA` IP and rewrite the destination, only valid when `domainaddress` exists, the value `A`/`AAAA` | A | -| bypass | bool | **Only available on iOS, Android.** Bypass, default `false`. If `true` and `domainaddress`, then `ipaddress` or `ipaddressfrombypassdns` must be specified. It is an OR relationship with GUI Bypass IP | false | +| bypass | bool | Bypass, default `false`. If `true` and `domainaddress`, then `ipaddress` or `ipaddressfrombypassdns` must be specified. It is an OR relationship with GUI Bypass IP | false | | mitm | bool | Whether to perform MITM, default `false`. Only valid when `network` is `tcp`. Need to install CA, see below | false | | mitmprotocol | string | MITM protocol needs to be specified explicitly, the value is `http`/`https` | https | | mitmcertdomain | string | The MITM certificate domain name, which is taken from `domainaddress` by default. If `ipaddress` and `mitm` is `true` and `mitmprotocol` is `https` then must be must be specified explicitly | example.com | @@ -924,6 +1002,7 @@ Because if Security DNS is turned on, the Fake DNS will not work. So we have to - Chrome on Mobile: Settings -> Privacy and security -> Use secure DNS -> Off - Chrome on Desktop: Settings -> Privacy and security -> Security -> Use secure DNS -> Off - Windows: Windows Settings -> Network & Internet -> Your Network -> DNS settings -> Edit -> Preferred DNS -> Unencrypted only -> 8.8.8.8 +- iOS/Mac avoid upgrading to secure DNS: related DST can be blocked by script. You can also create a DNS by yourself: `brook dnsserver --listen :53` Other systems and software, please find out whether it exists and how to close it diff --git a/brooklink.go b/brooklink.go index cc053ac6..d5bd9536 100644 --- a/brooklink.go +++ b/brooklink.go @@ -90,6 +90,9 @@ func NewBrookLink(link string) (*BrookLink, error) { } tc.RootCAs = roots } + if kind == "wssserver" { + tc.NextProtos = []string{"http/1.1"} + } if kind == "quicserver" { tc.NextProtos = []string{"h3"} } @@ -106,9 +109,6 @@ func NewBrookLink(link string) (*BrookLink, error) { if v.Get("tlsfingerprint") == "chrome" { tlsfingerprint = utls.HelloChrome_Auto } - if v.Get("tlsfingerprint") == "firefox" { - tlsfingerprint = utls.HelloFirefox_Auto - } } } return &BrookLink{ diff --git a/cli/brook/main.go b/cli/brook/main.go index 77dfb8a8..3a97d972 100644 --- a/cli/brook/main.go +++ b/cli/brook/main.go @@ -809,7 +809,7 @@ func main() { }, &cli.StringFlag{ Name: "tlsfingerprint", - Usage: "When server is brook wssserver, select tls fingerprint, value can be chrome or firefox", + Usage: "When server is brook wssserver, select tls fingerprint, value can be: chrome", }, &cli.BoolFlag{ Name: "withoutBrookProtocol", @@ -882,9 +882,6 @@ func main() { if c.String("tlsfingerprint") == "chrome" { s.TLSFingerprint = utls.HelloChrome_Auto } - if c.String("tlsfingerprint") == "firefox" { - s.TLSFingerprint = utls.HelloFirefox_Auto - } g.Add(&runnergroup.Runner{ Start: func() error { return s.ListenAndServe() @@ -1220,7 +1217,7 @@ func main() { }, &cli.StringFlag{ Name: "tlsfingerprint", - Usage: "When server is brook wssserver, select tls fingerprint, value can be chrome or firefox", + Usage: "When server is brook wssserver, select tls fingerprint, value can be: chrome", }, &cli.IntFlag{ Name: "tcpTimeout", @@ -1353,7 +1350,7 @@ func main() { }, &cli.StringFlag{ Name: "tlsfingerprint", - Usage: "When server is brook wssserver, select tls fingerprint, value can be chrome or firefox", + Usage: "When server is brook wssserver, select tls fingerprint, value can be: chrome", }, &cli.BoolFlag{ Name: "withoutBrookProtocol", @@ -1537,7 +1534,7 @@ func main() { }, &cli.StringFlag{ Name: "tlsfingerprint", - Usage: "When server is brook wssserver, select tls fingerprint, value can be chrome or firefox", + Usage: "When server is brook wssserver, select tls fingerprint, value can be: chrome", }, &cli.StringFlag{ Name: "link", @@ -1905,7 +1902,7 @@ func main() { }, &cli.StringFlag{ Name: "tlsfingerprint", - Usage: "When server is brook wssserver, select tls fingerprint, value can be chrome or firefox", + Usage: "When server is brook wssserver, select tls fingerprint, value can be: chrome", }, }, Action: func(c *cli.Context) error { @@ -2204,21 +2201,41 @@ func main() { Name: "type", Aliases: []string{"t"}, Usage: "Type, such as A", - Value: "NS", + Value: "A", + }, + &cli.BoolFlag{ + Name: "short", + Usage: "Short for A/AAAA", }, }, Action: func(c *cli.Context) error { + if c.String("domain") == "" { + return cli.ShowSubcommandHelp(c) + } t, ok := dns.StringToType[c.String("type")] if !ok { return errors.New("invalid type") } dc := &brook.DNSClient{Server: c.String("dns")} m := &dns.Msg{} - m.SetQuestion(c.String("domain")+".", t) + m.SetQuestion(strings.TrimRight(c.String("domain"), ".")+".", t) m, err := dc.Exchange(m) if err != nil { return err } + if c.Bool("short") && (c.String("type") == "A" || c.String("type") == "AAAA") { + for _, v := range m.Answer { + if t, ok := v.(*dns.A); ok { + fmt.Println(t.A) + return nil + } + if t, ok := v.(*dns.AAAA); ok { + fmt.Println(t.AAAA) + return nil + } + } + return nil + } fmt.Println(m) return nil }, @@ -2369,10 +2386,17 @@ func main() { Name: "type", Aliases: []string{"t"}, Usage: "Type, such as A", - Value: "NS", + Value: "A", + }, + &cli.BoolFlag{ + Name: "short", + Usage: "Short for A/AAAA", }, }, Action: func(c *cli.Context) error { + if c.String("domain") == "" { + return cli.ShowSubcommandHelp(c) + } t, ok := dns.StringToType[c.String("type")] if !ok { return errors.New("invalid type") @@ -2382,11 +2406,24 @@ func main() { return err } m := &dns.Msg{} - m.SetQuestion(c.String("domain")+".", t) + m.SetQuestion(strings.TrimRight(c.String("domain"), ".")+".", t) m, err = dc.Exchange(m) if err != nil { return err } + if c.Bool("short") && (c.String("type") == "A" || c.String("type") == "AAAA") { + for _, v := range m.Answer { + if t, ok := v.(*dns.A); ok { + fmt.Println(t.A) + return nil + } + if t, ok := v.(*dns.AAAA); ok { + fmt.Println(t.AAAA) + return nil + } + } + return nil + } fmt.Println(m) return nil }, diff --git a/cli/brook/static/index.html b/cli/brook/static/index.html index 2391aa70..26bd311c 100644 --- a/cli/brook/static/index.html +++ b/cli/brook/static/index.html @@ -422,7 +422,7 @@
{{zh ? '或者:' : 'Or:'}}
@@ -445,7 +445,7 @@
diff --git a/docs/cli.html b/docs/cli.html index 52e49258..a6588c97 100644 --- a/docs/cli.html +++ b/docs/cli.html @@ -1141,6 +1141,9 @@
  • connect
  • relay
  • dnsserver
  • +
  • dnsclient
  • +
  • dohserver
  • +
  • dohclient
  • dhcpserver
  • socks5
  • socks5tohttp
  • @@ -1185,6 +1188,9 @@

    connect
  • relay
  • dnsserver
  • +
  • dnsclient
  • +
  • dohserver
  • +
  • dohclient
  • dhcpserver
  • socks5
  • socks5tohttp
  • @@ -1210,8 +1216,11 @@

    Brook

    -
    [--dialWithIP4]=[value]
    +
    [--dialWithDNSPrefer]=[value]
    +[--dialWithDNS]=[value]
    +[--dialWithIP4]=[value]
     [--dialWithIP6]=[value]
    +[--dialWithNIC]=[value]
     [--dialWithSocks5Password]=[value]
     [--dialWithSocks5TCPTimeout]=[value]
     [--dialWithSocks5UDPTimeout]=[value]
    @@ -1233,10 +1242,16 @@ 

    GLOBAL OPTIONS

    +

    --dialWithDNS="": When a domain name needs to be resolved, use the specified DNS. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required. Note that for client-side commands, this does not affect the client passing the domain address to the server

    + +

    --dialWithDNSPrefer="": This is used with the dialWithDNS parameter. Prefer A record or AAAA record. Value is A or AAAA

    +

    --dialWithIP4="": When the current machine establishes a network connection to the outside IPv4, both TCP and UDP, it is used to specify the IPv4 used

    --dialWithIP6="": When the current machine establishes a network connection to the outside IPv6, both TCP and UDP, it is used to specify the IPv6 used

    +

    --dialWithNIC="": When the current machine establishes a network connection to the outside, both TCP and UDP, it is used to specify the NIC used

    +

    --dialWithSocks5="": When the current machine establishes a network connection to the outside, both TCP and UDP, with your socks5 proxy, such as 127.0.0.1:1081

    --dialWithSocks5Password="": If there is

    @@ -1403,6 +1418,8 @@

    --tcpTimeout="": time (s) (default: 0)

    +

    --tlsfingerprint="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox

    +

    --udpTimeout="": time (s) (default: 60)

    --withoutBrookProtocol: The data will not be encrypted with brook protocol

    @@ -1481,6 +1498,8 @@

    https://dns.alidns.com/dns-query?address=223.5.5.5:443, the address is required (default: 223.5.5.5:53)

    --insecure: When server is brook wssserver or brook quicserver, client do not verify the server's certificate chain and host name

    @@ -1519,6 +1538,8 @@

    https://dns.alidns.com/dns-query?address=223.5.5.5:443, the address is required (default: 223.5.5.5:53)

    --dnsForDefault="": DNS server for resolving domains NOT in list (default: 8.8.8.8:53)

    @@ -1569,6 +1590,8 @@

    --server, -s="": Support brook server, brook wsserver, brook wssserver, socks5 server, brook quicserver. Like: 1.2.3.4:9999, ws://1.2.3.4:9999, wss://google.com:443/ws, socks5://1.2.3.4:1080, quic://google.com:443

    +

    --tlsfingerprint="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox

    +

    --udpovertcp: When server is brook server, UDP over TCP

    --username, -u="": Username, when server is socks5 server

    @@ -1629,7 +1654,7 @@

    dnsserver

    -

    Run as standalone dns server, both TCP and UDP

    +

    Run as standalone dns server

    --blockDomainList="": One domain per line, suffix match mode. https://, http:// or local absolute file path. Like: https://txthinking.github.io/bypass/example_domain.txt

    @@ -1637,13 +1662,63 @@

    --disableAAAA: Disable AAAA query

    -

    --dns="": DNS server which forward to (default: 8.8.8.8:53)

    +

    --dns="": DNS server which forward to. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required (default: 8.8.8.8:53)

    --listen, -l="": Listen address, like: 127.0.0.1:53

    --tcpTimeout="": time (s) (default: 0)

    --udpTimeout="": time (s) (default: 60)

    +

    +dnsclient

    + +

    Send a dns query

    + +

    --dns, -s="": DNS server, such as 8.8.8.8:53 (default: 8.8.8.8:53)

    + +

    --domain, -d="": Domain

    + +

    --short: Short for A/AAAA

    + +

    --type, -t="": Type, such as A (default: A)

    +

    +dohserver

    + +

    Run as standalone doh server

    + +

    --blockDomainList="": One domain per line, suffix match mode. https://, http:// or local absolute file path. Like: https://txthinking.github.io/bypass/example_domain.txt

    + +

    --cert="": The cert file absolute path for the domain, such as /path/to/cert.pem. If cert or certkey is empty, a certificate will be issued automatically

    + +

    --certkey="": The cert key file absolute path for the domain, such as /path/to/certkey.pem. If cert or certkey is empty, a certificate will be issued automatically

    + +

    --disableA: Disable A query

    + +

    --disableAAAA: Disable AAAA query

    + +

    --dns="": DNS server which forward to. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required (default: 8.8.8.8:53)

    + +

    --domainaddress="": Such as: domain.com:443, if you want to create a https server. If you choose to automatically issue certificates, the domain must have been resolved to the server IP and 80 port also will be used

    + +

    --listen="": listen address, if you want to create a http server behind nico

    + +

    --path="": URL path (default: /dns-query)

    + +

    --tcpTimeout="": time (s) (default: 0)

    + +

    --udpTimeout="": time (s) (default: 60)

    +

    +dohclient

    + +

    Send a dns query

    + +

    --doh, -s="": DOH server, the address is required (default: https://dns.google/dns-query?address=8.8.8.8%3A443)

    + +

    --domain, -d="": Domain

    + +

    --short: Short for A/AAAA

    + +

    --type, -t="": Type, such as A (default: A)

    dhcpserver

    @@ -1657,6 +1732,8 @@

    --gateway="": The router gateway which you want to assign to clients, such as: 192.168.1.1

    +

    --interface="": Select interface on multi interface device. Linux only

    +

    --netmask="": Subnet netmask which you want to assign to clients (default: 255.255.255.0)

    --serverip="": DHCP server IP, the IP of the this machine, you shoud set a static IP to this machine before doing this, such as: 192.168.1.10

    diff --git a/docs/cli.md b/docs/cli.md index db66e418..fdc9f73c 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -8,8 +8,11 @@ Brook - A cross-platform network tool designed for developers Brook ``` +[--dialWithDNSPrefer]=[value] +[--dialWithDNS]=[value] [--dialWithIP4]=[value] [--dialWithIP6]=[value] +[--dialWithNIC]=[value] [--dialWithSocks5Password]=[value] [--dialWithSocks5TCPTimeout]=[value] [--dialWithSocks5UDPTimeout]=[value] @@ -32,10 +35,16 @@ Brook [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] # GLOBAL OPTIONS +**--dialWithDNS**="": When a domain name needs to be resolved, use the specified DNS. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required. Note that for client-side commands, this does not affect the client passing the domain address to the server + +**--dialWithDNSPrefer**="": This is used with the dialWithDNS parameter. Prefer A record or AAAA record. Value is A or AAAA + **--dialWithIP4**="": When the current machine establishes a network connection to the outside IPv4, both TCP and UDP, it is used to specify the IPv4 used **--dialWithIP6**="": When the current machine establishes a network connection to the outside IPv6, both TCP and UDP, it is used to specify the IPv6 used +**--dialWithNIC**="": When the current machine establishes a network connection to the outside, both TCP and UDP, it is used to specify the NIC used + **--dialWithSocks5**="": When the current machine establishes a network connection to the outside, both TCP and UDP, with your socks5 proxy, such as 127.0.0.1:1081 **--dialWithSocks5Password**="": If there is @@ -203,6 +212,8 @@ Run as brook wssclient, both TCP and UDP, to start a socks5 proxy, [src <-> sock **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpTimeout**="": time (s) (default: 60) **--withoutBrookProtocol**: The data will not be encrypted with brook protocol @@ -281,6 +292,8 @@ Run as relay over brook, both TCP and UDP, this means access [from address] is e **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--to, -t**="": Address which relay to, like: 1.2.3.4:9999 **--udpTimeout**="": time (s) (default: 60) @@ -307,7 +320,7 @@ Run as dns server over brook, both TCP and UDP, [src <-> $ brook dnserversoverbr **--dns**="": DNS server for resolving domains NOT in list (default: 8.8.8.8:53) -**--dnsForBypass**="": DNS server for resolving domains in bypass list (default: 223.5.5.5:53) +**--dnsForBypass**="": DNS server for resolving domains in bypass list. Such as 223.5.5.5:53 or https://dns.alidns.com/dns-query?address=223.5.5.5:443, the address is required (default: 223.5.5.5:53) **--insecure**: When server is brook wssserver or brook quicserver, client do not verify the server's certificate chain and host name @@ -319,6 +332,8 @@ Run as dns server over brook, both TCP and UDP, [src <-> $ brook dnserversoverbr **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpTimeout**="": time (s) (default: 60) **--udpovertcp**: When server is brook server, UDP over TCP @@ -347,7 +362,7 @@ Run as transparent proxy, a router gateway, both TCP and UDP, only works on Linu **--disableAAAA**: Disable AAAA query -**--dnsForBypass**="": DNS server for resolving domains in bypass list (default: 223.5.5.5:53) +**--dnsForBypass**="": DNS server for resolving domains in bypass list. Such as 223.5.5.5:53 or https://dns.alidns.com/dns-query?address=223.5.5.5:443, the address is required (default: 223.5.5.5:53) **--dnsForDefault**="": DNS server for resolving domains NOT in list (default: 8.8.8.8:53) @@ -369,6 +384,8 @@ Run as transparent proxy, a router gateway, both TCP and UDP, only works on Linu **--tcpTimeout**="": time (s) (default: 0) +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpTimeout**="": time (s) (default: 60) **--udpovertcp**: When server is brook server, UDP over TCP @@ -393,6 +410,8 @@ Generate brook link **--server, -s**="": Support brook server, brook wsserver, brook wssserver, socks5 server, brook quicserver. Like: 1.2.3.4:9999, ws://1.2.3.4:9999, wss://google.com:443/ws, socks5://1.2.3.4:1080, quic://google.com:443 +**--tlsfingerprint**="": When server is brook wssserver, select tls fingerprint, value can be chrome or firefox + **--udpovertcp**: When server is brook server, UDP over TCP **--username, -u**="": Username, when server is socks5 server @@ -429,7 +448,7 @@ Run as standalone relay, both TCP and UDP, this means access [from address] is e ## dnsserver -Run as standalone dns server, both TCP and UDP +Run as standalone dns server **--blockDomainList**="": One domain per line, suffix match mode. https://, http:// or local absolute file path. Like: https://txthinking.github.io/bypass/example_domain.txt @@ -437,7 +456,7 @@ Run as standalone dns server, both TCP and UDP **--disableAAAA**: Disable AAAA query -**--dns**="": DNS server which forward to (default: 8.8.8.8:53) +**--dns**="": DNS server which forward to. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required (default: 8.8.8.8:53) **--listen, -l**="": Listen address, like: 127.0.0.1:53 @@ -445,6 +464,56 @@ Run as standalone dns server, both TCP and UDP **--udpTimeout**="": time (s) (default: 60) +## dnsclient + +Send a dns query + +**--dns, -s**="": DNS server, such as 8.8.8.8:53 (default: 8.8.8.8:53) + +**--domain, -d**="": Domain + +**--short**: Short for A/AAAA + +**--type, -t**="": Type, such as A (default: A) + +## dohserver + +Run as standalone doh server + +**--blockDomainList**="": One domain per line, suffix match mode. https://, http:// or local absolute file path. Like: https://txthinking.github.io/bypass/example_domain.txt + +**--cert**="": The cert file absolute path for the domain, such as /path/to/cert.pem. If cert or certkey is empty, a certificate will be issued automatically + +**--certkey**="": The cert key file absolute path for the domain, such as /path/to/certkey.pem. If cert or certkey is empty, a certificate will be issued automatically + +**--disableA**: Disable A query + +**--disableAAAA**: Disable AAAA query + +**--dns**="": DNS server which forward to. Such as 8.8.8.8:53 or https://dns.google/dns-query?address=8.8.8.8%3A443, the address is required (default: 8.8.8.8:53) + +**--domainaddress**="": Such as: domain.com:443, if you want to create a https server. If you choose to automatically issue certificates, the domain must have been resolved to the server IP and 80 port also will be used + +**--listen**="": listen address, if you want to create a http server behind nico + +**--path**="": URL path (default: /dns-query) + +**--tcpTimeout**="": time (s) (default: 0) + +**--udpTimeout**="": time (s) (default: 60) + +## dohclient + +Send a dns query + +**--doh, -s**="": DOH server, the address is required (default: https://dns.google/dns-query?address=8.8.8.8%3A443) + +**--domain, -d**="": Domain + +**--short**: Short for A/AAAA + +**--type, -t**="": Type, such as A (default: A) + ## dhcpserver Run as standalone dhcp server. Note that you need to stop other dhcp servers, if there are. @@ -457,6 +526,8 @@ Run as standalone dhcp server. Note that you need to stop other dhcp servers, if **--gateway**="": The router gateway which you want to assign to clients, such as: 192.168.1.1 +**--interface**="": Select interface on multi interface device. Linux only + **--netmask**="": Subnet netmask which you want to assign to clients (default: 255.255.255.0) **--serverip**="": DHCP server IP, the IP of the this machine, you shoud set a static IP to this machine before doing this, such as: 192.168.1.10 diff --git a/docs/gui-zh.html b/docs/gui-zh.html index f64b9343..9b58303e 100644 --- a/docs/gui-zh.html +++ b/docs/gui-zh.html @@ -1235,70 +1235,70 @@

    bypass bool -仅在 iOS, Android 有效。是否 Bypass, 默认 false. 如果为 true 并且是 domainaddress, 那么必须指定 ipaddressipaddressfrombypassdns. 与 GUI Bypass IP 是或的关系 +是否 Bypass, 默认 false. 如果为 true 并且是 domainaddress, 那么必须指定 ipaddressipaddressfrombypassdns. 与 GUI Bypass IP 是或的关系 false @@ -1928,6 +1956,7 @@

    bypass bool -Only available on iOS, Android. Bypass, default false. If true and domainaddress, then ipaddress or ipaddressfrombypassdns must be specified. It is an OR relationship with GUI Bypass IP +Bypass, default false. If true and domainaddress, then ipaddress or ipaddressfrombypassdns must be specified. It is an OR relationship with GUI Bypass IP false @@ -1928,6 +1956,7 @@

    - +
    @@ -290,7 +290,7 @@
    {{ zh ? '移除某个开机命令' : 'Remove one added command' }}
    - +
    diff --git a/ipk/control/control b/ipk/control/control index 54e2b712..05765100 100644 --- a/ipk/control/control +++ b/ipk/control/control @@ -1,5 +1,5 @@ Package: brook -Version: 20230401 +Version: 20230404.5.1 Architecture: all Maintainer: cloud Homepage: https://github.com/txthinking/brook diff --git a/plugins/dialwithnic/dialwithnic.go b/plugins/dialwithnic/dialwithnic.go index 42d4cbd5..e23cab44 100644 --- a/plugins/dialwithnic/dialwithnic.go +++ b/plugins/dialwithnic/dialwithnic.go @@ -40,15 +40,28 @@ func (p *DialWithNIC) IP(v46 string) (net.IP, error) { if err != nil { return nil, err } - for _, v := range addrs { - if v46 == "6" && v.(*net.IPNet).IP.IsGlobalUnicast() && v.(*net.IPNet).IP.To4() == nil { - return v.(*net.IPNet).IP, nil + if v46 == "6" { + for _, v := range addrs { + if v.(*net.IPNet).IP.IsGlobalUnicast() && v.(*net.IPNet).IP.To4() == nil { + return v.(*net.IPNet).IP, nil + } } - if v46 == "4" && v.(*net.IPNet).IP.IsGlobalUnicast() && v.(*net.IPNet).IP.To4() != nil { - return v.(*net.IPNet).IP, nil + return nil, errors.New("no ipv6 from nic") + } + if v46 == "4" { + for _, v := range addrs { + if v.(*net.IPNet).IP.IsGlobalUnicast() && !v.(*net.IPNet).IP.IsPrivate() && v.(*net.IPNet).IP.To4() != nil { + return v.(*net.IPNet).IP, nil + } + } + for _, v := range addrs { + if v.(*net.IPNet).IP.IsGlobalUnicast() && v.(*net.IPNet).IP.IsPrivate() && v.(*net.IPNet).IP.To4() != nil { + return v.(*net.IPNet).IP, nil + } } + return nil, errors.New("no ipv4 from nic") } - return nil, errors.New("no " + v46 + " ip from " + p.NIC) + return nil, errors.New("black hole") } func (p *DialWithNIC) TouchBrook() { diff --git a/protocol/brook-link-protocol.md b/protocol/brook-link-protocol.md index 105f0040..747be378 100644 --- a/protocol/brook-link-protocol.md +++ b/protocol/brook-link-protocol.md @@ -54,6 +54,7 @@ brook://wsserver?password=hello&wsserver=ws%3A%2F%2F1.2.3.4%3A9999%2Fws - `insecure`: `true` [Optional] - `withoutBrookProtocol`: `true` [Optional] - `ca`: CA content [Optional] + - `tlsfingerprint`: `chrome` [Optional] Example diff --git a/websocket.go b/websocket.go index 6db61b95..8d0d1d3c 100644 --- a/websocket.go +++ b/websocket.go @@ -77,16 +77,30 @@ func WebSocketDial(src, dst, addr, host, path string, tc *tls.Config, timeout in InsecureSkipVerify: tc.InsecureSkipVerify, RootCAs: tc.RootCAs, }, tlsfingerprint) - if !tc.InsecureSkipVerify { - if err := c1.Handshake(); err != nil { - c1.Close() - return nil, err - } - s := host - h, _, err := net.SplitHostPort(host) - if err == nil { - s = h + s := host + h, _, err := net.SplitHostPort(host) + if err == nil { + s = h + } + if err := c1.BuildHandshakeState(); err != nil { + return nil, err + } + for _, v := range c1.Extensions { + if vv, ok := v.(*utls.ALPNExtension); ok { + if tlsfingerprint.Client == "Chrome" { + vv.AlpnProtocols = []string{"http/1.1"} + } + break } + } + if err := c1.BuildHandshakeState(); err != nil { + return nil, err + } + if err := c1.Handshake(); err != nil { + c1.Close() + return nil, err + } + if !tc.InsecureSkipVerify { if err := c1.VerifyHostname(s); err != nil { c1.Close() return nil, err diff --git a/wsserver.go b/wsserver.go index dff7710a..81173ec2 100644 --- a/wsserver.go +++ b/wsserver.go @@ -106,14 +106,14 @@ func (s *WSServer) ListenAndServe() error { Log(err) } }() - t = &tls.Config{GetCertificate: m.GetCertificate} + t = &tls.Config{GetCertificate: m.GetCertificate, ServerName: s.Domain, NextProtos: []string{"http/1.1"}} } if s.Cert != nil && s.CertKey != nil { ct, err := tls.X509KeyPair(s.Cert, s.CertKey) if err != nil { return err } - t = &tls.Config{Certificates: []tls.Certificate{ct}, ServerName: s.Domain} + t = &tls.Config{Certificates: []tls.Certificate{ct}, ServerName: s.Domain, NextProtos: []string{"http/1.1"}} } s.HTTPServer = &http.Server{ Addr: s.Addr,