久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

閑談IPv6...

 supercodec 2021-04-30

正則安安每晚每隔三小時必然哭鬧,我索性也就不睡了,,反正也睡不好,,起來泡茶,喝酒,,作文,。

浙江溫州皮鞋?濕,下雨??進水不會胖,!

杭州,,外面依然是寒雨夜,屋里也沒開空調,,我穿個夏天的短袖,,旁邊放一杯熱茶,喝完了還有昨晚實在喝不下去的漢拿山燒酒,,再喝完還有上周菜市場買的米酒…作此文一篇,。


在我們check IPv6的基本特征列表時,總是可以看到IPv6對Anycast的支持,。說實話,,對于很多人而言,,這是個比較陌生的概念,對于希望看看Anycast到底是什么樣子的人而言,,甚至在網上很難搜到關于 如何配置Anycast 的資源,。這是比較令人遺憾的。

拋開概念,,那么本文嘗試從不同的角度來針對Anycast探究一番,。


IPv4年代的Anycast

說起Anycast,并不是在IPv6標準中突然出現的概念,,一個概念怎么可能突然出現,?不可能的。

早在很久很久以前,,業(yè)界就針對IPv4提出了Anycast的說法,,只不過相對而言,IPv6在操作上將其標準化了而已,,如果說IPv4年代的Anycast標準只是 建議 ,,那么IPv6的Anycast就是規(guī)定了些許 MUSTMAY,。

建議閱讀:
RFC1546-Host Anycasting Servicehttps://tools./html/rfc1546
RFC3513:IPv6 Addressing Architecturehttps://tools./html/rfc3513#section-2.6

那么,,到底如何理解Anycast?


本質上,, Anycast就是將同一個IP地址配置在不同的主機網卡上,,然后利用各種選路機制欺騙源主機的一種通信方式。

什么,?同一個IP地址配置在不同的主機上,,這不是地址沖突了嗎?我們記得在初學網絡基礎的時候,,教程上就講過 IP地址不能沖突,! 現在為什么IP沖突變成了一種通信方式了呢?真是只許州官放火,,不許百姓點燈?。?/p>

其實不然,,我倒是覺得Anycast是內功深到一定程度,,自然而然的一個想法。我們簡單地從路由說起,。

我們知道,,IP地址存在的目的就是為了指揮路由器選路,最終將數據包路由到目的地,,那么IP地址沖突的結果是什么,?

IP地址沖突不是問題,,路由沖突才是!,!
IP地址沖突只有導致路由器的路由沖突(be confusing)的時候才有問題,。

比如路由器R上配置的下面的兩條路由:

1.1.1.1 nexthop 2.2.2.2 dev e2
1.1.1.1 nexthop 3.3.3.3 dev e3

請問一個去往目的地1.1.1.1的數據包到達路由器R之后到底是從e2走呢,還是從e3走呢,?這就是問題,。但是同樣的路由,加一個約束就不會有問題:

1.1.1.1 nexthop 2.2.2.2 dev e2 metric 100
1.1.1.1 nexthop 3.3.3.3 dev e3 metric 10

路由器會毫不猶豫地將去往1.1.1.1的數據包從e3發(fā)出,!

對于上述的兩條路由,,你說是IP地址沖突嗎?不,!并不是,。

互聯網本身就是一個互相網狀連通的連通圖,到達同一個目的地的路徑不止一條,,對于路由器R而言,,它只管選路,逐跳轉發(fā)數據包,,它并不關注1.1.1.1這個目標地址到底在哪里,。

好了,現在我們知道只要路由不沖突,,就沒有問題,,數據包總是可以特定的路徑,逐跳被轉發(fā),,最終到達目的地?,F在,我們看一下這條路是如何形成的,,或者說路由器R是怎么知道到達1.1.1.1有兩條路可走的。

由于這只是一篇散文,,并不是技術文檔,,所以我并不想引入BGP,AS這些概念,,姑且把全球的互聯網看作是一張如下圖所示的連通圖:
在這里插入圖片描述
然后在這張圖標識的網絡開始工作時,,各個節(jié)點開始彼此交換自己攜帶的子網信息,我們可以將其理解為 路由通告,。顯然路由器節(jié)點P向上游路由器R0通告了子網1.1.1.0/24,,意思就是說, “嗨,,R0鄰居兄弟,,如果有到達1.1.1.0/24的包,,請交給我” ,同樣的信息,,路由器P也會告訴它的所有其它鄰居,,然后路由器R0回復路由器P,放心吧,,我知道了,,我已經配置上了1.1.1.0/24 nexthop 4.4.4.4 dev e0,并且我也已經將這個消息轉給了我的所有鄰居,,放心吧,,它們如果有到達你那里1.1.1.0/24的包,會先交給我的…

就這樣,,子網信息,,路由信息在整張網上彼此交換,傳播,,最終在每一臺路由器上形成了穩(wěn)定的路由表:
在這里插入圖片描述
請注意,,A會在兩個接口同時收到關于1.1.1.0/24的通告,這并不會造成路由沖突:

  • 常規(guī)路由協議以及SPF算法均有避環(huán)的措施,;
  • 有意為之的環(huán)被視為備份路由,,由Metric做優(yōu)先級取舍或者由ECMP管理。

如果說在這張網中有A和C需要訪問1.1.1.1,,那么很顯然,,路徑如下:
在這里插入圖片描述
非常好,道路是通達的,,但是并不完美,!Why?

這會造成路由器R1和路由器P之間的鏈路異常擁堵,,為什么R0不能分擔一部分流量呢,?

嗯,我能想到的,,TCP/IP標準化協會的那幫人難道能想不到,?這就是ECMP的由來。再后來,,干脆來個SDN全局統一分發(fā)好了…但是這和Anycast沒有半毛錢的關系,,所以就此打住,我們來看看另外一種引出Anycast的解法,。

試想,, 如果B節(jié)點也通告1.1.1.0/24的路由會怎樣?

按照前面的路子,我們知道,,B和P均通告相同的路由,,這會造成圖上所有路由器均會收到來自B和P關于1.1.1.0/24的通告,按照上面的兩個基本原則:

  • 常規(guī)路由協議以及SPF算法均有避環(huán)的措施,;
  • 有意為之的環(huán)被視為備份路由,,由Metric做優(yōu)先級取舍或者由ECMP管理。

你猜怎么著,?最終成了下面的樣子了:
在這里插入圖片描述

是不是很像在世界互聯網上部署了一個天然的負載均衡設施?。∈堑?!這就是所有的 IP地址沖突導致的結果,! 這就是 Anycast

其精髓就是: 在路由器看來,,它們并不知道不同指向的下一跳最終將數據包導向不同的目的地,,它們只是認為這只是通往同一個目的地的不同路徑罷了! 簡單點說,, Anycast之所以得以部署和實現,,就是利用了IP協議逐跳尋址的特性!

事實上,,Anycast的結果是,,相同的IP地址位于不同的主機,因此,,它的弊端也是顯而易見的,。

由于 逐跳的路由收斂端到端的五元組連接 之間并沒有同步,因此Anycast并不適合基于端到端連接的TCP應用,。

TCP并沒有廣域范圍的連接遷移機制,,因此如果路由重新收斂,將會導致連接斷開,!比如上述的例子,,如果A到B之間的線路擁塞或者說斷開,那么路由會重新收斂到A-R-R1-P這條路徑,,A和B的1.1.1.0/24子網的主機之間的TCP連接將會斷開,,這并不是人們所期望的。

因此,,上述描述中的Anycast只適合于一來一回兩個包的oneshot式的交互通信,比如DNS,!

是的,,DNS就是這么部署的,比如我們經常使用的Google DNS 8.8.8.8,它實際上就是Anycast部署在世界不同地方的多臺主機,,地址全部都是8.8.8.8,!

請使勁閱讀:https://developers.google.com/speed/public-dns/faq

然后去深擼這個站點,溯源:https://bgp.
在這里插入圖片描述

至此,,我覺得關于Anycast的概念,,已經大致陳述清楚了。

下面是IPv6的世界,。我們跟蹤問題本身以及其解法,,跟著RFC來梳理IPv6 Anycast的來龍去脈,其實一切都很清晰,。


IPv6的Anycast

重看Anycast在IPv4上的問題,,我們知道, 把同一個IP地址配置在不同的主機上,,這確實是不妥的,,比如占據互聯網流量頭把交椅的TCP應用就不適合, 既然無法讓主子心安理得的承認,,那索性在Anycast標準化中就不要這么做就是了,。

但是,只要Anycast不是部署在端節(jié)點,,而是部署在路徑節(jié)點,,比如路由器上,那就是妥妥的,。逐跳尋址原則最終導致Anycast部署在路由器上之后,,會自然而然地實現ECMP,即多條路徑分擔同樣的端到端通信,。

在繼續(xù)下去之前,,這里先說一個觀點。那就是 端到端通信多路分擔這種機制對TCP是不好的,!

又TMD的是TCP,,是的,這里,,我覺得這不是逐跳尋址的問題,,這根本就是TCP的缺陷!缺陷,!缺陷,!

TCP要求在協議層面而不是應用層面按序到達,這就要求所有的字節(jié)最好是一路上順序地排隊前進,,而多路徑會影響順序同步性,,導致亂序,。TCP的字節(jié)按序到達這個約束會惡化流量高峰期的鏈路擁塞。

由此而得到的另一個Trick就是Flowlet,!它大大增加了端到端擁塞控制的復雜度,。
然而我們看看QUIC,它就并沒有要求嚴格的字節(jié)按序到達,,而是基于窗口的按序到達,,這就使得QUIC可以大大利用多路徑分擔帶來的收益。

其實對于TCP而言,,不光是鏈路最好不要多路徑,,甚至在路由器,交換機這種中間節(jié)點,,多CPU,,多處理卡也不能負載均衡分擔同一條TCP流的不同數據包!

有了TCP,,幾乎所有的負載均衡都得按照流的粒度進行,。
TCP真是太惡心了!

好了,,我們先不管TCP了,,任它腐爛吧!


IPv6對Anycast進行了標準化,,首先在RFC3513中,,它對Anycast提出了兩點約束:

o An anycast address must not be used as the source address of an
IPv6 packet.


o An anycast address must not be assigned to an IPv6 host, that is,
it may be assigned to an IPv6 router only.

有了這兩點約束,我們可以知道: 在IPv6中,,Anycast不是用來通信的,,而是用來尋址的。

緊接著,,RFC3513要求 所有的路由器的所有接口 都必須配置一個 必選的Anycast地址:

2.6.1 Required Anycast Address

The Subnet-Router anycast address is predefined. Its format is as
follows:

| n bits | 128-n bits |
±-----------------------------------------------±---------------+
| subnet prefix | 00000000000000 |
±-----------------------------------------------±---------------+

The “subnet prefix” in an anycast address is the prefix which
identifies a specific link. This anycast address is syntactically
the same as a unicast address for an interface on the link with the
interface identifier set to zero.

Packets sent to the Subnet-Router anycast address will be delivered
to one router on the subnet. All routers are required to support the
Subnet-Router anycast addresses for the subnets to which they have
interfaces.

比方說,,路由R有兩個接口,分別配置了兩個IP地址:

e0:  240e:909:2001::4e3/64
e1:  240e:101:4004::111/64

那么根據RFC的要求,,這個路由器上將會生成下面的Anycast地址:

e0 Anycast:  240e:909:2001::/64
e1 Anycast:  240e:101:4004::/64

為了使得這些Anycast能被訪問到,,需要添加兩條本地主機路由:

Local 240e:909:2001::/128 dev loopback
Local 240e:101:4004::/128 dev loopback

這里需要解釋一點,剛才不是說IPv6的Anycast不是用來通信的嗎,?那 為什么還要被訪問呢,?

因為需要鄰居解析(IPv6 Ndp)。如果有誰把這個地址設置為下一跳了,,那么需要解析這個地址,,這就是 被訪問!

納尼,?Anycast作為下一跳,?

是的,,這就是IPv6 Anycast的核心用法,它不是用來標識主機服務讓你的應用程序通信,,它是用來尋址的:

  • Anycast地址被設置為下一跳
  • Anycast地址被設置進IPv6路由擴展頭以支持源路由

來吧,我們還是舉例子的好,。

我的局域網為了備份,,希望部署兩臺或者多臺路由器做熱備,姑且就先兩臺吧:
在這里插入圖片描述

假設兩臺路由器都能接外網,,如果跑IPv4協議,,那么自然而然的想法就是安裝keepalived跑VRRP,這種成熟的東西,,想必都可以瞬間完成配置,。

但是,我們知道,,這兩臺路由器只有一臺是工作狀態(tài),,另外一臺處于backup standby,是不是感覺浪費了資源,?如果你想讓它們一起工作,,那就要:

  1. 為它們配置不同的IP地址,gw1,,gw2,;
  2. 內部局域網一半一半分別配置兩個不同的gateway,即gw1,,gw2,。

萬萬不能配置成相同的IPv4地址的,因為這種地址沖突會導致交換機的轉發(fā)表以及ARP表的混亂,。當然,,對于我個人而言,我是有辦法將其配置成相同的IP地址又不會confuse各種表的,,但是,,配置太復雜了(涉及iptables,ebtables,,arptables,,arp,iproute2,,STP等等),。正如IPv4的Anycast一樣,沒有什么是IPv4配置不出來的,,只是這些大部分都是奇技淫巧般的Trick,!玩物喪志,!

我們看一下用IPv6會怎樣。

不用干別的,,如果路由器的實現遵循RFC標準,,那么你只需要配置兩臺路由器不同的同網段地址即可,如下:

路由器1 e0: 240e:110:1001::fbb2:0a1e:0e59:15eb/64  [低64bit為EUI-64映射而來]
路由器2 e0: 240e:110:1001::eb7c:b2da:7088:3c38/64  [低64bit為EUI-64映射而來]

然后所有主機的默認網關設置成其Anycast地址即可:

::/0 nexthop 240e:110:1001::

就這么簡單,!Why,?

因為路由器1和路由器2在配置好內網e0的地址后,根據RFC3513,,它們會自動生成Anycast地址以及Anycast地址的主機路由以被內網主機鄰居解析,。

RFC要求各層尋址Anycast地址時以 本層次的路由距離 來度量,那么對于二層鏈路,,其距離默認就是物理距離,,光速不變,距離等效于時間,,因此會等效為 誰先回復我的鄰居請求,,誰就是我要尋址的Anycast節(jié)點!
在這里插入圖片描述
是不是天然的負載均衡了呢,?炫酷吧,!

現在有個不可回避的問題需要解決,那就是 訪問互聯網服務的正向包和返回包路徑不對稱問題,。

比如,,h1主機訪問服務器S走的R1作為默認網關,然而S返回h1時,,卻從R2返回,,此時R2解析h1的地址,h1收到R2的解析請求后,,會不會更新自己關于Anycast鄰居的信息呢,?如果是的話,那勢必會造成鄰居表信息的劇烈抖動??!

答案是 并不會! Why,?

因為IPv6在解析鄰居時,,ICMPv6協議頭里會寫清楚下面的信息:

  • 自己是不是路由器
  • 鄰居信息需不需要覆蓋

這一點和IPv4的ARP不同,ARP是雙向更新的,,在回復自己的MAC地址時,,同時也更新了自己的ARP表,但在IPv6中,,兩者分開了:

  • 請求你的MAC信息
  • 請更新你自己的鄰居信息

R2發(fā)送給h1的鄰居請求,,只是請求h1的MAC地址而已,,并沒有說要h1更新其鄰居信息,所以萬事大吉:
在這里插入圖片描述


配置和實現

現在該看看實現了,。

很少有資料講 如何在Linux上配置IPv6的Anycast 的,,這一次可能我又占了坑。

其實很簡單,,只要開啟IPv6的轉發(fā)即可:

sysctl -w net.ipv6.conf.all.forwarding=1

這個時候,,你就會在/proc/net/anycast6看到內容:

[root@localhost src]# cat  /proc/net/anycast6
3    enp0s8          fe800000000000000000000000000000     1
4    enp0s9          fe800000000000000000000000000000     1
4    enp0s9          240e0918800300000000000000000000     1

我在enp0s9上配置了如下的IPv6地址:

[root@localhost src]# ip -6 addr ls dev enp0s9
4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 240e:918:8003::3f5/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::eb7c:b2da:7088:3c38/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

所以說,什么都不用干,,Linux內核自動幫我生成了其對應的Anycast地址,對應RFC3513的2.6.1 Required Anycast Address格式:240e:918:8003::

按照上面一個小節(jié)最后的例子,,我們知道,,這個 240e:918:8003:: 是可以被鄰居發(fā)現而解析的,而我們知道,,IPv6的鄰居發(fā)現使用的是組播地址,,其組播構成規(guī)則詳見:
RFC3513-2.7 Multicast Addresseshttps://tools./html/rfc3513#section-2.7

對應組播地址:
FF02::1:FF00:0000/104 Solicited-Node Address [RFC3513] -RFC4291對其進行了增強更新

Solicited-Node Address: FF02:0:0:0:0:1:FFXX:XXXX

Solicited-node multicast address are computed as a function of a
node’s unicast and anycast addresses. A solicited-node multicast
address is formed by taking the low-order 24 bits of an address
(unicast or anycast) and appending those bits to the prefix
FF02:0:0:0:0:1:FF00::/104 resulting in a multicast address in the
range

FF02:0:0:0:0:1:FF00:0000
to
FF02:0:0:0:0:1:FFFF:FFFF

我們針對Linux的如上配置確認一下:

[root@localhost src]# cat /proc/net/igmp6
1    lo              ff020000000000000000000000000001     1 0000000C 0
1    lo              ff010000000000000000000000000001     1 00000008 0
...
# 下面這個便是!
4    enp0s9          ff0200000000000000000001ff000000     2 00000004 0
...

將Anycast地址作為默認網關發(fā)送數據,,最終鄰居解析的時候,,只要發(fā)送到組播地址 ff02::1:FF00:: 就可以解析出該網段上的Anycast地址的MAC地址信息,然后 取第一個到達的作為鄰居 即可,!

上面關于組播的設置,,請看 addrconf_join_anycast 函數:

static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
{
    struct in6_addr addr;

    if (ifp->prefix_len >= 127) /* RFC 6164 */
        return;
    ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
    if (ipv6_addr_any(&addr))
        return;
    ipv6_dev_ac_inc(ifp->idev->dev, &addr);
}

其中,ipv6_dev_ac_inc 值得觀摩,!


配置也配好了,,那么我們找兩臺機器練一練手吧。

這次我部署的另外一個機器是Windows 7系統,,順便玩一下netsh,。這臺Win7系統機器和我們的Linux Rh7.2直連,拓撲我就不畫了,,非常簡單,。我只是把Win7上的地址配置發(fā)布出來。

很簡單,,Win7上配置一個 240e:918:8003::/64* 同網段的IPv6地址:
在這里插入圖片描述

這個時候,,將Win7的默認網關設置成 240e:918:8003::* 這個Linux上使能的Anycast地址,看看如何通信,。

按照慣例,,ping一下這個 240e:918:8003::* 地址:
在這里插入圖片描述
不通!

在Linux上抓包,,發(fā)現是有回復ICMPv6 Echo Reply的,,只是說回復的源IP地址不是Win7期望的Anycast地址,,而是Linux上enp0s9網卡的地址,這正是印證了 An anycast address must not be used as the source address of an IPv6 packet. 這句話,!

我很好奇Linux內核是怎么做到 不讓Anycast地址作為源地址的 ,,ping不行,TCP的Telnet也不行…其實看一下代碼就完全明白了,。

先看下Telnet為什么完全就沒有SYN-ACK回復:
在這里插入圖片描述
再看看為什么ping回復的時候用的不是Anycast地址,,而是選擇了網卡上配置的地址:
在這里插入圖片描述
這個關于源地址選擇的細節(jié),詳見RFC3484以及我的前一篇閑談:
Default Address Selection for Internet Protocol version 6 (IPv6)https://www./rfc/rfc3484.txt
閑談IPv6-源IP地址的選擇(RFC3484讀后感)https://blog.csdn.net/dog250/article/details/87815123


脈絡理清了之后,,我們來反一下,,讓Win7主機配置Anycast。

我特意沒有按照RFC的規(guī)定,,去配置了一個非標準的Required Anycast Address,,且看:
在這里插入圖片描述
配置方法如下:
在這里插入圖片描述

我并沒有讓低n-bit為全0,竟然成功了,,這說明Win7并沒有嚴格按照RFC的規(guī)范行事,,它完全是手動的。

那么好,,我在Linux上去ping這個Win7的Anycast地址:
在這里插入圖片描述

得到了Win7的回復,,然而源地址不是Win7的Anycast地址,卻是Win7的物理網卡 本地連接 3 上配置的IPv6地址,。這依然印證了 An anycast address must not be used as the source address of an IPv6 packet. 這句話,。

只是說,Win7對Anycast地址 并沒有嚴格遵循subnet后面的低bits均為0的約束 ,,即Win7沒有實現 嚴格的Required Anycast Address,!

不管怎么樣,痛則不通,,通則不痛,,后面也沒啥可玩的了。


總結

IPv6的Anycast:

  • 以往IPv4的規(guī)則在IPv6 RFC約束下依然適用
  • 獨添了subnet-Anycast,,見上文

因為我們可以將Anycast總結為:

  1. 廣義的Global Anycast-作用于IPv4/IPv6
  2. 狹義的IPv6 subnet Anycast-作用于IPv6

此外,,RFC2526又規(guī)定了 保留的Anycast地址 用于不同的目的:
RFC2526-Reserved IPv6 Subnet Anycast Addresseshttps://tools./html/rfc2526
本文不涉及RFC2526的內容,但是提醒注意,,僅此而已,。

閱讀筆記

為了寫這篇文章,我深夜快速瀏覽了RFC標準,,因為我要在這些個標準之上才能胡扯形而上吧,。

這兩個截圖體現了IPv6 Anycast的作用,它到底用在哪?我想我在上文呢,,已經闡述清楚了,。
在這里插入圖片描述

在這里插入圖片描述


后記

為Anycast添加一條host路由,讓anycast地址可以被設置成網關,。

昨晚睡的有點早,,這周末又要去公司附近拉一車行李,有點忙,。白天基本沒空,,所以就以安安吃奶鬧鈴為由,作文一篇,。

浙江溫州皮鞋濕,,下雨進水不會胖。

    本站是提供個人知識管理的網絡存儲空間,,所有內容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內容中的聯系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現有害或侵權內容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多