闲谈IPv6-一起玩转IPv6地址自动配置
昨夜夢里驚魂,1997年,安陽市文峰中路老口腔醫院門口那個賣冰糖葫蘆的老人,他死了。1997年我剛上初中,他已經是老人了,我上學路上老是碰到他,卻從沒有買過他一個冰糖葫蘆…現在,他死了,那個賣洗衣膏的人也死了。
誒,冰糖葫蘆誒開口味誒…
滄海燒成酒,燙胸口,一口口都是愁。狂飲高歌,爽快唱!
上周末,我想再寫一篇關于IPv6自動配置的文章,但是周日下午瘋子開車帶我去我和室友暫住了小半年的小屋子里拉行李,就沒有了時間,也就只能大致理一個思路。在這深夜,我補全剩余的。正好今天晚上盯盤,把這篇文章完成。
早在2012年,我就開始扯IPv6的自動配置,比方說這篇:
閑談IPv6-典型特征的一些技術細節: https://blog.csdn.net/dog250/article/details/8169984
也說明,從那個時候開始,我就已經在寫 “IPv6閑談” 系列文章了。
我覺得這個要繼續下去,而且我也是一個理想味兒十足的現實主義患者,所以,光說不練假把式,于是本文將給大家帶來一種不一樣的感覺,本文是一個夾雜著形而上說辭的Howto,不倫不類,但可以看透是非。
我喜歡將所有理論擺平,但是本文中,我將展示一個可以實際操作的過程。
請閱讀。
IPv6自動配置
IPv6的地址不好記憶 一直是IPv4衛道士們的一個槽點,然而誰讓你去記憶IPv6地址了?
IPv6龐大到天文數字的地址數量,天生就是為 萬物互聯 而生的,如若真的每一粒沙子都有一個IPv6地址,試問哪個人可以靠記憶去手敲地址進行配置,就算不靠疲憊的大腦來記憶,如果把這些地址和配置打印在A4的紙上,實際上最大的圖書館都裝不下,那么存在計算機存儲介質上呢?你試著算算看它們將占據多大的存儲空間,以及讀取它們需要多久的時間?
別指望靠人去配置了!隨著技術的發展,人是越來越靠不住的,機器才可以。
于是,IPv6的一個殺手特性引起了人們的注意,即 自動配置!
來自RFC4862的福音,請先閱讀:
RFC 4862-IPv6 Stateless Address Autoconfiguration: https://tools.ietf.org/html/rfc4862
有人說,IPv4不也有DHCP嗎?是的,但是它們的本質卻是不同的。DHCP需要你去配置 另一個協議的服務 ,即你需要搭建DHCP服務器,你需要DHCP客戶端,比如在Windows上,你就要開啟dhcp client服務,天啊,這也是個服務!
換句話說,DHCP是IPv4協議本身之外的東西。而IPv6自動配置卻是其內在的東西,它是IPv6協議標準的一部分。一個IPv6終端,只要簡單的開機,它就會自動獲得IPv6地址。
廣泛點說,IPv4的Zeroconf不也是一種標準嗎?zeroconf詳見:
Zero-configuration networking : https://en.wikipedia.org/wiki/Zero-configuration_networking
嗯,看起來是啦,但還是不一定。
事實上,這種事一直在上演。Anycast這種Trick不也是在IPv4網絡被實踐了很多年嗎?互聯網領域內這種沒有門檻的算法之外的技術,只有想不到,沒有做不到,這不是粒子對撞機。
XXX古已有之 這種說辭到處可以說,我們早已習慣,但是看實質,那還真的不一樣。
IPv6地址生命周期
當使能IPv6自動配置時,一個節點在從獲得自動配置的地址開始,到地址不再可用的這段時間,成為該地址的一個生命周期,在時間軸上,我將其列如下:
我們在Linux系統中間隔幾秒連續兩次查看同一個網卡的同一個自動配置的地址(下圖中的自動配置的地址來自于我的常規配置,不必較真兒這是為什么,下面全部講清楚):
在Prefered和Invalid之間,即Prefered時間已經退到了0,而Invalid時間還有剩余,此時的地址就處在Deprecated狀態,該狀態的地址可以繼續作為目標地址,但是不建議作為源地址,除非它的scope更加合適,詳見RFC3484:
Rule 2: Prefer appropriate scope.
If Scope(SA) < Scope(SB): If Scope(SA) < Scope(D), then prefer SB
and otherwise prefer SA. Similarly, if Scope(SB) < Scope(SA): If
Scope(SB) < Scope(D), then prefer SA and otherwise prefer SB.
Rule 3: Avoid deprecated addresses.
The addresses SA and SB have the same scope. If one of the two
source addresses is “preferred” and one of them is “deprecated” (in
the RFC 2462 sense), then prefer the one that is “preferred.”
鄰居發現和Anycast
關于Anycast這個話題,詳見:
閑談IPv6-Anycast以及在Linux/Win7系統上的Anycast配置 :https://blog.csdn.net/dog250/article/details/88071601
如果想要徹底理解IPv6自動配置以及通信的過程,這里有必要聯系鄰居發現再說一下Anycast。
IPv6的鄰居發現和IPv4的ARP有大不同。
- IPv4的ARP
IPv4在發送ARP請求學習目標主機的MAC地址時,收到ARP請求的主機會 順便學習發送者的MAC地址 ,但是這會引起混亂!特別在防止ARP表項抖動的時候,需要非常復雜的配置或者說Hack! - IPv6的鄰居發現
IPv6地址發現將請求和通告嚴格區分為兩個獨立的過程。ICMPv6的鄰居發現使用override標識位來判斷需要不需要覆蓋舊的鄰居,而不僅僅根據狀態時間。
仔細看RFC4861中的協議格式:
RFC4861中對O位的解釋是:
Override flag. When set, the O-bit indicates that
the advertisement should override an existing cache
entry and update the cached link-layer address.
When it is not set the advertisement will not
update a cached link-layer address though it will
update an existing Neighbor Cache entry for which
no link-layer address is known. It SHOULD NOT be
set in solicited advertisements for anycast
addresses and in solicited proxy advertisements.
It SHOULD be set in other solicited advertisements
and in unsolicited advertisements.
【 注意,鄰居請求協議中沒有O位! 】
明確表明, 針對Anycast地址的鄰居請求,不會覆蓋已經有的鄰居條目 ,這意味著,一個Anycast set中的路由器,誰的通告先到達請求者,請求者就將誰設置為鄰居,后面再來的通告不會覆蓋已經有的鄰居項。
我們再看看專門對Anycast鄰居發現的約束:
Anycast addresses - Anycast addresses identify one of a set of
nodes providing an equivalent service, and multiple nodes on
the same link may be configured to recognize the same anycast
address. Neighbor Discovery handles anycasts by having nodes
expect to receive multiple Neighbor Advertisements for the
same target. All advertisements for anycast addresses are
tagged as being non-Override advertisements. A non-Override
advertisement is one that does not update or replace the
information sent by another advertisement. These
advertisements are discussed later in the context of Neighbor
advertisement messages. This invokes specific rules to
determine which of potentially multiple advertisements should
be used.
理解了這個,就可以明白為什么可以把Anycast地址設置位默認網關而不會出現鄰居表抖動了。
我們回顧一下IPv4的ARP。
ARP其實不算是標準的IP協議,它只能說是IP協議的輔助協議,它位于IP協議之下。比如它通信的時候,不必封裝標準IPv4協議頭。但是IPv6的鄰居發現則不同。
IPv6的鄰居發現封裝于ICMPv6報文中,而ICMPv6則必然立于IP協議之上,它是由標準的IPv6協議頭封裝的,于是,事情就統一了,好一個統一,帥得很!
也就是說,哪怕發送一個鄰居發現報文,即ICMPv6報文,也要封裝一個IPv6協議頭。但是自動配置之前,主機節點并不知道自己的IP地址,在先有雞還是先有蛋的困局下,于是鏈路本地地址就派上了用場。IPv6鏈路本地地址是一塊使能了IPv6協議的網卡與生俱來的!我們知道,IPv6自動配置中,鏈路本地地址是關鍵,它不像IPv4時代必須在后來見招拆招般規定一個保留地址段,比如169.254/16用于無地址通信。IPv6掃除了IPv4年代大部分Zeroconf機制存在的必要性!
既然ICMPv6鄰居發現協議也是一個普通的IPv6報文,那么如何解析Anycast地址的MAC呢?
如果把Anycast地址配置為默認網關,那么在發包到外網時,勢必需要解析它的MAC地址,然而Anycast節點是一個Set而不是一臺特定的主機,所以,基于 最短度量 ,IPv6采用 先到先得,不覆蓋 的原則來解析,即 離請求主機最近的Anycast Set中的路由器肯定最先回復鄰居通告 ,然后忽略掉后來的那些更遠的通告。這對正向主動的發包過程是很好理解的,但是如果返回路徑的包從另一個Anycast Set中的路由器過來呢?
該路由器R1不是正向數據包出發時經由的那臺路由器R0,它要解析主機的MAC地址,于是它發送鄰居請求給主機。
看到這里,我想很多人都會有個疑問,如果路由器R1發送鄰居請求,它是Anycast Set的一員,自然也有Anycast地址,那么它的鄰居請求被主機H接收到之后,R1的MAC地址會不會沖掉原始的R0鄰居項呢?
Anycast-R0的MAC會不會被Anycast-R1的MAC地址替換?你說呢?
答案是不會! Why?
因為關于Anycast,有一個原則,即 Anycast地址不要作為源地址! 因此,在路由器R1發出的針對H的鄰居請求的IPv6協議頭部中,源地址并不是這個Anycast地址,而是路由器R1的相關網卡的鏈路本地地址,詳情還是要參看RFC3484關于IPv6報文源地址的選擇細節,這里只要關注,IPv6鄰居發現報文是一個ICMPv6報文,它也是一個普通的IPv6協議封裝的報文!
皮鞋濕而不胖,請接著看。
臨時地址
IPv6真正標識了網絡,這點和IPv4有著本質的不同。
IPv6路由器管理的是網段,而不是主機。IPv6路由器靠 鄰居發現 僅僅管理到滿足它 知道這個鄰居屬于自己的一個網段 這樣的程度即可!這點是靠類似IPv6 EUI-64映射機制實現的。
也就是說,IPv6的主機標識由主機自己來生成和維護! IPv6實現了OSI模型的地址形式,將網絡路由器/路由器的尋址和路由器/主機之間的尋址區分了開來:
- 路由器/路由器尋址:使用路由協議交換轉發信息,最長前綴匹配算法尋址
- 路由器/主機尋址:使用ICMPv6鄰居發現協議尋址
嗯,真正的Internet!
但這會出現一個問題,且往下看。
在IPv4網絡中,如果一個節點換了IP地址,那基本上沒人會猜測到兩個IP地址之間的關聯,比如我的筆記本電腦在家的時候,它的地址是192.168.1.101,當我把這臺電腦帶到了一個星巴克,它可能會被分配另一個地址172.16.2.33,沒人知道這兩個地址標識的是一臺設備!
但是,這在IPv6中卻有問題。
簡單起見,我姑且把EUI-64先等同于MAC地址前導16個0組成,比如你的MAC地址是08:00:27:ff:26:e6,那么EUI-64生成的主機標識則是00:00:08:00:27:ff:26:e6,反正你就知道 能通過你的MAC唯一算出你的主機標識 就好了。
假設我家里的IPv6段是2001:111:222::/64,我的筆記本MAC地址是08:00:27:ff:26:e6,那么我的筆記本電腦的地址就是2001:111:222::00:00:08:00:27:ff:26:e6/64。
如果我把這臺電腦拿到了星巴克,雖然水網段前綴發生了變化,但是由于MAC地址沒有變化,因此 新IPv6地址的低64位是不變的!!
考慮到MAC地址的唯一性以及其和網卡廠商,售賣點等信息的關聯性,如果你買這個電腦時恰好用了微信支付或者支付寶,你相當于實名買了這臺電腦,那么只要你帶著這臺電腦并且使用,通過下面的線索就能定位你的隱私:
接入點搜集的鄰居信息–>你的MAC地址–>支付記錄以及MAC地址序列號的出貨記錄–>你是誰。
或者說,如果有人知道你的MAC地址,他就有可能知道你在什么時間去過什么地方…
所以說,某些時候,我們不希望使用EUI-64機制來生成主機標識信息,相反我們更希望使用隨機一點的值。這就是所謂IPv6臨時地址。
只要你啟用了IPv6臨時地址,那么當你收到路由器推送下來的前綴信息時,除了根據EUI-64機制生成一個常規的IPv6主機標識并和前綴拼形成一個IPv6地址之外,還會使用隨機算法生成一個隨機主機標識并和前綴拼接形成一個隨機的臨時IPv6地址。
一般而言,這個隨機的地址生命周期比較短,比如說一天時間。它一般作為源地址和遠程服務器通信,通過你的偏好配置,你可以在通信發生時讓協議棧 優選臨時地址作為源地址。 詳見RFC3484:https://tools.ietf.org/html/rfc3484#section-5 中的rule 7。
關于臨時地址的更多詳情,參閱RFC是最標準的做法:
RFC4941-Privacy Extensions for Stateless Address Autoconfiguration in IPv6: https://tools.ietf.org/html/rfc4941
Howto-Step by Step
理解了以上IPv6的地址特性,現在進入重頭戲。
這個小節將step-by-step演示IPv6的自動配置是如何玩的。為了簡單起見,我的拓撲如下:
下面我要兩臺機器輪流做路由器和需要被自動配置的節點主機,大家可以同時領略兩種不同操作系統配置的不同風味。
為了系統凈化,我特意將兩臺設備都進行了重置。
Windows 7作為路由器的配置過程
首先你要學會netsh的使用,它非常簡單和方便。值得一提的是,我沒有專門學習netsh,我看完RFC后,配置Windows路由器時,一路help下來的,就成功了。讓我感覺這非常人性化,和Cisco命令行很像,秒殺Linux的bash命令行或者iproute2。
我們首先用它來為 “本地連接 3” 這塊網卡添加一個IPv6地址:
C:\>netsh int ipv6 add addr "本地連接 3" 2007:777:666::555/64然后效果如下:
就簡單add了一個地址,結果出現了這么多地址,應有盡有,我來分別簡單解釋一下:
- 手工添加的地址 :配什么就是什么,類似IPv4的手工配置,可作為目標地址用于全局通信
- EUI-64拼接的地址 :根據RFC3513規范生成的地址,可作為源地址用于全局通信
- 臨時地址 :為了解決RFC4941陳述的問題而隨機生成的地址,可作為源地址用于全局通信
- 本地鏈路地址 :為實現自動配置而自動生成的Link地址
- Anycast地址 :依據RFC3513 Reqired Anycast規定而生成的地址
由于我手工配置的地址是 2007:777:666::555/64 ,那么其網絡前綴自然就是 2007:777:666::/64 ,這個也是該Windows機器作為路由器將來要自動配置給其網內主機的地址段。
說一下最后這個Anycast地址,為什么會生成這個地址,不是說路由器才有這個地址嗎?
是的,當然是只有路由器才有,所以說我已經把Windows機器變成了一臺路由器。如何變的呢?非常簡單,執行下面的命令即可:
C:\>netsh int ipv6 set int "本地連接 3" forwarding=enable是的,不要去regedit設置注冊表了,就著干就行!netsh,不二選擇!
為了讓本鏈路上的主機將自己設置為默認網關,還需要下面的命令:
C:\>netsh int ipv6 set int "本地連接 3" advertisedefault=enable好了,此時此刻,我們的Windows主機已經是一臺路由器了,并且按照相關的RFC規范,路由器需要的功能已經應有盡有,最后還差一步,即如何讓這個Windows路由器播報自己的前綴從而給發出路由器請求的節點推送網絡前綴呢?
非常簡單,只要下面的命令即可:
C:\>netsh int ipv6 set route 2007:777:666::555/64 "本地連接 3" publish=yes再次強調,netsh一定要多玩!
至此,Windows上的配置已經基本完畢。最后看一下“本地連接 3”的總配置:
此時,我的Linux主機的enp0s9網卡要開啟了!確認以下的配置是正確的:
# 接收路由器通告 net.ipv6.conf.enp0s9.accept_ra = 1 # 接受通告路由器作為默認網關 net.ipv6.conf.enp0s9.accept_ra_defrtr = 1 # 接受前綴通告,這是自動配置之關鍵 net.ipv6.conf.enp0s9.accept_ra_pinfo = 1值得注意的是,上述的配置會在自動配置過程中 被改變 !
這主要是由/sbin/NetworkManager搞的。如果一個主機頻繁收到不同的路由器通告,很容易出問題,所以最好是自己維護一個狀態機,只有在確認當前的自動分配的地址已經超時而Invalid時,才會重新開啟接收路由器通告。
NetworkManager在收到路由器通告后,會將相關網卡的accept_ra等配置參數給禁止掉,事情不容小覷。
不過我建議,初學者可以先干掉這個NetworkManager,不要被它詭異的行為影響。畢竟這主要是在演示原汁原味的純正IPv6自動配置,而不是真的要用它。
好了,在我killall -9 NetworkManager之后,事情明朗了。
此外,在IPv6中,路由器和主機的角色在配置上是 互斥的 。這點尤其注意。比如,當你將節點配置成路由器時,它將不再接收其它的路由器通告(除非強制配置,但不建議)。
此時此刻,同時開啟抓包!且看:
[root@localhost ~]# ifconfig enp0s9 up等待幾秒:
[root@localhost ~]# ip -6 add ls dev enp0s9 4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000# 自動配置的地址,由EUI-64生成并拼接主機標識inet6 2007:777:666:0:a00:27ff:fed0:3f5c/64 scope global mngtmpaddr dynamic# 注意這些時間!valid_lft 2591963sec preferred_lft 604763secinet6 fe80::a00:27ff:fed0:3f5c/64 scope linkvalid_lft forever preferred_lft forever [root@localhost ~]# [root@localhost ~]# ip -6 ro ls dev enp0s9 2007:777:666::/64 proto kernel metric 256 expires 2591890sec fe80::/64 proto kernel metric 256 # 推下來的路由通告中的默認路由指向Windows的本地鏈路地址! default via fe80::5db6:1b75:9d6f:bcbc proto ra metric 1024 expires 1690sec自動配置完美完成,Linux主機的IPv6地址為:
2007:777:666:0:a00:27ff:fed0:3f5c/64
我們來看一下抓包文件,看看發生了什么:
注意那個Router lifetime字段。RFC4861的6.2.3節這樣說:
6.2.3. Router Advertisement Message Content
…
A router might want to send Router Advertisements without advertising
itself as a default router. For instance, a router might advertise
prefixes for stateless address autoconfiguration while not wishing to
forward packets. Such a router sets the Router Lifetime field in
outgoing advertisements to zero.
我們實際抓包試試看,比如在disable和enable forwarding開關,僅僅保留publish開關時,看看Windows路由器發送的路由器通告有什么區別:
就這么點點不同而已,說明了Windows確實遵循了RFC規范。
自動配置完畢,來發個包試試看唄。
Linux主機不是接受Windows路由作為默認網關了嗎:
::/0 fe80::5db6:1b75:9d6f:bcbc UGDAe 1024 0 0 enp0s9下一跳是Windows路由器的本地鏈路地址。如果這是IPv4,在通信時,通信源地址根據和網關的最長前綴匹配原則,肯定會選擇為enp0s9的本地鏈路地址,但是IPv6卻不是這樣,它嚴格按照RFC3484來選擇源地址,我們來試試看:
[root@localhost ~]# telnet 3333:2222:1111::123 80 Trying 3333:2222:1111::123...抓包截圖:
命中RFC3484第5節的rule 5:
Rule 5: Prefer outgoing interface.
現在讓我們來總結一下。
全程配置使用netsh這個非常好用的Windows工具。
CentOS Linux作為路由器的配置過程
接下來該對換角色了。
這次Linux作為路由器,而Windows作為主機。為此,我重置了兩臺機器的既有配置。切記,一定要關閉Windows的路由器轉發以及路由器通告功能,它才能作為普通主機接收自動配置。
現在開始配置Linux路由器。這個很簡單,打開forwarding即可:
[root@localhost ~]# sysctl -w net.ipv6.conf.all.forwarding=1 net.ipv6.conf.all.forwarding = 1開啟這個路由轉發功能后,Anycast地址自然生成,這個和Windows一樣,遵循RFC的規范行事。接下來配置路由器通告。
在Linux中,這個可以由radvd守護進程完成。如果有人非要抬杠說 既然路由器通告是IPv6自帶的一部分,為何不在內核實現,而要專門由一個用戶態守護進程支持,這個和DHCP不也一樣么? 關于這點,我覺得, 本來就沒有什么內核態,用戶態之說 由于路由器通告配置比較復雜,擁有很多的參數,而內核態又不被建議被搞復雜,只能做在用戶態咯,這都無所謂。如果非要抬杠,給我兩天帶薪休假時間,我給你做進內核去。
言歸正傳,在我們的CentOS上,radvd并不需要編譯源碼,它比較成熟,直接yum install即可:
yum install radvd然后大致看一下manual:
RADVD(8) RADVD(8)
NAME
radvd - router advertisement daemon for IPv6
…
按照配置文件的建議,自行大約摸配置即可。或者說,你看一遍radvd.conf的manual就可以玩轉了,非常之詳細:
[root@localhost ~]# man radvd.conf限于篇幅,我也不想復制粘貼,我給出一個我自己的一個配置文件,位于/etc/radvd.conf:
interface enp0s9 {AdvSendAdvert on;MinRtrAdvInterval 30;MaxRtrAdvInterval 100; prefix 2001:dddd:1:0::/64{AdvOnLink on;AdvAutonomous on;AdvRouterAddr off;AdvValidLifetime 120; # 120秒過期AdvPreferredLifetime 100; # 100秒后不再建議使用};route 2006:222:666::444/128 # 推送這個主機路由{}; };下面開始配置過程,我感覺雖然配置上看起來比Windows配置簡單,但是并沒有Windows的直觀。
先給enp0s9配置一個和radvd通告的前綴一致的IPv6地址:
[root@localhost ~]# ip -6 a add dev enp0s9 2001:dddd:1:0::123/64好了,現在開啟radvd服務(同時開啟tcpdump/wireshark抓包):
[root@localhost ~]# service radvd start Redirecting to /bin/systemctl start radvd.service [root@localhost ~]#OK,這時看看Windows主機接收得如何,show一下address:
完美!該有的地址都有了。再看看默認路由有沒有推送下來,必須推下來了的:
對了,還有一條主機路由呢,我在radvd.conf里配置的那個:
必須有啊!
我們看看抓包,這一切背后發生了什么?看看Linux的路由器通告就好了:
一切全部浮到了水面上。IPv6的自動配置就是這么玩的。
Windows VS. Linux
這次,我竟然用Windows做路由器,拿Linux做靶子。也不奇怪,自從我第一眼看到netsh,我就喜歡它了,它竟然什么東西都能help出來,這一點讓我回憶起了我熟悉的Cisco命令行。
我經常拿netsh和Linux iproute2對對比,我一直傾向于在心理上希望iproute2更勝一籌,但事實上,我覺得netsh玩的更爽!
所以,在我演示這個IPv6自動配置這么重要的特性的過程中,Windows的netsh讓我感覺好舒服。
好玩嗎?我覺得比較好玩,但是游戲結束了。
后記
我的感覺,IPv6才是真正的互聯互通網絡協議,它真的是太方便了!真的是比IPv4方便多了。
即便是路由器上要手工配置的那個全局地址,那個被寫在了DNS節點AAAA里面的地址,它也是有章可循的,它的128比特地址里通過一些比特就知道它所處的路由位置,這些就是天然聚類的收益!
不過不要指望去靠某個人手工維護這些。
周末或者下周,我想聊聊關于IPv6編程的一些問題,敬請期待!
這是一個寂靜的雨后之夜,在今天早上,我發了一個朋友圈,關于一個知乎上的問題 “為什么東亞人活得這么累” 其中有一個回答,我是很贊同的,這個回答是這樣的:
然后,這是我的評價:
我是同意這個地緣學解釋的,這也是我的解釋。
我總是拿著家里那個標注地形地貌的地球儀給瘋子和小小看,“你們看,小時候老師給我們講中國地大物博,資源豐富,其實現在看來,那是騙人的。看看美國,歐洲,中南美,大部分都是海拔很低,地形平坦,有豐富植被以及水域覆蓋,而我們中國,這種地方僅限于從山東往南,經過浙江,沿海到廣東一帶,往西止于河南鄭州,湖北武漢連線,東北資源可以處于西伯利亞和季風要沖,異常寒冷。這怎么跟歐美比。在地球儀上看,我們和非洲中南部非常類似。。。”
就是這么簡單的道理,資源貧乏,但卻令人遺憾地培育了水稻這種作物,因此便在資源匱乏地帶養活了海量的人口,造成了一種現象,那就是“不管干什么事,拿人堆就行了”這種勞動密集型觀念,而勞動密集觀念其實是個“延長勞動時間”等價的,都是線性效應而不是指數效應。唉:-(
不用扯那些現代經濟學術語裝逼,再復雜的現象的本質往往道理都是最簡單的。動不動就外匯儲備什么,扯淡!中國古代人難道就不苦逼嗎?不苦逼怎么會有“頭懸梁錐子扎屁股,吃得苦中苦成為人上人,愚公移山,精衛填海,鐵杵磨針,書中自有BMW”這種苦逼至上價值觀?!
再看看歐洲古代中世紀,落后是落后,但人少,沒人干活自然要想一些在中國看來是奇技淫巧的技巧,再往前就是羅馬帝國后期了,那時有大量奴隸勞動力,也是拿人堆,但苦逼的是奴隸而不是普通老百姓啊。
歐洲文明中最苦逼和中國最像的就是羅馬打贏迦太基后到屋大維內戰結束那一段100多年的時間了,到很快結束了,畢竟高盧,北非,近東環地中海這片資源太豐富了!
又能怎么樣呢?我一直以來都不喜歡知乎,在知乎里面學不到知識,到處都是裝逼,抬杠,編那些啰里八嗦的故事,最煩的就是分割線,傻逼一樣的存在。好的答案沒幾個,卻讓讀者浪費了大量的時間,標榜高大上卻處處都是垃圾!
反正都是一樣。
浙江溫州皮鞋濕,下雨進水不會胖!
總結
以上是生活随笔為你收集整理的闲谈IPv6-一起玩转IPv6地址自动配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 控制用计算机论文,计算机在自动控制技术实
- 下一篇: Word 如何从任意页开始显示页码