Документация
→ make_config «один на порту» для isc-dhcpd
Задача: динамически формировать конфигурационный файл для dhcp-сервера isc-dhcpd. При этом, если в настройках учетной записи абонента стоит галка «один на порту», то не проверять его мак-адрес. В этом случае учитываются только порт подключения и мак-адрес свича. Как это будет выглядеть в сформированном конфиге:
class "host10.0.0.7" {match if suffix(option agent.circuit-id,1)=a and suffix(option agent.remote-id,6)=00:11:22:33:44:55;}
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; }
pool { range 10.0.0.7; allow members of "host10.0.0.7"; }
}
Здесь мы видим, что абонент, подключенный к порту 10 («a» в 16-ричной системе счисления) свича с мак-адресом 00:11:22:33:44:55 получит ip 10.0.0.7. Абонент с мак-адресом 00:11:00:11:00:22 получит ip 10.0.0.6. У первого абонента в настройках стоит галка «один на порту».
Создаем файл /usr/local/nodeny/kernel/make_config_dhcp.cfg:
run => 0,
period => 60,
template => {
'dhcp_ok.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;
},
hex => sub {
return sprintf('%x', $_[0]);
}
}
Создаем /usr/local/nodeny/kernel/make_config/dhcp_ok.tmpl:
allow unknown-clients;
option domain-name-servers 1.1.1.1, 8.8.8.8;
default-lease-time 28800;
min-lease-time 10000;
max-lease-time 128800;
authoritative;
ddns-update-style interim;
log-facility local7;
{% for user in users %}
{% if user.ips.0.ipa && user.ips.0.type eq 'static' && user.connection.0 && user.connection.0.oneconnect %}
{% one_line %}
class "host{{user.ips.0.ipa}}" { match if suffix(option agent.circuit-id,1)={{user.connection.0.device_port|hex}}
and suffix(option agent.remote-id,6)={{user.connection.0.device_mac|pretty_mac}}; }
{% one_line_end %}
{% endif %}
{% endfor %}
subnet 10.0.0.0 netmask 255.255.255.0 {
option subnet-mask 255.255.255.0;
option broadcast-address 10.0.0.255;
interface em1;
option routers 10.0.0.1;
{% for user in users %}
{% if user.ips.0.ipa && user.ips.0.type eq 'static' && user.connection.0 %}
{% if user.connection.0.oneconnect %}
pool { range {{user.ips.0.ipa}}; allow members of "host{{user.ips.0.ipa}}"; }
{% else %}
host host{{user.ips.0.ipa}} { hardware ethernet {{user.connection.0.mac|pretty_mac}}; fixed-address {{user.ips.0.ipa}}; }
{% endif %}
{% endif %}
{% endfor %}
}
Запустим с выводом результата на экран:
perl /usr/local/nodeny/nokernel.pl -v -m=make_config -g=make_config_dhcp
Если конфиг сформирован правильно, добавим запуск make_config в автозагрузку:
echo '/usr/bin/perl /usr/local/nodeny/nokernel.pl -m=make_config -g=make_config_dhcp -d &' >> /etc/rc.local
Небольшие комментарии по шаблону: