IPtables 按主机名将动态 IP 列入白名单

Tom*_*m B 7 domain-name-system iptables dynamic

我想使用 iptables 将对服务器的访问限制为某些 IP,但是:

  • 其中一个 IP 是动态的,是不时变化的正常 ISP 家庭连接。
  • 当 IP 更改时,使用与 dyndns 类似的服务自动更新子域(例如,dynamic.example.org)。

如果dynamic.example.org解析为该IP,是否可以让IPtables允许访问该端口?

我当前的想法是建立一个 systemd 单元,定期解析dynamic.example.org 并相应地调整 iptables。然而,这也需要知道旧的 IP 地址(因此将其存储在某个地方)才能将其从白名单中删除。

是否有更简单的方法可以做到这一点已经内置到 iptables 中?

miv*_*ivk 7

我这样做的方法是:

  • 从 crontab 每 x 分钟运行一个脚本来更新“ipset”
  • 让 IPtables 使用 ipset

假设此 ipset 中只有 1 个 IP 地址,则可以执行以下脚本:

#!/bin/bash
# Update ipset to let my dynamic IP in
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

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 $ip; 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 $ip
fi
Run Code Online (Sandbox Code Playgroud)

crontab我每 5 分钟调用此脚本一次:

*/5 * * * * root /usr/local/bin/ipset-update-dyn
Run Code Online (Sandbox Code Playgroud)

在 iptables 中,使用 ipset 的规则如下所示:

-A INPUT -p tcp -m set --match-set whitelist src -m state --state NEW -j ACCEPT
Run Code Online (Sandbox Code Playgroud)


Ral*_*edl 4

iptables适用于 IP 地址,不适用于主机名。您可以使用主机名作为参数,但它们将在输入命令时解析。对每个经过的数据包进行 DNS 查找会太慢。

因此,你的想法是调整规则,这是唯一的方法。这可以定期进行,由 systemd 或 cron 等程序控制,或者如果您能够在 IP 地址发生变化时收到通知,那就更好了。

您不必存储旧地址,只需为您的规则创建一个 iptables 链并替换该规则即可。请参阅-R的选项iptables。要在第一次检查时替换规则,只需添加一条虚拟规则,以便在第一次检查运行时有一条要替换的规则。

INPUT您还可以避免额外的链并替换或中特定位置的规则FORWARD,但这需要更多的维护工作,因为每当您添加或删除规则时,位置编号都会发生变化。

  • 在等待 DNS 查找时数据包会去哪里?堆栈的这一层不应该进行这种缓冲。如果在这一层引入缓冲区,它将如何处理 DNS 请求或响应丢失?当 iptables 注意到 DNS 响应没有返回时,首先触发 DNS 查找的数据包很可能已经被重新传输。因此,更新规则是一条更好的道路。当然,这仍然留下了一个悬而未决的问题:您是否足够信任 DNS 查找,让它们更改您的防火墙规则。 (2认同)