Заставить клиентов использовать прокси

Вот моя конфигурация сети:

http://daveden.files.wordpress.com/2013/05/network-configuration.png

Прокси-сервер работает под управлением Ubuntu со Squid на порту 3128 и DansGuardian на порту 8080.

Я хотел бы заставить всех клиентов использовать прокси-сервер - в частности, порт 8080 - для любого доступа HTTP/HTTPS.

Однако я не хочу прозрачно перенаправлять, потому что это не работает для HTTPS. Я не против настройки каждого клиента, и я не против, чтобы каждый клиент знал, что он использует прокси-сервер. Я просто не хочу, чтобы клиенты могли просматривать веб-страницы без настроек прокси.

Как мне это сделать? Могу ли я просто отбросить пакеты, если клиент не настроен на использование прокси-сервера на порту 8080?

Я пытался использовать iptables для отбрасывания пакетов, у которых был dport, отличный от 8080, но я думаю, что он слишком много отклонил, и я больше не мог получить доступ к чему-либо.

РЕДАКТИРОВАТЬ

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

РЕДАКТИРОВАТЬ 2

Я думаю, что, возможно, у меня сложилось неправильное впечатление. Просто чтобы прояснить, я совсем не заинтересован в фильтрации HTTPS-трафика (то есть в том, чтобы разбирать пакеты на прокси и проверять содержимое). I'm more interested in blocking sites with DansGuardian, whether it's over HTTP or HTTPS (by looking at the destination of the packets).

РЕДАКТИРОВАТЬ 3

Основываясь на предложении Александру-Флорина Винтиля ниже, вот что я сейчас делаю:

# Redirect HTTP traffic to port 8080 (DansGuardian)
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080

# Check TCP and UDP traffic against whitelist
iptables -A FORWARD -i eth1 -p tcp --dport 443 -j whitelist
iptables -A FORWARD -i eth1 -p udp --dport 443 -j whitelist

# Drop all other HTTPS traffic
iptables -A FORWARD -i eth1 -p tcp --dport 443 -j DROP
iptables -A FORWARD -i eth1 -p udp --dport 443 -j DROP

# Drop all traffic aimed straight at the proxy
iptables -A FORWARD -i eth1 -p tcp --dport 3128 -j DROP
iptables -A FORWARD -i eth1 -p udp --dport 3128 -j DROP
iptables -A FORWARD -i eth1 -p tcp --dport 8080 -j DROP
iptables -A FORWARD -i eth1 -p udp --dport 8080 -j DROP

Вкратце, перенаправьте HTTP-трафик на порт 8080, отбросьте весь HTTPS-трафик, который не входит в белый список (в отдельной цепочке), и отбросьте весь трафик, который явно использует прокси-сервер. Без последнего правила клиент может получить доступ к любому веб-сайту с использованием HTTPS, если он настроит свой браузер на использование прокси-сервера, потому что тогда порт назначения будет 8080, а не 443. Таким образом, даже удаление всего трафика, связанного с 443, не блокирует HTTPS в целом,

6 ответов

Решение

Мои 2 цента:

Относительно HTTP: Брандмауэр прозрачно перенаправляет трафик порта 80 на прокси / фильтр - это самый простой способ сделать что-либо. Нет необходимости в настройке клиента, + вы можете освободить любой хост / подсеть от использования прокси без необходимости перенастройки клиента. Это единственный способ, которым вы можете быть уверены, что все, что должно проходить через прокси, является.

Любой другой метод, кроме блокирования всего исходящего трафика HTTPS 443 и предоставления доступа только к подмножеству сайтов на основе ip для исходящего порта 443, не будет работать должным образом. Безопасный протокол HTTPS разработан (за исключением нескольких недостатков) для предотвращения атак "человек посередине" (прокси-серверы являются "легальными" MITM). Таким образом, HTTPS разрешается делать то, для чего он предназначен. Однако, если вы хотите IGNORE HTTPS, вы должны настроить свой Squid на использование DIRECT и не использовать CONNECT (постукивание), но даже если это так, вы все равно можете столкнуться с проблемными веб-сайтами со смешанными частями HTTP/HTTPS. Таким образом, ваш прокси-сервер Squid также будет управлять HTTPS. Это также должно быть отражено в прозрачной части пересылки вашего брандмауэра.

Всякий раз, когда вы видите, что что-то, что должно работать, не работает, вам нужно спросить, есть ли какой-то другой фактор, который вы не видите. Правило

sudo iptables -A INPUT -p tcp ! --dport 8080 -j REJECT

Похоже, что он должен работать, но вы добавили его в цепочку INPUT, так что, вероятно, он обойден предыдущим правилом в цепочке. Это правило должно быть само по себе адекватным, поскольку цепочка INPUT является первой цепочкой, в которую попадают входящие пакеты. Если они отклонены в цепочке INPUT, они никогда не попадут в цепочки FORWARD или OUTPUT. Конечно, это правило будет блокировать все TCP, которые не предназначены для порта 8080, что, вероятно, не совсем то, что вам действительно нужно, если прокси-сервер на 8080 не является единственной службой на компьютере, и вы входите только с консоли.

Итак, первое, что нужно сделать, это перечислить правила и посмотреть, что может вызывать прохождение пакетов:

sudo iptables -L

Если ваш брандмауэр обратный NAT, то вы должны также перечислить таблицу NAT.

sudo iptables -L -t nat

Затем попробуйте поставить то же правило в начале цепочки:

sudo iptables -I INPUT -p tcp ! --dport 8080 -j REJECT

и посмотрите, не решит ли это проблему, или, по крайней мере, даст вам больше уверенности, что вы понимаете, как iptables работает так, что вы можете завершить свой набор правил. Если вы работаете на этом хосте с удаленного компьютера, мое предложение отрежет вас, поэтому вы должны делать это только с консоли. Для безопасной работы с пульта см. Статью моего коллеги Эли Розенкруфта о настройке брандмауэров с пульта.

стандарт

Отдельная (определяемая пользователем) цепочка может помочь.

# create a chain just for user 100 (192.168.1.100)
iptables -N custom_user_100

# redirect all traffic FROM user 100 to custom chain
iptables -A INPUT -p tcp -s 192.168.1.100 -j custom_user_100

# return from user chain for valid traffic, drop all other
iptables -A custom_user_100 -p tcp --dport 8080 -j RETURN
iptables -A custom_user_100 -j DROP

Итак, что это делает, это перенаправить любой трафик с 192.168.1.100 в пользовательскую цепочку. Эта пользовательская (определяемая пользователем) цепочка просто возвращает, если найдено правильное совпадение (трафик, предназначенный для порта 8080). Весь другой несоответствующий трафик, который не приводит к возврату из цепочки, отбрасывается.

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

iptables -L -v -n

экспедиция

Теперь, если вы не обрабатываете переадресацию трафика, будет другой набор правил - но идея использования пользовательской (определенной пользователем) цепочки та же самая. Мне нравится ссылаться на диаграмму по этой ссылке: http://www.csie.ntu.edu.tw/~b93070/CNL/v4.0/CNLv4.0.files/Page697.htm при попытке понять поток пакеты.

В этом случае вы можете сделать что-то вроде следующего:

# create a chain just for user 100 (192.168.1.100)
iptables -N custom_user_100

# redirect all traffic FROM user 100 to custom chain
iptables -A FORWARD -p tcp -s 192.168.1.100 -j custom_user_100

# return from user chain for valid traffic, drop all other
iptables -A custom_user_100 -p tcp --dport 8080 -j RETURN
iptables -A custom_user_100 -j DROP

Это идентично первому, за исключением того, что правило, которое было применено к цепочке INPUT, вместо этого применяется к цепочке FORWARD.

Обновление 2013-05-24

Я перечитал ваш вопрос. Так начну сначала.

Давайте предположим, что ваш "прокси" на самом деле является маршрутизатором. То есть - он передает все пакеты от одного интерфейса к другому - возможно, с использованием NAT. Это означает, что все представляющие интерес пакеты проходят через цепочку FORWARD.

Далее: вы говорите, что настроите все клиенты, использующие порт 8080, для подключения к прокси-серверу. Хорошо. Это означает, что все эти пакеты будут входить в "прокси" через цепочку INPUT.

Итак: вы просто хотите, чтобы никто не выходил из порта 8080 в цепочке FORWARD.

iptables -A FORWARD -p tcp --dport 8080 -j REJECT

Это правило гарантирует, что все, что должно быть перенаправлено на порт назначения 8080, будет отклонено (ICMP-пакет будет отправлен клиенту, который попытался передать пакет через прокси-сервер).

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

iptables -L -v -n |grep 8080

и убедитесь, что счетчик увеличился. Если нет, то что-то не так с конфигурацией маршрутизатора.

Если вы не хотите, чтобы ваши клиенты просто заходили на сайты http {s} без прокси, вы можете просто DROP или же REJECT перенаправленные пакеты на порты 80 и 443:

IPTABLES -I FORWARD -i eth1 -p tcp -m multiport --dports 80,443 -j REJECT

куда eth1 это ваш внутренний интерфейс. Делая так, вам не придется возиться с другими портами / доступом.

Сначала прочитайте немного iptables документация - в частности, вам, по крайней мере, нужно знать, в какие цепочки в какие таблицы будет входить пакет (посмотрите здесь: http://www.iptables.info/en/structure-of-iptables.html).

Вам придется балансировать между двумя вещами: ваша цель заставить всех использовать прокси и удобство для всех. С одной стороны, вы можете вообще запретить пересылку любых пакетов (вы даже можете отключить ip_forwarding флаг в ядре). Таким образом, локальные компьютеры будут иметь доступ к Интернету только через ваш прокси-сервер. Но даже это не остановит всех от использования туннельного соединения через ваш http-прокси (и это даже проще с https). Таким образом, вы не сможете полностью контролировать или ограничивать использование Интернета.

С другой стороны, вы можете использовать еще более мягкий подход: просто ограничить исходящий трафик до порта 80. В этом случае программное обеспечение, которое не использует http (например, skype), не будет нуждаться в туннелировании трафика в http и клиентах с хорошим поведением. будет иметь все преимущества локального http кэша (более быстрый доступ к сайтам).

Ваша текущая конфигурация выглядит как первый вариант выше. Но у вас есть ненужные правила ПРИНЯТИЯ в цепочке FORWARD. Вы не хотите, чтобы маршрутизатор пересылал какие-либо пакеты. Локальные компьютеры подключаются к вашему прокси (пакеты проходят через цепочку INPUT), а не к удаленным хостам. С вашей текущей настройкой кто-то может найти прокси-сервер, прослушивающий порт 8080 в любом месте Интернета, и использовать его вместо вашего прокси.

Лично мне нравится устанавливать политики по умолчанию для цепочки INPUT и FORWARD на DROP

iptables -P INOUT DROP
iptables -P FORWARD DROP

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

Другие вопросы по тегам