You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -14,7 +14,6 @@ For a more detailed analysis of the routing function, please refer to [Routing F
14
14
{
15
15
"routing": {
16
16
"domainStrategy": "AsIs",
17
-
"domainMatcher": "hybrid",
18
17
"rules": [],
19
18
"balancers": []
20
19
}
@@ -25,20 +24,17 @@ For a more detailed analysis of the routing function, please refer to [Routing F
25
24
26
25
The domain name resolution strategy, which uses different strategies based on different settings.
27
26
28
-
-`"AsIs"`: Use only the domain name for routing selection. Default value.
27
+
-`"AsIs"`: No additional processing is performed. The domain name from the destination address or the sniffed domain is used for routing selection. Default value.
28
+
-`"IPIfNonMatch"`: After a full round of matching, if no rule is matched, the domain name is resolved to an IP address and a second matching pass is performed;
29
+
-`"IPOnDemand"`: Before starting the matching process, directly resolve the domain name to the IP address for matching;
29
30
30
-
-`"IPIfNonMatch"`: If the domain name does not match any rule, resolve the domain name into an IP address (A record or AAAA record) and match it again;
31
-
- When a domain name has multiple A records, it will try to match all A records until one of them matches a rule;
32
-
- The resolved IP only works for routing selection, and the original domain name is still used in the forwarded packets;
31
+
The actual resolution action is deferred until the first encounter with an IP rule to reduce latency. The result will include both IPv4 and IPv6 (you can further restrict this using the built-in DNS's `queryStrategy`). When a domain name resolves to multiple IPs, each rule will try all IPs sequentially; a rule is considered a hit if any IP matches the requirement.
33
32
34
-
-`"IPOnDemand"`: If any IP-based rules are encountered during matching, immediately resolve the domain name into an IP address for matching;
33
+
When `sniff + routeOnly` is enabled, allowing the routing system to see both the IP and the domain name simultaneously, if the above resolution occurs, the routing system will only see the IP resolved from the domain name and not the original target IP, unless the resolution fails.
35
34
36
-
> `domainMatcher`: "hybrid" | "linear"
35
+
When two domains exist (target domain + sniff result), the sniff result always has higher priority, whether used for resolution or domain name matching.
37
36
38
-
The domain name matching algorithm, which uses different algorithms based on different settings. This option affects all `RuleObject` that do not have a separately specified matching algorithm.
39
-
40
-
-`"hybrid"`: Use the new domain name matching algorithm, which is faster and takes up less space. Default value.
41
-
-`"linear"`: Use the original domain name matching algorithm.
37
+
Regardless of whether the resolution is performed or not, the routing system does not affect the actual target address; the requested target remains the original target.
42
38
43
39
> `rules`: [[RuleObject](#ruleobject)]
44
40
@@ -60,46 +56,39 @@ When a rule points to a load balancer, Xray selects an outbound through this loa
When multiple attributes are specified at the same time, these attributes need to be satisfied **simultaneously** in order for the current rule to take effect.
82
80
:::
83
81
84
-
> `domainMatcher`: "hybrid" | "linear"
85
-
86
-
The domain matching algorithm used varies depending on the settings. The option here takes priority over the `domainMatcher` configured in `RoutingObject`.
87
-
88
-
-`"hybrid"`: uses a new domain matching algorithm that is faster and takes up less space. This is the default value.
89
-
-`"linear"`: uses the original domain matching algorithm.
90
-
91
-
> `type`: "field"
92
-
93
-
Currently, only the option `"field"` is supported.
94
-
95
82
> `domain`: [string]
96
83
97
84
An array where each item is a domain match. There are several forms:
98
85
99
-
- Plain string: If this string matches any part of the target domain, the rule takes effect. For example, "sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
100
-
- Regular expression: Starts with `"regexp:"` followed by a regular expression. When this regular expression matches the target domain, the rule takes effect. For example, "regexp:\\\\.goo.\*\\\\.com$" matches "www.google.com" or "fonts.googleapis.com", but not "google.com".
86
+
- Plain string: Same as the substring below, but the "keyword:" prefix can be omitted.
87
+
- Regular expression: Starts with `"regexp:"` followed by a regular expression. When this regular expression matches the target domain, the rule takes effect. For example, "regexp:\\\\.goo.\*\\\\.com$" matches "www.google.com" and "fonts.googleapis.com", but not "google.com". Case sensitive.
101
88
- Subdomain (recommended): Starts with `"domain:"` followed by a domain. When this domain is the target domain or a subdomain of the target domain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
89
+
- Substring: Begins with `"keyword:"`, the remainder is a string. This rule applies when this string matches any part of the target domain. For example, "keyword:sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
102
90
- Exact match: Starts with `"full:"` followed by a domain. When this domain is an exact match for the target domain, the rule takes effect. For example, "full:xray.com" matches "xray.com" but not "www.xray.com".
91
+
- Dotless domain name: Begins with `"dotless:"`, followed by a string that cannot contain periods (.). This rule applies when the domain name does not contain periods (.) and this string matches any part of the target domain name. For example, "dotless:pc-" can match "pc-alice" and "mypc-alice", suitable for internal NetBIOS domains, etc. Case sensitive.
103
92
- Predefined domain list: Starts with `"geosite:"` followed by a name such as `geosite:google` or `geosite:cn`. The names and domain lists are listed in [Predefined Domain List](#predefined-domain-lists).
104
93
- Load domains from a file: Formatted as `"ext:file:tag"`, where the file is stored in the [resource directory](./features/env.md#resource-file-path) and has the same format as `geosite.dat`. The tag must exist in the file.
105
94
@@ -112,12 +101,10 @@ An array where each item is a domain match. There are several forms:
112
101
An array where each item represents an IP range. This rule will take effect when the target IP matches any of the IP ranges in the array. There are several types of IP ranges:
113
102
114
103
- IP: In the format of `"127.0.0.1"`.
115
-
116
-
-[CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing): In the format of `"10.0.0.0/8"`.
117
-
104
+
-[CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing): In the format of `"10.0.0.0/8"`, or you can use `"0.0.0.0/0"``::/0"` to specify all IPv4 or IPv6.
118
105
- Predefined IP lists: These lists are included in every Xray installation package under the file name `geoip.dat`. They can be used in the format of `"geoip:cn"`, where `cn` is a two-letter country code. The prefix `geoip:`(all lowercase) must be used, and nearly all countries that have internet access are supported.
119
106
- Special value: `"geoip:private"`, which includes all private addresses, such as `127.0.0.1`.
120
-
107
+
- The `!` function negates the selection; `"geoip:!cn"` represents results other than those in `geoip:cn`. Multiple negations are related by `AND`, while positive options, positive options, and all negations are related by `OR`. For example, `ip: ["geoip:!cn", "geoip:!us", "geoip:telegram"]` matches IPs that are neither in the US nor China, or IPs from Telegram.
121
108
- Loading IP from a file: In the format of `"ext:file:tag"`, where `file` is the file name and `tag` is a label that must exist in the file. The prefix `ext:` (all lowercase) must be used, and the file should be located in the [resource directory](./features/env.md#resource-file-path) with the same format as `geoip.dat`.
122
109
123
110
> `port`: number | string
@@ -136,41 +123,80 @@ The source port, which can take on three forms:
136
123
-`a`: `a` is a positive integer less than 65536. This rule will take effect when the source port is `a`.
137
124
- A mixture of the above two forms, separated by commas ",". For example: `"53,443,1000-2000"`.
138
125
126
+
> `localPort`:number | string
127
+
128
+
The local inbound port, in the same format as `port`/`sourcePort`, may be useful when listening on a range of inbound ports.
129
+
139
130
> `network`: "tcp" | "udp" | "tcp,udp"
140
131
141
132
This can be "tcp", "udp", or "tcp,udp". This rule will take effect when the connection method is the specified one.
142
133
143
-
> `source`: [string]
134
+
Since the core clearly supports only two Layer-4 protocols, TCP and UDP, a routing rule that contains only the "network": "tcp,udp" condition can be used as a catch-all to match any traffic. A typical use case is to place such a rule at the very end of the routing rule list to specify the default outbound when no other rules match (otherwise, the core uses the first one by default).
135
+
136
+
Of course, other obvious ways to match all traffic—such as specifying ports 1–65535, or using 0.0.0.0/0 together with ::/0 as IP conditions—serve a similar purpose.
137
+
138
+
> `sourceIP`: [string]
144
139
145
140
An array where each item represents an IP range in the format of IP, CIDR, GeoIP, or loading IP from a file. This rule will take effect when the source IP matches any of the IP ranges in the array.
146
141
142
+
alias: `source`
143
+
144
+
> `localIP`: \[string\]
145
+
146
+
The format is the same as other IP fields and is used to specify the IP address on which the local inbound connection is received. When listening on 0.0.0.0, different actual incoming IP addresses will result in different localIP values.
147
+
148
+
This field is not effective for UDP. Due to the message-oriented nature of UDP, the local IP cannot be tracked, and the listener IP is always reported.
149
+
147
150
> `user`: [string]
148
151
149
152
An array where each item represents an email address. This rule will take effect when the source user matches any of the email addresses in the array.
150
153
154
+
Similar to domain matching, this field also supports regular-expression matching with the `regexp:` prefix (note that `\` must be escaped as `\\`; see the explanation in the domain section).
155
+
156
+
> `vlessRoute`: number | string
157
+
158
+
For VLESS inbounds, the client is allowed to modify the 7th and 8th bytes of the configured UUID to any value. The server-side routing system uses these two bytes as vlessRoute data, allowing users to customize server-side routing behavior without changing any external fields.
159
+
160
+
```
161
+
--------------↓↓↓↓------------------
162
+
xxxxxxxx-xxxx-0000-xxxx-xxxxxxxxxxxx
163
+
```
164
+
165
+
In the configuration, the value is interpreted as a big-endian uint16. (If this sounds confusing, simply treat these four hexadecimal digits as a single hexadecimal number and convert it to decimal). For example: `0001 → 1`, `000e → 14`, `38b2 → 14514`. This design is used so that the syntax matches `port`, allowing multiple ranges to be specified freely for routing, just like port-based routing.
166
+
151
167
> `inboundTag`: [string]
152
168
153
169
An array where each item represents an identifier. This rule will take effect when the inbound protocol matches any of the identifiers in the array.
An array where each item represents a protocol. This rule will take effect when the protocol of the current connection matches any of the protocols in the array.
158
174
175
+
`http` Only HTTP/1.0 and HTTP/1.1 are supported; HTTP/2 (h2) is not currently supported. (Plaintext h2 traffic is also very rare.)
176
+
177
+
`tls` TLS versions 1.0 through 1.3 are supported.
178
+
179
+
`quic` Due to the complexity of the protocol, sniffing may occasionally fail.
180
+
181
+
`bittorrent` Only very basic sniffing is supported and may not work with many encrypted or obfuscated variants.
182
+
159
183
::: tip
160
184
The `sniffing` option in the inbound proxy must be enabled to detect the protocol type used by the connection.
161
185
:::
162
186
163
187
`attrs`: object
164
188
165
-
A json object with string keys and values, used to detect the HTTP headers of the traffic. It matches when all specified keys exist in the header and corresponding values are a substring of the header value. The key is case in-sensitive. You can use regex to match with value.
189
+
A JSON object in which both keys and values are strings. It is used to match attributes of HTTP traffic (for obvious reasons, only HTTP/1.0 and HTTP/1.1 are supported). A rule is considered matched when the HTTP headers contain **all** specified keys and the corresponding values contain the specified substrings.Header names are case-insensitive. Values support regular-expression matching.
166
190
167
-
Currently, only the inbound HTTP proxy sets this attribute.
191
+
Pseudo-headers similar to those in HTTP/2, such as `:method` and `:path`, are also supported for matching the request method and path (even though these headers do not exist in HTTP/1.1).
192
+
193
+
For HTTP inbounds using non-`CONNECT` methods, the attributes can be obtained directly. For other inbounds, sniffing must be enabled in order to obtain these values for matching.
168
194
169
195
Examples:
170
196
171
197
- Detect HTTP GET:`{":method": "GET"}`
172
-
- Detect HTTP Path:`{":path": "/test"}"`
173
-
- Detect Content Type:`{"accept": "text/html"}"`
198
+
- Detect HTTP Path:`{":path": "/test"}`
199
+
- Detect Content Type:`{"accept": "text/html"}`
174
200
175
201
> `outboundTag`: string
176
202
@@ -184,14 +210,22 @@ Corresponds to the identifier of a balancer.
184
210
`balancerTag` and `outboundTag` are mutually exclusive. When both are specified, `outboundTag` takes effect.
185
211
:::
186
212
213
+
> `ruleTag`: string
214
+
215
+
Optional. Has no functional effect and is used only to identify the rule.
216
+
217
+
When set, relevant information will be logged at the Info level when this rule is matched, which is useful for debugging and determining which routing rule was applied.
218
+
187
219
### BalancerObject
188
220
189
221
Load balancer configuration. When a load balancer is in effect, it selects the most appropriate outbound from the specified outbound according to the configuration and forwards traffic.
190
222
191
223
```json
192
224
{
193
225
"tag": "balancer",
194
-
"selector": []
226
+
"selector": [],
227
+
"fallbackTag": "outbound",
228
+
"strategy": {}
195
229
}
196
230
```
197
231
@@ -203,7 +237,133 @@ The identifier of this load balancer, used to match `balancerTag` in `RuleObject
203
237
204
238
An array of strings, each of which will be used to match the prefix of the outbound identifier. For example, in the following outbound identifiers: `[ "a", "ab", "c", "ba" ]`, `"selector": ["a"]` will match `[ "a", "ab" ]`.
205
239
206
-
If multiple outbounds are matched, the load balancer currently selects one randomly as the final outbound.
240
+
Generally, multiple outbounds are matched to distribute the load evenly.
241
+
242
+
> `fallbackTag`: string
243
+
244
+
If all outbounds fail to connect based on the connection observation results, the outbound specified by this configuration item will be used.
245
+
246
+
Note: You need to add either the [observatory](./observatory.md#observatoryobject) or [burstObservatory](./observatory.md#burstobservatoryobject) configuration item.
-`random` Default value. Randomly selects one of the matched outbound proxies.
262
+
-`roundRobin` Selects matched outbound proxies in sequential order.
263
+
-`leastPing` Selects the matched outbound proxy with the lowest latency based on connection observation results. Requires either the [observatory](./observatory.md#observatoryobject) or [burstObservatory](./observatory.md#burstobservatoryobject) configuration to be enabled.
264
+
-`leastLoad` Selects the most stable matched outbound proxy based on connection observation results. Requires either the [observatory](./observatory.md#observatoryobject) or [burstObservatory](./observatory.md#burstobservatoryobject) configuration to be enabled.
265
+
266
+
::: tip
267
+
Regardless of the selected strategy, once all nodes referenced by the `selector` are configured with either `observatory` or `burstObservatory`, unhealthy nodes can be filtered out. If no healthy nodes are available, `fallbackTag` will be attempted.
This is an optional configuration object. The configuration format varies depending on the load-balancing strategy. Currently, only the `leastLoad` strategy supports this configuration.
275
+
276
+
```json
277
+
{
278
+
"expected": 2,
279
+
"maxRTT": "1s",
280
+
"tolerance": 0.01,
281
+
"baselines": ["1s"],
282
+
"costs": [
283
+
{
284
+
"regexp": false,
285
+
"match": "tag",
286
+
"value": 0.5
287
+
}
288
+
]
289
+
}
290
+
```
291
+
292
+
> `expected`: number
293
+
294
+
The number of optimal nodes selected by the load balancer. Traffic will be randomly distributed among these nodes.
295
+
296
+
> `maxRTT`: string
297
+
298
+
The maximum acceptable RTT for latency measurements.
299
+
300
+
> `tolerance`: float
301
+
302
+
The maximum acceptable ratio of failed latency measurements. For example, `0.01` allows up to 1% of measurements to fail. (Appears to be not yet implemented.)
303
+
304
+
> `baselines`: [string]
305
+
306
+
The maximum acceptable standard deviation of RTT measurements.
307
+
308
+
> `costs`: [CostObject]
309
+
310
+
Optional. An array used to assign weights to outbounds.
311
+
312
+
> `regexp`: `true` | `false`
313
+
314
+
Whether to use a regular expression to match the outbound `tag`.
315
+
316
+
> `match`: string
317
+
318
+
The outbound `tag` to match.
319
+
320
+
> `value`: float
321
+
322
+
The weight value. A higher value makes the corresponding node less likely to be selected.
0 commit comments