配置iptables限制用户仅访问维基百科后所有访问被阻断的问题求助
配置iptables限制用户仅访问维基百科后所有访问被阻断的问题求助
我执行了以下iptables规则:
iptables -I OUTPUT -m owner --uid-owner kids -d www.wikipedia.org -p tcp --dport 443 -j ACCEPT iptables -I OUTPUT -m owner --uid-owner kids -d www.wikipedia.org -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -m owner --uid-owner kids -j REJECTip6tables也做了同样的配置。
现在查看iptables规则:
iptables -S -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A OUTPUT -d 208.80.154.224/32 -p tcp -m owner --uid-owner 1001 -m tcp --dport 80 -j ACCEPT -A OUTPUT -d 208.80.154.224/32 -p tcp -m owner --uid-owner 1001 -m tcp --dport 443 -j ACCEPT -A OUTPUT -m owner --uid-owner 1001 -j REJECT --reject-with icmp-port-unreachable但现在所有访问都被阻断了,包括维基百科。是不是我还需要允许访问其他网站?
问题原因分析
你遇到的问题主要有两个核心原因:
- DNS请求被阻断:要访问
www.wikipedia.org,首先得通过DNS把域名解析成IP地址,但你的规则完全没允许kids用户发起DNS请求(UDP/TCP 53端口),导致域名解析失败,自然连维基百科也访问不了。 - 维基百科IP不唯一:你执行规则时,
www.wikipedia.org被解析成了208.80.154.224,但维基百科有多个IP地址,当DNS解析到其他IP时,你的规则没有允许这些IP,请求就会被REJECT。
解决方案
步骤1:允许DNS请求
先添加规则允许kids用户访问DNS服务器的53端口(UDP是常规DNS查询,TCP用于大尺寸DNS响应,建议都加上):
# 允许UDP DNS请求 iptables -I OUTPUT -m owner --uid-owner kids -p udp --dport 53 -j ACCEPT # 允许TCP DNS请求 iptables -I OUTPUT -m owner --uid-owner kids -p tcp --dport 53 -j ACCEPT # ip6tables同步添加对应规则 ip6tables -I OUTPUT -m owner --uid-owner kids -p udp --dport 53 -j ACCEPT ip6tables -I OUTPUT -m owner --uid-owner kids -p tcp --dport 53 -j ACCEPT
步骤2:适配维基百科的多IP问题
因为维基百科的IP会变化且有多个,直接指定单个IP不可靠,推荐用ipset来动态维护维基百科的IP列表:
- 创建一个ipset集合:
ipset create wikipedia hash:ip
- 批量获取维基百科的IP并添加到集合:
dig +short www.wikipedia.org | while read ip; do ipset add wikipedia $ip; done
- 替换原有的单IP规则,改为匹配ipset集合:
# 删除旧的单IP规则 iptables -D OUTPUT -d 208.80.154.224/32 -p tcp -m owner --uid-owner 1001 -m tcp --dport 80 -j ACCEPT iptables -D OUTPUT -d 208.80.154.224/32 -p tcp -m owner --uid-owner 1001 -m tcp --dport 443 -j ACCEPT # 添加新的集合匹配规则 iptables -I OUTPUT -m owner --uid-owner kids -p tcp --dport 80 -m set --match-set wikipedia dst -j ACCEPT iptables -I OUTPUT -m owner --uid-owner kids -p tcp --dport 443 -m set --match-set wikipedia dst -j ACCEPT
- 设置定时任务定期更新IP(避免IP变化导致访问失败):
# 编辑crontab crontab -e # 添加一行,每天凌晨更新一次 0 0 * * * dig +short www.wikipedia.org | while read ip; do ipset add wikipedia $ip 2>/dev/null; done
备选方案(无需ipset)
如果不想用ipset,可以通过WHOIS查询维基百科的IP段,直接允许访问整个IP段,但这种方法灵活性差,IP段变化时需要手动更新规则。
验证配置
切换到kids用户测试访问:
su - kids curl -I https://www.wikipedia.org
如果返回正常的HTTP响应头,说明配置生效了。
备注:内容来源于stack exchange,提问作者Manu
相关产品推荐
相关产品推荐

