Browse Source

AmneziaWG 2.0: support for H1-H4 ranges

## Changes:
```
- [+] Added support for H1-H4 ranges
- [!] Fixed interface fields order (H1-H4 goes before I1-I5)
```

## Known issues:
```
- [!] no check for unique/overlap of H1-H4 values on settings apply:
  settings will be applied but wg interface will crash with "Invalid argument" error
```
pull/2480/head
CthulhuVRN 5 months ago
parent
commit
9d847da462
  1. 48
      src/app/pages/admin/interface.vue
  2. 17
      src/i18n/locales/en.json
  3. 36
      src/server/database/migrations/0003_breezy_colossus.sql
  4. 972
      src/server/database/migrations/meta/0003_snapshot.json
  5. 7
      src/server/database/migrations/meta/_journal.json
  6. 8
      src/server/database/repositories/interface/schema.ts
  7. 8
      src/server/database/repositories/interface/types.ts
  8. 10
      src/server/utils/WireGuard.ts
  9. 28
      src/server/utils/types.ts
  10. 16
      src/server/utils/wgHelper.ts

48
src/app/pages/admin/interface.vue

@ -69,6 +69,30 @@
:label="$t('awg.s4Label')"
:description="$t('awg.s4Description')"
/>
<FormNullTextField
id="h1"
v-model="data.h1"
:label="$t('awg.h1Label')"
:description="$t('awg.h1Description')"
/>
<FormNullTextField
id="h2"
v-model="data.h2"
:label="$t('awg.h2Label')"
:description="$t('awg.h2Description')"
/>
<FormNullTextField
id="h3"
v-model="data.h3"
:label="$t('awg.h3Label')"
:description="$t('awg.h3Description')"
/>
<FormNullTextField
id="h4"
v-model="data.h4"
:label="$t('awg.h4Label')"
:description="$t('awg.h4Description')"
/>
<FormNullTextField
id="i1"
v-model="data.i1"
@ -99,30 +123,6 @@
:label="$t('awg.i5Label')"
:description="$t('awg.i5Description')"
/>
<FormNullNumberField
id="h1"
v-model="data.h1"
:label="$t('awg.h1Label')"
:description="$t('awg.h1Description')"
/>
<FormNullNumberField
id="h2"
v-model="data.h2"
:label="$t('awg.h2Label')"
:description="$t('awg.h2Description')"
/>
<FormNullNumberField
id="h3"
v-model="data.h3"
:label="$t('awg.h3Label')"
:description="$t('awg.h3Description')"
/>
<FormNullNumberField
id="h4"
v-model="data.h4"
:label="$t('awg.h4Label')"
:description="$t('awg.h4Description')"
/>
</FormGroup>
<FormGroup>
<FormHeading>{{ $t('form.actions') }}</FormHeading>

17
src/i18n/locales/en.json

@ -183,6 +183,7 @@
"generic": {
"required": "{0} is required",
"validNumber": "{0} must be a valid number",
"validNumberRange": "{0} must be a valid number or number range",
"validString": "{0} must be a valid string",
"validBoolean": "{0} must be a valid boolean",
"validArray": "{0} must be a valid array",
@ -262,6 +263,14 @@
"s3Description": "Cookie reply packet junk size",
"s4Label": "Transport packet junk size (S4)",
"s4Description": "Transport packet junk size",
"h1Label": "Init magic header (H1)",
"h1Description": "Init packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
"h2Label": "Response magic header (H2)",
"h2Description": "Response packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
"h3Label": "Cookie reply magic header (H3)",
"h3Description": "Cookie reply packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
"h4Label": "Transport magic header (H4)",
"h4Description": "Transport packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
"i1Label": "Special junk packet 1 (I1)",
"i1Description": "Protocol mimic packet in hex format: <b 0x...>",
"i2Label": "Special junk packet 2 (I2)",
@ -272,14 +281,6 @@
"i4Description": "Protocol mimic packet in hex format: <b 0x...>",
"i5Label": "Special junk packet 5 (I5)",
"i5Description": "Protocol mimic packet in hex format: <b 0x...>",
"h1Label": "Init magic header (H1)",
"h1Description": "Init packet header value (5-2147483647, must be unique from H2-H4)",
"h2Label": "Response magic header (H2)",
"h2Description": "Response packet header value (5-2147483647, must be unique from H1, H3, H4)",
"h3Label": "Cookie reply magic header (H3)",
"h3Description": "Cookie reply packet header value (5-2147483647, must be unique from H1, H2, H4)",
"h4Label": "Transport magic header (H4)",
"h4Description": "Transport packet header value (5-2147483647, must be unique from H1-H3)",
"mtuNote": "Values depend on the MTU",
"obfuscationParameters": "AmneziaWG Obfuscation Parameters"
}

36
src/server/database/migrations/0003_breezy_colossus.sql

@ -0,0 +1,36 @@
PRAGMA foreign_keys=OFF;--> statement-breakpoint
CREATE TABLE `__new_interfaces_table` (
`name` text PRIMARY KEY NOT NULL,
`device` text NOT NULL,
`port` integer NOT NULL,
`private_key` text NOT NULL,
`public_key` text NOT NULL,
`ipv4_cidr` text NOT NULL,
`ipv6_cidr` text NOT NULL,
`mtu` integer NOT NULL,
`j_c` integer DEFAULT 7,
`j_min` integer DEFAULT 10,
`j_max` integer DEFAULT 1000,
`s1` integer DEFAULT 128,
`s2` integer DEFAULT 56,
`s3` integer,
`s4` integer,
`h1` text,
`h2` text,
`h3` text,
`h4` text,
`i1` text,
`i2` text,
`i3` text,
`i4` text,
`i5` text,
`enabled` integer NOT NULL,
`created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL,
`updated_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL
);
--> statement-breakpoint
INSERT INTO `__new_interfaces_table`("name", "device", "port", "private_key", "public_key", "ipv4_cidr", "ipv6_cidr", "mtu", "j_c", "j_min", "j_max", "s1", "s2", "s3", "s4", "h1", "h2", "h3", "h4", "i1", "i2", "i3", "i4", "i5", "enabled", "created_at", "updated_at") SELECT "name", "device", "port", "private_key", "public_key", "ipv4_cidr", "ipv6_cidr", "mtu", "j_c", "j_min", "j_max", "s1", "s2", "s3", "s4", "h1", "h2", "h3", "h4", "i1", "i2", "i3", "i4", "i5", "enabled", "created_at", "updated_at" FROM `interfaces_table`;--> statement-breakpoint
DROP TABLE `interfaces_table`;--> statement-breakpoint
ALTER TABLE `__new_interfaces_table` RENAME TO `interfaces_table`;--> statement-breakpoint
PRAGMA foreign_keys=ON;--> statement-breakpoint
CREATE UNIQUE INDEX `interfaces_table_port_unique` ON `interfaces_table` (`port`);

972
src/server/database/migrations/meta/0003_snapshot.json

@ -0,0 +1,972 @@
{
"version": "6",
"dialect": "sqlite",
"id": "68c43b7a-772d-4c34-8278-e9fce5b53df1",
"prevId": "e09bc17a-dab6-45a3-a09c-57af222b08fb",
"tables": {
"clients_table": {
"name": "clients_table",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"interface_id": {
"name": "interface_id",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"ipv4_address": {
"name": "ipv4_address",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"ipv6_address": {
"name": "ipv6_address",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"pre_up": {
"name": "pre_up",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "''"
},
"post_up": {
"name": "post_up",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "''"
},
"pre_down": {
"name": "pre_down",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "''"
},
"post_down": {
"name": "post_down",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "''"
},
"private_key": {
"name": "private_key",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"public_key": {
"name": "public_key",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"pre_shared_key": {
"name": "pre_shared_key",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"expires_at": {
"name": "expires_at",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"allowed_ips": {
"name": "allowed_ips",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"server_allowed_ips": {
"name": "server_allowed_ips",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"persistent_keepalive": {
"name": "persistent_keepalive",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"mtu": {
"name": "mtu",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"j_c": {
"name": "j_c",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"j_min": {
"name": "j_min",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"j_max": {
"name": "j_max",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i1": {
"name": "i1",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i2": {
"name": "i2",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i3": {
"name": "i3",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i4": {
"name": "i4",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i5": {
"name": "i5",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"dns": {
"name": "dns",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"server_endpoint": {
"name": "server_endpoint",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"enabled": {
"name": "enabled",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {
"clients_table_ipv4_address_unique": {
"name": "clients_table_ipv4_address_unique",
"columns": [
"ipv4_address"
],
"isUnique": true
},
"clients_table_ipv6_address_unique": {
"name": "clients_table_ipv6_address_unique",
"columns": [
"ipv6_address"
],
"isUnique": true
}
},
"foreignKeys": {
"clients_table_user_id_users_table_id_fk": {
"name": "clients_table_user_id_users_table_id_fk",
"tableFrom": "clients_table",
"tableTo": "users_table",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "restrict",
"onUpdate": "cascade"
},
"clients_table_interface_id_interfaces_table_name_fk": {
"name": "clients_table_interface_id_interfaces_table_name_fk",
"tableFrom": "clients_table",
"tableTo": "interfaces_table",
"columnsFrom": [
"interface_id"
],
"columnsTo": [
"name"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"general_table": {
"name": "general_table",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false,
"default": 1
},
"setup_step": {
"name": "setup_step",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"session_password": {
"name": "session_password",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"session_timeout": {
"name": "session_timeout",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"metrics_prometheus": {
"name": "metrics_prometheus",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"metrics_json": {
"name": "metrics_json",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"metrics_password": {
"name": "metrics_password",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"hooks_table": {
"name": "hooks_table",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"pre_up": {
"name": "pre_up",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"post_up": {
"name": "post_up",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"pre_down": {
"name": "pre_down",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"post_down": {
"name": "post_down",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {},
"foreignKeys": {
"hooks_table_id_interfaces_table_name_fk": {
"name": "hooks_table_id_interfaces_table_name_fk",
"tableFrom": "hooks_table",
"tableTo": "interfaces_table",
"columnsFrom": [
"id"
],
"columnsTo": [
"name"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"interfaces_table": {
"name": "interfaces_table",
"columns": {
"name": {
"name": "name",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"device": {
"name": "device",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"port": {
"name": "port",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"private_key": {
"name": "private_key",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"public_key": {
"name": "public_key",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"ipv4_cidr": {
"name": "ipv4_cidr",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"ipv6_cidr": {
"name": "ipv6_cidr",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"mtu": {
"name": "mtu",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"j_c": {
"name": "j_c",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 7
},
"j_min": {
"name": "j_min",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 10
},
"j_max": {
"name": "j_max",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 1000
},
"s1": {
"name": "s1",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 128
},
"s2": {
"name": "s2",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 56
},
"s3": {
"name": "s3",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"s4": {
"name": "s4",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"h1": {
"name": "h1",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"h2": {
"name": "h2",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"h3": {
"name": "h3",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"h4": {
"name": "h4",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i1": {
"name": "i1",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i2": {
"name": "i2",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i3": {
"name": "i3",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i4": {
"name": "i4",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"i5": {
"name": "i5",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"enabled": {
"name": "enabled",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {
"interfaces_table_port_unique": {
"name": "interfaces_table_port_unique",
"columns": [
"port"
],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"one_time_links_table": {
"name": "one_time_links_table",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"one_time_link": {
"name": "one_time_link",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"expires_at": {
"name": "expires_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {
"one_time_links_table_one_time_link_unique": {
"name": "one_time_links_table_one_time_link_unique",
"columns": [
"one_time_link"
],
"isUnique": true
}
},
"foreignKeys": {
"one_time_links_table_id_clients_table_id_fk": {
"name": "one_time_links_table_id_clients_table_id_fk",
"tableFrom": "one_time_links_table",
"tableTo": "clients_table",
"columnsFrom": [
"id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"users_table": {
"name": "users_table",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"password": {
"name": "password",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"role": {
"name": "role",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"totp_key": {
"name": "totp_key",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"totp_verified": {
"name": "totp_verified",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"enabled": {
"name": "enabled",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {
"users_table_username_unique": {
"name": "users_table_username_unique",
"columns": [
"username"
],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"user_configs_table": {
"name": "user_configs_table",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"default_mtu": {
"name": "default_mtu",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"default_persistent_keepalive": {
"name": "default_persistent_keepalive",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"default_dns": {
"name": "default_dns",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"default_allowed_ips": {
"name": "default_allowed_ips",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"default_j_c": {
"name": "default_j_c",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 7
},
"default_j_min": {
"name": "default_j_min",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 10
},
"default_j_max": {
"name": "default_j_max",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": 1000
},
"default_i1": {
"name": "default_i1",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"default_i2": {
"name": "default_i2",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"default_i3": {
"name": "default_i3",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"default_i4": {
"name": "default_i4",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"default_i5": {
"name": "default_i5",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"host": {
"name": "host",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"port": {
"name": "port",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
},
"updated_at": {
"name": "updated_at",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(CURRENT_TIMESTAMP)"
}
},
"indexes": {},
"foreignKeys": {
"user_configs_table_id_interfaces_table_name_fk": {
"name": "user_configs_table_id_interfaces_table_name_fk",
"tableFrom": "user_configs_table",
"tableTo": "interfaces_table",
"columnsFrom": [
"id"
],
"columnsTo": [
"name"
],
"onDelete": "cascade",
"onUpdate": "cascade"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}

7
src/server/database/migrations/meta/_journal.json

@ -22,6 +22,13 @@
"when": 1761298328460,
"tag": "0002_keen_sleepwalker",
"breakpoints": true
},
{
"idx": 3,
"version": "6",
"when": 1770902426367,
"tag": "0003_breezy_colossus",
"breakpoints": true
}
]
}

8
src/server/database/repositories/interface/schema.ts

@ -20,15 +20,15 @@ export const wgInterface = sqliteTable('interfaces_table', {
s2: int().default(56),
s3: int(),
s4: int(),
h1: text(),
h2: text(),
h3: text(),
h4: text(),
i1: text(),
i2: text(),
i3: text(),
i4: text(),
i5: text(),
h1: int().default(0),
h2: int().default(0),
h3: int().default(0),
h4: int().default(0),
// does nothing yet
enabled: int({ mode: 'boolean' }).notNull(),
createdAt: text('created_at')

8
src/server/database/repositories/interface/types.ts

@ -38,15 +38,15 @@ export const InterfaceUpdateSchema = schemaForType<InterfaceUpdateType>()(
s2: SSchema,
s3: SSchema,
s4: SSchema,
h1: HSchema,
h2: HSchema,
h3: HSchema,
h4: HSchema,
i1: ISchema,
i2: ISchema,
i3: ISchema,
i4: ISchema,
i5: ISchema,
h1: HSchema,
h2: HSchema,
h3: HSchema,
h4: HSchema,
port: PortSchema,
device: device,
enabled: EnabledSchema,

10
src/server/utils/WireGuard.ts

@ -213,7 +213,7 @@ class WireGuard {
WG_DEBUG('New Wireguard Keys generated successfully.');
}
if (wgInterface.h1 === 0) {
if (!wgInterface.h1) {
WG_DEBUG('Generating random AmneziaWG obfuscation parameters...');
const headers = new Set<number>();
@ -222,10 +222,10 @@ class WireGuard {
}
const [h1, h2, h3, h4] = Array.from(headers);
wgInterface.h1 = h1!;
wgInterface.h2 = h2!;
wgInterface.h3 = h3!;
wgInterface.h4 = h4!;
wgInterface.h1 = String(h1)!;
wgInterface.h2 = String(h2)!;
wgInterface.h3 = String(h3)!;
wgInterface.h4 = String(h4)!;
Database.interfaces.update(wgInterface);
}

28
src/server/utils/types.ts

@ -34,7 +34,33 @@ export const JmaxSchema = z.number().max(1280).nullable();
export const SSchema = z.number().max(1132).nullable();
export const HSchema = z.number().min(5).max(2147483647).nullable();
const H_MIN = 5;
const H_MAX = 2 ** 31 - 1;
export const HSchema = z
.string()
.transform(v => v.replace(/\s+/g, ''))
.refine(v => v === '' || /^\d+(-\d+)?$/.test(v), {
message: t('zod.generic.validNumberRange')
})
.refine(v => {
// if single number
if (!v.includes('-')) {
const num = Number(v);
if ( num < H_MIN || num > H_MAX )
return false;
return `${num}`;
}
// if number range
const [min, max] = v.split('-').map(Number);
if ( min < H_MIN || max > H_MAX || min > max )
return false;
return min === max ? `${min}` : `${min}-${max}`;
}, {
message: t('zod.generic.validNumberRange')
})
.nullable();
export const ISchema = z.string().nullable();

16
src/server/utils/wgHelper.ts

@ -63,15 +63,15 @@ AllowedIPs = ${allowedIps.join(', ')}${extraLines.length ? `\n${extraLines.join(
S2: wgInterface.s2,
S3: wgInterface.s3,
S4: wgInterface.s4,
H1: wgInterface.h1,
H2: wgInterface.h2,
H3: wgInterface.h3,
H4: wgInterface.h4,
I1: wgInterface.i1,
I2: wgInterface.i2,
I3: wgInterface.i3,
I4: wgInterface.i4,
I5: wgInterface.i5,
H1: wgInterface.h1,
H2: wgInterface.h2,
H3: wgInterface.h3,
H4: wgInterface.h4,
} as const;
awgLines = Object.entries(parameters)
@ -131,15 +131,15 @@ PostDown = ${iptablesTemplate(hooks.postDown, wgInterface)}`;
S2: wgInterface.s2,
S3: wgInterface.s3,
S4: wgInterface.s4,
H1: wgInterface.h1,
H2: wgInterface.h2,
H3: wgInterface.h3,
H4: wgInterface.h4,
I1: client.i1,
I2: client.i2,
I3: client.i3,
I4: client.i4,
I5: client.i5,
H1: wgInterface.h1,
H2: wgInterface.h2,
H3: wgInterface.h3,
H4: wgInterface.h4,
} as const;
awgLines = Object.entries(parameters)

Loading…
Cancel
Save