Решения на базе Squid пользуются заслуженной популярностью у системных администраторов как мощное и гибкое средство контроля за интернет трафиком. Отдельного внимания заслуживают богатые возможности фильтрации, позволяющие ограничить доступ для определенных групп пользователей к нежелательным интернет ресурсам. Широкое внедрение шифрования в последние годы сделало процесс фильтрации несколько затруднительным, но и здесь Squid придет нам на помощь, как это сделать мы расскажем в этой статье.
Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Данный материал во многом повторяет нашу предыдущую инструкцию Ubuntu Server. Настраиваем роутер NAT + DHCP + Squid3, благо никаких принципиальных изменений в процессе настройки с тех пор не произошло. Поэтому мы не будем подробно останавливаться на повторяющихся настройках, а просто приведем необходимые участки конфигурационных файлов с минимальными пояснениями. В нашем случае использовался Debian 9, но данная статья будет справедлива для любого основанного на Debian / Ubuntu дистрибутиве.
Настройка сети
В данном примере у нас будет статическая настройка внешнего сетевого интерфейса, если же вы используете динамические подключение, такие как PPPoE или PPTP, то для их настройки обратитесь к соответствующим инструкциям (по ссылкам).
Для настройки сети откроем файл /etc/network/interfaces:
nano /etc/network/interfaces
И внесем в него следующие изменения (названия интерфейсов и адреса указаны только для примера):
auto ens33
iface ens33 inet static
address 172.18.0.106
netmask 255.255.240.0
gateway 172.18.0.1
dns-nameservers 172.18.0.1auto ens34
iface ens34 inet static
address 192.168.187.1
netmask 255.255.255.0post-up /etc/nat
Если внешний интерфейс получает настройки по DHCP, то используйте следующие настройки:
auto ens33
allow-hotplug ens33
iface ens33 inet dhcp
Сразу создадим файл для хранения настроек брандмауэра и сделаем его исполняемым:
touch /etc/nat
chmod +x /etc/nat
Перезапустим сеть:
service networking restart
После чего у вас на сервере должен появиться интернет, сразу следует обновить систему и установить необходимый минимум утилит для администрирования:
apt update
apt upgrade
apt install mc ssh
Настройка NAT и брандмауэра
Существуют разные взгляды на настройку брандмауэра, но общепринятой является схема с нормально открытым брандмауэром для внутренней сети (разрешено все, что не запрещено) и нормально закрытым для внешней (запрещено все, что не разрешено). Ниже будет приведена минимально достаточная конфигурация.
Откроем созданный нами файл /etc/nat и внесем в него следующие строки:
#!/bin/sh
# Включаем форвардинг пакетов
echo 1 > /proc/sys/net/ipv4/ip_forward# Сбрасываем настройки брандмауэра
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X# Разрешаем доступ из локальной сети
iptables -A INPUT -i ens34 -j ACCEPT
# Разрешаем инициированные нами подключения извне
iptables -A INPUT -i ens33 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешаем подключения по SSH
iptables -A INPUT -i ens33 -p tcp --dport 22 -j ACCEPT
#Запрещаем входящие извне
iptables -A INPUT -i ens33 -j DROP
# Разрешаем инициированные нами транзитные подключения извне
iptables -A FORWARD -i ens33 -o ens34 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Запрещаем транзитный трафик извне
iptables -A FORWARD -i ens33 -o ens34 -j DROP
# Включаем маскарадинг для локальной сети
iptables -t nat -A POSTROUTING -o ens33 -s 192.168.187.0/24 -j MASQUERADE
Чтобы применить изменения просто запустим измененный файл:
/etc/nat
Убедиться, что правила применились мы можем командами:
iptables -L -vn
iptables -t nat -L -vn
Если теперь вручную настроить сеть на рабочей станции, указав роутер в качестве шлюза с использованием DNS-сервера провайдера (или публичного), вы должны попасть в интернет.
Настройка DHCP и кеширующего DNS
В наших решениях эту роль обычно исполняет dnsmasq, не будем отступать от традиций и в этот раз. Установим данный пакет:
apt install dnsmasq
Для настройки откроем файл /etc/dnsmasq.conf и внесем некоторые изменения. Прежде всего ограничим адреса, которые будут слушать наши службы:
listen-address=127.0.0.1, 192.168.187.1
Затем зададим пул для выдачи адресов через DHCP и срок аренды:
dhcp-range=192.168.187.120,192.168.187.199,255.255.255.0,12h
Для одноранговой сети будет неплохо указать DNS-суффикс, чтобы избежать сложностей с разрешением плоских имен:
local=/interface31.lab/
Перезапустим службу:
service dnsmasq restart
Теперь проверим получение адреса на клиенте и возможность доступа с него в интернет, если вы не допустили ошибок, то все должно работать.
Просмотреть список выданных в аренду адресов можно командой:
cat /var/lib/misc/dnsmasq.leases
Настройка прокси-сервера Squid3 с поддержкой SSL
К сожалению, в репозиториях нет пакета squid с поддержкой SSL, поэтому потребуется собрать его самому, как это сделать мы рассказывали в статье Сборка Squid 3.5 с поддержкой SSL из исходных кодов для Debian / Ubuntu, поэтому будем считать, что вы уже выполнили эту процедуру, либо используете уже собранные нами пакеты.
Будем считать, что собранные пакеты squid скачаны и располагаются в отдельной директории. Перейдем в нее и установим пакеты командой:
dpkg -i squid*.deb
В процессе установки вы получите сообщения о неудовлетворенных зависимостях, поэтому разрешим их командой:
apt install -f
Чтобы наши пакеты не были перезаписаны пакетами из репозитория при обновлении их следует зафиксировать:
apt-mark hold squid
apt-mark hold squid-common
apt-mark hold squidclient
Если у вас был уже установлен squid, то просто удалите его и установите наши пакеты, все настройки при этом будут подхвачены автоматически, хотя на всякий случай сохраните куда-нибудь файл конфигурации:
cp /etc/squid/squid.conf /root/squid.conf.back
Установив пакеты с поддержкой SSL, перейдем к конфигурированию нашего прокси. Для этого откроем файл /etc/squid/squid.conf, все указанные ниже опции надо либо найти и раскомментировать, приведя к указанному виду, либо создать.
Следующий блок, задающий стандартные ACL-элементы присутствует по умолчанию:
acl localnet src 192.168.187.0/24 # RFC1918 possible internal network
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
В нем мы должны изменить только опцию acl localnet src - указав диапазон собственной локальной сети.
Затем добавим несколько своих списков, прежде всего укажем диапазон адресов офисных ПК, которые мы раздаем по DHCP, это будут основные кандидаты на применение к ним правил фильтрации:
acl office src 192.168.187.120-192.168.187.199
Затем идет элемент со списком значений "черного списка", который хранится в виде regex-выражений в файле /etc/squid/blacklist:
acl blacklist url_regex -i "/etc/squid/blacklist"
В принципе, мы можем использовать общий список для фильтрации HTTP и HTTPS, но лучше будет разделить списки. Во-первых, HTTP позволяет фильтровать по части URL, блокируя не весь сайт, а только некоторые его страницы или разделы. Во-вторых, чем больше список - тем выше нагрузка, а так как сайты редко работают сразу по обоим протоколам, то логично будет иметь свои варианты списков для каждого из них.
Также помните, что фильтровать защищенные соединения мы можем только по имени домена, никакие параметры URL учитываться не будут. Для того, чтобы заблокировать домен часто используют следующее выражение:
vk\.com
Но это заблокирует не только vk.com, но и все сайты с окончанием на vk.com, скажем mvk.com. Чтобы этого избежать, при этом надежно заблокировав домен с поддоменами, следует использовать конструкцию:
^([A-Za-z0-9.-]*\.)?vk\.com
Для проверки созданных вами регулярных выражений мы рекомендуем использовать онлайн-сервис Regex101.
Следующий блок также является стандартным, просто контролируем его наличие:
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
После чего добавим свое правило для фильтрации HTTP-трафика:
http_access deny blacklist office
Которое запретит для всех ПК офиса доступ к ресурсам перечисленным в черном списке. Далее следует стандартный набор списков доступа:
http_access allow localnet
http_access allow localhost
http_access deny all
Это самый простой вариант, но тем не менее достаточный в качестве примера.
Теперь укажем порты для работы с шифрованным и нешифрованным трафиком, для прозрачного режима это должно выглядеть так:
http_port 3128 intercept
https_port 3129 intercept ssl-bump options=ALL:NO_SSLv3:NO_SSLv2 connection-auth=off cert=/etc/squid/squid.pem
Для непрозрачного:
http_port 3128 ssl-bump options=ALL:NO_SSLv3:NO_SSLv2 connection-auth=off cert=/etc/squid/squid.pem
В параметрах HTTPS-порта задаются рекомендованные опции (ALL) и выключаются небезопасные устаревшие протоколы SSLv2 и SSLv3, также указывается сертификат squid, который мы создадим позже.
Ниже укажем ряд необходимых опций:
always_direct allow all
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
Первая опция указывает направлять весь трафик сразу в интернет, без использования вышестоящих кешей, а последние две разрешают соединение даже с ошибками проверки сертификата, так как окончательно решение о посещении такого ресурса должен осуществлять пользователь, а не сервер.
Зададим черный список для SSL:
acl blacklist_ssl ssl::server_name_regex -i "/etc/squid/blacklist_ssl"
Как было сказано выше, мы будем использовать раздельные списки, данный список будет хранится в файле /etc/squid/blacklist_ssl и также содержать регулярные выражения, описывающие блокируемые домены.
Следующий элемент указывает на глубину перехвата HTTPS-трафика, нам нужен только домен, поэтому ограничимся минимальным вмешательством:
acl step1 at_step SslBump1
А теперь укажем, что делать с защищенным трафиком:
ssl_bump peek step1
ssl_bump terminate blacklist_ssl office
ssl_bump splice all
Действие peek "заглядывает" в соединение на указанную нами глубину, terminate блокирует соединения по совпадению условий (черный список + офисный диапазон адресов) и наконец splice разрешает все остальные соединения, не вмешиваясь в них.
Следующая опция также необходима для работы squid с SSL:
sslcrtd_program /usr/lib/squid/ssl_crtd -s /var/lib/ssl_db -M 4MB
Также обязательно укажем DNS-сервер, который следует использовать squid, он должен обязательно совпадать с DNS-сервером, используемым клиентами, в нашем случае это dnsmasq, в доменной сети следует указать доменные DNS:
dns_nameservers 127.0.0.1
Ниже приведены параметры кеша:
cache_mem 512 MB
maximum_object_size_in_memory 512 KB
memory_replacement_policy lru
cache_dir aufs /var/spool/squid 2048 16 256
И настройка логов:
access_log daemon:/var/log/squid/access.log squid
logfile_rotate 7
В нашем случае используется 7 ротаций (неделя), поэтому установите нужное вам значение.
Сохраняем конфигурационный файл, но не будем пока перезапускать squid, так как у нас отсутствуют некоторое объекты, перечисленные в конфигурации. Прежде всего создадим файл черного списка:
touch /etc/squid/blacklist_ssl
Либо можем скопировать уже существующий:
cp /etc/squid/blacklist /etc/squid/blacklist_ssl
Для примера мы заблокировали две популярные соцсети использовав следующие записи:
^([A-Za-z0-9.-]*\.)?vk\.com
^([A-Za-z0-9.-]*\.)?ok\.ru
Затем создадим сертификат для squid:
openssl req -new -newkey rsa:1024 -days 3650 -nodes -x509 -keyout squid.pem -out squid.pem
Так как он нужен сугубо для прокси и ни на что не влияет, то мы указали срок его действия в 10 лет, что позволит забыть о нем в обозримом будущем (с учетом того, что про него и так забудут).
Вот теперь можем проверить конфигурацию:
squid -k check
Остановим прокси, перестроим кеш (так как мы изменили его параметры) и запустим заново:
service squid stop
squid -z
service squid start
Если вы используете прозрачный режим, то в конец файла /etc/nat добавьте следующие строки:
# Заворачиваем http на прокси
iptables -t nat -A PREROUTING -i ens34 ! -d 192.168.187.0/24 -p tcp --dport 80 -j REDIRECT --to-ports 3128# Заворачиваем https на прокси
iptables -t nat -A PREROUTING -i ens34 ! -d 192.168.187.0/24 -p tcp --dport 443 -j REDIRECT --to-ports 3129
Для непрозрачного режима следует настроить WPAD, для автоматической настройки параметров прокси на клиентах (прописывать настройки руками в 21 веке дурной тон).
Проверим доступ к запрещенному ресурсу, как видим - все работает:
Ошибка "local IP does not match any domain IP"
Внешне данная ошибка проявляется в том, что squid в прозрачном режиме разрывает соединение с защищенным сайтом, регистрируя ошибку с указанным текстом в лог. Фактически такое поведение squid не является ошибкой, а связано со старой уязвимостью CVE-2009-0801, которая позволяла в прозрачном режиме обходить систему контроля доступа путем изменения HTTP-заголовков.
Коротко суть проблемы состоит в следующем: один и тот же ресурс на клиенте и на сервере разрешается в разные IP-адреса, этому в основном подвержены крупные ресурсы, имеющие несколько адресов для одного домена, а также сайты, использующие различные CDN (например, CloudFlare). Для squid такая ситуация равносильна попытке подмены заголовка, и он разрывает соединение.
Некоторые инструкции в сети советуют при сборке наложить патч client_side_request.patch, который по сути вернет уязвимость обратно. Заявления автора патча, что он не несет угрозы безопасности с отсылкой к одному из разработчиков squid не совсем верно отражают суть проблемы. Действительно, данная уязвимость никак не отражается на безопасности самого прокси-сервера, она позволяет клиентам, при определенных условиях, обойти его систему контроля доступа.
Как избежать данной ситуации? Использовать общий DNS-сервер как для клиента, так для прокси-сервера, мы обращали на это ваше внимание при описании соответствующей опции. Но не все так просто, ситуацию осложняет локальный DNS-кеш, который присутствует на любом клиенте и может содержать иную запись, нежели локальный кеш сервера. И добиться полной синхронизации кешей будет довольно сложно.
Однако данная проблема встречается не так часто, поэтому вполне будет достаточно очистить клиентский кеш и начать использовать общий DNS-сервер, но 100% гарантией избавления от проблемы это не будет.
Как решить вопрос окончательно? Ответ прост: не использовать прозрачный режим. Если трезво глянуть на ситуацию, то его достоинства по большей части преувеличены, у прозрачного прокси нет никаких существенных преимуществ, кроме простоты настройки. Протокол WPAD не только позволяет автоматически настраивать параметры прокси на клиентах, но и предоставляет большую гибкость в определении того, какой трафик пускать через прокси, а какой напрямую, прост во внедрении и поддерживается всеми типами клиентов.
Надеемся, что данная статья окажется вам полезна и поможет начать эффективно фильтровать защищенные соединения при помощи прокси-сервера squid.
Онлайн-курс по устройству компьютерных сетей
На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.
Последние комментарии