Dhcp-конфиг с помощью make config

Материал из NoDeny Plus
Перейти к: навигация, поиск

Конфиги будут разными в зависимости от разных факторов (option82, один на порту, существует ли привязка mac к ip или нет). Сначала рассмотрим типичный случай. Допустим, надо сформировать конфигурационный файл для isc-dhcpd в таком виде:

option domain-name-servers 1.1.1.1, 8.8.8.8;
default-lease-time 28800;
subnet 10.0.0.0 netmask 255.255.255.0 {
    option subnet-mask 255.255.255.0;
    option broadcast-address 10.0.0.255;
}
host host10.0.0.6 {
    hardware ethernet 00:11:00:11:00:22;
    fixed-address 10.0.0.6;
}
host host10.0.0.2 {
    hardware ethernet 00:11:22:33:44:77;
    fixed-address 10.0.0.2;
}

По данному конфигу isc-dhcpd будет выдавать ip в зависимости от мак-адреса, привязанного к учетке абонента. Например, видим, что для двух абонентов прописаны такие связки мак → ip:

  • 00:11:00:11:00:22 → 10.0.0.6
  • 00:11:22:33:44:77 → 10.0.0.2

Эта информация зависит от данных в биллинге, поэтому ее необходимо заменить на переменные. Создадим шаблон /usr/local/nodeny/kernel/make_config/dhcp.tmpl:

option domain-name-servers 1.1.1.1, 8.8.8.8;
subnet 10.0.0.0 netmask 255.255.255.0 {
    option subnet-mask 255.255.255.0;
    option broadcast-address 10.0.0.255;
}

{% for user in users %}
    {% for con in user.connection %}
        {% if con.type eq 'static' && con.mac %}
        host host{{con.ipa}} {
            hardware ethernet {{con.mac|pretty_mac}};
            fixed-address {{con.ipa}};
        }
        {% endif %}
    {% endfor %}
{% endfor %}

Мы видим, что информация по связкам мак-ip была заменена на относительно непонятную конструкцию. Давайте разберемся в ней:

Все что находится внутри {% .. %} или {{ .. }} - это команды для шаблонизатора.

  • {% for user in users %} - в переменную user загружаем данные пользователя (сначала первого из users, затем второго и т.д).;
  • {% for con in user.connection %} - в переменную con загружаем информацию по первому подключению (затем второму и т.д);
  • {% if con.type eq 'static' && con.mac %} - это проверка, что в соединении ip статический и к нему привязан не пустой мак-адрес;
  • {{ con.ipa }} - в данное место будет вставлен ip адрес. Обратите внимание, что в базе данных ip хранятся в виде чисел (для сокращения объема), поэтому, чтобы ip был в виде xx.xx.xx.xx нужно использовать переменную ipa;
  • {{ con.mac|pretty_mac }} - в данное место будет вставлен мак-адрес, при этом он будет приведен в удобочитаемую форму (вставлены разделители в виде двоеточия);


Кроме самого шаблона необходим файл настроек для модуля make_config: kernel/make_config.cfg. Он может быть таким:

run     => 0,
period  => 60,
template  => {
            'dhcp.tmpl' => {
                # куда будет записан сформированный конфиг
                file       => '/usr/local/etc/dhcpd.conf',

                # системная команда, которая будет выполнена перед записью конфига, можно ''
                cmd_before => '',

                # системная команда, которая будет выполнена после записи конфига, можно ''
                cmd_after  => '/usr/local/etc/rc.d/isc-dhcpd forcestart >/dev/null',

                # удалять пустые строки
                pretty => 1,
            },
},
subs    => {
            pretty_mac => sub {
                my $mac = shift;
                $mac =~ s/(..)/$1:/g;
                chop $mac;
                return $mac;
            },
}

Здесь:

  • dhcp.tmpl - имя файла с шаблоном;
  • /usr/local/etc/dhcpd.conf - имя файла, куда будет записан результат;
  • переменная period указывает на период в секундах, с которым будут проверяться изменения данных в биллинге. Например, если period = 60 секундам, то при изменении ip какого-либо абонента, эти изменения отобразятся в конфиге dhcp максимум через 60 секунд (обычно раньше: от 1 до 60 сек);
  • pretty_mac - функция, которая добавляет двоеточия в мак-адрес (в базе мак хранится в виде 001122334455).

Запустим модуль make_config с выводом результата на экран:

perl /usr/local/nodeny/nokernel.pl -v -m=make_config

Если результат корректный, добавим запуск make_config в автозагрузку:

echo '/usr/bin/perl /usr/local/nodeny/nokernel.pl -m=make_config -d &' >> /etc/rc.local






Можно запустить несколько копий модуля для формирования разных конфигов:

perl nokernel.pl -v -m=make_config -g=make_config_2

При этом необходимо создать файл /usr/local/nodeny/kernel/make_config_2.cfg






Ключ connection

ключ connection - это текущие подключения абонента. Обычно он хранит список ip. Но при использовании модуля dhcp, в connection попадает информация о мак-адресе клиентского оборудования, мак-адресе свича, порта и другие параметры.

По умолчанию список ip, выданных абоненту, не имеет прямого соответствия с привязанными мак-адресами. Поэтому, модуль make_config сам их связывает в неопределенном порядке. Вероятно, вас это устроит, если не требуется жестко привязывать ip к конкретному устройству абонента.

Обычно, к учетной записи привязан один ip и один мак-адрес. В этом случае make_config объединит ip и mac в одно соединение.

В случае использования нескольких подключений на одну учетку, есть возможность привязать ip к mac:

Ip mac bind.png

Если не все привязанные ip будут привязаны к мак - эти связки будут созданы автоматически, но в неопределенном порядке.

Пример, фрагментов шаблонов для разных ситуаций:

{% for user in users %}
    {% for con in user.connection %}
        {% if con.device_mac %}
            class "host-{{con.ipa}}" { match if suffix(option agent.circuit-id,1)={{con.device_port}} and suffix(option agent.remote-id,6)={{con.device_mac|pretty_mac}}; } 
        {% endif %}
    {% endfor %}
{% endfor %}

Данный шаблон сформирует записи такого вида:

class "host-10.0.0.26" { match if suffix(option agent.circuit-id,1)=1 and suffix(option agent.remote-id,6)=77:88:77:00:00:11; }

Обратите внимание на {% if con.device_mac %} - это проверка, что в подключении указан мак устройства. Следовательно, данное подключение "использует" option 82. Если в вашей сети один абонент на порту управляемого свича - мак адрес абонента можно не проверять, что и сделано в данном примере.

В сети может быть как управляемое, так и неуправляемое оборудование. Вы можете формировать комбинированный конфиг, учитывающий option82 и не учитывающий:

{% for user in users %}
    {% for con in user.connection %}
        {% if con.device_mac %}
            class "host-{{con.ipa}}" { match if suffix(option agent.circuit-id,1)={{con.device_port}} and suffix(option agent.remote-id,6)={{con.device_mac|pretty_mac}}; } 
        {% endif %}
    {% endfor %}
{% endfor %}

{% for user in users %}
    {% for con in user.connection %}
        {% if ! con.device_mac && con.mac %}
            host {{con.ipa}} { hardware ethernet {{con.mac|pretty_mac}}; fixed-address {{con.ipa}}; }
        {% endif %}
    {% endfor %}
{% endfor %}