github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/common/tls/reality_server.go (about) 1 //go:build with_reality_server 2 3 package tls 4 5 import ( 6 "context" 7 "crypto/tls" 8 "encoding/base64" 9 "encoding/hex" 10 "net" 11 "time" 12 13 "github.com/inazumav/sing-box/adapter" 14 "github.com/inazumav/sing-box/common/dialer" 15 "github.com/inazumav/sing-box/log" 16 "github.com/inazumav/sing-box/option" 17 "github.com/sagernet/reality" 18 "github.com/sagernet/sing/common/debug" 19 E "github.com/sagernet/sing/common/exceptions" 20 M "github.com/sagernet/sing/common/metadata" 21 N "github.com/sagernet/sing/common/network" 22 "github.com/sagernet/sing/common/ntp" 23 ) 24 25 var _ ServerConfigCompat = (*RealityServerConfig)(nil) 26 27 type RealityServerConfig struct { 28 config *reality.Config 29 } 30 31 func NewRealityServer(ctx context.Context, logger log.Logger, options option.InboundTLSOptions) (*RealityServerConfig, error) { 32 var tlsConfig reality.Config 33 34 if options.ACME != nil && len(options.ACME.Domain) > 0 { 35 return nil, E.New("acme is unavailable in reality") 36 } 37 tlsConfig.Time = ntp.TimeFuncFromContext(ctx) 38 if options.ServerName != "" { 39 tlsConfig.ServerName = options.ServerName 40 } 41 if len(options.ALPN) > 0 { 42 tlsConfig.NextProtos = append(tlsConfig.NextProtos, options.ALPN...) 43 } 44 if options.MinVersion != "" { 45 minVersion, err := ParseTLSVersion(options.MinVersion) 46 if err != nil { 47 return nil, E.Cause(err, "parse min_version") 48 } 49 tlsConfig.MinVersion = minVersion 50 } 51 if options.MaxVersion != "" { 52 maxVersion, err := ParseTLSVersion(options.MaxVersion) 53 if err != nil { 54 return nil, E.Cause(err, "parse max_version") 55 } 56 tlsConfig.MaxVersion = maxVersion 57 } 58 if options.CipherSuites != nil { 59 find: 60 for _, cipherSuite := range options.CipherSuites { 61 for _, tlsCipherSuite := range tls.CipherSuites() { 62 if cipherSuite == tlsCipherSuite.Name { 63 tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, tlsCipherSuite.ID) 64 continue find 65 } 66 } 67 return nil, E.New("unknown cipher_suite: ", cipherSuite) 68 } 69 } 70 if len(options.Certificate) > 0 || options.CertificatePath != "" { 71 return nil, E.New("certificate is unavailable in reality") 72 } 73 if len(options.Key) > 0 || options.KeyPath != "" { 74 return nil, E.New("key is unavailable in reality") 75 } 76 77 tlsConfig.SessionTicketsDisabled = true 78 tlsConfig.Type = N.NetworkTCP 79 tlsConfig.Dest = options.Reality.Handshake.ServerOptions.Build().String() 80 81 tlsConfig.ServerNames = map[string]bool{options.ServerName: true} 82 privateKey, err := base64.RawURLEncoding.DecodeString(options.Reality.PrivateKey) 83 if err != nil { 84 return nil, E.Cause(err, "decode private key") 85 } 86 if len(privateKey) != 32 { 87 return nil, E.New("invalid private key") 88 } 89 tlsConfig.PrivateKey = privateKey 90 tlsConfig.MaxTimeDiff = time.Duration(options.Reality.MaxTimeDifference) 91 92 tlsConfig.ShortIds = make(map[[8]byte]bool) 93 for i, shortIDString := range options.Reality.ShortID { 94 var shortID [8]byte 95 decodedLen, err := hex.Decode(shortID[:], []byte(shortIDString)) 96 if err != nil { 97 return nil, E.Cause(err, "decode short_id[", i, "]: ", shortIDString) 98 } 99 if decodedLen > 8 { 100 return nil, E.New("invalid short_id[", i, "]: ", shortIDString) 101 } 102 tlsConfig.ShortIds[shortID] = true 103 } 104 105 handshakeDialer, err := dialer.New(adapter.RouterFromContext(ctx), options.Reality.Handshake.DialerOptions) 106 if err != nil { 107 return nil, err 108 } 109 tlsConfig.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { 110 return handshakeDialer.DialContext(ctx, network, M.ParseSocksaddr(addr)) 111 } 112 113 if debug.Enabled { 114 tlsConfig.Show = true 115 } 116 117 return &RealityServerConfig{&tlsConfig}, nil 118 } 119 120 func (c *RealityServerConfig) ServerName() string { 121 return c.config.ServerName 122 } 123 124 func (c *RealityServerConfig) SetServerName(serverName string) { 125 c.config.ServerName = serverName 126 } 127 128 func (c *RealityServerConfig) NextProtos() []string { 129 return c.config.NextProtos 130 } 131 132 func (c *RealityServerConfig) SetNextProtos(nextProto []string) { 133 c.config.NextProtos = nextProto 134 } 135 136 func (c *RealityServerConfig) Config() (*tls.Config, error) { 137 return nil, E.New("unsupported usage for reality") 138 } 139 140 func (c *RealityServerConfig) Client(conn net.Conn) (Conn, error) { 141 return ClientHandshake(context.Background(), conn, c) 142 } 143 144 func (c *RealityServerConfig) Start() error { 145 return nil 146 } 147 148 func (c *RealityServerConfig) Close() error { 149 return nil 150 } 151 152 func (c *RealityServerConfig) Server(conn net.Conn) (Conn, error) { 153 return ServerHandshake(context.Background(), conn, c) 154 } 155 156 func (c *RealityServerConfig) ServerHandshake(ctx context.Context, conn net.Conn) (Conn, error) { 157 tlsConn, err := reality.Server(ctx, conn, c.config) 158 if err != nil { 159 return nil, err 160 } 161 return &realityConnWrapper{Conn: tlsConn}, nil 162 } 163 164 func (c *RealityServerConfig) Clone() Config { 165 return &RealityServerConfig{ 166 config: c.config.Clone(), 167 } 168 } 169 170 var _ Conn = (*realityConnWrapper)(nil) 171 172 type realityConnWrapper struct { 173 *reality.Conn 174 } 175 176 func (c *realityConnWrapper) ConnectionState() ConnectionState { 177 state := c.Conn.ConnectionState() 178 return tls.ConnectionState{ 179 Version: state.Version, 180 HandshakeComplete: state.HandshakeComplete, 181 DidResume: state.DidResume, 182 CipherSuite: state.CipherSuite, 183 NegotiatedProtocol: state.NegotiatedProtocol, 184 NegotiatedProtocolIsMutual: state.NegotiatedProtocolIsMutual, 185 ServerName: state.ServerName, 186 PeerCertificates: state.PeerCertificates, 187 VerifiedChains: state.VerifiedChains, 188 SignedCertificateTimestamps: state.SignedCertificateTimestamps, 189 OCSPResponse: state.OCSPResponse, 190 TLSUnique: state.TLSUnique, 191 } 192 } 193 194 func (c *realityConnWrapper) Upstream() any { 195 return c.Conn 196 }