github.com/xraypb/xray-core@v1.6.6/infra/conf/shadowsocks.go (about) 1 package conf 2 3 import ( 4 "strings" 5 6 "github.com/golang/protobuf/proto" 7 "github.com/sagernet/sing-shadowsocks/shadowaead_2022" 8 C "github.com/sagernet/sing/common" 9 "github.com/xraypb/xray-core/common/protocol" 10 "github.com/xraypb/xray-core/common/serial" 11 "github.com/xraypb/xray-core/proxy/shadowsocks" 12 "github.com/xraypb/xray-core/proxy/shadowsocks_2022" 13 ) 14 15 func cipherFromString(c string) shadowsocks.CipherType { 16 switch strings.ToLower(c) { 17 case "aes-128-gcm", "aead_aes_128_gcm": 18 return shadowsocks.CipherType_AES_128_GCM 19 case "aes-256-gcm", "aead_aes_256_gcm": 20 return shadowsocks.CipherType_AES_256_GCM 21 case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305": 22 return shadowsocks.CipherType_CHACHA20_POLY1305 23 case "xchacha20-poly1305", "aead_xchacha20_poly1305", "xchacha20-ietf-poly1305": 24 return shadowsocks.CipherType_XCHACHA20_POLY1305 25 case "none", "plain": 26 return shadowsocks.CipherType_NONE 27 default: 28 return shadowsocks.CipherType_UNKNOWN 29 } 30 } 31 32 type ShadowsocksUserConfig struct { 33 Cipher string `json:"method"` 34 Password string `json:"password"` 35 Level byte `json:"level"` 36 Email string `json:"email"` 37 Address *Address `json:"address"` 38 Port uint16 `json:"port"` 39 } 40 41 type ShadowsocksServerConfig struct { 42 Cipher string `json:"method"` 43 Password string `json:"password"` 44 Level byte `json:"level"` 45 Email string `json:"email"` 46 Users []*ShadowsocksUserConfig `json:"clients"` 47 NetworkList *NetworkList `json:"network"` 48 IVCheck bool `json:"ivCheck"` 49 } 50 51 func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { 52 if C.Contains(shadowaead_2022.List, v.Cipher) { 53 return buildShadowsocks2022(v) 54 } 55 56 config := new(shadowsocks.ServerConfig) 57 config.Network = v.NetworkList.Build() 58 59 if v.Users != nil { 60 for _, user := range v.Users { 61 account := &shadowsocks.Account{ 62 Password: user.Password, 63 CipherType: cipherFromString(user.Cipher), 64 IvCheck: v.IVCheck, 65 } 66 if account.Password == "" { 67 return nil, newError("Shadowsocks password is not specified.") 68 } 69 if account.CipherType < shadowsocks.CipherType_AES_128_GCM || 70 account.CipherType > shadowsocks.CipherType_XCHACHA20_POLY1305 { 71 return nil, newError("unsupported cipher method: ", user.Cipher) 72 } 73 config.Users = append(config.Users, &protocol.User{ 74 Email: user.Email, 75 Level: uint32(user.Level), 76 Account: serial.ToTypedMessage(account), 77 }) 78 } 79 } else { 80 account := &shadowsocks.Account{ 81 Password: v.Password, 82 CipherType: cipherFromString(v.Cipher), 83 IvCheck: v.IVCheck, 84 } 85 if account.Password == "" { 86 return nil, newError("Shadowsocks password is not specified.") 87 } 88 if account.CipherType == shadowsocks.CipherType_UNKNOWN { 89 return nil, newError("unknown cipher method: ", v.Cipher) 90 } 91 config.Users = append(config.Users, &protocol.User{ 92 Email: v.Email, 93 Level: uint32(v.Level), 94 Account: serial.ToTypedMessage(account), 95 }) 96 } 97 98 return config, nil 99 } 100 101 func buildShadowsocks2022(v *ShadowsocksServerConfig) (proto.Message, error) { 102 if len(v.Users) == 0 { 103 config := new(shadowsocks_2022.ServerConfig) 104 config.Method = v.Cipher 105 config.Key = v.Password 106 config.Network = v.NetworkList.Build() 107 config.Email = v.Email 108 return config, nil 109 } 110 111 if v.Cipher == "" { 112 return nil, newError("shadowsocks 2022 (multi-user): missing server method") 113 } 114 if !strings.Contains(v.Cipher, "aes") { 115 return nil, newError("shadowsocks 2022 (multi-user): only blake3-aes-*-gcm methods are supported") 116 } 117 118 if v.Users[0].Address == nil { 119 config := new(shadowsocks_2022.MultiUserServerConfig) 120 config.Method = v.Cipher 121 config.Key = v.Password 122 config.Network = v.NetworkList.Build() 123 124 for _, user := range v.Users { 125 if user.Cipher != "" { 126 return nil, newError("shadowsocks 2022 (multi-user): users must have empty method") 127 } 128 config.Users = append(config.Users, &shadowsocks_2022.User{ 129 Key: user.Password, 130 Email: user.Email, 131 }) 132 } 133 return config, nil 134 } 135 136 config := new(shadowsocks_2022.RelayServerConfig) 137 config.Method = v.Cipher 138 config.Key = v.Password 139 config.Network = v.NetworkList.Build() 140 for _, user := range v.Users { 141 if user.Cipher != "" { 142 return nil, newError("shadowsocks 2022 (relay): users must have empty method") 143 } 144 if user.Address == nil { 145 return nil, newError("shadowsocks 2022 (relay): all users must have relay address") 146 } 147 config.Destinations = append(config.Destinations, &shadowsocks_2022.RelayDestination{ 148 Key: user.Password, 149 Email: user.Email, 150 Address: user.Address.Build(), 151 Port: uint32(user.Port), 152 }) 153 } 154 return config, nil 155 } 156 157 type ShadowsocksServerTarget struct { 158 Address *Address `json:"address"` 159 Port uint16 `json:"port"` 160 Cipher string `json:"method"` 161 Password string `json:"password"` 162 Email string `json:"email"` 163 Level byte `json:"level"` 164 IVCheck bool `json:"ivCheck"` 165 UoT bool `json:"uot"` 166 } 167 168 type ShadowsocksClientConfig struct { 169 Servers []*ShadowsocksServerTarget `json:"servers"` 170 } 171 172 func (v *ShadowsocksClientConfig) Build() (proto.Message, error) { 173 if len(v.Servers) == 0 { 174 return nil, newError("0 Shadowsocks server configured.") 175 } 176 177 if len(v.Servers) == 1 { 178 server := v.Servers[0] 179 if C.Contains(shadowaead_2022.List, server.Cipher) { 180 if server.Address == nil { 181 return nil, newError("Shadowsocks server address is not set.") 182 } 183 if server.Port == 0 { 184 return nil, newError("Invalid Shadowsocks port.") 185 } 186 if server.Password == "" { 187 return nil, newError("Shadowsocks password is not specified.") 188 } 189 190 config := new(shadowsocks_2022.ClientConfig) 191 config.Address = server.Address.Build() 192 config.Port = uint32(server.Port) 193 config.Method = server.Cipher 194 config.Key = server.Password 195 config.UdpOverTcp = server.UoT 196 return config, nil 197 } 198 } 199 200 config := new(shadowsocks.ClientConfig) 201 serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers)) 202 for idx, server := range v.Servers { 203 if C.Contains(shadowaead_2022.List, server.Cipher) { 204 return nil, newError("Shadowsocks 2022 accept no multi servers") 205 } 206 if server.Address == nil { 207 return nil, newError("Shadowsocks server address is not set.") 208 } 209 if server.Port == 0 { 210 return nil, newError("Invalid Shadowsocks port.") 211 } 212 if server.Password == "" { 213 return nil, newError("Shadowsocks password is not specified.") 214 } 215 account := &shadowsocks.Account{ 216 Password: server.Password, 217 } 218 account.CipherType = cipherFromString(server.Cipher) 219 if account.CipherType == shadowsocks.CipherType_UNKNOWN { 220 return nil, newError("unknown cipher method: ", server.Cipher) 221 } 222 223 account.IvCheck = server.IVCheck 224 225 ss := &protocol.ServerEndpoint{ 226 Address: server.Address.Build(), 227 Port: uint32(server.Port), 228 User: []*protocol.User{ 229 { 230 Level: uint32(server.Level), 231 Email: server.Email, 232 Account: serial.ToTypedMessage(account), 233 }, 234 }, 235 } 236 237 serverSpecs[idx] = ss 238 } 239 240 config.Server = serverSpecs 241 242 return config, nil 243 }