Виртуальное сетевой устройство с криптованием

Вопросы программного кода и архитектуры Linux

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение Olej » 14 мар 2012, 00:22

kit_D писал(а): netdev_rx_handler_register получается так, что эта функция появилась в 2.6.36
по крайней мере, в 2.6.35. её нет:

Код: Выделить всё

[olej@nvidia ~]$ uname -r
2.6.35.14-96.fc14.i686.PAE
[olej@nvidia ~]$ cat /proc/kallsyms | grep T | grep netdev_rx_handler_register
[olej@nvidia ~]$ 

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение Olej » 14 мар 2012, 01:29

Olej писал(а): kit_D, пока я не добрался до более позднего ядра, скопируйте мне (да и не только мне) сюда прототипы (из /linux/*.h) функций:
- netdev_rx_handler_register()
- netdev_rx_handler_unregister()
1. Как я понял (? ;-) ) из кода примера, netdev_rx_handler_register() имеет прототип что-то типа такого? :
??? netdev_rx_handler_register( net_device* slave, rx_handler_result_t (func*)( struct sk_buff ** ), ??? );
- где func() - это регистрация функции, которая будет вызываться при приёме каждого сокетного буфера.
- где slave - это зарегистрированный ранее виртуальный (фиктивный?) сетевой интерфейс.

2. А зачем этот вызов обкладывается такими:
rtnl_lock();
...
rtnl_unlock();
- какая в этом глубокая сермяжная правда?

Я не очень знаю-понимаю что это?

Код: Выделить всё

[olej@notebook net-crypto]$ cat /proc/kallsyms | grep T | grep rtnl_
c07241c4 T rtnl_is_locked
c07242d2 T rtnl_unregister
c072431d T __rtnl_register
c072438f T rtnl_register
c07243bd T rtnl_unregister_all
c0724afa T rtnl_create_link
c0724c50 T rtnl_put_cacheinfo
c0724ce0 T rtnl_set_sk_err
c0724cf8 T rtnl_notify
c0724e2d T rtnl_unicast
c0724ea9 T __rtnl_link_unregister
c0724f08 T __rtnl_link_register
c0724f31 T rtnl_trylock
c0724f45 T rtnl_unlock
c0724f54 T __rtnl_unlock
c0724f68 T rtnl_lock
c0725149 T rtnl_link_unregister
c072516b T rtnl_kill_links
c07251b2 T rtnl_link_register

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение Olej » 14 мар 2012, 01:44

Olej писал(а): 2. А зачем этот вызов обкладывается такими:
rtnl_lock();
...
rtnl_unlock();
- какая в этом глубокая сермяжная правда?
Ага ;-)
<linux/rtnetlink.h>

Код: Выделить всё

/* RTNL is used as a global lock for all changes to network configuration  */
extern void rtnl_lock(void);                                               
extern void rtnl_unlock(void);
extern int rtnl_trylock(void);
extern int rtnl_is_locked(void);

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение kit_D » 14 мар 2012, 11:19

По-поводу прототипов, их можно увидеть здесь: http://lxr.free-electrons.com/source/in ... ce.h?v=3.0
А по-поводу локов, то это написано в комментарии перед определением самой функции netdev_rx_handler_register() :http://lxr.free-electrons.com/source/ne ... =3.0#L3059 . Без них крешит - проверено

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение kit_D » 14 мар 2012, 19:13

Выкладываю новую версия кода.
Слегка изменилась архитектура. После загрузки модуля появляется новое устройство crypto, но оно пока не ассоциировано с реальным(подчиненным, slave) устройством. Для того чтобы сделать такую ассоциацию надо вызвать команду:
./crypto_us wlan0
Она назначает устройству crypto подчиненное устройство wlan0. Вероятно это будет работать если подчиненное устройство eth<N> - не знаю, не проверял.

Далее при передаче пакетов в crypto (таблица маршрутизации должна быть правильно сконфигурирована) перекладывает свои исходящие пакеты в очередь подчиненного wlan0, и наоборот, входящие пакеты на wlan0 перекладываются во входящую очередь crypto устройства.

Существующее устройство wlan0 имеет вид
wlan0 Link encap:Ethernet HWaddr 14:da:e9:f0:d3:96
inet addr:172.28.155.7 Bcast:172.28.155.255 Mask:255.255.255.0
inet6 addr: fe80::16da:e9ff:fef0:d396/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1420 errors:0 dropped:0 overruns:0 frame:0
TX packets:1793 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:149932 (149.9 KB) TX bytes:204712 (204.7 KB)

Вот что надо сделать чтобы заставить эту адскую смесь работать:

insmod crypto0.ko
ifconfig crypto down
ifconfig crypto 172.28.155.7
./crypto_us wlan0
route del -net 172.28.155.0/24 wlan0
ifconfig crypto up

Обратите внимание, что crypto будет иметь тот же MAC и IP адрес что и wlan0. Это пока не совсем очевидно, надо подумать.
В результате, пинг на 172.28.155.3 успешно проходит через crypto и принимается ответ от 172.28.155.3. ARP таблица также показываеть правильно заполненный кеш с записями соответствующими crypto интерфейсу.

Однако, после некоторого времени WiFi сеть падает. Причина понятна - точка доступа и сетевая карта обмениваются EAP пакетами (аутентификация по 802.11). При включении виртуального устройства это EAP пакеты поглощаются crypto устройством в в результате сеть "отваливается". Думаю это можно починить.

Кроме того надо бы правильно организовать взаимодействие с модулем, изменение параметров его работы (через ioctl), обработку уведомлений об отключении подчиненного устройства, да и потестировать не плохо было бы.
Вложения
crypto1.tar.gz
(6.05 КБ) 466 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение Olej » 14 мар 2012, 20:31

kit_D писал(а): Слегка изменилась архитектура. После загрузки модуля появляется новое устройство crypto, но оно пока не ассоциировано с реальным(подчиненным, slave) устройством. Для того чтобы сделать такую ассоциацию надо вызвать команду:
./crypto_us wlan0
Она назначает устройству crypto подчиненное устройство wlan0. Вероятно это будет работать если подчиненное устройство eth<N> - не знаю, не проверял.
Странно...
Ведь всё, что вы делаете в ./crypto_us - это ioctl() команда на выполнение netdev_rx_handler_register() (ну, и + дублирование адресов MAC & IP).
Почему то же нельзя сделать в функции инициализации модуля? Или почему это не работает из функции инициализации модуля? ... проверяли? Так как это було сделано в предыдущем варианте.
kit_D писал(а): Далее при передаче пакетов в crypto (таблица маршрутизации должна быть правильно сконфигурирована) перекладывает свои исходящие пакеты в очередь подчиненного wlan0, и наоборот, входящие пакеты на wlan0 перекладываются во входящую очередь crypto устройства.
как я понял (что успел):

- исходящие пакеты из crypto не перекладываются, а вы их перекладываете в netdev_tx_t crypto_xmit() ... вот этим местом ;-) :

Код: Выделить всё

skb->dev = priv->slave;
вот здесь подменился выходной интерфейс?

- а входящие пакеты wlan0 тоже перекладываете вы в коде ранее зарегистрированной функции:

Код: Выделить всё

rx_handler_result_t handle_frame(struct sk_buff **pskb)
{
    struct sk_buff *skb = *pskb;
    /* printk(KERN_WARNING "%s: Address src=%pM dst=%pM len=%d data_len=%d mac_len=%d\n", skb->dev->name, eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, skb->len, skb->data_len, skb-
#if 1
    /* We need to remove scb from slave device and push it to crypto device */
    if (crypto_dev)
    {
        struct crypto_priv *priv = netdev_priv(crypto_dev);
        
        priv->priv_stats.rx_packets++;
        priv->priv_stats.rx_bytes += skb->len;

        printk("injecting frame from %s to %s\n", skb->dev->name, crypto_dev->name);
        skb->dev = crypto_dev;
        netif_receive_skb(skb);
    }
    return RX_HANDLER_CONSUMED;
#else
    return RX_HANDLER_PASS;
#endif
}

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение Olej » 14 мар 2012, 20:44

А дальше ... меня многое смущает:
kit_D писал(а): Существующее устройство wlan0 имеет вид
wlan0 Link encap:Ethernet HWaddr 14:da:e9:f0:d3:96
inet addr:172.28.155.7 Bcast:172.28.155.255 Mask:255.255.255.0
inet6 addr: fe80::16da:e9ff:fef0:d396/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1420 errors:0 dropped:0 overruns:0 frame:0
TX packets:1793 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:149932 (149.9 KB) TX bytes:204712 (204.7 KB)

Вот что надо сделать чтобы заставить эту адскую смесь работать:

insmod crypto0.ko
ifconfig crypto down
ifconfig crypto 172.28.155.7
./crypto_us wlan0
route del -net 172.28.155.0/24 wlan0
ifconfig crypto up

Обратите внимание, что crypto будет иметь тот же MAC и IP адрес что и wlan0. Это пока не совсем очевидно, надо подумать.
В результате, пинг на 172.28.155.3 успешно проходит через crypto и принимается ответ от 172.28.155.3. ARP таблица также показываеть правильно заполненный кеш с записями соответствующими crypto интерфейсу.

Однако, после некоторого времени WiFi сеть падает. Причина понятна - точка доступа и сетевая карта обмениваются EAP пакетами (аутентификация по 802.11). При включении виртуального устройства это EAP пакеты поглощаются crypto устройством в в результате сеть "отваливается". Думаю это можно починить.

Кроме того надо бы правильно организовать взаимодействие с модулем, изменение параметров его работы (через ioctl), обработку уведомлений об отключении подчиненного устройства, да и потестировать не плохо было бы.
На вскидку то, что вызывает вопросы:

1. Как мне помнится из У.Стивенса "Illustrated TCP/IP" в системе (в компьютере) не может быть 2 сетевых интерфейса, принадлежащих к одной подсети (IP:маска).
т.е. могут быть eth0=192.168.1.1:255.255.255.0 & eth0=192.168.2.1:255.255.255.0
или eth0=192.168.1.1:255.255.255.248 & eth0=192.168.2.33:255.255.255.248 (маска /28).
но не может быть 192.168.1.1/24 & 192.168.1.2/24


2. После удаления маршрута у вас

Код: Выделить всё

route del -net 172.28.155.0/24 wlan0
наверное, нужно добавить новый? :

Код: Выделить всё

route add -net 172.28.155.0/24 crypto

3. ох, нехорошо отлаживаться на подсетке 172.*.*.* (там маска дефаултная не на границе байта, много путаницы вносит), лучше 10.*.*.* или 192.168.*.*

... ну и ещё какие-то сомнения меня гложут ;-)


P.S. пока у меня идёт компиляция ядра 3.0.9 ... закончится - посмотрю runtime.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение Olej » 14 мар 2012, 20:53

Olej писал(а): 2. После удаления маршрута у вас

Код: Выделить всё

route del -net 172.28.155.0/24 wlan0
наверное, нужно добавить новый? :

Код: Выделить всё

route add -net 172.28.155.0/24 crypto
Покажите что у вас в таблице до, что-то типа:

Код: Выделить всё

[olej@notebook variants]$ route 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     *               255.255.255.0   U     2      0        0 wlan0
default         192.168.1.1     0.0.0.0         UG    0      0        0 wlan0
И что после, когда вы начинаете экспериментировать с обменом.

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение kit_D » 14 мар 2012, 22:18

>>Странно...
>>Ведь всё, что вы делаете в ./crypto_us - это ioctl() команда на выполнение netdev_rx_handler_register() (ну, и + дублирование адресов MAC & IP).
>>Почему то же нельзя сделать в функции инициализации модуля? Или почему это не работает из функции инициализации модуля? ... проверяли?
>>Так как это було сделано в предыдущем варианте.

В конечном счете, как мне видится, модуль будет загружаться при старте системы и будет создаваться что-то типа /dev/net/crypto. Далее я буду открывать это устройство и давать ему команды на создание crypto интерфейса, его ассоциацию с подчиненным интерфейсом ну и его удаление. Поэтому я просто вынес хардкод имени подчиненного интерфейса из тела модуля. Опять же, пока рано говорить о конечной архитектуре взаимодействия с модулем.

>> skb->dev = priv->slave;
>> вот здесь подменился выходной интерфейс?
Да, это перекладывание из crypto в wlan0

На вскидку то, что вызывает вопросы:

>>1. Как мне помнится из У.Стивенса "Illustrated TCP/IP" в системе (в компьютере) не может быть 2 сетевых интерфейса, принадлежащих к
>> одной подсети (IP:маска).
>>т.е. могут быть eth0=192.168.1.1:255.255.255.0 & eth0=192.168.2.1:255.255.255.0
>>или eth0=192.168.1.1:255.255.255.248 & eth0=192.168.2.33:255.255.255.248 (маска /28).
>>но не может быть 192.168.1.1/24 & 192.168.1.2/24

Ну это в реальном мире, но ведь у нас "виртуальное" устройство, которое почти полностью поглощает весь трафик проходящий через wlan0, а не два равноправных устройства. В конечном счете я расчитываю пустить весь трафик через crypto, а wlan0 не будет присутствовать в таблице маршрутизации. Поєтому желательно, чтобы адрес должен быть тот же что и у настоящего устройства - реальное устройство получает адрес по DHCP или статически. Ну а исходящий трафик должен иметь тот же IP адрес источника, чтобы не нарушать существующие настройки маршрутизации принятые в сети. Представьте, что вы подключились к беспроводной сети и автоматически получили IP адрес. В этом случае логично было бы если пакеты, исходящие из вашего устройства имеют именно этот адрес в качестве источника, а не какой-то который ві сами себе назначили. Кроме того, тот факт что у вас 2 интерфейса с одинаковыми адресами никому кроме вас не известен - извне он будет видится как один (более того у них даже одинаковый МАК адрес! - причина в том, что точка доступа вероятно не пропустит пакеты с несоответствующим МАК адресом, кроме того реальное устройство и не примет в ответ фрейм у которого будет МАК отличный от МАК-а самого реального устройства).

Возможно в конечном счете с wlan0 вообще придется убрать IP адрес, но тогда наверное некоторые сопутствующие вещи тоже перестанут работать. Не знаю какие именно, но возможно ARP, мультикаст.... Надо пробовать.

И еще, по-поводу одинаковых IP адресов. Идея такой реализации с перекладыванием исходящих пакетов из псевдо-интерфейса в реальный у меня появилась на основе двух вещей
1) Трафик шейпер, написанный Аланом Коксом работает на том же принципе: http://lwn.net/1998/1119/shaper.html
Цитата: The host/address, mask, and broadcast parameters need to match those of the underlying physical interface.

2) Insane инетрфейс, который эмулирует потерю пакетов используя аналогичный принцип: http://www.linux.it/~rubini/docs/vinter/vinter.html
Цитата:
borea# insmod insane ; # load module
borea# ifconfig insane borea ; # give same IP as eth0

Так что, как видите, идея не нова :-)


>> После удаления маршрута у вас
>> route del -net 172.28.155.0/24 wlan0
>> наверное, нужно добавить новый? :
>> route add -net 172.28.155.0/24 crypto

Тут дело в том, что когда поднимется crypto интерфейс с адресом 172.28.155.7, то для него автоматически добавляется запись в таблицу маршрутизации. Все что остается это удалить маршрут 172.28.155.0/24 wlan0, и весь 172.28.155.0 трафик "потечет" через crypto

>>P.S. пока у меня идёт компиляция ядра 3.0.9 ... закончится - посмотрю runtime.
А зачем вы компилируете, почему бы не установить из репозитория
sudo apt-get install linux-image-3.0.0-16
sudo apt-get install linux-headers-3.0.0-16
(пишу по памяти - может неправильное название пакетов)
Последний раз редактировалось kit_D 14 мар 2012, 23:04, всего редактировалось 3 раза.

kit_D
Писатель
Сообщения: 52
Зарегистрирован: 13 мар 2012, 13:14
Откуда: Харьков
Контактная информация:

Re: Виртуальное сетевой устройство с криптованием

Непрочитанное сообщение kit_D » 14 мар 2012, 22:24

>>Покажите что у вас в таблице до, что-то типа:
>>И что после, когда вы начинаете экспериментировать с обменом.
Это только завтра - приду на работу отпишу. Но суть в том, чтобы убрать wlan0 из таблицы маршрутизации, а crypto подставить на его место.

Кстати, в конечном счете предвидеться адаптировать код и к более ранним версиям ядра. Навскидку - к 2.6.35, которое используется на Android GingerBread. В связи с этим надо будет искать заменитель для netdev_rx_handler_register(), которая появилась только в 2.6.36. Вероятно надо будет копать код в /net/bridge - собственно откуда я и подсмотрел netdev_rx_handler_register(). Может как-то поможет нетфильтер?

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей