📜 ⬆️ ⬇️

Automatic import of users' full names from Active Directory to Lightsquid

Many who manage the Squid proxy server in the enterprise have a need to periodically show employees use statistics on the Internet to management. In addition to Squid, a log analyzer such as SARG, Lightsquid, etc. is installed to present statistics. At the same time, the organization often has a directory service (it is assumed to be Active Directory), in which all employees have accounts and authorization in the proxy server is based on the accounts. Naturally, for management, when it looks at a report, it is more convenient to identify an employee by his first and last name. Surprisingly, in many forums and IT-portals this task is offered to be solved manually, scoring the names and surnames in the log analyzer configuration files. This solution has a drawback - when enrolling / firing any employee, you will have to edit configs.
This article describes the method of automatically extracting data about the names and surnames of employees from ActiveDirectory and inserting them into Lightsquid reports.

Objective: to ensure the output of reports via Lightsquid for each Active Directory user logging in to the Internet, indicating his first and last name (looking ahead, I will say that in AD this field corresponds to the "display name" field; in LDAP queries it is referred to by the displayName variable )


Initial data:


')
Decision:

First, I will describe the mechanism for transferring data about the full name to Lightsquid from Active Directory, then I will give its implementation.

Information about the name is presented in AD in the properties of the domain user, in the field "Display Name". To get information from AD, you need to interact with it through LDAP requests. In this case, you can interact only on behalf of an authorized domain user. Since Lightsquid is written in Perl, the Net :: LDAP module is required to complete these requests. And for automatic output of information from AD in the report, it is necessary to replace the simple receipt of a login from squid with an LDAP request.

First, you need to create an account with the most limited rights in AD, which will be used to perform LDAP queries. To do this, start the Active Directory Users and Computers snap-in and create a new user. Give it a name expressing its purpose. For example, LightSquidAgent. Then create a new GPO and enter its properties (or properties of an existing object). Next Computer Configuration-> Windows Configuration-> Security Settings-> Local Policies-> User Rights Assignment. In the "Deny access to a computer from the network" parameter, enter LightSquidAgent. In the "Reject local login" setting, also enter LightSquidAgent.

Now install the Net :: LDAP module in Perl. Run bash or a similar command shell and execute
 perl -MCPAN -e shell 
. After entering the cpan interpreter, we execute
 install Net::LDAP 
. Next, the installer will display the question of whether we want to allow it to perform auto-configuration. Just hit Enter. At the end you should see
 LDAP module was installed successfully 
.

After that, you can edit the code that generates reports. Go to the folder with the installed LightSquid, go to the folder ip2name and open the file ip2name.squidauth. It should look like this:
 #contributor: esl #specialy for squid with turned on user authentication #simple version sub StartIp2Name() { } sub Ip2Name($$$) { # $Lhost,$user,$Ltimestamp my $Lhost=shift; my $user =shift; $user =URLDecode($user); #decode user name return $user if ($user ne "-"); return $Lhost; } sub StopIp2Name() { } #warning !!! 1; 

UPD: The recommendations of the author Lightsquid about caching user names.

UPD2: Fixed bug with hang script when recognizing unauthorized users

UPD3: Fixed bug with script hangup when a domain controller is unavailable and if it is impossible to log in under the LightSquidAgent account

In the file header, you need to register the namespace in which the functions we need are and declare 3 new variables:
 #contributor: esl #specialy for squid with turned on user authentication #simple version use strict; use warnings; use Net::LDAP; use Encode; my $ldap; my $message; my %hDisplayName; 


We replace the empty definition of StartIp2Name with ours, in which the connection to the domain controller is established

 sub StartIp2Name() { my $server = "ldap://ourserver.domain.com"; $ldap = Net::LDAP->new( $server ); return if(!defined $ldap); $message = $ldap->bind(q(domain\LightSquidAgent), password => "passwd"); } 


Replacing the definition of the Ip2Name function, our version of the function will take from the domain controller the full name of employees

In the branch of the conditional operator, duplicate logins will be skipped; only one LDAP request will be made for each user.

Instead
 sub Ip2Name($$$) { # $Lhost,$user,$Ltimestamp my $Lhost=shift; my $user =shift; $user =URLDecode($user); #decode user name return $user if ($user ne "-"); return $Lhost; } 

we insert
 sub Ip2Name($$$) { # $Lhost,$user,$Ltimestamp my $Lhost=shift; my $user =shift; $user =URLDecode($user); #decode user name return $Lhost if ($user eq "-"); return $user if (!defined $ldap); return $user if ($message->code()); if (!defined $hDisplayName{$user}) { my $result = $ldap->search( base => "dc=domain,dc=com", filter => "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" . $user . "))", ); my $first_entry = $result->entry(0); if (!defined $first_entry) { return $Lhost; } my $pure_displayName = $first_entry->get_value("displayName"); $pure_displayName =~ s/ /_/g; Encode::from_to($pure_displayName, 'utf-8', 'windows-1251'); $hDisplayName{$user}=$pure_displayName; } return $hDisplayName{$user}; } 


Last: In the StopIp2Name function, we disconnect from the domain controller

 sub StopIp2Name() { return if (!defined $ldap); $message = $ldap->unbind; } 


Objective criticism is welcome.

Source: https://habr.com/ru/post/227289/


All Articles