Настройка Squid и iptables в Linux


Ограничение доступа с помощью Squid и iptables

Самый простой способ заблокировать доступ пользователям к определенный веб узлам, это поднять прокси сервер Squid и настроить сетевой экран iptables.

Настройка Squid на Linux

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

Да уж, вот это я понимаю трудное детство: Linux, не игровая консоль, терминал. 😀

В сегодняшней статье речь пойдет о том, как организовать систему ограниченного доступа в интернет с помощью Squid и iptables.

Установка и настройка Squid

Part.1 Кальмар пускает щупальцу

Тот, кто когда либо юзал Linux знает, что Squid является самым распространенным прокси сервером для этой ОС. Для установки Squid нужно выполнить в консоли команду:

[user@localhost /]# sudo apt-get squid3

или

[root@localhost /]# yum -y install squid

в зависимости от дистрибутива Linux.

Следующим этапом необходимо изменить (настроить) конфигурационный файл Squid.conf

[root@localhost /]# kwrite /etc/squid/squid.conf

Для редактирования системных файлов в Linux, можно использовать разные утилиты, в данном случае мне было удобнее работать в kwrite.

Моей задачей было организовать доступ по принципу, все что не разрешено — запрещено.

Поэтому я решил создать белый список в котором будут находиться разрешенные сайты, и доступ к ним будет реализован по двум протоколам http и https.

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

google\.ru
google\.com
yandex\.ru
mail\.ru

и т. д.

В итоге конфиг у меня получился следующий:

acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32
acl url_filtred src 192.168.1.1-192.168.1.255
acl whitelist url_regex -i "/etc/squid/whitelist"
acl localnet src 192.168.1.0/24
acl SSL_ports port 443 # https
acl SSL_ports port 563 # snews
acl SSL_ports port 873 # rsync
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 Safe_ports port 631 # cups
acl Safe_ports port 873 # rsync
acl Safe_ports port 901 # SWAT
acl purge method PURGE
acl CONNECT method CONNECT
# Разрешаем по https доступ только к whitelist
http_access allow CONNECT SSL_ports whitelist
# Разрешаем по http доступ к сайтам в whitelist
http_access allow whitelist
# Доступ ко всем остальным сайтам запрещаем
http_access deny all
# Порты прокси-сервера:
http_port 127.0.0.1:3128 transparent
# Путь к логу, для мониторинга:
access_log /var/log/squid/access.log squid

В завершении я перезагрузил кальмара service squid restart и поставил галочку в браузере использовать прокси сервер, указав порт 3128.

В итоге требуемый результат был получен. :)

Но, спустя одну минуту тут же поймал себя на мысли, что данный вид ограничения доступа достаточно уязвим, ведь squid стоит на том же (localhost) компьютере, который имеет всего один интерфейс и сняв галочку в браузере, пользователь получит полный доступ в сеть, а это не есть good в любом случае.

Настройка iptables

Для тех, кто живет вдалеке от железной дороги, поясню:

iptables — это сетевой экран, который присутствует в каждом дистрибутиве Linux, и при условии грамотной настройки выполняет достаточно функциональную защиту ОС от различных атак.

Чисто теоретически использовать прокси сервер Squid на локальном компьютере не очень удобно, но в Linux специально для этого случая можно реализовать перенаправление портов для конкретного пользователя.

Делается это так:

iptables -A OUTPUT -p tcp -m tcp --dport 80 -m owner --uid-owner user -j REDIRECT --to-ports 3128

Теперь даже если юзер уберет галочку использовать прокси в браузере, весь исходящий трафик с 80 порта будет редиректиться на порт 3128, а там, как вы уже наверное догадались — балалайка! :)

Part.2 Обрубаем щупальцы кальмару.

В данной защите имеет место одна очень серьезная дыра, это использование https протокола на 443 порту.

Да, пользователь не сможет зайти в контакт набрав в адресной строке браузера vk.com, но добавив к урлу протокол https получит зеленый свет, т. е. полный доступ.

Можно конечно перенаправить все пакеты отправляемые пользователем user с 443 на 3129 порт:

iptables -A OUTPUT -p tcp -m tcp --dport 443 -m owner --uid-owner user -j REDIRECT --to-ports 3129

Но тогда и разрещенные сайты не будут работать по протоколу https, а бедный пользователь увидит только такое окно:

Ошибка при установлении защищённого соединения

Part.3 А не, не обрубаем. 😀

Дело в том, что в Squid и на такой случай имеется свой костыль. Реализуется он созданием и добавлением собственного SSL сертификата в конфигурационный файл squid.conf

Для этого нужно пересобрать сквид с поддержкой SSL, а по умолчанию ее нет и сгенерировать собственный сертификат:

openssl req -new -newkey rsa:1024 -days 365 -nodes -x509 -keyout squid.pem -out squid.pem

openssl x509 -in squid.pem -outform DER -out squid.der

Потом добавить два созданных файла squid.pem и squid.key в папку сквида, а после дополнить конфигурационный файл:

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

Но я решил этого не делать, а просто поставил галочку в браузере. 😉

P.S. И посоветовал знакомому использовать более гуманные методы в воспитании ребенка, такие, как профилактические беседы. А вы за какие методы воспитания? :)