Правила iptables, разрешающие HTTP-трафик только одному домену


20

Мне нужно настроить мой компьютер так, чтобы он разрешал только HTTP-трафик на / с serverfault.com. Все остальные сайты, порты служб недоступны. Я придумал эти правила iptables:

#drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP

#Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

#allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

Это не очень хорошо работает:

  • После того, как я все отброшу и перейду к правилу 3:

    iptables -A ВЫХОД -p tcp -d serverfault.com --dport 80 -j ПРИНЯТЬ

Я получаю эту ошибку:

iptables v1.4.4: host/network `serverfault.com' not found
Try `iptables -h' or 'iptables --help' for more information.

Как вы думаете, это связано с DNS? Должен ли я это позволить? Или я должен просто поставить IP-адреса в правилах? Как вы думаете, то, что я пытаюсь сделать, может быть достигнуто с помощью более простых правил? Как?

Буду признателен за любую помощь или намеки на это. Большое спасибо!


2
Не забывайте sstatic.net и другие. serverfault.com не полностью происходит от serverfault.com
— Zoredache

Можете ли вы запустить прокси в другой системе? Это лучшее / простое решение: serverfault.com/questions/215134
— mattdm

Ответы:


29

С правилами IPTables порядок имеет значение. Правила добавляются и применяются по порядку. Более того, при добавлении правил вручную они применяются немедленно. Таким образом, в вашем примере любые пакеты, проходящие через цепочки INPUT и OUTPUT, начинают отбрасываться, как только устанавливается политика по умолчанию. Это также, кстати, почему вы получили сообщение об ошибке, которое вы сделали. Что происходит, это:

  1. Применяется политика DROP по умолчанию
  2. IPTables получает имя хоста в качестве пункта назначения
  3. IPTables пытается выполнить поиск DNS на «serverfault.com»
  4. Поиск DNS заблокирован действием DROP

Хотя параметры источника / назначения будут принимать имена хостов, это настоятельно не рекомендуется. Процитирую справочную страницу,

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

Слиллибри ударил по гвоздю по голове, на что своим ответом вы пропустили правило DNS ACCEPT. В вашем случае это не имеет значения, но обычно я бы установил политику по умолчанию позже в процессе. Последнее, что вам нужно - это работать удаленно и разрешить SSH после включения запрета по умолчанию.

Кроме того, в зависимости от вашего дистрибутива вы сможете сохранить правила брандмауэра, чтобы они автоматически применялись во время запуска.

Зная все это и переставляя ваш сценарий, вот что я бы порекомендовал.

# Allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

# Allow DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

# Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP

3
Красивый, хорошо проработанный ответ.
— Джейк Робинсон

1
Я ценю это, хотя вы, должно быть, тоже упустили мою ошибку. К сожалению.
— Скотт Пак

3
На самом деле, вы можете поместить свои iptables -Pоператоры в любом месте вашего скрипта, так как политики цепочки применяются только тогда, когда пакеты «падают» с конца цепочки. Обычно я помещаю утверждения политики (обычно DROPполитики) в начало моих сценариев iptables.
— Стивен Понедельник

1
@ Стивен: Вы абсолютно правы. OP, кажется, вводит их в интерактивном режиме. Давайте представим, что вы подключены к вашему хосту через SSH, и ваше первое правило относится к политике DROP. Ваше SSH-соединение будет разорвано, прежде чем вы сможете ввести другие правила. Это та же временная проблема, если иное проявление, чем она столкнулась.
— Скотт Пак

Спасибо. Пытался это. Но не работал без добавления sudo iptables -I OUTPUT 1 -o lo -j ACCEPT. Разве это не должно быть добавлено?
— Киран


5

Этот вид требования может быть лучше обработан с помощью веб-прокси и / или фильтра. Dansgaurdian может быть настроен для этого. Вам нужно будет использовать правила NAT, чтобы заставить ваш трафик через фильтр.

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


1
Полностью с этим согласен. iptablesэто, вероятно, неправильный инструмент для использования здесь, так как он не очень хорошо работает с DNS-именами. Веб-прокси с соответствующими настройками фильтра подходит гораздо лучше.
— Стивен Понедельник

2

Боюсь, что iptables не работает на этом уровне, его интересует только IP-адрес, а не имя хоста. Если вы хотите заблокировать доступ к другим виртуальным хостам с тем же IP-адресом, вам нужно посмотреть на размещение файлов .htaccess.


Дело в том, что когда я пробую правило 3, не «отбрасывая все», оно отлично работает с iptables!
— Zenet

2
хм, я неправильно понял вопрос Правильно, что происходит в фоновом режиме, это то, что iptables разрешит serverfault.com до 64.34.119.12 (см. Ответ от slillibri, чтобы понять, почему разрешение не работает). Однако, поскольку iptables не понимает имен хостов и просто разрешает ip, вы сможете подключиться к любому веб-сайту на этом ip, если у него есть несколько сайтов.
— Найл Донеган

2
@ Эмили, это может работать нормально, добавляя правило, но если IP-адрес serverfault.com изменится, трафик не будет разрешен. Разрешение на сайт, такой как google.com, который имеет сотни адресов, которые часто меняются, не будет работать вообще.
— Зоредаче

1

Вы должны настроить это на своем веб-сервере. iptables - это фильтр пакетов. HTTP-транзакции отправляют имя сайта (т. Е. Stackoverflow) как часть полезной нагрузки TCP (т. Е. Не как часть заголовка TCP, который легко читается iptables).

Учитывая это, и тот факт, что HTTP-транзакции почти наверняка будут распределены по нескольким пакетам (то есть вы не можете просто сопоставить строку в заголовке HTTP), это гораздо лучше обрабатывается конфигурацией вашего веб-сервера или прокси-сервером впереди. этого

Было бы полезно узнать причину этого, есть несколько других альтернатив:

  1. Перенаправить на правильный URL-адрес, если они введут неправильный URL-адрес (например, перенаправить на stackoverflow.com, если они введут www.stackoverflow.com)
  2. Скажите вашему веб-серверу не обслуживать хосты, отличные от stackoverflow.com
  3. Поместите сайт на отдельный IP-адрес, к которому больше ничего не разрешает, и заставьте ваш веб-сервер прослушивать это.

Привет Фил, я не уверен, что понимаю, какой веб-сервер? У меня нет веб-сервера. Я делаю эту конфигурацию на моем компьютере.
— Zenet
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.