zed.0xff.me
ng_sbinat – (Symmetric | Simple) Bidirectional NAT
1. что это?
это такой простой двусторонний нат.
работает в ядре freebsd, внутри нетграфа.
вешается непосредственно на ng_ether интерфейс (напр. em0)
2. для чего это?
для трансляции одной /16 сетки в другую (например 192.168.×.y <—> 10.22.×.y)
3. требования?
- freebsd >= 7.0
- netgraph
- сорцы ядра
- прямые руки :)
4. где взять / more info ?
[PATCH] ng_netflow: ifIndex from vlan
Во время оптимизации ng_netflow и выносом его на отдельную машину возникла такая проблема, что вместе с логами трафика из ng_netflow нужно сохранять и номер vlan’а, в котором пришел этот трафик.
Самое очевидное – использовать для этого netflow-поле ifIndex, благо трафик собирается с единственного (пока) роутера, и физических интерфейсов на нём негусто, так что ifIndex фактически не используется.
Самое неочевидное – заставить ng_netflow прописывать в потоках в ifIndex номер vlan’а..
Я пошел недеструктивным путём, и постарался при добавлении нового функционала ничего не сломать :)
В результате в команду NGM_NETFLOW_SETCONFIG добавлено новое значение: NG_NETFLOW_CONF_VLAN = 16, и включается новый режим на интерфейсе так:
(вместо iface=0 и conf=19 пропишите соответственно номер интерфейса и флаги, которые вам нужны, обращая внимание на +16 к значению conf если нужен новый режим установки ifIndex по vlan’у)
1 2 3 |
ngctl msg netflow: setconfig \{ iface=0 conf=19 \} # 16 = NG_NETFLOW_CONF_VLAN # 2 = NG_NETFLOW_CONF_EGRESS # 1 = NG_NETFLOW_CONF_INGRESS |
а вот, собственно, и патч:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
diff -ur /usr/src/sys/netgraph/netflow/ng_netflow.c kld/ng_netflow.c --- /usr/src/sys/netgraph/netflow/ng_netflow.c 2009-04-15 09:14:26.000000000 +0600 +++ kld/ng_netflow.c 2009-09-04 06:25:42.000000000 +0600 @@ -486,7 +486,7 @@ struct m_tag *mtag; int pullup_len = 0; int error = 0, bypass = 0; - unsigned int src_if_index; + unsigned int src_if_index = 0; if (hook == priv->export) { /* @@ -585,6 +585,10 @@ M_CHECK(sizeof(struct ip)); eh = mtod(m, struct ether_header *); ip = (struct ip *)(eh + 1); + if( (m->m_flags & M_VLANTAG) && (iface->info.conf & NG_NETFLOW_CONF_VLAN) ){ + // tag is stored out-of-band + src_if_index = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); + } break; case ETHERTYPE_VLAN: { @@ -596,6 +600,9 @@ if (ntohs(evh->evl_proto) == ETHERTYPE_IP) { M_CHECK(sizeof(struct ip)); ip = (struct ip *)(evh + 1); + if (iface->info.conf & NG_NETFLOW_CONF_VLAN){ + src_if_index = evh->evl_tag; + } break; } } @@ -639,6 +647,10 @@ switch (ntohs(eh->ether_type)) { case ETHERTYPE_IP: ip = (struct ip *)(eh + 1); + if( (m->m_flags & M_VLANTAG) && (iface->info.conf & NG_NETFLOW_CONF_VLAN) ){ + // tag is stored out-of-band + src_if_index = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); + } break; case ETHERTYPE_VLAN: { @@ -646,6 +658,9 @@ evh = mtod(m, struct ether_vlan_header *); ip = (struct ip *)(evh + 1); + if (iface->info.conf & NG_NETFLOW_CONF_VLAN){ + src_if_index = evh->evl_tag; + } break; } default: @@ -662,13 +677,16 @@ #undef M_CHECK + /* Determine packet input interface. Prefer configured. */ - src_if_index = 0; - if (hook == iface->out || iface->info.ifinfo_index == 0) { - if (m->m_pkthdr.rcvif != NULL) - src_if_index = m->m_pkthdr.rcvif->if_index; - } else - src_if_index = iface->info.ifinfo_index; + if(!(iface->info.conf & NG_NETFLOW_CONF_VLAN) || src_if_index == 0){ + src_if_index = 0; + if (hook == iface->out || iface->info.ifinfo_index == 0) { + if (m->m_pkthdr.rcvif != NULL) + src_if_index = m->m_pkthdr.rcvif->if_index; + } else + src_if_index = iface->info.ifinfo_index; + } error = ng_netflow_flow_add(priv, ip, src_if_index); diff -ur /usr/src/sys/netgraph/netflow/ng_netflow.h kld/ng_netflow.h --- /usr/src/sys/netgraph/netflow/ng_netflow.h 2009-04-15 09:14:26.000000000 +0600 +++ kld/ng_netflow.h 2009-09-03 19:27:03.000000000 +0600 @@ -98,6 +98,7 @@ #define NG_NETFLOW_CONF_EGRESS 2 #define NG_NETFLOW_CONF_ONCE 4 #define NG_NETFLOW_CONF_THISONCE 8 +#define NG_NETFLOW_CONF_VLAN 16 /* This structure is passed to NGM_NETFLOW_SETCONFIG */ struct ng_netflow_setconfig { |
netgraph не умеет ловить исходящие пакеты в тэгированном интерфейсе
1 2 3 4 5 6 7 |
ifconfig vlan10 create ifconfig vlan10 vlandev em0 vlan 10 ifconfig vlan10 10.10.0.2/24 ngctl mkpeer em0: tee lower left ngctl name em0:lower tee0 ngctl conn em0: tee0: upper right |
напускаем в em0 тэгированного трафика, либо смотрим на живом роутере. результат один и тот же:
nghook -a tee0: left2right – трафик есть.
nghook -a tee0: right2left – трафика нет!!
т.е. в нетграф попадают только пакеты входящие в тазик, а исходящие благополучно проходят мимо нетграфа прямиком на сетевой интерфейс.
по этой причине и пришлось вынести netflow на отдельную машину, что вцелом более правильно и красиво :)
FreeBSD & more than 32 arpd's
0. Предыстория
- Есть фрибсд-сервер.
- На сервере есть куча интерфейсов (~200).
- На некоторых интерфейсах надо пускать arpd.
1. Bug
- 16 arpd-ей запустились нормально.
- На запуске 17-го получаем “arpd: bad interface configuration: not IP or Ethernet”
- Копание в исходниках показало что проблема в libdnet, в коем гвоздями прибито не юзать /dev/bpf’ы с номером более 32
3. Patch for /usr/ports/net/libdnet
1 2 3 4 5 6 7 8 9 10 11 |
--- src/eth-bsd.c.orig 2009-04-16 14:22:44.000000000 +0600 +++ src/eth-bsd.c 2009-04-16 14:23:31.000000000 +0600 @@ -45,7 +45,7 @@ int i; if ((e = calloc(1, sizeof(*e))) != NULL) { - for (i = 0; i < 32; i++) { + for (i = 0; i < 256; i++) { snprintf(file, sizeof(file), "/dev/bpf%d", i); e->fd = open(file, O_WRONLY); if (e->fd != -1 || errno != EBUSY) |
4. FreeBSD PR: ports/133772
отложенный шеллбомбинг в freebsd 7.1 :)
(но необходим доступ на запись в /etc :-\ )
1 2 3 4 5 6 |
echo ipfw > /etc/ipfw echo ipfw >> /etc/ipfw echo ipfw >> /etc/ipfw echo ipfw >> /etc/ipfw echo ipfw >> /etc/ipfw chmod +x /etc/ipfw |
и всё жестоко встанет колом в 3 часа ночи :) (в 80-90% инсталляций)
и причину найти будет достаточно неочевидно.
PS: возможно сработает и на более старых версиях