快速介绍
ipv6地址共 128 位(二进制),转化成16进制共32位, 每4位分成1组, 用分号隔开, 共8组
如果有多个零, 可以省略成 ::
, ipv6地址中只能有一个 ::
# 同一组地址
fddd:f00d:cafe:0000:0000:0000:0000:0001
fddd:f00d:cafe:0:0:0:0:1
fddd:f00d:cafe::1
前三组是路由前缀
第48-64位(第四个小组)能切割作为不同子网, 和前三组加起来就是子网前缀
后四组64位是给子网内设备分配地址的
2开头的是公网地址, f开头的是内网地址
3大运营商IPv6地址前缀:
- 中国移动:2409:8000::/20
- 中国电信:240e::/20
- 中国联通:2408:8000::/20
ifconfig
带 temporary
是临时地址, 为了安全,
检测v6的网站
获取ipv4 url
http://checkip.dyndns.com
http://4.ipw.cn
获取ipv6 url
http://checkipv6.dyndns.com/
http://6.ipw.cn/
检测优先级
https://ipw.cn/
生成ipv6前缀
https://cd34.com/rfc4193/
获取ipv6-pd
之前能够获取到pd地址, 换了路由后获取不到, 只下发了 /64 的地址, 无法再分配
方案1: 实测有效
添加防火墙规则,允许 ipv6 udp 456 端口和 ipv6 的 igmp 协议进入本设备
方案2:
vim /etc/hotplug.d/iface/99-ipv6
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
[ "$INTERFACE" = wan ] || exit 0
#sleep 18s 从我的粗略测试来看,有没有这一行都能正常获得我们想要的效果
uci set network.globals.ula_prefix="$(ip -6 route show | grep default | sed -e 's/^.*from //g' | sed 's/ via.*$//g')"
uci commit network
/sbin/ifup lan
chmod a+x /etc/hotplug.d/iface/99-ipv6
重启
# 如果无法升级版本,可以利用策略路由,把来自 WAN 的 IPv6 无脑(删掉 路由到 LAN:
mkdir -p /etc/ppp/ip-up.d
vi /etc/ppp/ip-up.d/00-pppoe-ipv6.sh
# 脚本内容
#!/bin/sh
[ "$1" = "pppoe-wan" ] || exit 0
ip -6 route add default dev br-lan table 6
ip -6 rule add iif $1 lookup 6
# 记得加可执行权限 chmod +x /etc/ppp/ip-up.d/00-pppoe-ipv6.sh
方案3:
vi /etc/hotplug.d/iface/99-ipv6
===
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
[ "$INTERFACE" = wan ] || exit 0
uci set network.globals.ula_prefix="$(ip -6 route show | grep default | sed -e 's/^.*from //g' | sed 's/ via.*$//g')"
uci commit network
/sbin/ifup lan
===
chmod a+x /etc/hotplug.d/iface/99-ipv6
reboot
设置ipv6
教程: https://post.smzdm.com/p/awzodmpp/?sort_tab=hot%2525252F
添加wan接口
- 添加新的接口, 名称填 wwan6 (原来ipv4的接口是wwan), 协议选 dhcpv6, 设备选 接口别名@wwan
- 请求ipv6地址选 try, 长度选自动
- 高级设置, 委托前缀打勾, 分配长度禁用
- 防火墙选 wan
- dhcp服务器不开启
- 最终获取接口能够获取到v6地址, 如图, 关键是ipv6-pd, :/62(反正小于等于64) 这个地址段, 可以供我们分配
修改lan接口
高级设置
- 委托前缀不需要, 因为设备都在路由下, 不需要再切割地址
- 分配长度选64
- 分配提示不需要(自定义子网的最后一位地址)
- 后缀填
::1
3. 最终如图所示
dhcp服务器
- ipv6设置, ra模式选服务器, dhcpv6选服务器(也有的说开了slaac,就不要用dhcpv6, 让设备自己注册), ndp禁用
- ipv6ra 设置, 启用slaac, ra标记受管配置, 其他配置
如果没有下发pd
- 修改wwan6接口, 配置DHCP服务器
- 勾选忽略此接口,并且在IPv6设置里勾选 指定的主接口,RA服务、DHCPv6服务、NDP代理都选择中继模式, 学习路由
- 修改lan, DHCP服务器->IPv6设置里同样全部选择中继模式, 学习路由. 不勾选指定主接口
ddns
使用 ddns 插件
教程: https://blog.upx8.com/3110
缺点: 似乎不能批量更新域名, 改为 ddns-go
需要安装的插件 luci-i18n-ddns-zh-cn curl ddns-scripts-cloudflare
使用ddns-go
- 用上面的url, 测试自己是否有ipv6
- 到cloudflare添加
AAAA
记录
- 安装插件
luci-i18n-ddns-go-zh-cn
- 先改下端口, 不要用默认的
[::]:1
- dns选择 cloudflare, 需要到 cloudflare 设置 token
创建令牌->编辑区域 DNS (使用模板)-->区域资源选择所有区域
ipv4访问ipv6
利用 cloudflare的cdn, 要开启小云朵
ipv4 --> cloudflare CDN --> ipv6
https://mymuwu.net/?p=489
# http 能走cdn的端口
80 8080 8880 2052 2082 2086 2095
# https 能走cdn的端口
443 2053 2083 2087 2096 8443
路由器设置
- 防火墙放行对应的ipv6端口
网络 -- 防火墙 -- 通信规则
- 端口转发
安装 luci-i18n-socat-zh-cn
添加端口转发, 把ipv6转发到ipv4地址的端口
安装完第一次添加状态是x, 重启下 socat 和 firewall 服务
也可以转发到局域网设备的端口, 这样局域网设备虽然也有ipv6, 但不用ddns, 只需要路由转发就够了
- 这样访问时还需要在域名后添加 2052 端口, 利用 cloudflare 的规则可以自动添加
规则 --> Origin Rules --> 创建规则 --> 自定义筛选表达式 --> 主机名等于 --> 重写端口到2052
cloudflare ddns 脚本
https://appscross.com/2023/08/url-redirect-record/
curl --request GET \
--url https://api.cloudflare.com/client/v4/zones/{ZoneID}/dns_records \
--header 'Content-Type: application/json' \
--header 'X-Auth-Email: {Email}' \
--header 'Authorization: Bearer {Token}' \
| python3 -m json.tool
#!/bin/sh
cat << EOF > /bin/cf-ddns6.sh
#!/bin/sh
sleep 10
IP6=\$(ip -6 addr show dev {interface} | awk '/global/ {print \$2}' | awk -F "/" '{print \$1}')
if [ -z "\$IP6" ]; then
exit
fi
response=\$(curl -s -o /dev/null -w %{http_code} --request PUT \
--url "https://api.cloudflare.com/client/v4/zones/{ZoneID}/dns_records/{RecordID}" \
--header "Content-Type: application/json" \
--header "X-Auth-Email: {Email}" \
--header "Authorization: Bearer {Token}" \
--data '{
"type": "AAAA",
"name": "{Fullname}",
"content": "'"\$IP6"'",
"proxied": false
}')
if [ "\$response" = "200" ]; then
echo "DNS记录更新成功"
else
echo "DNS记录更新失败,HTTP状态码: \$response"
fi
EOF
chmod +x /bin/cf-ddns6.sh
- {interface}: 替换为监测的网络接口,例如 eth0。
- {ZoneID}: 替换为 Cloudflare 域名所在的区域 ID。
- {RecordID}: 替换为要更新的 DNS 记录的 ID。
- {Email}: 替换为你的 Cloudflare 帐户的注册电子邮件地址。
- {Token}: 替换为你获取的 Cloudflare API Token。
- {Fullname}: 替换为要更新的完整主机域名,如ai.xxxx.eu.org
curl -sSL -o ddns6.sh https://raw.githubusercontent.com/evanawn65/appscross/main/generate-cf-ddns6.sh && chmod +x ./ddns6.sh && ./ddns6.sh &&vim /bin/cf-ddns6.sh
sudo nano /etc/NetworkManager/dispatcher.d/99-ip6-address-change
#!/bin/bash
IFACE="$1"
REASON="$2"
if [ "$IFACE" = "eth0" ] && [ "$REASON" = "dhcp6-change" ]; then
# 调用 DNS 记录更新脚本
/bin/cf-ddns6.sh
fi
# 赋权、属组、属主设为root
curl -sSL -o /etc/NetworkManager/dispatcher.d/99-ip6-address-change https://github.com/evanawn65/appscross/raw/main/99-ip6-address-change
#!/bin/bash
# 需要jq
#LEDE/Openwrt may need install ca-bundle curl(opkg install ca-bundle curl)
#Add you custom record to the CloudFlare first.
#Your sub domain
SUB_DOMAIN="webdav.shiyitopo.tech"
#dash --> example.com --> Overview --> Zone ID:
#https://dash.cloudflare.com/_your_account_id_/example.com
ZONE_ID=""
#API Tokens
#https://dash.cloudflare.com/profile/api-tokens
#Manage access and permissions for your accounts, sites, and products
#example.com- Zone:Read, DNS:Edit
TOKEN_ID=""
#The path of jq binaries . Download from https://stedolan.github.io/jq/download/
#If the system has installed jq. Just typed jq.
#If you custom a special binary. Just type the path of jq
JQ_PATH="/root/jq-linux64"
if [ -n "$DNS_ZONE_ID" ]; then
echo "The user has not configure the the ZONE ID "
exit 1
fi
echo "Your dns zone id is: $ZONE_ID"
jsonResult=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${TOKEN_ID}" \
-H "Content-Type: application/json")
curlResult=$(echo $jsonResult | $JQ_PATH -r .success)
if [ "$curlResult" = true ]; then
echo "Get dns record success."
else
echo "Get dns record fail.$jsonResult"
exit 1
fi
recordSize=$(echo $jsonResult | $JQ_PATH .result | $JQ_PATH length)
echo "Total found $recordSize record"
index=0
while [ $index -lt $recordSize ]; do
tResult=$(echo $jsonResult | $JQ_PATH -r .result[$index])
tmpDomain=$(echo $tResult | $JQ_PATH -r .name)
type=$(echo $tResult | $JQ_PATH -r .type)
if [ "$tmpDomain"x = "$SUB_DOMAIN"x ]; then
if [ "AAAA"x = "$type"x ]; then
echo "Found AAAA domain:$tmpDomain"
identifier_v6=$(echo $tResult | $JQ_PATH -r .id)
elif [ "A"x = "$type"x ]; then
echo "Found A domain:$tmpDomain"
identifier_v4=$(echo $tResult | $JQ_PATH -r .id)
else
echo "Please add the A or AAAA record manually first."
fi
fi
index=$(expr $index + 1)
done
if [ -z "$identifier_v4" ] && [ -z "$identifier_v6" ]; then
echo "Get '$SUB_DOMAIN' identifier failed. Please add the A or AAAA record manually first."
exit 1
else
echo "Get '$SUB_DOMAIN' identifier success. [A] identifier:$identifier_v4 [AAAA] identifier:$identifier_v6"
fi
if [ -z "$identifier_v4" ]; then
echo "IPv4 address are not required."
else
#IP=$(curl -s http://members.3322.org/dyndns/getip)
IP=$(curl -s http://ip.3322.net/)
regex='\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
matchIP=$(echo $IP | grep -E $regex)
if [ -n "$matchIP" ]; then
echo "[$IP] IPv4 matches..."
jsonResult=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${identifier_v4}" \
-H "Authorization: Bearer ${TOKEN_ID}" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"'${SUB_DOMAIN}'","content":"'${IP}'","ttl":1,"proxied":false}')
curlResult=$(echo $jsonResult | $JQ_PATH -r .success)
if [ "$curlResult" = true ]; then
echo "Update IPv4 dns record success."
else
echo "Update IPv4 dns record fail."
fi
else
echo "[$IP]IPv4 doesn't match!"
fi
fi
if [ -z "$identifier_v6" ]; then
echo "IPv6 addresses are not required."
else
#IP=$(curl -6 ip.sb)
IP=$(ip addr show dev ens18|sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'|grep 2409|head -1)
regex='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$'
matchIP=$(echo $IP | grep -E $regex)
if [ -n "$matchIP" ]; then
echo "[$IP] IPv6 matches..."
echo "Update IPv6 ..."
jsonResult=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${identifier_v6}" \
-H "Authorization: Bearer ${TOKEN_ID}" \
-H "Content-Type: application/json" \
--data '{"type":"AAAA","name":"'${SUB_DOMAIN}'","content":"'${IP}'","ttl":1,"proxied":true}')
curlResult=$(echo $jsonResult | $JQ_PATH -r .success)
if [ "$curlResult" = true ]; then
echo "Update IPv6 dns record success."
else
echo "Update IPv6 dns record fail."
fi
else
echo "[$IP] IPv6 doesn't match!"
fi
fi
ipv4优先
vim /etc/gai.conf
precedence ::ffff:0:0/96 200
配置Openwrt无线中继随身WIFI,IPv6NAT
https://post.smzdm.com/p/ad9qkz9k/
https://zhuanlan.zhihu.com/p/492774540?utm_id=0
https://gitlab.com/XDOSC/WIFI/-/wikis/tips/ipv-6-router
要下载的那个脚本
#!/bin/sh /etc/rc.common
# NAT6 init script for OpenWrt // Depends on package: kmod-ipt-nat6
# edited by Sad Pencil at 2020-02-09
# replace route command with ip command to solve issues on new OpenWRT
# edited by Sad Pencil at 2021-11-29
# update line WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.device" || uci get "network.$WAN6_NAME.ifname")
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=5
# 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
WAN6_INTERFACE=eth1
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=$(ip -6 route | grep -i '^default.*via' | grep -i -F "dev $WAN6_INTERFACE" | grep -i -o 'via.*' | wc -l)
done
logger -t NAT6 "Setting up NAT6"
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="2001:da8:xxxx:xxxx::1"
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
ip -6 route add 2000::/3 via "$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
}