Refactor WireGuard

This commit is contained in:
Meow
2026-09-14 09:21:42 +08:00
parent 46c680b71b
commit 7aa9bea0df
16 changed files with 432 additions and 252 deletions
+1 -1
View File
@@ -62,7 +62,7 @@
У Dokodemo door есть два основных варианта использования: прозрачное проксирование (см. ниже) и перенаправление портов.
Иногда некоторые сервисы не поддерживают прямое проксирование, такое как Socks5, а использование Tun или Tproxy является излишним, и эти сервисы взаимодействуют только с одним IP-адресом и одним портом (например: iperf, сервер Minecraft, конечная точка Wireguard), тогда можно использовать произвольную дверь.
Иногда некоторые сервисы не поддерживают прямое проксирование, такое как Socks5, а использование Tun или Tproxy является излишним, и эти сервисы взаимодействуют только с одним IP-адресом и одним портом (например: iperf, сервер Minecraft, конечная точка WireGuard), тогда можно использовать произвольную дверь.
Например, следующая конфигурация (предполагается, что исходящее соединение по умолчанию является допустимым прокси):
+75 -34
View File
@@ -1,9 +1,9 @@
# Wireguard
# WireGuard
Реализация протокола Wireguard в пользовательском пространстве.
Реализация протокола WireGuard в пространстве пользователя для установления туннеля WireGuard с удалённым узлом и приёма входящего через этот туннель трафика.
::: danger
**Протокол Wireguard не предназначен для обхода блокировок. Использование его на внешнем уровне может привести к блокировке сервера из-за характерных признаков.**
**Протокол WireGuard не предназначен специально для обхода блокировок. При использовании на внешнем уровне его характерные признаки могут привести к блокировке сервера.**
:::
## InboundConfigurationObject
@@ -16,16 +16,20 @@
{
// ...
"protocol": "wireguard",
// [!code focus:10]
// [!code focus:14]
"settings": {
"secretKey": "PRIVATE_KEY",
"secretKey": "SERVER_PRIVATE_KEY",
"peers": [
{
"publicKey": "PUBLIC_KEY",
"allowedIPs": [""]
"publicKey": "CLIENT_PUBLIC_KEY",
"preSharedKey": "PRE_SHARED_KEY",
"keepAlive": 0,
"allowedIPs": ["0.0.0.0/0", "::/0"],
"email": "love@xray.com",
"level": 0
}
],
"mtu": 1420 // необязательно, по умолчанию 1420
"mtu": 1420
}
}
]
@@ -34,48 +38,85 @@
> `secretKey`: string
Приватный ключ. Обязательное поле.
Закрытый ключ сервера. Обязательное поле.
Пару ключей сервера можно создать командой `xray wg`. Укажите здесь полученный `PrivateKey`; выведенный вместе с ним `Password (PublicKey)` является открытым ключом сервера. Если Xray используется в качестве клиента WireGuard, открытый ключ сервера следует указать в `outbounds[].settings.peers[].publicKey`.
> `peers`: \[ [PeersObject](#peersobject) \]
Список клиентов WireGuard, каждый элемент которого содержит конфигурацию одного клиента. Если настроено несколько клиентов, Xray сопоставляет адрес источника расшифрованного внутреннего IP-пакета с `allowedIPs` каждого клиента, чтобы определить, какому клиенту принадлежит трафик.
::: details Сетевая модель входящего подключения Xray WireGuard
В обычной сети WireGuard, включая соединения «точка — точка», «точка — сеть» и «сеть — сеть», обе стороны участвуют в IP-маршрутизации через сетевые интерфейсы третьего уровня.
В отличие от такой схемы, входящее подключение Xray WireGuard не создаёт TUN-интерфейс в системе, а серверу не требуется назначать внутренний IP-адрес туннеля. Расшифрованные внутренние IP-пакеты обрабатываются встроенным сетевым стеком: содержащийся в них TCP- и UDP-трафик преобразуется в прокси-соединения и передаётся системе маршрутизации Xray вместо дальнейшей пересылки исходных IP-пакетов.
Клиент может отправлять как собственный трафик, так и трафик сетей за ним, выступая в роли шлюза. Сервер Xray не является доступным клиентам узлом третьего уровня внутри туннеля и не передаёт исходные IP-пакеты системному ядру для дальнейшей маршрутизации или NAT.
`allowedIPs` используется при обработке пакетов в обоих направлениях: при приёме WireGuard проверяет адрес источника расшифрованного внутреннего IP-пакета, а Xray использует этот адрес для определения клиента; при отправке ответных пакетов WireGuard выбирает соответствующего клиента по внутреннему адресу назначения.
:::
> `mtu`: int
Размер фрагментации уровня tun в Wireguard.
MTU внутренних IP-пакетов в туннеле WireGuard. Значение по умолчанию — 1420.
<details>
<summary>Метод расчета MTU</summary>
Структура пакета Wireguard выглядит следующим образом:
::: details Расчёт MTU
Структура пакета WireGuard:
```
- 20-байтный IPv4-заголовок или 40-байтный IPv6-заголовок
- 8-байтный UDP-заголовок
- 4 байта — тип
- 4 байта — индекс ключа
- 8 байт — nonce
- N байт — зашифрованные данные
- 16 байт — аутентификационный тег
- 20-byte IPv4 header or 40 byte IPv6 header
- 8-byte UDP header
- 4-byte type
- 4-byte key index
- 8-byte nonce
- N-byte encrypted data
- 16-byte authentication tag
```
`N байт — зашифрованные данные` — это и есть значение MTU, которое зависит от того, используется ли IPv4 или IPv6. Значение может быть 1440 (IPv4) или 1420 (IPv6). В особых условиях значение может быть дополнительно уменьшено (например, для PPPoE — минус 8 байт).
`N-byte encrypted data` — требуемое значение MTU. В зависимости от того, использует ли endpoint IPv4 или IPv6, оно может составлять 1440 (IPv4) или 1420 (IPv6). В особых сетевых условиях значение при необходимости следует дополнительно уменьшить, например ещё на 8 байт для домашнего подключения через PPPoE.
:::
</details>
> `peers`: \[ [Peers](#peers) \]
Список серверов peers, каждая запись представляет конфигурацию одного сервера.
### Peers
### PeersObject
```json
{
"publicKey": "PUBLIC_KEY",
"allowedIPs": ["0.0.0.0/0"] // необязательно, по умолчанию ["0.0.0.0/0", "::/0"]
"publicKey": "CLIENT_PUBLIC_KEY",
"preSharedKey": "PRE_SHARED_KEY",
"keepAlive": 0,
"allowedIPs": ["0.0.0.0/0", "::/0"],
"email": "love@xray.com",
"level": 0
}
```
> `publicKey`: string
Публичный ключ для верификации.
Открытый ключ клиента, используемый для проверки. Обязательное поле.
> `allowedIPs`: string array
Если Xray используется в качестве клиента WireGuard, здесь следует указать `Password (PublicKey)`, соответствующий закрытому ключу клиента в `outbounds[].settings.secretKey`.
Разрешенные исходные IP-адреса.
> `preSharedKey`: string
Дополнительный симметричный ключ шифрования. Необязательное поле. Он должен совпадать с ключом в конфигурации клиента.
> `keepAlive`: int
Интервал отправки сервером этому клиенту пакетов persistent keepalive, в секундах. Значение по умолчанию — `0`, то есть пакеты не отправляются.
> `allowedIPs`: \[ string \]
Задаёт IP-адреса или подсети, которые этому клиенту разрешено использовать в качестве адреса источника. Каждый элемент указывается в формате CIDR.
Значение `address` исходящего подключения клиента должно входить в `allowedIPs` соответствующего пира на сервере. Например, если `outbounds[].settings.address` клиента равно `["10.0.0.2"]`, здесь можно указать `["10.0.0.2/32"]`.
В `allowedIPs` можно указывать не только внутренний IP-адрес клиента, но и сети, трафик которых маршрутизируется через этот пир. Например, если сторонний клиент WireGuard служит шлюзом для `192.168.10.0/24`, эту сеть можно добавить сюда; на самом клиенте также необходимо настроить маршрутизацию и включить пересылку IP-пакетов.
При наличии только одного клиента поле можно опустить; значение по умолчанию — `["0.0.0.0/0", "::/0"]`. Если настроено несколько клиентов, необходимо явно указать непересекающиеся значения `allowedIPs`, иначе надёжно различать клиентов будет невозможно.
> `email`: string
Необязательный адрес электронной почты пользователя для различения трафика разных пользователей. Отображается в журналах и статистике.
> `level`: number
Уровень пользователя. Для соединений применяется [локальная политика](../policy.md#levelpolicyobject), соответствующая этому уровню. Значение по умолчанию — 0.
+76 -57
View File
@@ -1,9 +1,9 @@
# Wireguard
# WireGuard
Стандартная реализация протокола Wireguard.
Реализация протокола WireGuard в пространстве пользователя для установления туннеля WireGuard с удалённым узлом и отправки исходящего трафика через этот туннель.
::: danger
**Протокол Wireguard не предназначен для обхода блокировок. Использование его на внешнем уровне может привести к блокировке сервера из-за характерных признаков.**
**Протокол WireGuard не предназначен специально для обхода блокировок. При использовании на внешнем уровне его характерные признаки могут привести к блокировке сервера.**
:::
## OutboundConfigurationObject
@@ -16,24 +16,23 @@
{
// ...
"protocol": "wireguard",
// [!code focus:19]
// [!code focus:18]
"settings": {
"secretKey": "PRIVATE_KEY",
"secretKey": "CLIENT_PRIVATE_KEY",
"address": [
// необязательно, по умолчанию ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]
"IPv4_CIDR",
"IPv6_CIDR",
"10.0.0.1",
"fd59:7153:2388:b5fd:0000:0000:0000:0001",
"and more..."
],
"peers": [
{
"endpoint": "ENDPOINT_ADDR",
"publicKey": "PUBLIC_KEY"
"endpoint": "SERVER_ADDR",
"publicKey": "SERVER_PUBLIC_KEY"
}
],
"noKernelTun": false,
"mtu": 1420, // необязательно, по умолчанию 1420
"reserved": [1, 2, 3],
"mtu": 1420,
"reserved": [0, 0, 0],
"domainStrategy": "ForceIP"
}
}
@@ -41,77 +40,95 @@
}
```
::: tip
На данный момент протокол Wireguard в режиме outbound не поддерживает настройку `streamSettings`.
:::
> `secretKey`: string
Личный ключ пользователя. Обязательное поле.
Закрытый ключ клиента. Обязательное поле.
> `address`: string array
Пару ключей клиента можно создать командой `xray wg`. Укажите здесь полученный `PrivateKey`; выведенный вместе с ним `Password (PublicKey)` является открытым ключом клиента. Если Xray используется в качестве сервера WireGuard, открытый ключ клиента следует указать в `inbounds[].settings.peers[].publicKey`.
Wireguard запускает локальный виртуальный сетевой интерфейс tun. Поддерживается использование одного или нескольких IP-адресов, включая IPv6.
> `address`: \[ string \]
Задаёт локальные адреса источника для внутренних IP-пакетов, создаваемых исходящим подключением WireGuard, то есть внутренние IP-адреса клиента в туннеле. Можно указать один или несколько адресов IPv4 или IPv6.
Значение по умолчанию — `["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]`.
Xray автоматически выбирает адрес источника нужного семейства в зависимости от адреса назначения. Если настроено несколько адресов одного семейства, подходящий адрес выбирается по внутренним правилам.<br>
Конфигурация входящего подключения на сервере WireGuard должна разрешать эти адреса, и каждый из них должен быть уникальным в конфигурации входящего подключения WireGuard на сервере.
> `noKernelTun`: true | false
По умолчанию система проверяет, работает ли она на Linux и имеет ли пользователь права CAP_NET_ADMIN, чтобы решить, использовать ли системный виртуальный интерфейс. Если он не используется, применяется gvisor. Системный виртуальный интерфейс обеспечивает более высокую производительность. Обратите внимание, что это относится только к обработке IP-пакетов и не связано с ядром Wireguard.
Отключает использование TUN. Значение по умолчанию — `false`; в средах LXC или Docker может потребоваться значение `true`.
Эта проверка может быть неточной. Например, некоторые виртуализации lxc могут изначально не иметь прав на TUN, что приведет к невозможности работы outbound. В таких случаях можно вручную отключить использование системного интерфейса.
::: details Нужно ли включать `noKernelTun`?
При значении `false` Xray автоматически выбирает способ обработки внутренних IP-пакетов: в Linux, если процесс Xray имеет привилегию `CAP_NET_ADMIN`, создаётся TUN-интерфейс и используется сетевой стек ядра; на других платформах или при недостаточных правах используется работающий внутри процесса сетевой стек gVisor. При значении `true` используется только сетевой стек gVisor и TUN-интерфейс не создаётся. Использование TUN обычно обеспечивает более высокую производительность.
При использовании системного интерфейса IPv6 резервирует таблицу маршрутов с номером 10230. Для каждого нового Wireguard outbound таблица увеличивается на 1 (10231, 10232 и т.д.).
Этот параметр определяет только способ обработки внутренних IP-пакетов. Сам протокол WireGuard по-прежнему обрабатывается пользовательской реализацией Xray и не связан с модулем WireGuard ядра.
Если на одной машине запускается второй экземпляр Xray, он попытается использовать таблицу 10230, что вызовет конфликт с первым экземпляром. В таких случаях необходимо отключить использование системного интерфейса.
Описанное автоматическое определение не всегда работает точно. Например, некоторые среды LXC могут не позволять использовать TUN даже при наличии привилегии `CAP_NET_ADMIN`, из-за чего исходящее подключение не будет работать. В таком случае установите значение `true`.
При использовании TUN задействуется таблица маршрутизации IPv6 с номером 10230. Каждое следующее исходящее подключение WireGuard последовательно использует следующую таблицу: например, второе подключение использует таблицу 10231 и так далее.
Если на том же компьютере запустить второй экземпляр Xray, нумерация таблиц не продолжится: второй экземпляр также попытается использовать таблицу 10230. Поскольку она уже занята первым экземпляром Xray, подключение установить не удастся. Если запуск нескольких экземпляров необходим, используйте этот параметр для отключения TUN.
:::
> `mtu`: int
MTU нижнего уровня tun в Wireguard.
MTU внутренних IP-пакетов в туннеле WireGuard. Значение по умолчанию — 1420.
<details>
<summary>Метод расчета MTU</summary>
Структура пакета Wireguard:
::: details Расчёт MTU
Структура пакета WireGuard:
```
- 20-байтный заголовок IPv4 или 40-байтный заголовок IPv6
- 8-байтный заголовок UDP
- 4 байта — тип
- 4 байта — индекс ключа
- 8 байт — nonce
- N байт — зашифрованные данные
- 16 байт — аутентификационный тег
- 20-byte IPv4 header or 40 byte IPv6 header
- 8-byte UDP header
- 4-byte type
- 4-byte key index
- 8-byte nonce
- N-byte encrypted data
- 16-byte authentication tag
```
`N байт — зашифрованные данные` — это значение MTU. Для IPv4 оно равно 1440, для IPv6 — 1420. В особых условиях значение может быть уменьшено (например, для PPPoE — минус 8 байт).
`N-byte encrypted data` — требуемое значение MTU. В зависимости от того, использует ли endpoint IPv4 или IPv6, оно может составлять 1440 (IPv4) или 1420 (IPv6). В особых сетевых условиях значение при необходимости следует дополнительно уменьшить, например ещё на 8 байт для домашнего подключения через PPPoE.
:::
</details>
> `reserved` \[ byte \]
> `reserved` \[ number \]
Три зарезервированных байта протокола WireGuard. По умолчанию все три равны 0; при необходимости укажите требуемые значения.
Зарезервированные байты Wireguard, заполняются при необходимости.
> `peers`: \[ [PeersObject](#peersobject) \]
> `peers`: \[ [Peers](#peers) \]
Список серверов WireGuard, каждый элемент которого содержит конфигурацию одного сервера. Если настроено несколько серверов, Xray сопоставляет IP-адрес назначения с `allowedIPs` каждого сервера по префиксу и направляет трафик на совпавший сервер. Таким образом, разные сети назначения можно обслуживать через разные серверы WireGuard.
Список серверов Wireguard. Каждая запись представляет конфигурацию одного сервера.
::: details Модель пакетов исходящего подключения Xray WireGuard
TCP- и UDP-соединения, поступающие в исходящее подключение WireGuard, преобразуются сетевым стеком во внутренние IP-пакеты. Внутренний адрес источника выбирается из `address`, а внутренним адресом назначения становится IP-адрес назначения проксируемого трафика.
Xray сопоставляет внутренний адрес назначения с `allowedIPs` каждого пира по префиксу. Совпавший пир шифрует и инкапсулирует пакет, после чего внешний UDP-пакет отправляется на `endpoint` этого пира. Таким образом, `address` задаёт внутренние адреса источника клиента, `allowedIPs` служит таблицей маршрутов назначения для выбора пира, а `endpoint` является адресом сервера для внешнего соединения.
:::
::: tip
Каждый сервер WireGuard должен разрешать все адреса из `address`, семейство которых совпадает с семейством адресов в его `allowedIPs`: если `allowedIPs` содержит только сети IPv4, необходимо разрешить все IPv4-адреса из `address`; если только сети IPv6 — все IPv6-адреса; если присутствуют сети обоих семейств — все указанные адреса.
Если в качестве сервера WireGuard используется Xray, перечислите эти адреса в `inbounds[].settings.peers[].allowedIPs`.
:::
> `domainStrategy`: "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4" | "ForceIP"
Управляет стратегией разрешения доменных имен, когда адрес сервера Wireguard является доменным именем или целевой адрес проксируемого трафика является доменным именем.
Управляет стратегией разрешения доменных имён, когда адрес сервера WireGuard или адрес назначения проксируемого трафика является доменным именем.
В отличие от большинства прокси-протоколов, Wireguard не позволяет передавать доменные имена в качестве целей. Если цель задана доменным именем, перед передачей его необходимо разрешить в IP. Значения этого поля соответствуют стратегиям `Force` в [sockopt.domainStrategy](../transports/sockopt.md#sockoptobject). По умолчанию используется `ForceIP`.
В отличие от большинства прокси-протоколов, WireGuard не позволяет передавать доменные имена в качестве назначения. Поэтому, если входящее назначение задано доменным именем, перед отправкой его необходимо разрешить в IP-адрес. Значения этого поля соответствуют стратегиям `Force` в [sockopt.domainStrategy](../transports/sockopt.md#sockoptobject). Значение по умолчанию — `ForceIP`.
В `sockopt.domainStrategy` доступны опции, такие как `UseIP`, которые здесь отсутствуют, так как Wireguard должен получить действительный IP-адрес и не может выполнять откат к доменному имени после неудачного разрешения `UseIP`.<br>
Примечание: при применении к проксируемому трафику эта опция также ограничивается опцией `address`. Например, если вы установили `ForceIPv6v4`, но в `address` не задан IPv6-адрес, то даже при наличии у целевого домена AAAA-записей они не будут разрешены.
В `sockopt.domainStrategy` есть такие параметры, как `UseIP`, но здесь они недоступны: WireGuard должен получить пригодный IP-адрес и не может вернуться к доменному имени при ошибке разрешения `UseIP`.<br>
Примечание: при применении к проксируемому трафику этот параметр также ограничен настройкой `address`. Например, если задано `ForceIPv6v4`, но в `address` нет адреса IPv6, записи AAAA не будут разрешаться, даже если они существуют для домена назначения.
### Peers
### PeersObject
```json
{
"endpoint": "ENDPOINT_ADDR",
"publicKey": "PUBLIC_KEY",
"preSharedKey": "PRE_SHARED_KEY", // необязательно, по умолчанию "0000000000000000000000000000000000000000000000000000000000000000"
"keepAlive": 0, // необязательно, по умолчанию 0
"allowedIPs": ["0.0.0.0/0"] // необязательно, по умолчанию ["0.0.0.0/0", "::/0"]
"endpoint": "SERVER_ADDR",
"publicKey": "SERVER_PUBLIC_KEY",
"preSharedKey": "PRE_SHARED_KEY",
"keepAlive": 0,
"allowedIPs": ["0.0.0.0/0", "::/0"]
}
```
@@ -119,21 +136,23 @@ MTU нижнего уровня tun в Wireguard.
Адрес сервера. Обязательное поле.
Формат URL:порт, например, `engage.cloudflareclient.com:2408`.
Формат IP:порт, например, `162.159.192.1:2408` или `[2606:4700:d0::a29f:c001]:2408`.
Формат URL:порт, например `engage.cloudflareclient.com:2408`<br>
Формат IP:порт, например `162.159.192.1:2408` или `[2606:4700:d0::a29f:c001]:2408`
> `publicKey`: string
Публичный ключ сервера для проверки. Обязательное поле.
Открытый ключ сервера, используемый для проверки. Обязательное поле.
Если Xray используется в качестве сервера WireGuard, здесь следует указать `Password (PublicKey)`, соответствующий закрытому ключу сервера в `inbounds[].settings.secretKey`.
> `preSharedKey`: string
Дополнительный симметричный ключ шифрования.
Дополнительный симметричный ключ шифрования. Необязательное поле. Он должен совпадать с ключом в конфигурации сервера.
> `keepAlive`: int
Интервал отправки пакетов heartbeat, в секундах. Значение по умолчанию — 0 (отсутствие heartbeat).
Интервал отправки клиентом этому серверу пакетов persistent keepalive, в секундах. Они поддерживают возможные сопоставления NAT или состояние межсетевого экрана в периоды простоя. Включайте этот параметр только при необходимости и только на стороне клиента. Значение по умолчанию — `0`, то есть пакеты не отправляются.
> `allowedIPs`: string array
Wireguard пропускает только трафик с определенных IP-адресов.
Задаёт IP-сети назначения, пересылаемые через этот сервер. Каждый элемент указывается в формате CIDR. При наличии только одного сервера поле можно опустить: значение по умолчанию — `["0.0.0.0/0", "::/0"]`, то есть через сервер направляется весь трафик к адресам IPv4 и IPv6. Если настроено несколько серверов, необходимо явно задать `allowedIPs` для каждого из них и распределить сети назначения между соответствующими серверами; Xray выбирает сервер путём сопоставления префикса IP-адреса назначения.
+1 -1
View File
@@ -13,7 +13,7 @@
Вот как это настроить (на примере Debian 10):
## 1. Установите прокси-сервер или VPN-клиент (например, Wireguard, IPsec и т.д.)
## 1. Установите прокси-сервер или VPN-клиент (например, WireGuard, IPsec и т.д.)
Обратитесь к официальной документации для получения инструкций по установке для вашей системы и программного обеспечения.