Наращиваем функционал Squid’а: распознаем пользователей Active Directory

2 мая 2011 г.

Настроив Squid в качестве корпоративного прокси с авторизацеий в Active Directory и разделением привилегий по группам AD, стало понятно, что не хватает одной небольшой, но очень нужной вещи: назначения прав доступа конкретному пользователю сети. По(гугл, яндекс, нигма)ив, готового известного решения я так и не нашел. Единственным, что предлагалось, был вариант, когда права выдаются ip-адресу. Однако, в сети с автоматической выдачей адресов это не вариант. А для доменной сети это уж совсем не вариант, так как пользователь может пользоваться ресурсами сети Интернет с разных компьютеров, а для организации с распределенной сетью и филиалами…

Что мы имеем
  1. При авторизации squid получает имя учетной записи пользователя и помещает ее в переменную %LOGIN.
  2. В стандартной поставке squid’а присутствует скрипт на Perl, который принимает на вход имя учетной записи пользователя, имя группы Active Directory и проверяет принадлежность пользователя группе. Скрипт забирает из STDIN входные данные и выводит в STDOUT результат (OK\n|ERR\n), при этом имя учетной записи берется из переменной %LOGIN, а имя группы задается в ACL.
Что мы хотим получить

Нам необходим скрипт, который будет принимать на вход значение переменной %LOGIN и имя пользователя из ACL, сравнивать их, и в случае соответствия выводить в STDOUT OK\n, что позволит применить указанное правило к обратившемуся пользователю, в противном случае скрипт должен будет вывести ERR\n, что не позволит применить правило этому пользователю.

Выбираем инструмент

По сути, мы должны решить школьную задачку о сравнении строк. Сразу скажу, что первым моим решением был скрипт на bash, который при обкатке сваливался сам и сваливал squid при обращении к нему более 4-х пользователей. Поэтому, недолго думая (так как пользователи уже начинали нервничать), было решено написать скрипт на Perl по образу и подобию уже существующего wbinfo_group.pl. Почему я сразу не выбрал этот вариант? Потому что никогда не писал на Perl.

Что мы получили

А получили мы вот такой скриптик…

#!/usr/bin/perl -w
$|=1;
while (<STDIN>){
        chop;
        ($user1, $user2) = split(/\s+/);
        if ((defined $user1) && (defined $user2))
        {
                if ($user1 eq $user2)
                {
                        print "OK\n";
                }
                else
                {
                        print "ERR\n";
                }
        }
        else
        {
                print "ERR\n";
        }
}
Как это работает

В squid.conf добавляем следующее:

# указываем, что будем использовать наш скрипт
external_acl_type nt_user %LOGIN /usr/lib/squid/wbuser.pl
...
# задаем пользователя в виде ACL
# IvanIvanov мы будем использовать при назначении прав
# ivan.ivanov – доменный логин пользователя
acl IvanIvanov external nt_user ivan.ivanov
...
# ACL specific_site необходимо определить ранее
http_access deny IvanIvanov specific_site

Если персонифицированные правила разместить перед правилами групп, то избранному члену группы можно:

  • разрешить то, что запрещено группе пользователя;
  • запретить то, что разрешено группе пользователя.