Ensure VLESS users include encryption field (#588)
This commit is contained in:
parent
80b0b12dc0
commit
ef2e4088ef
@ -14,14 +14,19 @@ const (
|
||||
// DefaultFlow is applied to VLESS clients when no explicit flow is
|
||||
// provided. It matches the tlsSettings baked into the template.
|
||||
DefaultFlow = "xtls-rprx-vision"
|
||||
|
||||
// DefaultEncryption is required by Xray for all VLESS users in the
|
||||
// outbound array.
|
||||
DefaultEncryption = "none"
|
||||
)
|
||||
|
||||
// Client represents an entry under outbounds[].settings.vnext[].users[] in the Xray
|
||||
// config.
|
||||
type Client struct {
|
||||
ID string
|
||||
Email string
|
||||
Flow string
|
||||
ID string
|
||||
Email string
|
||||
Flow string
|
||||
Encryption string
|
||||
}
|
||||
|
||||
// Generator updates the Xray configuration file based on a template and a set of
|
||||
@ -111,6 +116,11 @@ func replaceClients(root map[string]interface{}, clients []Client) error {
|
||||
flow = DefaultFlow
|
||||
}
|
||||
entry["flow"] = flow
|
||||
encryption := strings.TrimSpace(client.Encryption)
|
||||
if encryption == "" {
|
||||
encryption = DefaultEncryption
|
||||
}
|
||||
entry["encryption"] = encryption
|
||||
clientObjects = append(clientObjects, entry)
|
||||
}
|
||||
|
||||
|
||||
@ -13,9 +13,10 @@ type testConfig struct {
|
||||
Settings struct {
|
||||
VNext []struct {
|
||||
Users []struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Flow string `json:"flow,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Flow string `json:"flow,omitempty"`
|
||||
Encryption string `json:"encryption"`
|
||||
} `json:"users"`
|
||||
Address string `json:"address"`
|
||||
} `json:"vnext"`
|
||||
@ -57,7 +58,7 @@ func TestGeneratorGenerate(t *testing.T) {
|
||||
}
|
||||
|
||||
clients := []Client{
|
||||
{ID: "uuid-a", Email: "a@demo", Flow: "xtls-rprx-vision"},
|
||||
{ID: "uuid-a", Email: "a@demo", Flow: "xtls-rprx-vision", Encryption: "custom"},
|
||||
{ID: "uuid-b"},
|
||||
}
|
||||
|
||||
@ -94,7 +95,10 @@ func TestGeneratorGenerate(t *testing.T) {
|
||||
if gotUsers[0].Flow != "xtls-rprx-vision" {
|
||||
t.Fatalf("unexpected first user flow: %+v", gotUsers[0])
|
||||
}
|
||||
if gotUsers[1].ID != "uuid-b" || gotUsers[1].Email != "" || gotUsers[1].Flow != DefaultFlow {
|
||||
if gotUsers[0].Encryption != "custom" {
|
||||
t.Fatalf("unexpected first user encryption: %+v", gotUsers[0])
|
||||
}
|
||||
if gotUsers[1].ID != "uuid-b" || gotUsers[1].Email != "" || gotUsers[1].Flow != DefaultFlow || gotUsers[1].Encryption != DefaultEncryption {
|
||||
t.Fatalf("unexpected second user: %+v", gotUsers[1])
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,12 +19,13 @@ The XControl platform manages access to an Xray proxy node that exposes a single
|
||||
|
||||
## Data Model
|
||||
|
||||
| Field | Source | Notes |
|
||||
|--------------|---------------|-----------------------------------------------------------|
|
||||
| `id` | Account table | Stored as UUID v4 for compatibility with Xray clients. |
|
||||
| `email` | Account table | Optional identifier; used for auditing and debugging. |
|
||||
| `flow` | Derived | Optional; defaults to `xtls-rprx-vision` for Vision mode. |
|
||||
| `enabled` | Account table | Only enabled users contribute to the generated array. |
|
||||
| Field | Source | Notes |
|
||||
|--------------|---------------|------------------------------------------------------------------------|
|
||||
| `id` | Account table | Stored as UUID v4 for compatibility with Xray clients. |
|
||||
| `email` | Account table | Optional identifier; used for auditing and debugging. |
|
||||
| `flow` | Derived | Optional; defaults to `xtls-rprx-vision` for Vision mode. |
|
||||
| `encryption` | Derived | Required by Xray; defaults to `none` when not explicitly configured. |
|
||||
| `enabled` | Account table | Only enabled users contribute to the generated array. |
|
||||
|
||||
The backend queries all enabled accounts and materializes the JSON payload expected by Xray.
|
||||
|
||||
@ -54,8 +55,8 @@ The backend queries all enabled accounts and materializes the JSON payload expec
|
||||
4. **Generate Configuration**:
|
||||
- Load the base template for `/usr/local/etc/xray/config.json`.
|
||||
- Replace the `outbounds[].settings.vnext[].users[]` node with the freshly computed array. New registrations simply append to the
|
||||
slice composed in memory before the generator writes it back. Each client entry includes the UUID, optional email, and any
|
||||
flow directive required by the transport profile.
|
||||
slice composed in memory before the generator writes it back. Each client entry includes the UUID, optional email, required `encryption`
|
||||
flag (defaulting to `none`), and any flow directive required by the transport profile.
|
||||
- Persist the resulting JSON atomically (write to temp file then move into place).
|
||||
5. **Validate JSON**:
|
||||
- Run `jq . /usr/local/etc/xray/config.json` or an equivalent Go `json.Unmarshal` check to confirm syntax correctness.
|
||||
@ -72,9 +73,10 @@ The backend queries all enabled accounts and materializes the JSON payload expec
|
||||
```go
|
||||
// Client represents an entry in outbounds[].settings.vnext[].users[].
|
||||
type Client struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Flow string `json:"flow"`
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Flow string `json:"flow"`
|
||||
Encryption string `json:"encryption"`
|
||||
}
|
||||
|
||||
func SyncXrayClients(ctx context.Context, db *sql.DB, fs afero.Fs, runner command.Runner) error {
|
||||
@ -93,6 +95,9 @@ func SyncXrayClients(ctx context.Context, db *sql.DB, fs afero.Fs, runner comman
|
||||
if cfg.Outbounds[0].Settings.VNext[0].Users[i].Flow == "" {
|
||||
cfg.Outbounds[0].Settings.VNext[0].Users[i].Flow = "xtls-rprx-vision"
|
||||
}
|
||||
if cfg.Outbounds[0].Settings.VNext[0].Users[i].Encryption == "" {
|
||||
cfg.Outbounds[0].Settings.VNext[0].Users[i].Encryption = "none"
|
||||
}
|
||||
}
|
||||
|
||||
buf, err := json.MarshalIndent(cfg, "", " ")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user