Я хочу ограничить доступ к серверу определенными 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
, но это требует гораздо больше работы, поскольку номер позиции изменяется всякий раз, когда вы добавляете или удаляете правила.
Я делаю это так:
Предполагая, что у вас есть только 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