Вот моя сетевая конфигурация:
Моя сетевая конфигурация 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-трафик (т.е. просмотр разбора пакетов на прокси и проверка содержимого). Меня больше интересуетблокировкасайтов с DansGuardian, независимо от того, работает ли он по протоколу HTTP или HTTPS (проверяя назначение пакетов).
ПРАВКА 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 полностью.
решение1
Мои 2 цента:
Что касается HTTP: наличие брандмауэра, прозрачно перенаправляющего трафик порта 80 на прокси/фильтр, является самым простым способом сделать это. Нет необходимости в настройке клиента, + вы можете исключить любой хост/подсеть из использования прокси без необходимости перенастройки клиента. Это единственный способ, которым вы можете быть уверены, что все, что должно проходить через прокси, проходит.
Любой метод, кроме блокировки всего исходящего трафика HTTPS 443 и разрешения только подмножества сайтов на основе IP-адреса, разрешенного для исходящего порта 443, не будет работать так, как ожидается. Защищенный протокол HTTPS разработан (за исключением нескольких недостатков) для предотвращения атак типа «человек посередине» (прокси-серверы ЯВЛЯЮТСЯ «легальными» MITM). Таким образом, HTTPS разрешено делать то, для чего он был разработан. Однако, если вы хотитеИГНОРИРОВАТЬHTTPS, вам следует настроить ваш squid на использование DIRECT, а не CONNECT (прослушивание), но даже в этом случае вы все равно можете столкнуться с проблемными веб-сайтами со смешанными частями HTTP/HTTPS. Таким образом, ваш прокси-сервер Squid также будет управлять HTTPS. Это также должно быть отражено в прозрачной пересылке вашего брандмауэра.
решение2
Всякий раз, когда вы видите, что что-то, что должно работать, не работает, вам нужно спросить, нет ли здесь какого-то другого фактора, который вы не видите. Правило
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
работает, чтобы вы могли завершить свой набор правил. Если вы работаете на этом хосте удаленно, мое предложение отключит вас, поэтому вам следует делать это только с консоли. Чтобы безопасно работать удаленно, обратитесь к моему коллегеПост Эли Розенкрафта о настройке брандмауэров удаленно.
решение3
Стандарт
Здесь может помочь отдельная (определяемая пользователем) цепочка.
# 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
и убедитесь, что счетчик увеличился. Если нет, то что-то не так с конфигурацией маршрутизатора.
решение4
Если вы не хотите, чтобы ваши клиенты просто получали доступ к http{s}-сайтам без прокси-сервера, то вы можете просто DROP
перенаправить REJECT
пакеты на порты 80 и 443:
IPTABLES -I FORWARD -i eth1 -p tcp -m multiport --dports 80,443 -j REJECT
Где eth1
у вас внутренний интерфейс. Сделав так, вам не придется возиться с другими портами/доступом.