Перейти к содержанию

Вопрос

Опубликовано (изменено)

Добрый день!

Для нормальной работы 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)"

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

Изменено пользователем avn

Рекомендуемые сообщения

  • 0
Опубликовано (изменено)
  В 16.08.2024 в 13:18, 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, то он выглядит так

  Показать контент

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

Изменено пользователем avn
  • 0
Опубликовано (изменено)

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

 

Изменено пользователем avn
  • 0
Опубликовано

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

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

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

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

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

Untitled.jpg

  • 0
Опубликовано
  В 21.08.2024 в 10:24, Le ecureuil сказал:

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

Показать  

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

  Показать контент

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

1.lkkПолучение информации... 3.lkkПолучение информации...

  • 0
Опубликовано (изменено)
  В 21.08.2024 в 10: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
	}
}
Изменено пользователем avn
  • 0
Опубликовано

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

  • 0
Опубликовано (изменено)

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

 

image.thumb.png.673dd427bda2761d6f4aea273b8234ca.png

 

image.png.b581b28b57ac7b81f94e2feb91e1a582.png

Изменено пользователем avn
  • 0
Опубликовано
  В 05.09.2024 в 07: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
Опубликовано

@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
Опубликовано (изменено)
  В 15.09.2024 в 08:51, 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.

Изменено пользователем avn
  • 0
Опубликовано
  В 15.09.2024 в 08:51, 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.

  • 0
Опубликовано
  В 16.09.2024 в 07:22, Le ecureuil сказал:

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

Показать  

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

interface Wireguard2 no wireguard asc

 

  • 0
Опубликовано
  В 19.09.2024 в 08:54, avn сказал:

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

interface Wireguard2 no wireguard asc

 

Показать  

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

  • 0
Опубликовано (изменено)
  В 19.09.2024 в 09:28, 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.

 

Изменено пользователем avn
  • 0
Опубликовано (изменено)
  В 19.09.2024 в 12:23, 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, но мне кажется все умрет к чертям

Изменено пользователем avn
  • 0
Опубликовано

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

  • 0
Опубликовано
  В 19.09.2024 в 13:21, avn сказал:

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

Показать  

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

  • 0
Опубликовано (изменено)
  В 19.09.2024 в 13:23, 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

Изменено пользователем avn
  • 0
Опубликовано

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

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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...

Важная информация

На этом сайте используются файлы cookie. Нажимая "Я принимаю" или продолжая просмотр сайта, вы разрешаете их использование: Политика конфиденциальности.