Minor fixes & Add documentation

This commit is contained in:
世界 2022-08-19 11:35:58 +08:00
parent 32cb511b7c
commit 3dec345680
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
10 changed files with 351 additions and 57 deletions

View File

@ -20,11 +20,7 @@ type TLSDialer struct {
config *tls.Config config *tls.Config
} }
func NewTLS(dialer N.Dialer, serverAddress string, options option.OutboundTLSOptions) (N.Dialer, error) { func TLSConfig(serverAddress string, options option.OutboundTLSOptions) (*tls.Config, error) {
if !options.Enabled {
return dialer, nil
}
var serverName string var serverName string
if options.ServerName != "" { if options.ServerName != "" {
serverName = options.ServerName serverName = options.ServerName
@ -105,9 +101,20 @@ func NewTLS(dialer N.Dialer, serverAddress string, options option.OutboundTLSOpt
} }
tlsConfig.RootCAs = certPool tlsConfig.RootCAs = certPool
} }
return &tlsConfig, nil
}
func NewTLS(dialer N.Dialer, serverAddress string, options option.OutboundTLSOptions) (N.Dialer, error) {
if !options.Enabled {
return dialer, nil
}
tlsConfig, err := TLSConfig(serverAddress, options)
if err != nil {
return nil, err
}
return &TLSDialer{ return &TLSDialer{
dialer: dialer, dialer: dialer,
config: &tlsConfig, config: tlsConfig,
}, nil }, nil
} }

View File

@ -0,0 +1,138 @@
### Structure
```json
{
"inbounds": [
{
"type": "hysteria",
"tag": "hysteria-in",
"listen": "::",
"listen_port": 443,
"sniff": false,
"sniff_override_destination": false,
"domain_strategy": "prefer_ipv6",
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window_client": 0,
"max_conn_client": 0,
"disable_mtu_discovery": false,
"tls": {}
}
]
}
```
!!! warning ""
QUIC, which is required by hysteria is not included by default, see [Installation](/#Installation).
### Listen Fields
#### listen
==Required==
Listen address.
#### listen_port
==Required==
Listen port.
#### sniff
Enable sniffing.
See [Sniff](/configuration/route/sniff/) for details.
#### sniff_override_destination
Override the connection destination address with the sniffed domain.
If the domain name is invalid (like tor), this will not work.
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the requested domain name will be resolved to IP before routing.
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
### Hysteria Fields
#### up, down
==Required==
Format: `[Integer] [Unit]` e.g. `100 Mbps, 640 KBps, 2 Gbps`
Supported units (case sensitive, b = bits, B = bytes, 8b=1B):
bps (bits per second)
Bps (bytes per second)
Kbps (kilobits per second)
KBps (kilobytes per second)
Mbps (megabits per second)
MBps (megabytes per second)
Gbps (gigabits per second)
GBps (gigabytes per second)
Tbps (terabits per second)
TBps (terabytes per second)
#### up_mbps, down_mbps
==Required==
`up, down` in Mbps.
#### obfs
Obfuscated password.
#### auth
Authentication password, in base64.
#### auth_str
Authentication password.
#### recv_window_conn
The QUIC stream-level flow control window for receiving data.
`15728640 (15 MB/s)` will be used if empty.
#### recv_window_client
The QUIC connection-level flow control window for receiving data.
`67108864 (64 MB/s)` will be used if empty.
#### max_conn_client
The maximum number of QUIC concurrent bidirectional streams that a peer is allowed to open.
`1024` will be used if empty.
#### disable_mtu_discovery
Disables Path MTU Discovery (RFC 8899). Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.
Force enabled on for systems other than Linux and Windows (according to upstream).
#### tls
==Required==
TLS configuration, see [TLS inbound structure](/configuration/shared/tls/#inbound-structure).

View File

@ -23,6 +23,7 @@
| `vmess` | [VMess](./vmess) | | `vmess` | [VMess](./vmess) |
| `trojan` | [Trojan](./trojan) | | `trojan` | [Trojan](./trojan) |
| `naive` | [Naive](./naive) | | `naive` | [Naive](./naive) |
| `hysteria` | [Hysteria](./hysteria) |
| `tun` | [Tun](./tun) | | `tun` | [Tun](./tun) |
| `redirect` | [Redirect](./redirect) | | `redirect` | [Redirect](./redirect) |
| `tproxy` | [TProxy](./tproxy) | | `tproxy` | [TProxy](./tproxy) |

View File

@ -0,0 +1,169 @@
### Structure
```json
{
"outbounds": [
{
"type": "hysteria",
"tag": "hysteria-out",
"server": "127.0.0.1",
"server_port": 1080,
"up": "100 Mbps",
"up_mbps": 100,
"down": "100 Mbps",
"down_mbps": 100,
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
"recv_window_conn": 0,
"recv_window": 0,
"disable_mtu_discovery": false,
"network": "tcp",
"tls": {},
"detour": "upstream-out",
"bind_interface": "en0",
"routing_mark": 1234,
"reuse_addr": false,
"connect_timeout": "5s",
"domain_strategy": "prefer_ipv6",
"fallback_delay": "300ms"
}
]
}
```
### Hysteria Fields
#### server
==Required==
The server address.
#### server_port
==Required==
The server port.
#### up, down
==Required==
Format: `[Integer] [Unit]` e.g. `100 Mbps, 640 KBps, 2 Gbps`
Supported units (case sensitive, b = bits, B = bytes, 8b=1B):
bps (bits per second)
Bps (bytes per second)
Kbps (kilobits per second)
KBps (kilobytes per second)
Mbps (megabits per second)
MBps (megabytes per second)
Gbps (gigabits per second)
GBps (gigabytes per second)
Tbps (terabits per second)
TBps (terabytes per second)
#### up_mbps, down_mbps
==Required==
`up, down` in Mbps.
#### obfs
Obfuscated password.
#### auth
Authentication password, in base64.
#### auth_str
Authentication password.
#### recv_window_conn
The QUIC stream-level flow control window for receiving data.
`15728640 (15 MB/s)` will be used if empty.
#### recv_window
The QUIC connection-level flow control window for receiving data.
`67108864 (64 MB/s)` will be used if empty.
#### disable_mtu_discovery
Disables Path MTU Discovery (RFC 8899). Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.
Force enabled on for systems other than Linux and Windows (according to upstream).
#### tls
==Required==
TLS configuration, see [TLS inbound structure](/configuration/shared/tls/#inbound-structure).
#### network
Enabled network
One of `tcp` `udp`.
Both is enabled by default.
### Dial Fields
#### detour
The tag of the upstream outbound.
Other dial fields will be ignored when enabled.
#### bind_interface
The network interface to bind to.
#### routing_mark
!!! error ""
Linux only
The iptables routing mark.
#### reuse_addr
Reuse listener address.
#### connect_timeout
Connect timeout, in golang's Duration format.
A duration string is a possibly signed sequence of
decimal numbers, each with optional fraction and a unit suffix,
such as "300ms", "-1.5h" or "2h45m".
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
#### domain_strategy
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
If set, the server domain name will be resolved to IP before connecting.
`dns.strategy` will be used if empty.
#### fallback_delay
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
That is, is the amount of time to wait for IPv6 to succeed before assuming
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
If zero, a default delay of 300ms is used.
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.

View File

@ -23,6 +23,7 @@
| `vmess` | [VMess](./vmess) | | `vmess` | [VMess](./vmess) |
| `trojan` | [Trojan](./trojan) | | `trojan` | [Trojan](./trojan) |
| `wireguard` | [Wireguard](./wireguard) | | `wireguard` | [Wireguard](./wireguard) |
| `hysteria` | [Hysteria](./hysteria) |
| `dns` | [DNS](./dns) | | `dns` | [DNS](./dns) |
| `selector` | [Selector](./selector) | | `selector` | [Selector](./selector) |

View File

@ -52,7 +52,7 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
MaxConnectionReceiveWindow: options.ReceiveWindowClient, MaxConnectionReceiveWindow: options.ReceiveWindowClient,
MaxIncomingStreams: int64(options.MaxConnClient), MaxIncomingStreams: int64(options.MaxConnClient),
KeepAlivePeriod: hysteria.KeepAlivePeriod, KeepAlivePeriod: hysteria.KeepAlivePeriod,
DisablePathMTUDiscovery: options.DisableMTUDiscovery, DisablePathMTUDiscovery: options.DisableMTUDiscovery || !(C.IsLinux || C.IsWindows),
EnableDatagrams: true, EnableDatagrams: true,
} }
if options.ReceiveWindowConn == 0 { if options.ReceiveWindowConn == 0 {
@ -113,7 +113,7 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
udpSessions: make(map[uint32]chan *hysteria.UDPMessage), udpSessions: make(map[uint32]chan *hysteria.UDPMessage),
} }
if options.TLS == nil || !options.TLS.Enabled { if options.TLS == nil || !options.TLS.Enabled {
return nil, ErrTLSRequired return nil, errTLSRequired
} }
if len(options.TLS.ALPN) == 0 { if len(options.TLS.ALPN) == 0 {
options.TLS.ALPN = []string{hysteria.DefaultALPN} options.TLS.ALPN = []string{hysteria.DefaultALPN}

View File

@ -45,10 +45,7 @@ type Naive struct {
h3Server any h3Server any
} }
var ( var errTLSRequired = E.New("TLS required")
ErrTLSRequired = E.New("TLS required")
ErrNaiveMissingUsers = E.New("missing users")
)
func NewNaive(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.NaiveInboundOptions) (*Naive, error) { func NewNaive(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.NaiveInboundOptions) (*Naive, error) {
inbound := &Naive{ inbound := &Naive{
@ -61,10 +58,10 @@ func NewNaive(ctx context.Context, router adapter.Router, logger log.ContextLogg
authenticator: auth.NewAuthenticator(options.Users), authenticator: auth.NewAuthenticator(options.Users),
} }
if options.TLS == nil || !options.TLS.Enabled { if options.TLS == nil || !options.TLS.Enabled {
return nil, ErrTLSRequired return nil, errTLSRequired
} }
if len(options.Users) == 0 { if len(options.Users) == 0 {
return nil, ErrNaiveMissingUsers return nil, E.New("missing users")
} }
tlsConfig, err := NewTLSConfig(logger, common.PtrValueOrDefault(options.TLS)) tlsConfig, err := NewTLSConfig(logger, common.PtrValueOrDefault(options.TLS))
if err != nil { if err != nil {

View File

@ -50,6 +50,7 @@ nav:
- VMess: configuration/inbound/vmess.md - VMess: configuration/inbound/vmess.md
- Trojan: configuration/inbound/trojan.md - Trojan: configuration/inbound/trojan.md
- Naive: configuration/inbound/naive.md - Naive: configuration/inbound/naive.md
- Hysteria: configuration/inbound/hysteria.md
- Tun: configuration/inbound/tun.md - Tun: configuration/inbound/tun.md
- Redirect: configuration/inbound/redirect.md - Redirect: configuration/inbound/redirect.md
- TProxy: configuration/inbound/tproxy.md - TProxy: configuration/inbound/tproxy.md
@ -63,6 +64,7 @@ nav:
- VMess: configuration/outbound/vmess.md - VMess: configuration/outbound/vmess.md
- Trojan: configuration/outbound/trojan.md - Trojan: configuration/outbound/trojan.md
- WireGuard: configuration/outbound/wireguard.md - WireGuard: configuration/outbound/wireguard.md
- Hysteria: configuration/outbound/hysteria.md
- DNS: configuration/outbound/dns.md - DNS: configuration/outbound/dns.md
- Selector: configuration/outbound/selector.md - Selector: configuration/outbound/selector.md
- Route: - Route:

View File

@ -26,13 +26,9 @@ type HysteriaOutboundOptions struct {
Obfs string `json:"obfs,omitempty"` Obfs string `json:"obfs,omitempty"`
Auth []byte `json:"auth,omitempty"` Auth []byte `json:"auth,omitempty"`
AuthString string `json:"auth_str,omitempty"` AuthString string `json:"auth_str,omitempty"`
ALPN string `json:"alpn,omitempty"`
ServerName string `json:"server_name,omitempty"`
Insecure bool `json:"insecure,omitempty"`
CustomCA string `json:"ca,omitempty"`
CustomCAStr string `json:"ca_str,omitempty"`
ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"` ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
ReceiveWindow uint64 `json:"recv_window,omitempty"` ReceiveWindow uint64 `json:"recv_window,omitempty"`
DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"` DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
Network NetworkList `json:"network,omitempty"` Network NetworkList `json:"network,omitempty"`
TLS *OutboundTLSOptions `json:"tls,omitempty"`
} }

View File

@ -5,9 +5,7 @@ package outbound
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"crypto/x509"
"net" "net"
"os"
"sync" "sync"
"github.com/sagernet/quic-go" "github.com/sagernet/quic-go"
@ -45,34 +43,19 @@ type Hysteria struct {
udpDefragger hysteria.Defragger udpDefragger hysteria.Defragger
} }
var errTLSRequired = E.New("TLS required")
func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HysteriaOutboundOptions) (*Hysteria, error) { func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HysteriaOutboundOptions) (*Hysteria, error) {
tlsConfig := &tls.Config{ if options.TLS == nil || !options.TLS.Enabled {
ServerName: options.ServerName, return nil, errTLSRequired
InsecureSkipVerify: options.Insecure,
MinVersion: tls.VersionTLS13,
} }
if options.ALPN != "" { tlsConfig, err := dialer.TLSConfig(options.Server, common.PtrValueOrDefault(options.TLS))
tlsConfig.NextProtos = []string{options.ALPN}
} else {
tlsConfig.NextProtos = []string{hysteria.DefaultALPN}
}
var ca []byte
var err error
if options.CustomCA != "" {
ca, err = os.ReadFile(options.CustomCA)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} tlsConfig.MinVersion = tls.VersionTLS13
if options.CustomCAStr != "" { if len(tlsConfig.NextProtos) == 0 {
ca = []byte(options.CustomCAStr) tlsConfig.NextProtos = []string{hysteria.DefaultALPN}
}
if len(ca) > 0 {
cp := x509.NewCertPool()
if !cp.AppendCertsFromPEM(ca) {
return nil, E.New("parse ca failed")
}
tlsConfig.RootCAs = cp
} }
quicConfig := &quic.Config{ quicConfig := &quic.Config{
InitialStreamReceiveWindow: options.ReceiveWindowConn, InitialStreamReceiveWindow: options.ReceiveWindowConn,