Доработка парсера логов Squid для корректного просмотра посещенных HTTPS ресурсов

Всем привет! Я получал, и получаю множество писем от людей с вопросами по Squid, который работает на основе моей статьи. Наиболее часто возникает вопрос про просмотр логов Squid каким-либо парсером. Проблема в том, что версия Squid 3.5.8 с настроенным прозрачным проксированием HTTPS логирует посещаемые HTTPS ресурсы не в виде доменных имен, а в виде IP адресов с портами (прим. 164.16.43.56:443). Соответственно, при просмотре статистики посещений вместо человеческой информации проскакивают эти самые IP адреса. Собирать статистику с такими данными довольно сложно. Я связывался с разработчиками Squid по этому поводу, но внятного ответа так и не получил. Единственное, что я выяснил, нормальное логирование работает в более новых версиях Squid, но на них прозрачное проксирование лично у меня так и не заработало должным образом. Поэтому возник вопрос о том, как сделать резолв IP адресов в самом парсере логов.

Лично я пользуюсь парсером Screen Squid, и именно в нем я решил попробовать сделать нужные изменения. Так как мне подобный резолв бывает нужен просто при работе в терминале с Bash, я решил весь процесс резолва сделать в виде скрипта на Bash, а в Screen Squid уже средствами PHP его использовать, когда это будет нужно.

Итак, для всего задуманного нам нужны:

  1. собственно, сам парсер Screen Squid (инструкцию по его установке печатать не буду, все есть на оф.сайте).
  2. Grep
  3. Sed
  4. Nslookup
  5. Whois
  6. Прямые руки

Сам Bash-скрипт представляет из себя следующее:
#!/bin/bash

#Единственный входной параметр - ip адрес, запишем его в переменную
IP="$1";

#Пробуем резолвить IP адрес с помощью NSLOOKUP, применяя GREP и SED
#для извлечение из результата нужной нам информации
hostname=$(nslookup $IP | grep -m 1 "name"  | sed 's|.*= ||'|sed -r 's/ Auth.+//' | sed 's/^[ \t]*//;s/[ \t]*$//' );

#Если попытка резолва с помощью NSLOOKUP не удалась, 
#то узнаем информацию об IP адресе с помощью whois, опять же
#применяя GREP и SED для извлечение из результата нужной нам информации
if [[ "$hostname" == '' ]]; then
	hostname=$(whois $IP | grep -m 1 "owner\|OrgName\|orgname\|NetName\|netname\|origin" | sed 's|.*: ||'|sed -r 's/. Auth.+//' | sed 's/^[ \t]*//;s/[ \t]*$//')
fi

#Выводим на экран результат резолва
echo "$hostname"

exit 0;

В принципе, он уже откомментирован, описывать здесь особенно и нечего. Мы получаем информацию об IP адресе сначала с помощью Nslookup, параллельно фильтруя вывод команды с помощью grep и sed, чтобы исключить ненужную информацию. Дабы не писать кучу строк, были использованы возможности grep по включению нескольких условий для выборки (символы »\|»). Сохраняйте скрипт в любом удобном месте, назначайте ему права на выполнение. Допустим, он сохранен в /usr/bin под именем gethost.sh.

Скрипт можно использовать просто из терминала:

gethost.sh ip_address 

Далее расскажу, как этот скрипт прикрутить к Screen Squid. Допустим, что установлен он в /var/www/html. В этой папке будет подпапка reports, где находится файл reports.php. Вот именно в нем необходимо сделать изменения. В этом файле необходимо найти строки:
$result=mysql_query($queryOneIpaddressTraffic) or die (mysql_error());
$numrow=1;
$totalmb=0;
while ($line = mysql_fetch_array($result,MYSQL_NUM)) {
echo "";
echo "".$numrow."";

if($enableUseiconv==1)
$line[0]=iconv("CP1251","UTF-8",urldecode($line[0]));

echo "".$line[0]."";

И вместо последней строки вставить следующее:
//Проверяем, HTTPS ресурс в строке или нет (по наличию символа ':')
//Если символа нет, значит это HTTP ресурс, сразу отображаем на страницу
$dv=strpos($line[0], ":") ;
if ($dv < 1) {
echo "".$line[0]."";
} else 
{

// Если же все таки символ ':' присутствует, следовательно это HTTPS ресурс, значит
// производим "колдовские" действия...

// Отделяем IP адрес от всей строки, т.е. все символы до ':'
$str1=strpos($line[0], ":");
$row1=substr($line[0], 0, $str1);
$ipaddress = ltrim($ipaddress);
$ipaddress = $row1;

// Производим резолв IP адреса с помощью скрипта gethost.sh
$hostname = shell_exec('/usr/bin/gethost.sh ' . $ipaddress);

// Выводим в таблицу полученную информацию об IP адресе
echo "".$hostname."";
}

Код писАлся на скорую руку, но вполне работает. А срабатывает он, когда открывается просмотр отчета «Трафик пользователей IP адреса», лично мне по большей части необходим только такой отчет. При желании, можно добавить подобный код на любые другие отчеты.

Сам код довольно прост: сначала определяется, какой в данный момент ресурс выводится на экран в таблицу: HTTP или HTTPS, и если это HTTPS (определяется по наличию символа »:»), то отделяем IP адрес от порта, передаем IP адрес в скрипт gethost.sh, получаем вывод скрипта в виде информации об IP адресе, и выводим на экран.

Были мысли заносить в БД сразу нужные данные, но резолв вышеуказанным образом на этапе заполнения БД приводит к длительному процессу распития кофейных напитков, поэтому я от него отказался.

Ах да, чуть не забыл, скрипт должен быть на том же сервере, где расположен парсер Screen Squid. Ну это так, к слову.

Если есть предложения по улучшению, доработке, переделке данного скрипта, буду рад выслушать.

Комментарии (11)

  • 14 августа 2016 в 06:25

    +1

    хоть какое то решение но…
    первая же в нем проверка… не учитывает что вообще то — на одном IP может быть более одного SSL-сайта (SNI в том числе для того и придуман), используют shared-хостинги и CDN
    вторая же — в случае если сайт за CDN — даст ошибку
    как пример — допустим у вас в логах посещение https://test.anatra.me/ — ваш скрипт скажет что это CloudFlare и все., а какой именно сайт воспользовался этой CDN — не скажет.
    • 14 августа 2016 в 09:25

      0

      Я ожидал подобный комментарий. К сожалению, пока это единственный способ…
  • 14 августа 2016 в 09:18

    0

    Странные люди сисадмины :)
    Сначала изобретают SSL и прочих что бы скрыть то куда они ходят.
    А потом изобретают вот такое:)
    • 14 августа 2016 в 09:27

      0

      Ну, не совсем) мне не хочется знать, что там было внутри туннеля, а вот куда юзер заходил, очень даже хочется
      • 14 августа 2016 в 09:29

        0

        Не скромный вопрос: для чего?
        Все 'нормальные ' пользователи ходят по нужным сайтам с мобил планшетов.
        • 14 августа 2016 в 09:36

          0

          Не у всех есть смартфон, планшет тем более. У нас целевая, так сказать, аудитория — именно такие люди, но все любят использовать корпоративный Интернет в личных целях. Это необходимо отслеживать. И это не прихоть сисадмина…
  • 14 августа 2016 в 11:52

    –1

    агент от DLP системы на компьютере пользователя решит проблемы с https, но естественно за деньги.
    • 14 августа 2016 в 11:54

      0

      Речь идёт, во первых, о Squid, при чем здесь dlp? Тем более, что агенты ставятся на каждый пк, и довольно тормозят сам пк, и сеть. Во вторых, какие проблемы он решит?
      • 14 августа 2016 в 12:29 (комментарий был изменён)

        –1

        агент будет получать данные до их шифрования
        к тому же у вас основная цель, как я понял, узнать кто куда ходил, а не поиграться со squid…
        • 14 августа 2016 в 12:48

          +1

          А кто ему эти не шифрованные данные отдаст? Браузер?
        • 14 августа 2016 в 12:49 (комментарий был изменён)

          0

          Основная цель — узнать, кто куда ходил, и предотвратить дальнейшее посещение этих ресурсов. Поскольку, Squid настроен на прозрачное проксирование HTTPS, пользователи не могут влиять на мои наблюдения. Плюс ко всему, ПК лишний раз не нагружаются. Плюс ко всему, DLP вещь не дешевая, учитывая, сколько у меня в конторе ПК используется.
          К тому же, разве DLP не использует MITM для HTTPS?

© Habrahabr.ru