Jump to content

Question

Posted (edited)

Добрый день!

Для нормальной работы warp на keenetic хотелось бы реализовать возможность влиять на поле Reserved структуры message_header.

По аналогии с командой asc

interface {name} wireguard warp {b1} {b2} {b3}

У китайцев в Xray-Core получилось это сделать правкой двух методов Xray-core-main\proxy\wireguard\bind.go:

func (bind *netBindClient) connectTo(endpoint *netEndpoint) error {
	c, err := bind.dialer.Dial(bind.ctx, endpoint.dst)
	if err != nil {
		return err
	}
	endpoint.conn = c

	go func(readQueue <-chan *netReadInfo, endpoint *netEndpoint) {
		for {
			v, ok := <-readQueue
			if !ok {
				return
			}
			i, err := c.Read(v.buff)

			if i > 3 {
				v.buff[1] = 0
				v.buff[2] = 0
				v.buff[3] = 0
			}

			v.bytes = i
			v.endpoint = endpoint
			v.err = err
			v.waiter.Done()
			if err != nil && errors.Is(err, io.EOF) {
				endpoint.conn = nil
				return
			}
		}
	}(bind.readQueue, endpoint)

	return nil
}

func (bind *netBindClient) Send(buff [][]byte, endpoint conn.Endpoint) error {
	var err error

	nend, ok := endpoint.(*netEndpoint)
	if !ok {
		return conn.ErrWrongEndpointType
	}

	if nend.conn == nil {
		err = bind.connectTo(nend)
		if err != nil {
			return err
		}
	}

	for _, buff := range buff {
		if len(buff) > 3 && len(bind.reserved) == 3 {
			copy(buff[1:], bind.reserved)
		}
		if _, err = nend.conn.Write(buff); err != nil {
			return err
		}
	}
	return nil
}

 

Тестовый конфиг можно получить так:

bash -c "$(curl -L warp-reg.vercel.app)"

Может и нам можно добавить этот функционал?

Edited by avn
  • Upvote 2

Recommended Posts

  • 0
Posted (edited)
7 часов назад, Le ecureuil сказал:

Я правильно понял, что нужно три байта подствлять в message_header при отправке, и все?

Да, правильно. Но надо помнить, что эти изменения только стороны клиента (не сервера). Также при коннекте клиентом, они их еще и зануляют.

func (bind *netBindClient) connectTo(endpoint *netEndpoint) error {
   ......
			i, err := c.Read(v.buff)

			if i > 3 {
				v.buff[1] = 0
				v.buff[2] = 0
				v.buff[3] = 0
			}

Вообще, если смотреть конфиг WARP в оригинале, запрошенный через api, то он выглядит так

Скрытый текст
{
	"id": "79647",
	"type": "a",
	"model": "PC",
	"name": "FDF5F5",
	"key": "v9NMcOaNTFw=",
	"account": {
		"id": "6714a5c",
		"account_type": "limited",
		"created": "2022-12-18T09:54:43.491648Z",
		"updated": "2024-07-30T12:12:54.223368Z",
		"premium_data": 139000000000,
		"quota": 139000000000,
		"warp_plus": true,
		"referral_count": 139,
		"referral_renewal_countdown": 0,
		"role": "child",
		"license": "87zW",
		"ttl": "2024-10-28T12:12:54.047402Z"
	},
	"config": {
		"client_id": "LHJ3",
		"peers": [
			{
				"public_key": "bmVo51h2wPfgyo=",
				"endpoint": {
					"v4": "188.114.99.229:0",
					"v6": "[2606:4700:d1::a29f:c30a]:0",
					"host": "engage.cloudflareclient.com:2408",
					"ports": [
						854,
						859,
						864,
						878,
						880,
						890,
						891,
						894,
						903,
						908,
						928,
						934,
						939,
						942,
						943,
						945,
						946,
						955,
						968,
						987,
						988,
						1002,
						1010,
						1014,
						1018,
						1070,
						1074,
						1180,
						1387,
						1843,
						2371,
						2506,
						3138,
						3476,
						3581,
						3854,
						4177,
						4198,
						4233,
						5279,
						5956,
						7103,
						7152,
						7156,
						7281,
						7559,
						8319,
						8742,
						8854,
						8886
					]
				}
			}
		],
		"interface": {
			"addresses": {
				"v4": "172.16.0.2",
				"v6": "2606:4700:110:822e:3e0"
			}
		},
		"services": {
			"http_proxy": "172.16.0.1:2480"
		}
	},
	"warp_enabled": false,
	"waitlist_enabled": false,
	"created": "2022-12-18T09:54:43.039543Z",
	"updated": "2024-08-15T13:45:10.034331432Z",
	"tos": "2022-12-18T09:54:41.536765Z",
	"place": 0,
	"locale": "en-US",
	"enabled": true,
	"install_id": "",
	"fcm_token": ""
}

 

Здесь client_id - это "client_id": "LHJ3". Но китайцы раскладывают его на массив из 3 байт.

Edited by avn
  • 0
Posted (edited)

Вот еще одна реализация, правда опять на go. Может станет понятнее.

 

Edited by avn
  • 0
Posted

У меня почему-то удаленная сторона WARP с вашим конфигом вообще не отвечает.

Потому проверьте на следующей бете сами.

Команда
interface Wireguard0 wireguard peer <peer> client-id send <value>

value - десятеричное число, сделанное простым переводом hex: из 0x1620a6 получается просто 1450150

В итоге в сеть улетает как задумано:

Untitled.jpg

  • Upvote 2
  • 0
Posted

Спасибо. Обязательно попробую и посмотрю различия в транспорте.

  • 0
Posted
В 21.08.2024 в 13:24, Le ecureuil сказал:

Вобщем, проверяйте на следующей beta.

Не завелось. Пакеты одинаковые. Слева - keenetic (неуспешно), справа (проходящий трафик) те же настройки (успешно). Я вообще не понимаю, что происходит. Не приходит ни одного пакета обратно.

Скрытый текст

image.thumb.png.81fb28cfd2c4e37908ae80be3aee67e6.png

Трейс (WireShark) - keenetic 1.lkk, проходящий - 3.lkk

1.lkk 3.lkk

  • 0
Posted (edited)
В 21.08.2024 в 13:24, Le ecureuil сказал:

Вобщем, проверяйте на следующей beta.

Думаю ошибка где-то здесь, нужно занулить три байта header-а. Мне кажется это подходящее место. Если пойдет прием, значит мы на верном пути. Сейчас прием по нулям.

static void wg_packet_consume_data_done(struct wg_peer *peer,
					struct sk_buff *skb,
					struct endpoint *endpoint)
{

  ????????????

	skb->dev = dev;
	/* We've already verified the Poly1305 auth tag, which means this packet
	 * was not modified in transit. We can therefore tell the networking
	 * stack that all checksums of every layer of encapsulation have already
	 * been checked "by the hardware" and therefore is unnecessary to check
	 * again in software.
	 */
	skb->ip_summed = CHECKSUM_UNNECESSARY;

 

func (b *Bind) NewReceiveFunc(fn conn.ReceiveFunc) conn.ReceiveFunc {
	return func(buf []byte) (n int, ep conn.Endpoint, err error) {
		n, ep, err = fn(buf)
		if err != nil || n < 4 {
			return
		}

		if buf[1] != b.reseved[0] || buf[2] != b.reseved[1] || buf[3] != b.reseved[2] {
			err = errors.New("bad reseved")
			return
		}

		buf[1] = 0
		buf[2] = 0
		buf[3] = 0
		return
	}
}
Edited by avn
  • 0
Posted

Если захват происходит на интерфейсе ISP, то тут вопрос не в Keenetic, что нет ответа. До модуля wg эти пакеты еще даже не дошли в момент захвата, потому что-то занулять бессмысленно, пока не будет ответа в проводе от ISP.

  • 0
Posted (edited)

Прописал ключи в WireShark. Сразу видно разницу в пакетах. WireShark не может расшифровать пакет с Keenetic

 

image.thumb.png.673dd427bda2761d6f4aea273b8234ca.png

 

image.png.b581b28b57ac7b81f94e2feb91e1a582.png

Edited by avn
  • 0
Posted
В 05.09.2024 в 10:11, Le ecureuil сказал:

Посмотрел дампы, разницы не вижу. Видимо что-то еще важно, но непонятно что.

Пересмотрел еще раз патч, смущает кусок с cpu_to_le32 для маски:

#define SKB_TYPE_LE32(skb, asc) ((((struct message_header *)(skb)->data)->type) & ((asc) ? 0xFFFFFFFF : cpu_to_le32(0xFF)))

Не может он быть корнем проблемы?

  • 0
Posted

@Le ecureuil

У нас WireShark не декодирует пакет. Т.е. mac1 не соответствует данным.

	if (wg_noise_handshake_create_initiation(&packet,
						 &peer->handshake,
						 wg->advanced_security_config.init_packet_magic_header,
						 peer->client_id)) {
		wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);

Можете попробовать, сделать присвоение client_id после вызова wg_cookie_add_mac_to_packet() (Т.е. тут wg_noise_handshake_create_initiation  client_id не задавать)?

 

  • 0
Posted (edited)
4 часа назад, avn сказал:

@Le ecureuil

У нас WireShark не декодирует пакет. Т.е. mac1 не соответствует данным.

	if (wg_noise_handshake_create_initiation(&packet,
						 &peer->handshake,
						 wg->advanced_security_config.init_packet_magic_header,
						 peer->client_id)) {
		wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);

Можете попробовать, сделать присвоение client_id после вызова wg_cookie_add_mac_to_packet() (Т.е. тут wg_noise_handshake_create_initiation  client_id не задавать)?

 

Становится понятен алгоритм. Перед отправкой данных на сервер, уже в готовом пакете данных с рассчитанным mac1 и полем type = 0x00000001 записывается client-id.

При получении пакета от сервера, для его успешной расшифровки поле client-id зануляется.

Сейчас пакет шифруется в месте с полем client-id. Это приводит к тому, что мы не видим ответов от сервера.

Для пакетов с типами 2,3,4 алгоритм такой же.

Т.е client-id как бы ещё один уровень транспортного пакета. Перед отправкой установили, при получении сняли. Но во внутренних процессах все работает по старому без client-id.

Edited by avn
  • 0
Posted
9 часов назад, avn сказал:

@Le ecureuil

У нас WireShark не декодирует пакет. Т.е. mac1 не соответствует данным.

	if (wg_noise_handshake_create_initiation(&packet,
						 &peer->handshake,
						 wg->advanced_security_config.init_packet_magic_header,
						 peer->client_id)) {
		wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);

Можете попробовать, сделать присвоение client_id после вызова wg_cookie_add_mac_to_packet() (Т.е. тут wg_noise_handshake_create_initiation  client_id не задавать)?

 

Ок, перемещу.

Вроде все заработало, посмотрите на 4.2.b3.

  • Thanks 1
  • 0
Posted
2 часа назад, Le ecureuil сказал:

Ок, перемещу.

Вроде все заработало, посмотрите на 4.2.b3.

На b3, или b4 все таки?

  • 0
Posted
В 16.09.2024 в 10:22, Le ecureuil сказал:

Тьфу, b4 конечно.

Работает! Только с ASС не очень дружит. Посмотрю потом на ASC.

Браво, спасибо.

 

  • 0
Posted
В 16.09.2024 в 10:22, Le ecureuil сказал:

Тьфу, b4 конечно.

После снятия asc параметров пришлось роутер перегрузить. Команда не снимает параметры с kernel-space.

interface Wireguard2 no wireguard asc

 

  • 0
Posted
33 минуты назад, avn сказал:

После снятия asc параметров пришлось роутер перегрузить. Команда не снимает параметры с kernel-space.

interface Wireguard2 no wireguard asc

 

Проверю, возможно есть такое.

  • 0
Posted (edited)
2 часа назад, Le ecureuil сказал:

Проверю, возможно есть такое.

Как Вам такая идея для поддержки asc и отправки мусорных пакетов перед коннектом.

Для Warp многие задают такие настройки:

{jc} {jmin} {jmax} 0 0 1 2 3 4
{jc} {jmin} {jmax} 0 0 0 0 0 0

Заводим еще одну переменную

advanced_security_enabled_mask =
wg->advanced_security_config.advanced_security_enabled && (
wg->client_id == 0 ||
wg->advanced_security_config.init_packet_magic_header != MESSAGE_HANDSHAKE_INITIATION ||
wg->advanced_security_config.response_packet_magic_header != MESSAGE_HANDSHAKE_RESPONSE ||
wg->advanced_security_config.cookie_packet_magic_header != MESSAGE_HANDSHAKE_COOKIE || 
wg->advanced_security_config.transport_packet_magic_header != MESSAGE_DATA ||
wg->advanced_security_config.init_packet_junk_size != 0 ||
wg->advanced_security_config.response_packet_junk_size != 0)

И переделываем вызов макросов на нее

#define SKB_TYPE_LE32(skb, asc) ((((struct message_header *)(skb)->data)->type) & ((asc) ? 0xFFFFFFFF : cpu_to_le32(0xFF)))
#define SKB_CLEAR_TYPE(skb, asc) ((((struct message_header *)(skb)->data)->type) &= ((asc) ? 0xFFFFFFFF : cpu_to_le32(0xFF)))

на:

SKB_TYPE_LE32(skb, advanced_security_enabled_mask)
SKB_CLEAR_TYPE(skb, advanced_security_enabled_mask)

Это позволит использовать asc для Warp и client_id.

 

Edited by avn
  • Thanks 1
  • 0
Posted

Так уже можно использовать asc совместно с client-id, единственное ограничение - что h1/h2/h3/h4 должны быть меньше чем 255 (0xFF). В остальном никаких вопросов.

  • Upvote 1
  • 0
Posted (edited)
55 минут назад, Le ecureuil сказал:

Так уже можно использовать asc совместно с client-id, единственное ограничение - что h1/h2/h3/h4 должны быть меньше чем 255 (0xFF). В остальном никаких вопросов.

Да, только когда clientid=0. А с заданным значением нельзя. Маска будет раскрываться неправильно.

что h1/h2/h3/h4 должны быть меньше чем 255

Тоже работать не будет, только 0 0 0 0 или 1 2 3 4

Это видно из кода

	wg->advanced_security_config.init_packet_magic_header = MESSAGE_HANDSHAKE_INITIATION;
	wg->advanced_security_config.response_packet_magic_header = MESSAGE_HANDSHAKE_RESPONSE;
	wg->advanced_security_config.cookie_packet_magic_header = MESSAGE_HANDSHAKE_COOKIE;
	wg->advanced_security_config.transport_packet_magic_header = MESSAGE_DATA;

Далее, если значение параметра 0, оно не будет перетираться.

Сейчас приходит пакет, и он его идентифицировать не может. Т.к. SKB_CLEAR_TYPE не сбросит биты при включенном ASC. А без client_id, они уже = 0.

#define SKB_TYPE_LE32(skb, asc) ((((struct message_header *)(skb)->data)->type) & ((asc) ? 0xFFFFFFFF : cpu_to_le32(0xFF)))
#define SKB_CLEAR_TYPE(skb, asc) ((((struct message_header *)(skb)->data)->type) &= ((asc) ? 0xFFFFFFFF : cpu_to_le32(0xFF)))

static size_t validate_header_len(struct sk_buff *skb, struct wg_device *wg)
{
	__le32 type = 0;

	if (unlikely(skb->len < sizeof(struct message_header)))
		return 0;

	type = SKB_TYPE_LE32(skb, wg->advanced_security_config.advanced_security_enabled);

	if (type == cpu_to_le32(wg->advanced_security_config.transport_packet_magic_header) &&
	    skb->len >= MESSAGE_MINIMUM_LENGTH)
		return sizeof(struct message_data);
	if (type == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header) &&
	    skb->len == MESSAGE_INITIATION_SIZE)
		return MESSAGE_INITIATION_SIZE;
	if (type == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header) &&
	    skb->len == MESSAGE_RESPONSE_SIZE)
		return MESSAGE_RESPONSE_SIZE;
	if (type == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header) &&
	    skb->len == MESSAGE_COOKIE_REPLY_SIZE)
		return MESSAGE_COOKIE_REPLY_SIZE;
	return 0;

Т.е. сейчас обмен с включенным asc выглядит так:

image.thumb.png.ef0bee155f99692d15b05868a2126902.png

 

typeid = 0x028c284  И протокол его дешифровать не может.

Можно попробовать задать параметры 0x018c284 0x028c284 0x038c284 0x048c284, но мне кажется все умрет к чертям

Edited by avn
  • 0
Posted

Ладно, это так мысли можно и без asc жить. Тем более эти настройки сейчас вместе не разрешены. Хотя если сначала задать asc, то можно.

  • 0
Posted
1 минуту назад, avn сказал:

Ладно, это так мысли можно и без asc жить. Тем более эти настройки сейчас вместе не разрешены. Хотя если сначала задать asc, то можно.

Попробуйте все же задать параметры с client-id внутри, может и заработает )

  • 0
Posted (edited)
13 минуты назад, Le ecureuil сказал:

Попробуйте все же задать параметры с client-id внутри, может и заработает )

Не работает, т.к. дешифровка пакета не происходит. Я уже трейсы снял. На скриншоте видно.

Без ASC все работает отлично.

 

С ASC примерно так:

client_id=0x00000. Приходит пакет 0x02000000 SKB_TYPE_LE32 = 0x02000000 & 0xFFFFFFFF = 0x02000000 => MESSAGE_HANDSHAKE_RESPONSE

client_id=0x112233. Приходит пакет 0x02112233 SKB_TYPE_LE32 = 0x02112233 & 0xFFFFFFFF = 0x02112233 !=> MESSAGE_HANDSHAKE_RESPONSE

ASC выключен:

client_id=0x00000. Приходит пакет 0x02000000 SKB_TYPE_LE32 = 0x02000000 & 0xFF000000 = 0x02000000 => MESSAGE_HANDSHAKE_RESPONSE

client_id=0x112233. Приходит пакет 0x02112233 SKB_TYPE_LE32 = 0x02112233 & 0xFF000000= 0x02000000 => MESSAGE_HANDSHAKE_RESPONSE

Edited by avn
  • 0
Posted

Оставлю комментарий для себя на будущее. Думаю, что проблема в цепочке

wg_packet_receive->prepare_skb_header->validate_header_len. validate_header_len возвращает 0. И далее все падает.

  • 0
Posted

Сделал. Теперь если h1/h2/h3/h4 меньше или равны 0xFF, то сосуществование с client-id работает. Если хоть один из них больше - работает только ASC.

  • Thanks 5

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

This site uses cookies. By clicking "I accept" or continuing to browse the site, you authorize their use in accordance with the Privacy Policy.