Правила 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-адреса в правилах? Как вы думаете, то, что я пытаюсь сделать, может быть достигнуто с помощью более простых правил? Как?

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

Zenet
источник
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. Разве это не должно быть добавлено?
Киран
7

Добавлять

iptables -A OUPUT -p udp --dport 53 -j ACCEPT

разрешить поиск DNS.

slillibri
источник
5

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

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

BillThor
источник
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