IPtables заносят в белый список динамический IP-адрес по имени хоста

Я хочу ограничить доступ к серверу определенными IP-адресами с помощью iptables, но:

  • Один из IP-адресов является динамическим, это обычное домашнее соединение ISP, которое время от времени меняется на time.
  • Поддомен, например, dynamic.example.org, автоматически обновляется при изменении IP-адреса с использованием службы, аналогичной dyndns.

Возможно ли, чтобы IPtables разрешал доступ к порту, если dynamic.example.org разрешает этот IP-адрес?

Моя текущая идея состоит в том, чтобы настроить модуль systemd, который периодически разрешает dynamic.example.org и соответствующим образом корректирует iptables . Однако для этого также необходимо знать старый IP-адрес (чтобы его где-то сохранить), чтобы удалить его из белого списка.

Есть ли более простой способ сделать это, уже встроенный в iptables?

0
задан 25 October 2018 в 22:51
3 ответа

iptables работает на IP-адресах, а не на именах хостов. В качестве аргументов можно использовать имена хостов, но они будут разрешены при вводе команды. Выполнение DNS поиска для каждого проходящего пакета было бы слишком медленным.

Ваша идея по настройке правил, таким образом, является единственным подходом. Это может быть либо по обычному расписанию, управляемому программой типа systemd или cron, либо лучше, если вы сможете управлять получением уведомлений при изменении IP адреса.

Вам не нужно хранить старый адрес, просто сделайте цепочку iptables для вашего правила и замените правило. Смотрите опцию -R для iptables. Чтобы иметь заменяющее правило при первой проверке, просто добавьте фиктивное правило, чтобы при первой проверке было заменено правило.

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

.
3
ответ дан 4 December 2019 в 12:16

Я делаю это следующим образом:

  • Запускаю сценарий каждые x минут из crontab для обновления «ipset»
  • Использую IPtables для использования ipset

Предполагая, что у вас есть только 1 IP-адрес в этом ipset, подойдет следующий скрипт:

#!/bin/bash
# Update ipset to let my dynamic IP in

set=whitelist
host=myhost.dynamic.example.com

me=$(basename "$0")

ip=$(dig +short $host)

if [ -z "$ip" ]; then
    logger -t "$me" "IP for '$host' not found"
    exit 1
fi

# make sure the set exists
ipset -exist create $set hash:ip

if ipset -q test $set $host; then
    logger -t "$me" "IP '$ip' already in set '$set'."
else 
    logger -t "$me" "Adding IP '$ip' to set '$set'."
    ipset flush $set
    ipset add $set $host
fi

В crontab я вызываю этот скрипт каждые 5 минут:

*/5 * * * * root /usr/local/bin/ipset-update-dyn

В iptables правило, использующее ipset, выглядит так:

-A INPUT -p tcp -m set --match-set whitelist src -m state --state NEW -j ACCEPT
3
ответ дан 12 February 2020 в 09:30

Еще проще с помощью dig:

iptables -I INPUT -p tcp -s $(dig +short yourdomain.ddns.net) -m state --state NEW -m tcp -j ACCEPT

Объяснение:

dig +short yourdomain.ddns.netзапускается в подпроцессе, возвращающем ваш IPv4 IP. Результат этого подпроцесса передается в двоичный файл iptables, добавляющий новое правило.

Обратите внимание, что мы использовали -I, чтобы добавить правило ко всем остальным, если вы хотите добавить, используйте-A

iptables -A INPUT -p tcp -s $(dig +short yourdomain.ddns.net) -m state --state NEW -m tcp -j ACCEPT

Обновить:

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

Наилучшим подходом было бы создать цепочку для хранения правил DDNS и просто сбросить пользовательскую цепочку перед добавлением нового правила.

Создайте пользовательскую цепочку, если она не существует, и сбросьте цепочку.:

iptables -N myDDNS 2>/dev/null;iptables -F myDDNS

Если цепочка существует, возникнет ошибка, но пользовательская цепочка не будет дублирована. Перенаправление ошибки на /dev/null предотвратит появление ошибки на STDIN.

Добавьте правило к пользовательской цепочке.:

iptables -I myDDNS -p tcp -s $(dig +short yourdomain.ddns.net) -m state --state NEW -m tcp -j ACCEPT

Просто соберите все вместе в один лайнер и вызывайте скрипт из cron каждые N минут.

iptables -N myDDNS 2>/dev/null;iptables -F myDDNS && iptables -I myDDNS -p tcp -s $(dig +short yourdomain.ddns.net) -m state --state NEW -m tcp -j ACCEPT

Добавление &&междуiptables -F(flush)и предшествующим правилом гарантирует, что правило будет добавлено только в том случае, если команда flush возвращает 0

0
ответ дан 27 November 2021 в 13:39

Теги

Похожие вопросы