有人可以建议一种在 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 和端口敲击,黑客几乎不可能访问您的服务器(当然,还有您的密钥……因此,这三种保护措施都难以破解)。