Тег «dhcp freeradius relay agent»

DHCP Relay: freeradius + dhcrelay, версия 2

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

--- freeradius-server-2.2.0/src/main/dhcpd.c.orig       2012-09-10 14:51:34.000000000 +0300
+++ freeradius-server-2.2.0/src/main/dhcpd.c    2013-04-26 08:30:14.483740654 +0300
@@ -267,6 +267,7 @@
        int rcode;
        unsigned int i;
        VALUE_PAIR *vp;
+       VALUE_PAIR *vp1;
        dhcp_socket_t *sock;

        vp = pairfind(request->packet->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */
@@ -397,6 +398,11 @@
        vp = pairfind(request->reply->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */
        if (vp && (vp->vp_ipaddr != htonl(INADDR_ANY))) {
                /* Answer to client's nearest DHCP relay */
+               vp1=pairfind(request->reply->vps, DHCP2ATTR(270));
+               /*ATTRIBUTE     DHCP-Relay-To-IP-Address        270     ipaddr*/
+               if(vp1){
+                   vp = vp1;
+               }
                request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
        } else if ((request->reply->code == PW_DHCP_NAK) ||
            ((vp = pairfind(request->reply->vps, DHCP2ATTR(262))) /* DHCP-Flags */ &&


И в настройках сервера:

        update reply {
            DHCP-DHCP-Server-Identifier = "%{DHCP-Gateway-IP-Address}"
            DHCP-Gateway-IP-Address = "%{DHCP-Gateway-IP-Address}"
            DHCP-Relay-To-IP-Address = "%{Packet-Src-IP-Address}"
        }


 

Теги: ,

DHCP Relay: freeradius + dhcrelay

Для решения некой задачи была выбрана связка freeradius и dhcrelay. Другие варианты или сложнее, или не дают нужного набора функций.

Начальный эксперименты дали интересный результат. Если все делать по красивому, то наверное результат будет. Шаг в сторону и все разваливается. Причин несколько — мало документации и примеров, ну и не совсем очевидное поведение программ.

Решение проблем:

1. Запуск freeradius и dhcrelay на одном хосте. В принципе работает из «коробки»,  но запуск dhcrelay только после freeradius и все цеплять на lo (127.0.0.1)!!

2. dhcrelay должен знать, куда слать и откуда принимать пакеты:

dhcrelay -i <интерфейс, принимающий пакеты от клиентов> -i <интерфейс, принимающий пакеты от freeradius> -a <ip freeradius>

3.  freeradius должен понимать, куда возвращать пакеты. Обычно делает исходя из маршрутов. Если их нет, то можно присвоить DHCP-Gateway-IP-Address адрес dhcrelay-я, но тогда крыша едет у dhcrelay-я (он шлет ответы клиенту на этот же адрес) :( Пришлось добавить параметр в конфигурацию freeradius для указания этого адреса.

--- freeradius-server-2.2.0/src/main/dhcpd.c.orig       2012-09-10 14:51:34.000000000 +0300
+++ freeradius-server-2.2.0/src/main/dhcpd.c    2013-04-22 15:15:35.378274587 +0300
@@ -65,6 +65,7 @@
        RADCLIENT       dhcp_client;
        const char      *src_interface;
         fr_ipaddr_t     src_ipaddr;
+        fr_ipaddr_t     gw_ipaddr;
 } dhcp_socket_t;

 #ifdef WITH_UDPFROMTO
@@ -397,7 +398,14 @@
        vp = pairfind(request->reply->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */
        if (vp && (vp->vp_ipaddr != htonl(INADDR_ANY))) {
                /* Answer to client's nearest DHCP relay */
-               request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
+               if(sock->gw_ipaddr.ipaddr.ip4addr.s_addr != htonl(INADDR_ANY) &&
+                       sock->gw_ipaddr.ipaddr.ip4addr.s_addr != sock->ipaddr.ipaddr.ip4addr.s_addr){
+                   DEBUG("use gw_ipaddr");
+                   request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = sock->gw_ipaddr.ipaddr.ip4addr.s_addr;
+               }else{
+                   DEBUG("use DHCP-Gateway-IP-Address");
+                   request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
+               }
        } else if ((request->reply->code == PW_DHCP_NAK) ||
            ((vp = pairfind(request->reply->vps, DHCP2ATTR(262))) /* DHCP-Flags */ &&
                (vp->vp_integer & 0x8000) &&
@@ -535,6 +543,20 @@
                memcpy(&sock->src_ipaddr, &sock->ipaddr, sizeof(sock->src_ipaddr));
        }

+       cp = cf_pair_find(cs, "gw_ipaddr");
+       if (cp) {
+               memset(&sock->gw_ipaddr, 0, sizeof(sock->gw_ipaddr));
+               sock->gw_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
+               rcode = cf_item_parse(cs, "gw_ipaddr", PW_TYPE_IPADDR,
+                                     &sock->gw_ipaddr.ipaddr.ip4addr, NULL);
+               if (rcode < 0) return -1;
+
+               sock->gw_ipaddr.af = AF_INET;
+               DEBUG("set gw_ipaddr");
+       } else {
+               memcpy(&sock->gw_ipaddr, &sock->ipaddr, sizeof(sock->gw_ipaddr));
+       }
+
        /*
         *      Initialize the fake client.
         */

4. конфигурация сервера dhcp у freeradius будет такой:

    listen {
        type = "dhcp"
        port = 67
        ipaddr = listen_IP
        gw_ipaddr = dhcrelay_IP
        broadcast = no
    }
 
    dhcp DHCP-xxxxx {
        update reply {
            DHCP-DHCP-Server-Identifier = "%{DHCP-Gateway-IP-Address}"
            DHCP-Gateway-IP-Address = "%{DHCP-Gateway-IP-Address}"
        }
    .....
    }

4. Отдельная тема — передача параметров и атрибуты в dictionary. Эта тему можно поискать на nag.ru

Скачать патч dhcp-gw.

Ссылки  по теме:

 http://stas-v.livejournal.com/8636.html

http://forum.nag.ru/forum/index.php?showtopic=65906

http://forum.nag.ru/forum/index.php?showtopic=63047

 

 

 

Теги: ,