如何使用域名创建 Iptables 规则

如何使用域名创建 Iptables 规则

有人可以建议一种在 iptables 规则中使用域名的方法吗?

答案1

如果可能的话,请考虑设置一个透明的应用程序级代理。使用应用程序代理进行此类过滤可能更容易。

如果必须使用 iptables 来执行此操作,那么一个笨拙的选项就是创建一个链,创建一个命令行脚本,该脚本会使用您需要使用的名称的 DNS 结果定期更新该特定链。

如果有人试图创建这样一种真正基于数据包过滤的 DNS 的东西,几乎肯定必须通过用户空间来完成。具体来说,你可以使用类似libnetfilter_queue。我从来没有用过它,但是封包可能接近做到这一点,但似乎维护得不是很好。

另一种选择可能是设置第 7 层过滤如果 DNS 名称作为数据包有效负载的一部分被转换,您可能能够过滤部分请求。

答案2

简短的回答,如果你确定 IP 永远是静态的:

iptables -A INPUT -s `dig host.your-domain-name.com +short`/32 -p tcp -m tcp --dport 22 -j ACCEPT

答案3

我需要 iptables 来允许基于我家 ip 的域名进行 ssh 访问,但希望对所有其他地址保持关闭。由于我有一个偶尔会更改的动态 ip,因此我编写了一个脚本来根据我的动态 dns 条目的 ip 更新规则。我是这方面的新手,所以我确信有更好的方法。将“yourname”替换为您的动态 dns 主机名。

#!/bin/sh

/usr/bin/nslookup yourname.dynalias.org > temp
found=0
address=""
while read LINE
do
 if [[ "$LINE" == Address* ]]; then
        let found++
        if [[ $found == 2 ]]; then
                address=${LINE:8};
                /sbin/iptables-save > /root/rulesdump
                while read LINE2
                do
                        if [[ "$LINE2" == *$address* ]]; then
                                ruleexists=1;
                        fi
                done < /root/rulesdump;
                if [[ "$ruleexists" != 1 ]]; then
                        /sbin/iptables -D INPUT -j LOG_DROP
                        /sbin/iptables -A INPUT -s $address -p tcp -m tcp --dport 22 -j LOG_ACCEPT
                        /sbin/iptables -A INPUT -j LOG_DROP
                fi
        fi
 fi
done < /root/temp;

将上述脚本放入 crontab 中以便每隔一段时间运行。

答案4

从 Linux 2.4.x 开始,您ipset可以使用它来创建一组 IP,而无需调整防火墙规则。

# create the ipset (it may exist)
sudo ipset create dynamic_ips hash:ip -exist

# add a rule where the source IP must match that ipset
sudo iptables -A INPUT -p tcp -m tcp --dport 22 --syn \
               -m set --match-set dynamic_ips src -j ACCEPT

现在,只有当尝试连接的计算机具有与 中找到的地址匹配的地址时,该规则才会匹配dynamic_ips。当集合为空时,什么也不会发生(它无法匹配任何 IP)。我们使用以下命令向集合中添加一个新 IP 地址:

sudo ipset add dynamic_ips 10.10.10.10

要查看当前集合中的内容,请使用list如下命令:

sudo ipset list dynamic_ips

现在,要更新列表,您实际上希望以原子方式执行此操作。这是使用命令完成的ipset swap ...。为此,您需要创建一个新集合并将其与旧集合交换。在内部,它只是一个重命名,因此您可以拥有非常大的集合,并且交换它们所需的时间保持不变。

以下是我建议的事件顺序:

# destroy the new set in case something went wrong and it lingered
# ignore errors if the command fails
sudo ipset destroy new_ips

# for the following, fail on error

# create the new set
sudo ipset create new_ips hash:ip

# determine the list of ip(s)
new_ip=`dig example.com +short`

# add the ip(s) to the set
for ip in $new_ip
do
    sudo ipset add new_ips $ip
done

# finally swap the sets
sudo ipset swap dynamic_ips new_ips

# remove the old set, safer & saves some memory
sudo ipset destroy new_ips

我们可以看到,这是 100% 原子的,无需调整规则即可完成iptables,但这通常是不明智的。

笔记:

如果你非常确定域名解析为单个 IP 地址,那么您可以直接在命令ipset行上使用域名:

sudo ipset add dynamic_ips example.com

上述脚本解决的问题是,当查找该域名返回多个 IP 地址时,该ipset命令只会选择第一个 IP。

另外,我在这里展示了处理 IPv4 的命令。您还有另一组命令来处理 IPv6 IP 地址。请确保使用正确的命令集或根据需要同时处理两者。

例如,要创建正确的集合:

sudo ipset create dynamic_ip4 hash:ip family inet
sudo ipset create dynamic_ip6 hash:ip family inet6

您必须将 IPv6 添加到dynamic_ip6集合中。

有关集合的更多文档,请尝试man ipset


最后一句话:虽然封锁除你之外的所有 IP 非常安全,但一个好的黑客可以通过伪造数据包假装他的连接来自你的 IP 地址。因此,这是一种很好的保护,但你的服务器仍然很容易被渗透。另一个补充是使用端口敲击。 我有我自己的解决方案(文章中包含 iptables 规则)使用 ipload 工具进行设置我的 iplock 项目。混合使用您的 IP 和端口敲击,黑客几乎不可能访问您的服务器(当然,还有您的密钥……因此,这三种保护措施都难以破解)。

相关内容