Назад | Перейти на главную страницу

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

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

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

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

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

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

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

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

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

Я делаю это так:

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

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

#!/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