Openwrt 配置NAT6

在openwrt作为二级路由时一些情况下需要NAT6

NAT的缺点:
(1) NAT会增加延迟,因为要转换每个数据包包头的IP地址,自然要增加延迟.
(2) NAT会使某些要使用内嵌地址的应用不能正常工作.

1.准备工作

注意以下不是必要操作,如有luci界面自行略过。

固件是在lede官网下载的官方lede固件
LZ的设备是HG255D比较老,因此官网lede固件没有luci界面,需要自己安装,LZ先将路由器单独接入可以直接联网的网络,电脑使用网线接入HG255D,lede默认的dropbear开启了ssh端口22,我们使用xshell等终端连接到路由器
帐号密码root/admin
然后终端内输入命令

1
2
3
4
5
opkg update
opkg install luci
opkg install luci-i18n-base-zh-cn
opkg install luci-i18n-firewall-zh-cn
opkg install nano

这样luci界面就安装好了并且有了中文。

2.安装IPK包

将设备接入有提供IPv6的接口,
在luci界面里-接口-一栏设置好IPv4联网(pppoe或者其他),联网成功后,
然后使用ping ipv6.google.com查看是否可以ping通
可以通过则继续以下操作,此处默认是可以

安装本次nat的必要包

1
2
opkg install ip6tables
opkg install kmod-ipt-nat6

这两个包对内核要求还是蛮高的所以选择lede 其他的固件lz没有尝试

3.开始配置

使用终端nano、vi等命令修改也可以使用winscp工具打开
修改/etc/config/network文件,添加以下字段,若已存在字段仅地址不同,可以不用修改。或者改成你喜欢的前缀。

1
2
config globals 'globals'
option ula_prefix 'eeee:eeee:eeee::/48'

→等效于
在luci的web界面修改
接口-全局网络选项-IPv6 ULA 前缀,前缀可以不和lz一样可以自定义

4.配置DHCPv6

终端内使用nano、vi、winscp

修改/etc/config/dhcp文件,将config dhcp 'lan’那一栏修改为以下内容:

1
2
3
4
5
6
7
8
9
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv6 'server'
option ra 'server'
option ra_management '1'
option ra_default '1'

等效于
luci界面里打开
接口-lan-下方 DHCP服务器-ipv6设置
DHCPv6 服务 (DHCPv6-Service) 服务器模式
路由通告服务 (Router Advertisement-Service) 服务器模式
NDP 代理 (NDP-Proxy) 禁用
DHCPv6 模式 (DHCPv6-Mode) 无状态的 + 有状态的
总是通告默认路由(Always announce default Router) 勾选

5.添加防火墙脚本

修改/etc/firewall.user在文末添加
假设WAN对应的接口为eth0.2,不是eth0.2的,自行修改成你的wan口设备名,添加以下内容:

1
ip6tables -t nat -A POSTROUTING -o eth0.2 -j MASQUERADE

等效于在luci界面
网络-防火墙-自定义规则 添加这一行 保存应用

6.配置网关

在终端内使用

1
ip -6 route | grep default

查看当前IPv6默认路由
结果显示如下
default from (your ipv6) via (gateway) dev eth0.2 proto static metric 512

其中(gateway)括号里的 就是你网络状态下的网关
例如楼主这里显示
default from 2001:ebcd🔡:d:abcd via fe80::224e:71ff:bbbb:cccc dev eth0.2 proto static metric 512

那么其中的
fe80::224e:71ff:bbbb:cccc
就是当前网络的默认网关,这一步至关重要
我们需要将其添加到默认路由
终端里输入命令

1
route -A inet6 add default gw fe80::224e:71ff:bbbb:cccc dev eth0.2

至此配置方面就好了
接下来重启下服务使设置生效

1
2
/etc/init.d/firewall restart
/etc/init.d/network restart

注意:
如果是使用其他低内核的固件做如上的操作,
firewall那条命令的输出显示可能会提示什么ip6tables错误的 说明最开始安装的ip6tables不支持此固件的低内核 请换高版本内核使用此教程。network 重启会有短暂的断网 耐心等待网卡的DHCP。

两条命令结束后 电脑仍然无法打开ipv6的话 请重启电脑的网卡 具体操作网络和共享中心-更改适配器设置,右击禁用网卡,再启用网卡。

此时电脑就应该可以正常访问v6了。

7.添加开机自动加入IPv6路由

由于route -A inet6 add default gw 命令重启会失效所以我们需要建立一个脚本让路由器开机自动添加
具体操作
在/etc/hotplug.d/iface/目录下新建名字为 90-ipv6 的文件
修改内容为

1
2
3
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
route -A inet6 add default gw fe80::224e:71ff:bbbb:cccc dev eth0.2

注意:记得修改成自己的网关
然后给予可执行权限:

1
chmod +x 90-ipv6

至此开机启动也完成了。

8.ULA设置

在 网络-接口 中,将 IPv6 ULA 前缀 的第一个字母 f 改为 d

9.设置LAN口dhcp 。在ssh中输入以下命令:

1
2
3
uci set dhcp.lan.ra_default='1'

uci commit dhcp

10.新建NAT6服务 。在 /etc/init.d/ 目录下,新建一个 nat6 文件,文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/bin/sh /etc/rc.common
# NAT6 init script for OpenWrt // Depends on package: kmod-ipt-nat6

START=55

# Options
# -------

# Use temporary addresses (IPv6 privacy extensions) for outgoing connections? Yes: 1 / No: 0
PRIVACY=1

# Maximum number of attempts before this script will stop in case no IPv6 route is available
# This limits the execution time of the IPv6 route lookup to (MAX_TRIES+1)*(MAX_TRIES/2) seconds. The default (15) equals 120 seconds.
MAX_TRIES=15

# An initial delay (in seconds) helps to avoid looking for the IPv6 network too early. Ideally, the first probe is successful.
# This would be the case if the time passed between the system log messages "Probing IPv6 route" and "Setting up NAT6" is 1 second.
DELAY=10

# Logical interface name of outbound IPv6 connection
# There should be no need to modify this, unless you changed the default network interface names
# Edit by Vincent: I never changed my default network interface names, but still I have to change the WAN6_NAME to "wan" instead of "wan6"
WAN6_NAME="wan6"

# ---------------------------------------------------
# Options end here - no need to change anything below

boot() {
[ $DELAY -gt 0 ] && sleep $DELAY
logger -t NAT6 "Probing IPv6 route"
PROBE=0
COUNT=1
while [ $PROBE -eq 0 ]
do
if [ $COUNT -gt $MAX_TRIES ]
then
logger -t NAT6 "Fatal error: No IPv6 route found (reached retry limit)" && exit 1
fi
sleep $COUNT
COUNT=$((COUNT+1))
PROBE=$(route -A inet6 | grep -c '::/0')
done

logger -t NAT6 "Setting up NAT6"

WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.ifname")
if [ -z "$WAN6_INTERFACE" ] || [ ! -e "/sys/class/net/$WAN6_INTERFACE/" ] ; then
logger -t NAT6 "Fatal error: Lookup of $WAN6_NAME interface failed. Were the default interface names changed?" && exit 1
fi
WAN6_GATEWAY=$(route -A inet6 -e | grep "$WAN6_INTERFACE" | awk '/::\/0/{print $2; exit}')
if [ -z "$WAN6_GATEWAY" ] ; then
logger -t NAT6 "Fatal error: No IPv6 gateway for $WAN6_INTERFACE found" && exit 1
fi
LAN_ULA_PREFIX=$(uci get network.globals.ula_prefix)
if [ $(echo "$LAN_ULA_PREFIX" | grep -c -E "^([0-9a-fA-F]{4}):([0-9a-fA-F]{0,4}):") -ne 1 ] ; then
logger -t NAT6 "Fatal error: IPv6 ULA prefix $LAN_ULA_PREFIX seems invalid. Please verify that a prefix is set and valid." && exit 1
fi

ip6tables -t nat -I POSTROUTING -s "$LAN_ULA_PREFIX" -o "$WAN6_INTERFACE" -j MASQUERADE
if [ $? -eq 0 ] ; then
logger -t NAT6 "Added IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)"
else
logger -t NAT6 "Fatal error: Failed to add IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)" && exit 1
fi

route -A inet6 add 2000::/3 gw "$WAN6_GATEWAY" dev "$WAN6_INTERFACE"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Added $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
else
logger -t NAT6 "Error: Failed to add $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
fi

if [ $PRIVACY -eq 1 ] ; then
echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/accept_ra"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Accepting router advertisements on $WAN6_INTERFACE even if forwarding is enabled (required for temporary addresses)"
else
logger -t NAT6 "Error: Failed to change router advertisements accept policy on $WAN6_INTERFACE (required for temporary addresses)"
fi
echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/use_tempaddr"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Using temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
else
logger -t NAT6 "Error: Failed to enable temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
fi
fi

exit 0
}

11.启动NAT6服务 。命令如下:

1
2
chmod +x /etc/init.d/nat6
/etc/init.d/nat6 enable

12.修改 /etc/sysctl.conf 文件,添加以下内容(如果没有的话):

1
2
3
4
net.ipv6.conf.default.forwarding=2
net.ipv6.conf.all.forwarding=2
net.ipv6.conf.default.accept_ra=2
net.ipv6.conf.all.accept_ra=2

13.重启路由器,测试路由器下设备能否正常使用ipv6。如果还有问题可尝试在ssh输入以下命令(一般情况下可省略此步骤):

1
2
uci set firewall.@rule["$(uci show firewall | grep 'Allow-ICMPv6-Forward' | cut -d'[' -f2 | cut -d']' -f1)"].enabled='0'
uci commit firewall

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!