Серверное администрирование / Связка LightSquid + Active Directory

в 15:44, , рубрики: active directory, lightsquid, squid, метки: , ,

Использую на прокси-сервере squid анализатор логов LightSquid, и вот, однажды захотелось чтобы статистика была в виде компьютер – реальное имя, а так как править конфигурационный файл для 100+ юзеров показалось делом рутинным, ну и при изменении имени или добавлении новых пользователей лазить опять в конфиг не хотелось, решил брать автоматом имена из Active Directory. За деталями прошу под кат.

У меня используется Active Directory, но с минимальными изменениями скрипт должен работать и с обычной LDAP.
Описывать установку LightSquid не буду, она довольно проста, гугл вам в помощь. Для преобразования IP в hostname будем использовать DNS, описывается ето в конфигурационном файле lightsquid.cfg строчкой:

$ip2name=«dns»;

Парсер перечитывает файлы realname.cfg и group.cfg и берет оттуда реальные имена юзеров, привязаных к хостам. Формат файлов такой:

realname.cfg:
«hostname» «real name»

group.cfg:
«hostname» «group number» «group name»

Что нам надо?

Надо взять с АД хосты, имена юзеров привязаных к хостам, группы в каких содержатся юзеры; потом пишем всё ето в конфигурационные файлы в соответственном формате.

Вот собственно скрипт, который ето делает:

#!/usr/local/bin/perl # # ldap2lightsquid (c) Roman Melko <romanmelko@gmail.com> # Description:  Synchronize users and computers of LightSquid with LDAP server # Requirements: Should run periodically # Version:      2012030601 # License:      BSD #  use strict; use Net::LDAP;  my $domain = "example.ua"; # Domain is supposed to have 2 levels my @parts = split(/./,$domain); my $domain0 = $parts[1]; my $domain1 = $parts[0]; my $user = "<username>"; # LDAP user my $password = "<password>"; # LDAP password my $cfgpath = "/usr/local/etc/lightsquid/"; # depends on OS my $realname = "$cfgpath/realname.cfg"; my $group = "$cfgpath/group.cfg"; # departments OU my @units = (         "MGT",         "OPR",         "PRO",         "Sales "); # computers OU my @pcunits = (         "Developer servers",         "Servers",         "Workstation OPR",         "Workstations PRO",         "Workstations Sales",         "Workstations Telemarketing" ); my @dep = ("no in group"); my $ldap = Net::LDAP->new("$domain") or die "$0"; $ldap->bind("CN=$user,DC=$domain1,DC=$domain0", password=>$password); my $base_path = "OU=<some path>,OU=<some path>,DC=$domain1,DC=$domain0"; # base LDAP path, change to yours my $num = @units; my $pcnum = @pcunits; my $attrs = "sn, givenname, department, samaccountname"; my $filter = "(objectcategory=CN=Person,CN=Schema,CN=Configuration,DC=$domain1,DC=$domain0)"; my $pcattrs = "cn, managedBy"; my $pcfilter = "(objectcategory=CN=Computer,CN=Schema,CN=Configuration,DC=$domain1,DC=$domain0)"; my $count; my $results; my %department_id = (); my %department_name = ();  sub get_host_info {         for (my $i=0; $i<$count; $i++) {                 my $entry = $results->entry($i);                 my $hostname = join(".",lc($entry->get_value('cn')),$domain);                 my @tmp_array = split(/,/,$entry->get_value('managedBy'));                 @tmp_array = split(/=/,$tmp_array[0]);                 my $fullname = $tmp_array[1];                 if(!$fullname) {                         next;                 }                 print(REALNAME "$hostnamet$fullnamen");                 print(GROUP "$hostnamet$department_id{$fullname}t$department_name{$fullname}n");         } }  sub get_user_info {         for (my $i=0; $i<$count; $i++) {                 my $entry = $results->entry($i);                 my $depnum = @dep;                 my $depid = $depnum;                 $depid++;                 foreach $depnum (0 .. @dep) {                         if ($entry->get_value('department') eq $dep[$depnum]) {                                 $depid = $depnum;                         }                 }                 if ($depid > $depnum) {                         $dep[$depid] = $entry->get_value('department');                 }                 if (length $depid < 2) {                         $depid = "0".$depid;                 }                 my $name = $entry->get_value('givenname');                 my $surname = $entry->get_value('sn');                 $name =~ s/^s+//;                 $name =~ s/s+$//;                 $surname =~ s/^s+//;                 $surname =~ s/s+$//;                 my $fullname = join(" ",$name,$surname);                 $department_id{$fullname} = $depid;                 $department_name{$fullname} = $entry->get_value('department');         } }  open (REALNAME, ">", $realname) or die $!; open (GROUP, ">", $group) or die $!;  # Getting real names and departments  foreach $num (0 .. @units) {         my $base = 'OU='.$units[$num].','.$base_path;         $results = $ldap->search(base=>$base,filter=>$filter,attrs=>$attrs);         $count = $results->count;         if ($count > 0) {                 get_user_info();         } }  # Getting pc names and owners, writing results to conf files  foreach $pcnum (0 .. @pcunits) {         my $base = 'OU='.$pcunits[$pcnum].',OU=Resources,'.$base_path;         $results = $ldap->search(base=>$base,filter=>$pcfilter,attrs=>$pcattrs);         $count = $results->count;         if ($count > 0) {                 get_host_info();         } }  # Closing connection to LDAP and files  $ldap->unbind; close (REALNAME); close (GROUP);  exit 0 

Важные моменты:
— в каждом хосте в АД должно быть заполнено поле managedby, так привязывается хост к юзеру;
— в каждого юзера в АД должно быть заполнено поле department, так привязывается юзер к группе (у меня пока что так, до реальных групп руки не дошли, так как у меня один юзер может принадлежать к многим группам с похожыми именами);
— units и pcunits вы должны заполнить сами своими данными;
— для того чтобы заставить работать скрипт с стандартной базой LDAP курите маны, там есть различия с АД.

Автор: romanmelko

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js