Популяризация OpenBSD, часть3 (Шлюз-фильтр. Фильтруем http, https, считаем трафик по netflow.)

Полезные советы и программы от пользователей нашего форума.

Модератор: Модераторы разделов

Аватара пользователя
kasak
Сообщения: 887
ОС: OpenBSD

Популяризация OpenBSD, часть3

Сообщение kasak »

Вот дошли руки до следующей части моих трудов, в которой я опишу несколько сценариев которые могут пригодится.

Начнём с простого - фильтрация трафика через squid. Очень часто сквид применяют с авторизацией, однако это неудобно если нет домена, потому как заставлять пользователей сначала применять хитрые настройки в браузерах а потом ещё и вводить логины-пароли негуманно. Интернет сейчас не диковинка, да и в своих трудах я расскажу основы фильтрации через OpenBSD, а подстроить под свои нужны читатель справится самостоятельно, рецептов в интернете на эту тему очень много.
Итак поехали. У нас будет прозрачный прокси, в наши задачи для начала будет входить ограничить группу компьютеров, например если это компьютеры учебного класса. Туда можно допускать обновления для антивируса или мелко-мягкой программы, но нельзя допускать учащихся в интернеты. Ну или может быть открыть им какие-то нужные сайты а остальное закрыть.
Для начала установим squid:

Код: Выделить всё

pkg_add squid

В OpenBSD 5.6 будет предложено выбрать между версиями 3.4 или 3.5pre. Я выбрал 3.5 и проблем с ним не возникало.
После установки резонно почитать хелп который находится в

Код: Выделить всё

/usr/local/share/doc/pkg-readmes/squid-3.5pre20140626p1

Однако я укорочу его содержимое до того что нас интересует: нужно вписать в /etc/login.conf вот этот кусок:

Код: Выделить всё

squid:\
        :datasize=1500M:\
        :openfiles=4096:\
        :tc=daemon:


Без этого сквид сразу после запуска будет глохнуть ругаясь на too many open files.

Приступим к конфигурации сквида.
В OpenBSD рабочая папка сквида будет находится в /var/squid. Там будут лежать директории cache и logs.
Кэш нам не нужен, а вот логи пригодятся. логов будет два. Один - cache.log это лог в котором нужно искать выхлоп процесса squid. При возникновении неисправностей нужно смотреть туда. Второй лог access.log нам понадобится для формирования таблицы лодырей, кто больше всех насидел в контактике.

Конфигурирование сквида осуществляется правкой файла /etc/squid/squid.conf.
Для выполнения нашего первого сценария, необходимо собрать все мак адреса компьютеров у которых не должно быть доступа, и первично поправить конфиги.
Берём конфиг по умолчанию и начинаем добавлять:
Находим директиву http_port и меняем её чтобы выглядело следующим образом:
http_port 127.0.0.1:3128 intercept
После этой строчки сразу же добавляем ещё одну
http_port 3129
Всё вместе будет выглядеть так:

Код: Выделить всё

# Squid normally listens to port 3128
http_port 127.0.0.1:3128 intercept
http_port 3129

Обратите внимание на слово intercept. В ранних версиях OpenBSD приходилось писать transparent, если читатель работает с OpenBSD 5.4 например, может потребоваться указывать именно transparent. Рекомендую обновится!
Вторая строка нужна, ибо сквид ругается что ему нужен отдельный порт для работы.
Теперь нужно создать acl для компьютеров которым не будет доступа, и второй лист, в котором будет список сайтов куда доступ будет предоставлен.

Код: Выделить всё

acl maclist arp "/etc/squid/maclist"
acl maclisturl url_regex "/etc/squid/urlallow"

Я тут использую url_regex. Было бы более правильно использовать тут dstdomain или dstdom_regex, однако url_regex в моём случае используется для гибкости. Читатель может использовать то что удобно.
Spoiler
Небольшая сносочка. Я подумал что читатель возможно совсем не разбирается в сквидах, и уточню что есть что.
url_regex будет удовлетворён любым совпадением в полном адресе. Например если в списке url_regex присутствует avast.com то адрес https://www.google.ru/#q=avast.com тоже будет открыт!!!
dstdomain это просто указание домена. например avast.com в данном случае ссылка https://www.google.ru/#q=avast.com открыта не будет.
dstdom_regex позволяет использовать регулярные выражения, например avast.* будет означать любое значение avast.ru, avast.com, avast.net и так далее.

Невооружённым глазом видно, что список мак адресов для запрещения доступа надо вписать в файл /etc/squid/maclist а список сайтов куда будет имется доступ нужно вписать в /etc/squid/urlallow.
Теперь нужно сделать красивую страничку с ошибками:
Водим сначала вот это:

Код: Выделить всё

error_directory /usr/local/share/squid/errors/ru

А потом вот это:

Код: Выделить всё

deny_info ERR_MACLIST_DENIED_UTF maclist

Объясняю что к чему. Первое - указывает сквиду на папку в которой лежат странички с нужным языком (русским) по умолчанию он будет показывать английские странички.
А второе - указывает какую именно страницу надо показывать клиентам которым запрещён доступ. Страницы с указанным мной именем конечно же нету. Тут читатель должен взять в руки Bluefish и сверстать простую страницу с логотипом фирмы или чем-то подобным где будет доподлинно объяснятся почему запрещён доступ. На забудьте поместить её в нужную папку указанную в error_directory.
Теперь нужно непосредственно запретить доступ:

Код: Выделить всё

http_access allow maclist maclisturl
http_access deny maclist

Правила в сквиде проверяются сверху вниз. Срабатывает первое подошедшее правило.
Первое правило срабатывает когда клиент получает доступ к разрешённым сайтам. Второе правило запрещает доступ этим же ребятам.
Логика проста. Клиенты у которых подходит мак адрес, сначала будут проверены первым правилом, и и если оно не подойдёт, будут проверены вторым, а уж оно подходит точно.
Вписываем наш сквид в pkg_scripts и запускаем. /etc/rc.d/squid start
Теперь всё что осталось - это запустить глобально (или не очень) наш сквид.
Для этого рекомендую создать пару таблиц в pf.conf:

Код: Выделить всё

table <mynets> persist { 192.168.1.0/24, 192.168.0.0/24 }
table <squid> persist { 192.168.1.0/24, !192.168.1.206, !192.168.1.250 }

Зачем такие сложности:
В первую таблицу будем вписывать сайты, которые плохо реагируют на проксирование. К сожалению такие есть, взять к примеру netprint или nix. Хотя со вторым мне удалось разобраться) Всё вписанное в таблицу mynets - к этому доступ будет мимо прокси.
Вторая таблица это по сути список компьютеров которые будут ходить через прокси. У меня указаны все компьютеры кроме парочки. Иными словами в первую таблицу мы включаем удалённые сайты которые будут мимо прокси, а во вторую будем вписывать локальные компьютеры которые ходят мимо прокси.
Теперь завинчиваем трафик на проксик:

Код: Выделить всё

pass in quick inet proto tcp from <squid> to !<mynets> port www divert-to 127.0.0.1 port 3128

Это правило должно быть ДО правила с nat!
Всё должно работать как следует. Однако в этом способе есть один очень большой косяк: https... блокирован не будет.
Пожалуй прежде чем я начну рассказывать как с этим боротся, я расскажу как подсчитать трафик с помощью сквида.
Устанавливаем пакет lightsquid:

Код: Выделить всё

pkg_add lightsquid

Спасибо огромное Сергею Ерохину за эту замечательную программу!
Чтобы лайтсквид считал трафик правильно и удобно, нужно немного поднастроить сквид.
Куда-нибудь в конфиг сквида вставляем следующую строку:

Код: Выделить всё

logfile_rotate 1

можно конечно выставить и побольше, но лично мне кажется что этого вполне хватит, не имеет смысла держать гигантские логи долгое время.
Теперь настройка lightsqud. Я буду использовать nginx и slowcgi для отображения информации.
Первоначально зайдём в конфиг лайтсквида и поправим там пути. Lightsquid устанавливается в папку /var/www/htdocs/lightsquid.
Конфиг называется lightsquid.cfg
Проверяем все пути в этом файле, делая их абсолютными:

Код: Выделить всё

#path to additional `cfg` files
$cfgpath             ="/var/www/htdocs/lightsquid";
#path to `tpl` folder
$tplpath             ="/var/www/htdocs/lightsquid/tpl";
#path to `lang` folder
$langpath            ="/var/www/htdocs/lightsquid/lang";
#path to `report` folder
$reportpath          ="/var/www/htdocs/lightsquid/report";
#path to access.log
$logpath             ="/var/squid/logs";
#path to `ip2name` folder
$ip2namepath         ="/var/www/htdocs/lightsquid/ip2name";

#path to `lockfile` ;-)
$lockpath            =$reportpath;

Nginx сам исполнять скрипты не умеет, зато в openbsd есть очень хороший враппер для этого, slowcgi.
Однако, по умолчанию он запирает себя в jail который находится в /var/www/.
И в этой самой тюрьме, никакого пёрла у нас нет. И есть два пути решения проблемы.
1) собрать в этой тюрьме нужную структуру папок и скопировать туда пёрл и все его библиотеки.
2) Попросить slowcgi не запираться в тюрьме.

Скажем так, я пробовал идти по первому пути, и успешно прошёл. Однако это всё таки очень долгая заморочка и я предполагаю что если читатель способен сделать это всё самостоятельно - он не будет читать эту статью потому что всё написанное выше для него - пара пустяков.
Поэтому мы пойдём по второму пути. Пусть это и брешь в безопасности, но нельзя сказать что прям очень большая. Кроме того доступ к лайтсквиду будет только с определённых компьютеров. Обратите так же внимание, если идти по первому пути, в конфиге lightsquid нужно указывать пути без /var/www/
Итак идём вторым путём. Просим slowcgi не запираться в тюрьму. Для этого в /etc/rc.conf.local вписываем это:

Код: Выделить всё

slowcgi_flags="-p /

Теперь нужно указать лайтсквиду где хранятся логи и напомнить самому сквиду что логи нужно крутить. Для этого в /etc/daily.local вписываем:

Код: Выделить всё

/var/www/htdocs/lightsquid/lightparser.pl
/usr/local/sbin/squid -k rotate

Первая строка считает трафик из логов, вторая крутит лог сквида, руководствуясь параметром который мы указали ранее в squid.conf.
Теперь наши отчёты надо посмотреть. Мне придётся забежать немного вперёд и выложить кусок конфига nginx. Далее я расскажу про nginx поконкретнее. А щас просто кусок:

Код: Выделить всё

server {
        listen 80 default;
        root /htdocs;
        index index.html index.htm;

        server_name gate.somewhere.net;

        location / {
                try_files $uri $uri/ /index.html;
                allow 192.168.2.250;
                deny all;
        }

        location /lightsquid {
        root /htdocs;
        index index.cgi;
        allow 192.168.2.250;
        deny all;
        }

        location ~ \.cgi$ {
        gzip off;
        fastcgi_pass unix:/run/slowcgi.sock;
        fastcgi_index index.cgi;
        fastcgi_param  SCRIPT_NAME        /var/www/htdocs$fastcgi_script_name;
        include /etc/nginx/fastcgi_params;
        }
}

В этом кусочке мы разрешаем доступ к считалке только для одного айпишника. чтобы её открыть нужно запрашивать адрес сервера и добавлять к url "/lightsquid"
Если всё прошло правильно, можно возрадоваться. Если нет нужно открыть запустить /var/www/htdocs/lightsquid/check-setup.pl и посмотреть

Теперь у нас есть считалка http трафика и даже небольшая блокировка. И самое правильное что вы можете щас сделать: остановиться и больше ничего не ломать!!!
Дальше я расскажу как фильтровать https трафик. Это реально сделать однако я весьма не рекомендую это делать! Я очень рекомендую оказывать административное влияние на горе-работников а не устраивать в сети тотальный бедлам ломая всё подряд!
Поверьте опыту, сколько ни блокируй, сколько ни выписывай, всё равно найдутся индивиды которые поставят тор/найдут новый прокси/установят vpn сделают что угодно и создадут ещё больше проблем! В конце концов когда вы потратите недели своего времени на закрытие всего подряд, она просто придут со своими модемами, а у тех людей которые реально работают а не бездельничают возникнет огромное количество проблем, которые решать опять же - вам.
Я категорически рекомендую считать трафик по netflow и в случае возникновения проблем обращаться к руководству. Это значительно эффективнее чем затыкивать всё подряд. Как считать трафик по netflow я расскажу ниже. Ну а сейчас...
Способ фильтрафии https есть. И хоть он крив и косячен я о нём расскажу, не потому что следует его использовать а потому что он просто есть.
Перед тем как этим заниматься, следует понимать что мы делаем. https трафик вообще не предназначен для проксирования. Он передаётся целиком в шифрованном виде. То что мы будем делать - вклиниваться посередине, расшифровывать его, просматривать и устанавливать шифрованное соединение между прокси и сайтом назначения.

Сначала вписываем в squid.conf ещё одну строку:

Код: Выделить всё

 https_port 127.0.0.1:3130 intercept ssl-bump generate-host-certificates=on cert=/etc/squid/ssl/squid.pem key=/etc/squid/ssl/squid.key

Соответственно сертификаты squid.pem и squid.key следует сгенерировать самостоятельно.
Кроме того необходимо выполнить команду

Код: Выделить всё

/usr/local/libexec/squid/ssl_crtd -c -s /var/squid/lib/ssl_db

Теперь нужно отделить сайты на которых будет срабатывать блокировка от сайтов на которых она работать не будет. И я категорически не рекомендую делать иначе!
Сначала создаём список что именно надо блокировать. Обычно этот список даёт нам руководство. Это всяческие контактики, однокласснички, порнушка. Актуальный список всегда можно посмотреть в лайтсквиде, который мы только что настроили.
Добавляем:

Код: Выделить всё

acl badsites dstdomain "/home/kasak/sites.deny"
acl broken_ads url_regex "/home/kasak/broken_ads"

Первая строка - файл где будет хранится список желаемого от руковоства.
Вторая - побочный эффект блокировки. Поскольку очень часто на сайтах наличествуют всякие кнопочки типа "мы в контакте, мы на фейсбуке, мы в инстаграме" эти кнопочки могут создавать проблемы и на их месте будут вылезать куски страниц с ошибками.
В файл broken_ads нужно добавлять куски url которые мешают сайтам выглядеть как следует. соединение будет сбрасываться и не будет мешать.
Ещё проще тупо сбрасывать соединения на всё не угодно руководству, но это чревато тем что вы станете кол-центром для всех недовольных тем что "интернет показывает белую страницу" проще создать страницу с информацией почему именно заблокирован сайт.

Код: Выделить всё

http_access deny broken_ads
deny_info TCP_RESET broken_ads

http_access deny badsites
deny_info ERR_BADSITE_UTF badsites

Первая часть режет сломанные баннеры и кнопки, сбрасывая tcp соединение
Вторая показывает страшную страницу которую нужно создать самостоятельно, я уже говорил об этом выше.
Кстати обратите внимание, каждый раз при изменении конфигурации или добавления сайтов, нужно указывать об этом сквиду командой:

Код: Выделить всё

squid -k reconfigure

Не следует перезапускать сквид через /etc/rc.d/squid restart. это слишком долго и неудобно.
Теперь последний пункт, нужно выяснить все айпишники всех блокируемых сайтов и создать такое правило:

Код: Выделить всё

acl badips dst "/home/kasak/blockedips"
ssl_bump server-first blockedips

Смысл в том, что сквид, проксируя ssl трафик, будет сначала предлагать клиенту свой сертификат, а наш сертификат не подписан корневыми центрами, и поэтому при попытке открыть ВООБЩЕ любой сайт мы получим от любого браузера матюки.
Особо извращённые личности могут конечно импортировать сертификат по все браузеры во всех компьютерах, однако я решил вопрос проще. Просто собрал все айпишники всех сайтов которые надо заблокировать и вписал их в указанный выше файл.
Это позволило не мучаться с клиентскими компами. Заблокированные сайты выдают предупреждение что сертификат не тот, если его принять - попадаешь на сообщение о блокировке.
Теперь просто перенаправляем трафик в pf.conf:

Код: Выделить всё

pass in quick inet proto tcp from <squid> to !<mynets> port https divert-to 127.0.0.1 port 3130

Последнее что хотелось бы указать по сквиду, у меня возникала проблема с сайтом nix.ru. Он никак не хотел работать через прокси. Точнее он работал, но открывался по несколько минут. Вариантов решения два. Либо вписать ip адрес сайта в таблицу mynets в pf, описание этих таблиц я давал выше. Либо добавить вот это:

Код: Выделить всё

net.inet.tcp.rfc1323=0
в /etc/sysctl.conf. Кому как больше нравится.
кроме того, если вы всё таки не послушали меня и решили блокировать https, у вас перестанет работать сбербанк онлайн, и бесполезно что-то с этим делать. Добавляйте его в mynets. Возможно сломается ещё что-то, не могу знать всё.

Поверьте моему опыту, если пойти по этому пути, сотрудники которые на самом деле работают, даже не увидят разницы, а те кто сидит в соц сетях, сразу же начнут искать пути обхода и создавать ещё больше проблем, и тратить на это ещё больше времени. Объясните это руководству прежде чем что-то делать.

Теперь о netflow - это более правильный и красивый способ докладывать о нехороших ребятах.

Делается это очень просто. Сначала создайте файл /etc/hostname.pflow0 с содержимым:

Код: Выделить всё

flowsrc <wan ip> flowdst 192.168.1.21:20001 pflowproto 5
разумеется заменив <wan ip> на актуальный внешний адрес шлюза а 192.168.1.21 на адрес того сервера, где будет находится считалка трафика.
После этого отредактируйте сроку pf которая осуществляет nat следующим образом:

Код: Выделить всё

pass out on $wan inet from $lan_net to any nat-to $wan keep state (pflow)

Перезапустите комп, либо сеть, командой sh /etc/netstart и шлюз начнёт отсылать поток netflow на нужный сервер.
обратите внимание, что данные о потоке отсылаются только после того как поток был закрыт. Например если кто-то качает архив в 3 гб с какого-нибудь фтп сервера, считалка узнает об этом только когда файл будет скачан и поток будет закрыт. А если этого же господин решит скачать пару терабайт, считалка вообще узнает об этом очень и очень нескоро.

В качестве считалки трафика я использую netams. Спасибо большое разработчикам за этот замечательный инструмент, и хоть не всё в нём удобно, пока что лучшей считалки для трафика я не нашёл. Укажу так же что для этой считалки нужен довольно серьёзный комп. У меня это core i7, но подойдёт и что-то попроще. Однако подойдёт и что-то попроще. Но здесь всё-таки работает правило чем сильнее тем лучше. К примеру на core2quadro это всё работало категорически медленно.
С установкой netams читатель наверное справится сам. А вот с конфигурацией я подскажу.
Тут пригодились бы скриншоты, без них это будет просто много букв. Но к сожалению у меня их нет, так что если хотите сделать это, читайте и повторяйте в прямом эфире.
Открываем источники данных, добавляем туда netflow5, указываем в качестве параметров
listenat оставляем нули. Port берём из /etc/hostname.pflow0 параметр accept_from устанавливаем в наш внешний ip адрес, такой же как в /etc/hostname.pflow0
Далее идём в элементы-подсеть и добавляем подсеть локальных адресов. Далее идём в тарифы и добавляем бесплатный тариф. Это нетрудно. А так же добавляем группу контактов all.
Теперь идём в система-динамическое создание объектов, и добавляем задачу. Указываем все пункты!
Включён - галка
Источник данных - наш нетфлоу
подсеть - указывайте то что создали
создать учётный объект - да
создать контракт - да
способ именования контракта: укажите тут следующее: %1.%2.%3.%4
группа контрактов: укажите то что создали
создать лицевой счёт - да
валюта счёта - рубли
создать услугу - да
тарифный план - наш бесплатный.

После сохранения нашей схемы, полетят новые учётные записи.
Читателю надлежит самостоятельно изучить эту систему. Хоть в ней и есть неудобства, это всё ещё удобный способ посчитать трафик по netflow и вывести это дело на экран через браузер.
Очень просто и эффективно!

Как видите, любое действие в OpenBSD не требует великих знаний и умений. Почти всё решается всего парой строк, именно это и есть привлекательная черта OpenBSD.

Остался один пункт - реверсивное проксирование. В условиях когда один ip адрес должен предоставлять очень много разных сервисов, бывает полезно использование реверсивного прокси. Тут особенно много информации не будет.
OpenBSD 5.6 имеет в дефолтной поставке nginx. в 5.7 его выпилят, но он будет доступен из пакетов.
Я считаю для удобства нужно создавать папку /etc/nginx/sites и уже в эту папку складывать все нужные файлики с описаниями куда и что проксировать.
Родной поставочный конфиг можно не менять, а просто вписать в секцию http следующий инклюд:

Код: Выделить всё

include     /etc/nginx/sites/*;

После чего можем создавать в папке /etc/nginx/sites файлики с описанием проксей. Возьмём простой пример:

Код: Выделить всё

server {
listen 80;
server_name somesite.somewhere.net;

satisfy any;
allow 192.168.1.0/24;
allow 192.168.0.0/24;
allow 127.0.0.1;
deny all;
auth_basic "access error";
auth_basic_user_file /conf/http.password;

location / {
proxy_pass http://server1.lan;
include /etc/nginx/proxy.conf;
}

Тут мы описываем доступ к somesite.somewhere.net. Идея в том чтобы дать доступ из локальной сети без пароля, а из внешнего мира с паролем.
Все строки allow я думаю понятны - это адреса локальных сетей. а вот далее две строки - auth_basic первая это заголовок окошка с запросом логина-пароля. второе - это файл с логином и паролем. Он создаётся утилитой htpasswd. Обратите внимание на его расположение. Он лежит в /var/www/conf/http.password. nginx работает в jail, и путь к этому файлу нужно указывать такой, чтобы nginx имел к нему доступ во время работы в jail.
Последние строки в конфиге указывают куда проксировать нужное.

Вообще-то тут нет ничего сложного. Если не нужна авторизация - нужно просто убрать нужные две строки. Конфигурация nginx проста.
Но я этот кусок написал к тому что с самого начала я указал кусочек конфигурации nginx для работы lightsquid. Теперь этот кусочек есть куда вставить.
Не забудьте открыть нужный порт в pf.
Ну вот пожалуй и всё! Я рассказал некоторые аспекты при работе с системой openbsd, хотя она конечно очень похожа на другие системы. Внимательный читатель наверное заметил как просто и удобно работает pf, как просто настраивать сервисы и что они лежат на своих местах а не обитают непонтяно где в системе.
Последнее что мне осталось для финальной четвёрой статьи - описать действительно тонкости системы, которые имеются, а я их упустил. Пусть даже всё это есть в faq на сайте openbsd.org, но может быть не все у нас хорошо знают английский, а я опишу самые важные вещи по-русски. Это будет очень короткая статья, и скорее всего я размещу её не тут, а в разделе по BSD системам, а тут оставлю ссылку. Потому что это будет всё-таки не проект, а просто мой вольный перевод.

So long, and thanks for all the passwords!
Linux kasakoff 5.10.7-200.fc33.x86_64 #1 SMP Tue Jan 12 20:20:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Спасибо сказали:

Аватара пользователя
Stauffenberg
Сообщения: 2023
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: Популяризация OpenBSD, часть3

Сообщение Stauffenberg »

Вы это за один присест пишете?
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:

Аватара пользователя
kasak
Сообщения: 887
ОС: OpenBSD

Re: Популяризация OpenBSD, часть3

Сообщение kasak »

Stauffenberg писал(а):
27.04.2015 14:49
Вы это за один присест пишете?

да, не люблю прерываться, а то потом придётся вспоминать то что уже написал и о чём ещё надо писать. А там утром весь план в голове перечислил, и сразу написал. Да вобщем-то тут немного
Linux kasakoff 5.10.7-200.fc33.x86_64 #1 SMP Tue Jan 12 20:20:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Спасибо сказали:

Аватара пользователя
nerve
Сообщения: 280
ОС: OpenBSD

Re: Популяризация OpenBSD, часть3

Сообщение nerve »

ждем чего-то подобного по relayd...
Спасибо сказали: