共計 5037 個字符,預計需要花費 13 分鐘才能閱讀完成。
以下是根據我查到資料(維基等)、詢問 AI 還有我自行理解的字詞,若有不對,請在最下面留言指正,謝謝!
注意!下面 docker 網路切分網段 僅實測過 Debian 12 系統 是全新機器能跑起來 不代表你機器能 100% 跑起來
IPv6 主要是為了解決 IPv4 位址枯竭問題,因為 IPv4 它只有 42.9 億個 IP 位置 現在上網人數遠遠大於 42.9 億,在 IPv6 還沒普及時候 IPv4 就要用多層 NAT 來解決。
IPv6 組成格式
首先 IPv6 是 128 bit 每 1 字元 =4 Bit
可使用位置是 0 -9 和 a -f 其中 0 最小,f 最大
AAAA:BBBB:CCCC:DDDD:EEEE:FFFF:GGGG:HHHH* 為了避免有些 ”新手“ 說啊 G 和 H 不合法 我只是在給你看格式而已
縮排時例如
AAAA:BBBB:CCCC:DDDD::1縮排時不能出現兩個:: 是非法字元 例如AAAA:BBBB:CCCC:DDDD::1::cfea
IPv6 網段
::1/128 是本地迴環地址 類似於 127.0.0.1
內網 ip-fe80
首先根據查到資料有 fe80::/10 和 fe80::/64 因為我本人不太清楚 我用 grok 來解釋
關於 fe80::/10
- 官方範圍是由 RFC 4291(IPv6 地址架構)定義的:fe80::/10。這意味著前 10 位元是固定的 1111 1110 10(十六進位為 fe80),總範圍從 fe80:: 到 febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff。
- 為什麼保留這麼大的 /10(2^118 個地址)?這是為了未來擴展或特殊用途,但實際上,目前的標準強制後續 54 位元必須為 0(即 fe80:0000:0000:0000::)。這讓有效的前綴變成 fe80::/64,而不是整個 /10 都隨便用。這樣設計是為了簡化實現和避免碎片化。
關於 fe80::/64
- 在實務上,鏈路本地地址總是使用 fe80::/64 作為前綴,後面接 64 位元的介面識別碼(Interface Identifier, IID)。IID 通常基於 MAC 地址轉換(EUI-64 格式),或用隱私擴展隨機生成。
- 例如,一個典型的地址可能是 fe80::abcd:1234:5678:90ef%eth0(%eth0 是範圍識別,用來指定介面)。
- 為什麼 /64?因為 IPv6 標準要求每個子網(包括鏈路本地)的前綴長度為 /64,這是為了支援自動配置(如 SLAAC)。每個物理鏈路都被視為一個 /64 子網,所以同一個鏈路上的所有設備都共享 fe80::/64 前綴,但用不同的 IID 區分。
fd7a
以 fd7a::/8(由 fc00::/ 7 切分)開頭的一組獨特本地 (Unique Local Address, ULA) IPv6 位址,通常保留給 VPN 服務如 Tailscale 內部使用,作為私有、非公開的網路層級位址,方便裝置在私有網域中相互識別,但無法路由到公共網際網路
2000::/3(公網 IPv6)
* 以下的內容都會用 2001 開頭作為演示
首先你在網路上會很少看到 /8 /16 不像 IPv4 一樣有些 ASN 會有 / 8 網段或者是 /16 網段 (以下解釋是 grok AI 搜尋網路得到的 錯誤請指正)因為
- 地址空間過於龐大,不需要:一個 /8 在 IPv6 中是 2^120 個地址,這比整個 IPv4 地址空間(2^32 ≈ 43 億)大 2^88 倍,遠超任何單個 ISP 或 ASN 的需求。即使是全球最大的 ISP,也只需 /32 就能服務數億用戶(例如,一個 /32 可分出 65,536 個 /48)。給更短的前綴會導致嚴重浪費。
- 防止路由表爆炸:IPv6 設計時吸取 IPv4 教訓(IPv4 的 /8 是大型塊,但導致路由碎片)。如果每個 ASN 都得 /8 或 /16,全球路由器需要處理更多細碎路由,增加負荷。政策強制使用較長前綴來強制聚合。
- 政策限制:RIRs 的政策(如 RIPE-738、ARIN NRPM)明確規定 ISP 的初始分配上限為 /29,最小 /32。更大塊(如 /20)只給極大型 ISP,且需證明需求。即使 ISP 成長,也會給額外的 /32 或擴大到 /29,而不是直接給 /16。沒有一個 RIR 會給單個 ASN /8,因為那相當於分配整個地址池的 1/256,毫無必要。
- 每個 ASN 不一定綁定單一前綴:ASN 可以持有多个 IPv6 前綴(例如多個 /32),但不是單一的巨塊。這允許靈活,但保持聚合。
路由聚合(或聚合廣播)
你為啥會看到你明明你得到 IPv6 網段是 2001:abcd:abcd:abcd::/64 但查到都是 2001:abcd::/32 因為使用路由聚合(或聚合廣播)是將多個小前綴合併成一個大前綴來公告(advertise),減少路由器的負擔。
詳細內容可去參考維基百科,有些內容就是從那裡抓來的:https://en.wikipedia.org/wiki/IPv6
網段切分
網段的切分計算公式
例如 /32 網段 我想要切成 /48 網段 帶入公式可知道
你切割 64 網段 分配給每個項目 / 機器 那個項目看是 /64 但實際路由邏輯是 /128 因為你如果直接 /128 他會找不到網關,就會和 fe80 一樣效果 直接斷網,因此極限就是 /112 網段,再下去可能就會有反效果
如果假設你有一個 /64 網段要切分成 /112
你不能像我自己以前這樣 直接2001:abcd:abcd:1::/112
展開得2001:abcd:abcd:0001:0000:0000:0000:0/112
因為你指定是 /112 網段 但實際上是 /64 網段 因為前四段是 64bit 就是 /64(2001:abcd:abcd:1::/64)
正確的做法是前七位都補字 得:2001:abcd:abcd:abcd:abcd:abcd:1::/112
我怕有些人一臉矇 我用 claude AI 讓他講解
錯誤寫法:2001:abcd:abcd:1::/112
│────────────┘
這只有 4 段 = 64 bit
展開後:2001:abcd:abcd:0001:0000:0000:0000::/112
│─────────────┘
後面全是 0,沒有實際內容
問題:你說是 /112,但實際上只定義了前 64 bit
→ 系統會認為這是 2001:abcd:abcd:1::/64(因為看到後 64 bit 全是 0)→ /112 的宣告無效!(雖然能創建網路成功但是你只要一創建容器就會報錯:Invalid subnet)實戰 • Docker 切分網段
注意新手不要嘗試 因為失敗概率大
假設我有一個網段是只有 /64 也就是2001:abcd:1234:57::/64 我想要讓單一網路的裡面容器支持公網 IPv6 地址,切分是 /112 2001:abcd:1234:57:ab:cd:e7f4::/112
docker network create --ipv6 \
--subnet=2001:abcd:1234:57:ab:cd:e7f4::/112 \
-o "com.docker.network.driver.mtu=1480" \
-o com.docker.network.bridge.enable_ip_masquerade=false \(可選 讓容器 IPv6 變成公網的,不用經過宿主機 NAT)your_net_name它會自動將 2001:abcd:1234:57:ab:cd:e7f4:1 設置為網關
再來就是例如
docker run -itd \
--name nginx \
--network your_net_name \
--ip6 2001:abcd:1234:57:ab:cd:e7f4:1234 \\(可選,但你需要自行查看 ipv6 通常都會是2001:abcd:1234:57:ab:cd:e7f4:2 如果你沒有其它容器的話)nginx此時一定要調整 iptables 可以開著預設 docker 自動配置防火牆
插入這兩段 允許你網段你通 DOCKER-USER 鏈不會被 docker 自動配置吃掉
ip6tables -I DOCKER-USER 1 -d 2001:abcd:1234:57:ab:cd:e7f4::/112 -j ACCEPT
ip6tables -I DOCKER-USER 1 -s 2001:abcd:1234:57:ab:cd:e7f4::/112 -j ACCEPT
重點你可能上不了網 因為 ip6tables -t raw -S 你會看到
-P PREROUTING ACCEPT
-P OUTPUT ACCEPT
-A PREROUTING -d
2001:abcd:1234:57:ab:cd:e7f4:1234/128 ! -i br-f81fae428984 -j DROP不用刪除 -A PREROUTING -d .... ! -i ... -j DROP 直接 插入
ip6tables -t raw -I PREROUTING -d 2001:abcd:1234:57:ab:cd:e7f4::/112 -i 網卡(通常是 eth0 使用 ip a 查看)-j ACCEPT這個你不做就永遠不會通 ( 隧道的我是測試過 可以不用配置也能用 僅限 he.net)
cat <<EOF > /etc/sysctl.conf
# 全域轉發與代理
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.proxy_ndp=1
net.ipv6.conf.all.accept_ra = 2
# 預設新網卡自動開啟 (包含未來建立的網橋)
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.default.proxy_ndp=1
# 針對目前的特定網卡 (請根據你的 ip addr 修改)
net.ipv6.conf.eth0.forwarding=1
net.ipv6.conf.eth0.proxy_ndp=1
EOF
sysctl -p* eth0 是網卡名 如果和這個不一樣 自行調整
再來為了避免你重啟系統於是我們要安裝 ndppd(隧道的不用做,因為用不到)
apt-get install ndppd -y # Debian/Ubuntu
# 或
yum install ndppd -y # CentOS/RHEL再來
cat <<EOF > /etc/ndppd.conf
proxy eth0 {
rule 2001:abcd:1234:57:ab:cd:e7f4::/112 {auto}
}
EOF
systemctl enable --now ndppd* eth0 是網卡名 如果和這個不一樣 自行調整
如果你發現欸?不通那你可以試
cat <<EOF > /etc/ndppd.conf
proxy eth0 {
rule 2001:abcd:1234:57:ab:cd:e7f4::/112 {static}
}
EOF
systemctl restart ndppd通常 icmp 一定通而且能連上網路
隧道的路由
如果你發現 ip -6 route | grep br- 沒有你的網卡(iface)那請添加路由
# ip -6 route | grep br-
2001:abcd:1234:57:ab:cd:e7f4::/112 dev br-2ea07b6a1aec proto kernel metric 256 linkdown pref mediumip -6 route add <subnet> dev <iface>subnet 是網段 iface 就是使用 ip a 看你 subnet 所在網卡例如 ip a
6: br-2ea07b6a1aec: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1480 qdisc noqueue state DOWN group default
link/ether 56:0d:bd:58:56:fa brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-2ea07b6a1aec
valid_lft forever preferred_lft forever
inet6 2001:abcd:1234:57:ab:cd:e7f4::/112 scope global nodad8
valid_lft forever preferred_lft forever
inet6 fe80::540d:bdff:fe58:56fa/64 scope link
valid_lft forever preferred_lft forever其中 br-…. 就是網卡名
防火牆
此時要放開 ipv4 的 41 請求 否則你隧道不會通
iptables -I INPUT -p 41 -j ACCEPT探索更多來自 GEBU8F — 阿蒲的網站 的內容
訂閱即可透過電子郵件收到最新文章。
禁止人身攻擊,請理性發言。