日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
應對CC攻擊的自動防御系統(tǒng)的原理與實現(xiàn)

0x00 系統(tǒng)效果

創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站建設、成都網(wǎng)站制作與策劃設計,嵐山網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設10年,網(wǎng)設計領(lǐng)域的專業(yè)建站公司;建站業(yè)務涵蓋:嵐山等地區(qū)。嵐山做網(wǎng)站價格咨詢:13518219792

此DDOS應用層防御系統(tǒng)已經(jīng)部署在了http://www.yfdc.org網(wǎng)站上(如果訪問失敗,請直接訪問位于國內(nèi)的服務器http://121.42.45.55進行在線測試)。

此防御系統(tǒng)位于應用層,可以有效防止非法用戶對服務器資源的濫用:

只要是發(fā)送高頻率地、應用層請求以實現(xiàn)大量消耗系統(tǒng)資源的攻擊方式,皆可有效防御。

其實現(xiàn)的基本思想是:

定期分析所有訪問用戶在過去各個時間段內(nèi)的請求頻率,將頻率高于指定閾值的用戶判定為資源濫用者,將其封殺一段時間,時效過后,防御系統(tǒng)自動將其解封。

在線效果測試:

進入http://www.yfdc.org -> 點擊右上側(cè)在線查詢,此時將會進入/shell/yf域內(nèi),/shell/yf是一個用bash scripts寫的動態(tài)web-cgi程序,用戶每一次提交信息,此程序?qū)?zhí)行一些服務器端的查詢操作,然后將數(shù)據(jù)處理后返回到客戶端。

為了防止非法用戶高頻率地訪問這個程序,而影響到其他正常用戶的訪問,故需要進行一些保護措施。

最終效果:

被封信息頁面

在/shell/yf域內(nèi),按住F5不放,一直刷新,幾秒后松開,就能看到被封信息和解封時間。

只要某個用戶對/shell/yf的訪問超過了正常的頻率,服務將會對這個用戶關(guān)閉一段時間,期滿后自動解封。

0x01 系統(tǒng)原理

操作系統(tǒng): CentOS 6.5 x86_64 開發(fā)語言: Bash Shell Scripts Web服務器: Apache Httpd

(此圖為系統(tǒng)結(jié)構(gòu)的鳥瞰圖 可存至本地后放大查看)

2.1 自定義日志:/etc/httpd/logs/yfddos_log

(自定義日志文件的格式)

在httpd.conf的日志參數(shù)中,加入如下兩行:

LogFormat "%a \"%U\" %{local}p %D %{%s}t " yfddos

CustomLog logs/yfddos_log yfddos

我們接下來重點分析日志文件/etc/httpd/logs/yfddos_log.

LogFormat "%a \"%U\" %{local}p %D %{%s}t " yfddos

解釋:

%a -> 用戶的IP
%U -> 請求的URL地址,但并不包含query string(The URL path requested, not including any query string.)
%{local}p -> 用戶請求的服務器端口(一般為80)
%D -> 這個請求共消耗了服務器多少微秒(The time taken to serve the request, in microseconds.)
%{%s}t -> 服務器收到這個請求時,時間戳的值(seconds since 1970-01-01 00:00:00 UTC)

例子:

192.168.31.1 "/shell/yf" 80 118231 1417164313

譯為:IP為192.168.31.1的主機,在時間戳為1417164313的時候,訪問了/shell/yf,并由服務器的80端口向其提供服務,共耗時118231微秒

或為:IP為192.168.31.1的主機,在2014-11-28 16:45:13的時候,訪問了/shell/yf,并由服務器的80端口向其提供服務,共耗時0.118231秒

至于為什么不使用httpd.conf中官方定義的日志,原因如下:

- 用戶訪問日志的一條記錄可大約控制在60Bytes以內(nèi),數(shù)據(jù)量小,便于后期分析,官方定義的日志太過臃腫,影響分析速度
- 使用時間戳標志時間,便于后期分析,官方定義的日志時間參數(shù)為常規(guī)的表達方式,不便于直接進行處理
- httpd的日志系統(tǒng)本身就是從舊到新進行排序記錄的,所以/etc/httpd/logs/yfddos_log日志條目的時間戳,亦為從小到大進行排序的,數(shù)據(jù)記錄更加鮮明

2.2 yfddosd黑名單文件格式

黑名單文件格式

yfddosd黑名單文件/etc/yfddos/web-yf-search.b格式如下:

# ip add-stamp rmv-stamp
1.2.3.4 1416046335 1416046395
1.2.3.5 1416046336 1416046396
1.2.3.6 1416046339 1416046399

每一行為一個黑名單條目,上面第一個條目的意義為:

IP地址 :1.2.3.4

開始時間:時間戳1416046335,即 2014-11-15 18:12:15

終止時間:時間戳1416046395,即 2014-11-15 18:13:15

直觀意義為:

IP地址:1.2.3.4,從2014-11-15 18:12:15開始,被封殺1分鐘,在2014-11-15 18:13:15時自動解封。

這個文件將由駐留在系統(tǒng)中的daemon守護進程yfddosd進行維護更新。

2.3 守護進程yfddosd:防御系統(tǒng)的邏輯核心

守護進程的原理圖

守護進程yfddosd是整個CC防御系統(tǒng)的核心,而function analyze_and_insert_black()則是yfddosd的核心。

yfddosd的配置參數(shù):

yfddos_blackfilePath='/etc/yfddos/web-yf-search.b'
yfddos_accesslogPath='/etc/httpd/logs/yfddos_log'

function analyze_and_insert_black() {
  # analyze_and_insert_black() :
  #   $1:max frequency(seems as abuse if above that) $2:blackip-ttl,time to live,unit is seconds (s)
  #   $3:the access log ${3} seconds before will be analyzed to generate the abuse ip lists that we will block
  # example : analyze_and_insert_black "limit" "ttl" "time"
  # example : analyze_and_insert_black "4" "10" "5"
  # 分析在過去5s內(nèi)的用戶訪問日志 如果有人在這5s內(nèi)訪問量>=4 系統(tǒng)將視其為資源濫用者 將其加入服務黑名單
  # 一條黑名單的作用時間為10s 即在10s之后 系統(tǒng)自動刪除此黑名單條目 服務則繼續(xù)向其開放
  # global vars:
  # stamp logtmpfile yfddos_blackfilePath
  # ......
}

函數(shù)analyze_and_insert_black有三個輸入?yún)?shù):

例子: analyze_and_insert_black "4" "10" "5"

解釋: 分析日志文件/etc/httpd/logs/yfddos_log中,在過去5s內(nèi)的用戶訪問日志,如果有IP在這5s內(nèi)訪問量>=4,守護進程yfddosd將視其為資源濫用者,然后將這個IP加入到黑名單文件/etc/yfddos/web-yf-search.b中,此條黑名單的作用時間為10s,在10s之后,守護進程yfddosd將刪除此黑名單條目。

例子: analyze_and_insert_black "150" "2700" "905"

 解釋: 分析日志文件/etc/httpd/logs/yfddos_log中,在過去905s內(nèi)的用戶訪問日志,如果有IP在這905s內(nèi)訪問量>=150,守護進程yfddosd將視其為資源濫用者,然后將這個IP加入到黑名單文件/etc/yfddos/web-yf-search.b中,此條黑名單的作用時間為2700s,在2700s之后,守護進程yfddosd將刪除此黑名單條目。

簡記為: analyze_and_insert_black "limit" "ttl" "time"

解釋: 分析日志文件/etc/httpd/logs/yfddos_log中,在過去(time)s內(nèi)的用戶訪問日志,如果有IP在這(time)s內(nèi)訪問量>=limit,守護進程yfddosd將視其為資源濫用者,然后此IP將會被加入到黑名單文件/etc/yfddos/web-yf-search.b中,作用時間為(ttl)s,在(ttl)s之后,守護進程yfddosd將自動刪除此條目。

從上述中可看出,守護進程yfddosd至少需要完成如下三個任務:

◆分析日志文件/etc/httpd/logs/yfddos_log中指定時間內(nèi)的用戶訪問記錄

◆將資源濫用者的IP加入文件/etc/yfddos/web-yf-search.b,并設置封殺TTL參數(shù)值

◆將/etc/yfddos/web-yf-search.b中已經(jīng)過期的條目全部及時刪除

守護進程yfddosd是如何實現(xiàn)上面三個邏輯的:

◆分析日志文件/etc/httpd/logs/yfddos_log中指定時間內(nèi)的用戶訪問記錄:

(1) 取出/etc/httpd/logs/yfddos_log中過去time秒的訪問日志數(shù)據(jù),使用二分法將這一操作的時間復雜度壓縮到K*log2(N)以內(nèi),其中N為/etc/httpd/logs/yfddos_log中日志總行數(shù),K為一次測試的耗時量,一般為1ms以內(nèi),即如有1048576條訪問記錄,這一操作將僅需要20*1ms。

(2) 使用正則RE對這些數(shù)據(jù)進行二次處理,過濾出所有訪問指定URL的用戶IP(這個URL為想要防御的http服務url,例如在http://www.yfdc.org系統(tǒng)中,所防御的就是/shell/yf,這個服務向訪問者提供信息的search與get服務),再次使用sort與uniq對這些IP進行處理,以統(tǒng)計出每個IP的訪問次數(shù)并進行高低排序。

◆將資源濫用者的IP加入文件/etc/yfddos/web-yf-search.b,并設置封殺TTL參數(shù)值

將所有訪問次數(shù)超過閾值limit的IP更新到黑名單文件/etc/yfddos/web-yf-search.b中,每個黑名單條目的封殺時間為ttl秒

◆將/etc/yfddos/web-yf-search.b中已經(jīng)過期的條目全部及時刪除

遍歷/etc/yfddos/web-yf-search.b中所有黑名單條目,結(jié)合當前時間戳,將所有已經(jīng)過期的條目一一刪去

下面是守護進程yfddosd狀態(tài)機的偽代碼:(略去了一些處理細節(jié))

#init and FSM start work...
counter=0
while true
do
  sleep 5
  counter=counter+1
  delete obsolete items #將/etc/yfddos/web-yf-search.b中已經(jīng)過期的條目全部刪除
  if # every 5 seconds : 5s
  then
    analyze_and_insert_black "6" "10" "5"
    # 分析在過去5s內(nèi)訪問的用戶 如果有人其訪問量大于等于6 系統(tǒng)將視其為資源濫用者
    # 遂將其加入服務黑名單 其作用時間為10s 在10s之后 daemon進程自動刪除這個ip黑名單條目
  fi
  if #every 5*3 seconds : 15s
  then
    analyze_and_insert_black "14" "45" "15"
  fi
  if #every 5*3*4+5 seconds : 65s
  then
    analyze_and_insert_black "40" "840" "65"
  fi
  if #every 5*3*4*3*5+5 seconds : 905s : 15min
  then
    analyze_and_insert_black "150" "2700" "905"
  fi
  if #every 5*3*4*3*5*4+5 seconds : 3605s : 1h
  then
    analyze_and_insert_black "300" "7200" "3605"
  fi
  if #every 5*3*4*3*5*4*3+5 seconds : 10805s : 3h
  then
    analyze_and_insert_black "400" "21600" "10805"
    if #在每天的00:01-04:59時間區(qū)間 一天僅執(zhí)行一次
    then
        #備份日志
    fi
  fi
done

防御者應斟酌調(diào)整每個檢測時間點的參數(shù)值(封殺時間ttl與判定閾值limit),以調(diào)節(jié)系統(tǒng)應對CC攻擊到來時的反應時間。

0x02 源代碼

 
 
 
  1. ##################################### vim /usr/local/bin/yfddosd.sh :
  2. ##################################### nohup bash /usr/local/bin/yfddosd.sh &>"/etc/yfddos/""yfddosd-log-`date +%Y-%m-%d`" & 
  3. ##################################### yfddos daemon
  4. mkdir /etc/yfddos
  5. yfddos_blackfilePath='/etc/yfddos/web-yf-search.b'
  6. yfddos_accesslogPath='/etc/httpd/logs/yfddos_log'
  7.  
  8. ### refresh tll
  9. logtmpfile=`mktemp`
  10. stamp=`date +%s`
  11. touch "$yfddos_blackfilePath"
  12. if grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
  13. then
  14.   cat "$yfddos_blackfilePath" | while read i
  15.   do
  16.     deadstamp=`echo "$i" | grep -Po '[0-9]+$'` 
  17.     if [ "$stamp" -le "$deadstamp" ]
  18.     then
  19.       echo "$i" >>"$logtmpfile"
  20.     fi
  21.   done
  22. fi
  23. chmod o+r "$logtmpfile"
  24. mv -f "$logtmpfile" "$yfddos_blackfilePath"
  25. if ! grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
  26. then
  27.   echo '255.255.255.255 0 0' >> "$yfddos_blackfilePath"
  28. fi
  29.  
  30. function analyze_and_insert_black() { 
  31.   # analyze_and_insert_black() :
  32.   #   $1:max frequency(seems as abuse if above that) $2:blackip-ttl,time to live,unit is seconds (s) 
  33.   #   $3:the access log ${3} seconds before will be analyzed to generate the abuse ip lists that we will block
  34.   # example : analyze_and_insert_black "limit" "ttl" "time"
  35.   # example : analyze_and_insert_black "4" "10" "5"
  36.   # 分析在過去5s內(nèi)的用戶訪問日志 如果有人在這5s內(nèi)訪問量>=4 系統(tǒng)將視其為資源濫用者 將其加入服務黑名單
  37.   # 一條黑名單的作用時間為10s 即在10s之后 系統(tǒng)自動刪除此黑名單條目 服務則繼續(xù)向其開放
  38.   # global vars:
  39.   # stamp logtmpfile yfddos_blackfilePath
  40.   local threshold="$1"
  41.   local ttl="$2"
  42.   local stamp_pre="$3"
  43.   local i=0
  44.   local num=""
  45.   local fre=0
  46.   local ip=0
  47.   local localbuf=0
  48.   local linenum=0
  49.   local deadstamp=0
  50.   stamp_pre="$((stamp-stamp_pre))"
  51.  
  52.   #二分查找初始化
  53.   local temp=0
  54.   local yf_x='1'
  55.   local yf_y=`cat "$logtmpfile" | wc -l`
  56.   if [ "$yf_y" -le "1" ]
  57.   then
  58.     yf_y=1
  59.   fi
  60.   local yf_I=$(((yf_x+yf_y)/2))
  61.  
  62.   temp=`cat "$logtmpfile" | wc -l`
  63.   if [ "$temp" -gt "0" ]
  64.   then
  65.     temp=`sed -n '$p' "$logtmpfile" | grep -Po '[0-9]+ $'`
  66.     if [ "$temp" -lt "$stamp_pre" ]
  67.     then
  68.       num=""
  69.     else  
  70.       while true #使用二分查找的方法 快速地分析訪問日志
  71.       do
  72.         temp=`sed -n "${yf_x}p" "$logtmpfile" | grep -Po '[0-9]+ $'`
  73.         if [ "$temp" -ge "$stamp_pre" ]
  74.         then
  75.           break
  76.         fi
  77.         if [ "$((yf_y-yf_x))" -le "1" ]
  78.         then
  79.           yf_x="$yf_y"
  80.           break
  81.         fi
  82.         temp=`sed -n "${yf_I}p" "$logtmpfile" | grep -Po '[0-9]+ $'`
  83.         if [ "$temp" -lt "$stamp_pre" ]
  84.         then
  85.           yf_x="$yf_I"
  86.           yf_y="$yf_y"
  87.           yf_I="$(((yf_x+yf_y)/2))"
  88.           continue
  89.         fi
  90.         yf_x="$yf_x"
  91.         yf_y="$yf_I"
  92.         yf_I="$(((yf_x+yf_y)/2))"  
  93.         continue
  94.       done
  95.       temp=`sed -n "${yf_x}p" "$logtmpfile" | grep -Po '[0-9]+ $'`
  96.       if [ "$temp" -ge "$stamp_pre" ]
  97.       then
  98.         num="$yf_x"
  99.       else
  100.         num=""
  101.       fi
  102.     fi  
  103.  
  104.     if [ -n "$num" ]
  105.     then
  106.       sed -n "${num},\$p" "$logtmpfile" | grep -Po '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort -n | uniq -c | sort -rn | while read i
  107.       do
  108.         fre=`echo "$i" | grep -Po '[0-9]+' | head -1`
  109.         ip=`echo "$i" | grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' `
  110.         if [ "$fre" -ge "$threshold" ]
  111.         then #insert illegal ips : cat "$yfddos_blackfilePath"
  112.           # ip    add-stamp  rmv-stamp
  113.           #1.2.3.4 1416046335 1416046395
  114.           temp=`grep -Pn "${ip//./\\.} " "$yfddos_blackfilePath"`
  115.           if [ -n "$temp" ]
  116.           then
  117.             linenum=`echo "$temp" | grep -Po '^[0-9]+' | head -1`
  118.             deadstamp=`echo "$temp" | grep -Po '[0-9]+$' | sort -rn | head -1 `  
  119.             if [ "$((stamp+ttl))" -gt "$deadstamp" ]
  120.             then
  121.               sed -i "${linenum}s/.*/${ip} ${stamp} $((stamp+ttl))/g" "$yfddos_blackfilePath"
  122.             fi
  123.           else
  124.             sed -i "\$a ${ip} ${stamp} $((stamp+ttl))" "$yfddos_blackfilePath"
  125.           fi
  126.         else
  127.           break
  128.         fi
  129.       done
  130.     fi
  131.  
  132.   fi
  133. }
  134.  
  135. #init and yfddosd's FSM start work...
  136. counter=0
  137.  
  138. while true
  139. do
  140.   sleep 5
  141.   counter=$((counter+1))
  142.   echo -n `date +%Y-%m-%d\ %H:%M:%S`" ""counter ${counter}:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  143.   echo -n "refresh tll:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  144.   ### refresh tll
  145.     #refresh ttl: analyze file: "$yfddos_blackfilePath" if some items'ttl has been reach the date , we will remove it and open service to the ip had been banned before.
  146.       #insert illegal ips : cat "$yfddos_blackfilePath"
  147.       # ip    add-stamp  rmv-stamp
  148.       #1.2.3.4 1416046335 1416046395
  149.     #sed -i "/^.* $((stamp-5))$/d;/^.* $((stamp-4))$/d;/^.* $((stamp-3))$/d;/^.* $((stamp-2))$/d;/^.* $((stamp-1))$/d;/^.* $((stamp))$/d;/^$/d" "$yfddos_blackfilePath"  
  150.   logtmpfile=`mktemp`
  151.   stamp=`date +%s`
  152.   touch "$yfddos_blackfilePath"
  153.   if grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
  154.   then
  155.     cat "$yfddos_blackfilePath" | while read i
  156.     do
  157.       deadstamp=`echo "$i" | grep -Po '[0-9]+$'` 
  158.       if [ "$stamp" -le "$deadstamp" ]
  159.       then
  160.         echo "$i" >>"$logtmpfile"
  161.       fi
  162.     done
  163.   fi
  164.   chmod o+r "$logtmpfile"
  165.   mv -f "$logtmpfile" "$yfddos_blackfilePath"
  166.   if ! grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
  167.   then
  168.     echo '255.255.255.255 0 0' >> "$yfddos_blackfilePath"
  169.   fi
  170.  
  171.   logtmpfile=`mktemp`
  172.   stamp=`date +%s`
  173.   cat "$yfddos_accesslogPath" | grep -P ' "/shell/yf" ' >"$logtmpfile"
  174.   if true # every 5 seconds : 5s
  175.   then
  176.     echo -n "analyze_and_insert_black 6 10 5:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  177.     #analyze yfddos log : analyze_and_insert_black() $1:max frequency(seems as abuse if above that) $2:blackip-ttl $3:the access log ${3} seconds before will be analyzed to generate the abuse ips that we will block
  178.     analyze_and_insert_black "6" "10" "5"
  179.     # 分析在過去5s內(nèi)訪問的用戶 如果有人其訪問量大于等于6 系統(tǒng)將視其為資源濫用者 遂將其加入服務黑名單 其作用時間為10s 在10s之后 daemon進程自動刪除這個ip黑名單條目
  180.   fi
  181.   if [ "$((counter%(3)))" -eq "0" ] #every 5*3 seconds : 15s 
  182.   then
  183.     echo -n "analyze_and_insert_black 14 45 15:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "    
  184.   # example : analyze_and_insert_black "limit" "ttl" "time"
  185.     analyze_and_insert_black "10" "45" "15"
  186.   fi
  187.   if [ "$((counter%(3*4+1)))" -eq "0" ] #every 5*3*4+5 seconds : 65s
  188.   then
  189.     echo -n "analyze_and_insert_black 40 840 65:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  190.   # example : analyze_and_insert_black "limit" "ttl" "time"
  191.     analyze_and_insert_black "25" "840" "65"
  192.   fi
  193.   if [ "$((counter%(3*4*3*5+1)))" -eq "0" ] #every 5*3*4*3*5+5 seconds : 905s : 15min
  194.   then
  195.     echo -n "analyze_and_insert_black 150 2700 905:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  196.   # example : analyze_and_insert_black "limit" "ttl" "time"
  197.     analyze_and_insert_black "150" "2700" "905"
  198.   fi
  199.   if [ "$((counter%(3*4*3*5*4+1)))" -eq "0" ] #every 5*3*4*3*5*4+5 seconds : 3605s : 1h
  200.   then
  201.     echo -n "analyze_and_insert_black 300 7200 3605:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  202.   # example : analyze_and_insert_black "limit" "ttl" "time"
  203.     analyze_and_insert_black "300" "7200" "3605"
  204.   fi
  205.   if [ "$((counter%(3*4*3*5*4*3+1)))" -eq "0" ] #every 5*3*4*3*5*4*3+5 seconds : 10805s : 3h
  206.   then
  207.     echo -n "analyze_and_insert_black 400 21600 10805:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  208.   # example : analyze_and_insert_black "limit" "ttl" "time"
  209.     analyze_and_insert_black "400" "21600" "10805"
  210.     #### "${yfddos_accesslogPath}" backup : 在每天的00:01-04:59時間區(qū)間內(nèi) 備份日志一次
  211.     if [ "`date +%H`" -le "5" ] && ! [ -f "${yfddos_accesslogPath}-`date +%Y-%m-%d`" ]
  212.     then
  213.       service httpd stop
  214.       mv "${yfddos_accesslogPath}" "${yfddos_accesslogPath}-`date +%Y-%m-%d`"
  215.       service httpd start
  216.     fi
  217.   fi
  218.   rm -fr "$logtmpfile"
  219.   echo "sleep:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
  220. done

新聞名稱:應對CC攻擊的自動防御系統(tǒng)的原理與實現(xiàn)
分享鏈接:http://www.dlmjj.cn/article/cdioehi.html