解决ip6tables开放端口后IPv6无法访问问题
问题描述
同事在各地市有多台带有IPv6公网地址的服务器,相互之间在做一些拉流和推流的测试,后来考虑到安全问题,想通过ip6tables做一些安全策略,防止完全暴露到公网上遭受攻击,可是按照IPv4的逻辑收敛好端口后,发现策略没有生效,在白名单内的机器也无法正常访问。
场景复现
复现环境信息
| 主机名称 | IPv6网段 | IPv6地址 | IPv6网关 |
|---|---|---|---|
| IPv6-0001 | 2408:8648:8700:0002:0000:0000:0000:0000/64 | 2408:8648:8700:2::2d2 | 2408:8648:8700:2::1 |
| IPv6-0002 | 2408:8648:7700:0005:0000:0000:0000:0000/64 | 2408:8648:7700:5::156 | 2408:8648:7700:5::1 |
IPv6-0001策略配置
清空策略
1 | ip6tables -F |
配置策略
1 | ip6tables -A INPUT -i lo -j ACCEPT |
IPv6-0002策略配置
清空策略
1 | ip6tables -F |
现象描述
在IPv6-0002上通过ssh命令登录IPv6-0001无法登录
1 | [root@ipv6-0002 ~]# ssh 2408:8648:8700:2::2d2 |
排查过程
首先确认防火墙策略是否配置有误,在IPv6-0001上执行ip6tables-save查看IPv6的防火墙策略如下
1 | # Generated by ip6tables-save v1.4.21 on Fri Nov 17 15:53:25 2023 |
可以看到INPUT链的默认策略为DROP,对进入lo接口的流量全部接受,只允许来自2408:8648:7700:5::/64段并且目标端口为22/tcp的流量进入,规则上没发现有什么问题。
为了进一步排查在IPv6-0001的INPUT链规则末尾加入以下策略,将不匹配任何规则被丢弃的数据包信息写入日志(默认为/var/log/messages)
1 | ip6tables -A INPUT -j LOG |
规则添加完成后,在IPv6-0001上执行tail -f /var/log/messages实时查看日志信息,然后在IPv6-0002上通过ssh命令尝试登录IPv6-0001,然后查看日志发现有ICMPv6协议中type类型为134、135类型的数据包被丢弃
1 | Nov 17 16:16:09 ipv6-0001 kernel: IN=eth0 OUT= MAC=33:33:ff:00:02:d2:fa:16:3e:de:c8:61:86:dd SRC=fe80:0000:0000:0000:f816:3eff:fede:c861 DST=ff02:0000:0000:0000:0000:0001:ff00:02d2 LEN=72 TC=0 HOPLIMIT=255 FLOWLBL=0 PROTO=ICMPv6 TYPE=135 CODE=0 |
搜索相关资料,134类型的为RA(Router Advertisement,路由器通告)报文,135类型的为NS(Neighbor Solicitation,邻居请求)报文。RA、NS报文均属于ICMPv6协议中的子协议NDP(neighbor Discovery protocol,邻居发现协议),用于替代IPv4的ARP和ICMP路由器发现功能。而NDP(neighbor Discovery protocol,邻居发现协议)是通过ICMPv6来承载的,ICMPv6是在网络层上,因此会被ip6tables给DROP掉。
说明
当主机或其他网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(即IPv6地址)。但是仅有IPv6地址是不够的,因为IPv6数据报文必须封装成帧才能通过物理网络发送,因此发送方还必须有接收方的链路层地址(MAC地址),所以需要一个从IPv6地址到链路层地址的映射,保证数据报文的传送能够顺利进行。而ND(Neighbor Discovery,邻居发现)就是用来实现网络层IPv6地址与链路层MAC地址之间的映射的,是以太网通信的基础。
解决方法
在IPv6-0001上添加以下规则,允许ip6tables通过NDP对应的ICMPv6报文即可。
1 | ip6tables -I INPUT -p icmpv6 --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT |