H3C NX54不关ipv6防火墙,允许外网访问内网

前言

NX54终于更新固件了,新版本支持配置关闭ipv6防火墙,但是,防火墙关闭,相对而言风险也就上来了。其实最好的办法是,在防火墙上稍微开一个小口就行了,也就是,只允许目标地址是你指定IP的数据通过,今天就大概说说如何最小风险去处理这件事情。主要有以下两个操作:

  1. ip6tables限制指定目标ip转发
  2. 关闭要访问的服务器的ssh访问,windows主机可忽略

限制只有访问你主机才能通过ipv6防火墙

nx54就是一个openwrt的魔改版本,所以防火墙是基于ip6tables的,简单说一下iptables,维护着一个规则链,所以要达到我们的预期,需要把允许的规则配置到前面。

具体操作

访问http://[ip]/debug.asp,向下拉,找到telnet管理,勾选启动telnet,点旁边应用,在命令行执行如下命令

1
2
3
4
5
telnet <路由ip> 15000
# 输入密码
<your password>
# <H3C_NX54>后输入 debugshell
debugshell

查看ip6tables的FORWARD配置,显示只有一项为delegate_forward,再看delegate_forward配置,包含5项,通过继续查看第一项forwarding_rule,发现这条配置其实是空的。

1
2
3
4
5
6
7
8
9
10
11
12
ip6tables -L FORWARD -v -n --line-numbers
# delegate_forward

ip6tables -L delegate_forward -v -n --line-numbers
# forwarding_rule
# ACCEPT
# zone_lan_forward
# zone_wan_forward
# reject

ip6tables -L forwarding_rule -v -n --line-numbers
# null

简单说一下上面的意思,所有的转发流量,走delegate_forward,而delegate_forward分为了5步,如果前四步没有命中,那么会进入第5步的拒绝策略,也就是all reject。我们要做的就是在reject前,将自己的ipv6添加到ACCEPT的规则。看了一眼forwarding_rule,是个空的。所以有两个选择:delegate_forward下第1个位置插入自定义Chain,或者直接加到forwarding_rule。以直接加到forwarding_rule中为准:

1
2
# 添加允许目标为[ip]的规则到 forwarding_rule
ip6tables -A forwarding_rule -d device_ipv6 -j ACCEPT

为什么要使用forwarding_rule,而不直接加在最外层呢?因为ip会变,我们说了是最小风险,所以当ip变更后,要删除旧的规则,这里如果有自定义Chain名称,可以很方便操作。因为forwarding_rule只包含你那一条,所以直接删除forwarding_rule里所有的配置项就可以了。

1
ip6tables -F forwarding_rule

如果你的forwarding_rule不为空(应该不会),我们在添加规则的时候,也可以直接创建一个新Chain,加在delegate_forward下,forwarding_rule旁边就行了,总之就是一句话,让你的规则在reject前命中。

1
2
3
4
5
6
7
8
9
10

# 最开始插入一条forwarding_rule_ip6
ip6tables -I delegate_forward -j forwarding_rule_ip6
# 或者使用 ip6tables -A forwarding_rule -j forwarding_rule_ip6

# 将自己的ip添加到自定义规则中
ip6tables -A forwarding_rule_ip6 -d device_ipv6 -j ACCEPT

# 清空自定义规则
ip6tables -F forwarding_rule_ip6

主机直接关闭ssh密码访问

我本来就是想做个文件服务器,linux系统,既然路由上iptables限制了受访IP,再在开发板上加一道安全机制,限制外网使用ipv6通过密码来的方式进行ssh访问,这样一来,必须有访问需求的机器的key手动添加到服务器上才行。

1
2
3
4
5
6
# /etc/ssh/sshd_config
# 针对所有 IPv6 地址的配置 添加到文件末尾
Match Address ::/0
PasswordAuthentication no

# sudo systemctl restart sshd

至于如何生成key添加到服务器,这里就不说了。

ip变更后

做完以上配置,其实你的ipv6防火墙其实依然是开启状态,只不过加了一条目标ip的数据允许通过的规则。通过以上配置,已经可以达到理想的安全效果:只允许文件服务器被外网访问,外网不能通过ssh密码登录。但是nx54有一个问题,只要重新连接ipv6地址就会变化,所以需要将ip6tables命令加入定时任务中。我写过一个python脚本,通过定时触发,如果发现ip变动就给我email发一封邮件告诉我最新ip,在python中再添加如下加入清空自定义规则,加入允许访问IP规则。注意如果你自己新建了Chain,以你的名称为准。我是直接使用forwarding_rule。

1
2
3
4
# 删除旧规则
ip6tables -F forwarding_rule
# 添加新的允许访问ip
ip6tables -A forwarding_rule -d device_ipv6 -j ACCEPT

具体流程如下:

  1. 使用python获取最新非temporary的ip6地址。这一步对系统有兼容性,可能各种方式不一样。
  2. 对比上次获取的ipv6地址,比较是否一致,不一致说明有变化,需要更新,保存供下次比较。
  3. 参考我前面的blog,永久开启telnet,这一步网上有和第2步结合的脚本,但是使用curl发送的请求,那url又臭又长,不如参考我的一步到位。
  4. 使用python发送telnet,连接路由,输入密码,debugshell。
  5. ip6tables -F forwarding_rule
  6. ip6tables -A forwarding_rule -d your_device_ipv6 -j ACCEPT
  7. 加入crontab -e,半小时执行一次

和朋友交流后,朋友说可以不采用email形式,钉钉、飞书这类办公软件有webhook,也就是当你ip变动后,你使用curl发一个网络请求,飞书就会给你发送消息。因为我基本不用飞书钉钉,所以就算了吧。当然了,也可以直接绑定域名,我其实已经做了AAAA解析了,但是懒得弄DDNS了(有个开源的程序叫DDNS-GO),因为我外网连接机器这个并不是一个刚需且密集的事件,所以,需要的时候改ip地址就行了。

最后,非常感谢您的阅读。