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