天天看點

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

————————CONTENTS————————

  • 正規表達式基礎
  • Vim編輯器
  • TCP/IP網絡協定基礎
  • Linux系統程式設計
  • 進階Bash腳本程式設計指南

一、學習筆記

『正規表達式特殊符号』:

[:digit:]   Only the digits 0 to 9    
            比對數字  
[:alnum:]   Any alphanumeric character 0 to 9 OR A to Z or a to z.    
            字母和數字  
[:alpha:]   Any alpha character A to Z or a to z.   
            字母A-Z, a-z  
[:blank:]   Space and TAB characters only.    
            比對空格和 tag  
[:xdigit:]  Hexadecimal notation 0-9, A-F, a-f.  
            16進制數字  
[:punct:]   Punctuation symbols . , " ' ? ! ; : # $ % & ( ) * + - / < > = @ [ ] \ ^ _ { } | ~  
            标點符号  
[:print:]   Any printable character.  
            可列印字元  
[:space:]   Any whitespace characters (space, tab, NL, FF, VT, CR). Many system abbreviate as \s.  
            任何産生空白的字元  
[:graph:]   Exclude whitespace (SPACE, TAB). Many system abbreviate as \W.  
            除了空格和tag外的其他按鍵  
[:upper:]   Any alpha character A to Z.   
            大寫  
[:lower:]   Any alpha character a to z.  
            小寫  
[:cntrl:]   Control Characters NL CR LF TAB VT FF NUL SOH STX EXT EOT ENQ ACK SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC IS1 IS2 IS3 IS4 DEL.  
            代表鍵盤上的控制鍵
           

例如,建立文本并編輯:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

查找全部小寫字母:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

查找全部數字:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『語系對正規表達式的影響』:

由于不同語系的編碼資料不同,是以造成不同語系的資料選取結果有所差異。以英文大小寫為例,zh_CN.big5 及 C 這兩種語系差異如下:

  • LANG=C 時: 0 1 2 3 4....ABCDE...Zabcde...z
  • LANG=zh_CN 時:0 1 2 3 4...aAbBcCdD.....zZ

在使用正規表達式[A-Z]時, LANG=C 的情況下,找到的僅僅是大寫字元 ABCD..Z。而在 LANG=zh_CN 情況下,會選取到 AbBcCdD.....zZ 字元。是以在使用正規表達式時要特别留意語系。

由于我們一般使用的相容與 POSIX 的标準,是以使用 C 語系。

『grep指令常用參數』:

  • -a :将 binary 檔案以 text 檔案的方式搜尋資料
  • -c :計算找到 '搜尋字元串' 的次數
  • -i :忽略大小寫的不同,是以大小寫視為相同
  • -n :輸出行号
  • -v :反向選擇,亦即顯示出沒有 '搜尋字元串' 内容的那一行
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『字元組比對』:

[]中包含的任意一個字元。隻能是一個。

字元組支援由連字元“ - ”來表示一個範圍。當“ - ”前後構成範圍時,要求前面字元的碼位小于後面字元的碼位。

[^...] 排除型字元組。排除後面的字元。

  • [abc] :表示“a”或“b”或“c”
  • [0-9] :表示 0~9 中任意一個數字,等價于[0123456789]
  • [\u4e00-\u9fa5] :表示任意一個漢字
  • [^a1<] :表示除“a”、“1”、“<”外的其它任意一個字元
  • [^a-z] :表示除小寫字母外的任意一個字元

例如,查找“on”或“in”:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

查找不含“-”的字元串:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『行首符: ^ 與行尾符: $』:

查找行首為大寫字母的所有行:

  • '[1]' 表示以大寫字母開頭。
  • '[^A-Z]' 表示除了大寫字母 A-Z 的所有字元。
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『任意一個字元: " . "(小數點)與重複字元 “ * ”(星号)』:

例如:查找符合“.n”的字元串(小數點表示任意一個字元,一個小數點隻能表示一個未知字元)

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • *(星号):代表重複前面 0 個或者多個字元。
  • e*: 表示具有空字元或者一個以上 e 字元。
  • ee*,表示前面的第一個 e 字元必須存在。第二個 e 則可以是 0 個或者多個 e 字元。
  • eee*,表示前面兩個 e 字元必須存在。第三個 e 則可以是 0 個或者多個 e 字元。
  • ee*e :表示前面的第一個與第三個 e 字元必須存在。第二個 e 則可以是 0 個或者多個 e 字元。

『限定連續字元範圍{ }』:

{ }可限制一個範圍區間内的重複字元數。舉個例子,若要找出 2~5 個 o 的連續字元串,如何做? 此時便要用到{}了。由于 { 與 } 在 shell 中有特殊意義,需要用到轉義字元\。

例如:查找連續的兩個“l”

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『總結』:

  • ^word :表示帶搜尋的字元串(word)在行首
  • word$ :表示帶搜尋的字元串(word)在行尾
  • .(小數點) :表示 1 個任意字元
  • \ :表示轉義字元,在特殊字元前加\會将特殊字元意義去除
  • * :表示重複 0 到無窮多個前一個 RE(正規表達式)字元
  • [list] :表示搜尋含有 l,i,s,t 任意字元的字元串
  • [n1-n2] :表示搜尋指定的字元串範圍,例如[0-9] [a-z] [A-Z]等
  • [^list] :表示反向字元串的範圍,例如[0-9]表示非數字字元,[A-Z]表示非大寫字元範圍
  • {n,m} :表示找出 n 到 m 個前一個 RE 字元
  • {n,} :表示 n 個以上的前一個 RE 字元

『sed 工具指令』:

sed 是非互動式的編輯器。它不會修改檔案,除非使用 shell 重定向來儲存結果。預設情況下,所有的輸出行都被列印到螢幕上。

sed 編輯器逐行處理檔案(或輸入),并将結果發送到螢幕。具體過程如下:首先 sed 把目前正在處理的行儲存在一個臨時緩存區中(也稱為模式空間),然後處理臨時緩沖區中的行,完成後把該行發送到螢幕上。sed 每處理完一行就将其從臨時緩沖區删除,然後将下一行讀入,進行處理和顯示。處理完輸入檔案的最後一行後,sed 便結束運作。sed 把每一行都存在臨時緩沖區中,對這個副本進行編輯,是以不會修改原檔案。

如果要修改原檔案,可使用-i 選項。

  • 将 regular_express.txt 的内容列出并列印行号,同時,将第2行删除顯示:
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • 在原檔案中删除第1行并顯示:

    $ sed -i '1d' regular_express.txt

  • a表示在行後加上字元串,i表示在行前添加字元串:
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • 将 2-5 行内容取代為 No 2-5 number(c為替換内容選項):

    $ nl regular_express.txt | sed '2,5c No 2-5 number'

  • 列出 regular_express.txt 内第 5-7 行:

    $ nl regular_express.txt |sed '5,7p'

    ;sed 指令中-n 為安靜模式選項:

    $ nl regular_express.txt |sed -n '5,7p'

  • 替換字元串:

    sed 's/被替換字元串/新字元串/g'

『擴充正規表達式』:

grep 預設僅支援基礎正規表達式,如果要使用擴充性正規表達式,可以使用 grep - E。grep -E 與 egrep 相當于指令别名關系。

    • :表示重複一個或一個以上的前一個 RE 字元:

      $ egrep -n 'go+d' regular_express.txt

  • ? : 表示重複零個或一個前一個 RE 字元:

    $ egrep -n 'go?d' regular_express.txt

  • | :表示用或的方式找出數個字元串:

    $ egrep -n 'gd|good' regular_express.txt

  • () : 表示找出群組字元串:

    $ egrep -n 'g(la|oo)d' regular_express.txt

    ,也就是搜尋glad或 good 這兩個字元串
  • ()+ : 多個重複群組判别:

    $ echo 'AxyzxyzxyzxyzC'|egrep 'A(xyz)+C'

    ,找開頭是 A 結尾是 C 中間有一個以上的‘xyz’的字元串

二、參考資料

  • 正規表達式基礎 實驗樓
  • 淺析正規表達式—(原理篇)
  • 基礎正規表達式
  • 正規表達式
  • 正規表達式之基本原理
  • 正規表達式精萃

傳回目錄

學習筆記

一、基礎知識

『vim的幾種基本模式』:

  • 普通模式(Normal mode):在普通模式中,用的編輯器指令,比如移動光标,删除文本等等。這也是Vim啟動後的預設模式。Vim強大的編輯能來自于其普通模式指令。普通模式指令往往需要一個操作符結尾。例如普通模式指令

    dd

    删除目前行,但是第一個"d"的後面可以跟另外的移動指令來代替第二個d,比如用移動到下一行的"j"鍵就可以删除目前行和下一行。另外還可以指定指令重複次數,

    2dd

    (重複dd兩次),和dj的效果是一樣的。使用者學習了各種各樣的文本間移動/跳轉的指令和其他的普通模式的編輯指令,并且能夠靈活組合使用的話,能夠比那些沒有模式的編輯器更加高效的進行文本編輯。在普通模式中,有很多方法可以進入插入模式。比較普通的方式是按a(append/追加)鍵或者i(insert/插入)鍵。
  • 插入模式(Insert mode):在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新使用者希望文本編輯器編輯過程中一直保持這個模式。在插入模式中,可以按ESC鍵回到普通模式。
  • 可視模式(Visual mode):這個模式與普通模式比較相似。但是移動指令會擴大高亮的文本區域。高亮區域可以是字元、行或者是一塊文本。當執行一個非移動指令時,指令會被執行到這塊高亮的區域上。Vim的"文本對象"也能和移動指令一樣用在這個模式中。
  • 選擇模式(Select mode):這個模式和無模式編輯器的行為比較相似(Windows标準文本控件的方式)。這個模式中,可以用滑鼠或者光标鍵高亮選擇文本,不過輸入任何字元的話,Vim會用這個字元替換選擇的高亮文本塊,并且自動進入插入模式。
  • 指令行模式(Command line mode):在指令行模式中可以輸入會被解釋成并執行的文本。例如執行指令(:鍵),搜尋(/和?鍵)或者過濾指令(!鍵)。在指令執行之後,Vim傳回到指令行模式之前的模式,通常是普通模式。
  • Ex模式(Ex mode):這和指令行模式比較相似,在使用:visual指令離開Ex模式前,可以一次執行多條指令。

這其中常用到就是普通模式、插入模式和指令行模式,是以将重點學習。其他幾種模式了解即可。

『三種常用模式的切換』:

  • vim啟動進入普通模式
  • 插入/指令行模式→普通模式:按

    Esc

    或者

    Ctrl+[

  • 普通模式→插入模式:按

    i

    (插入)或

    a

    (附加)鍵
  • 普通模式→指令行模式:按

    :

  • 指令行模式中輸入wq回車後儲存并退出vim

『進入vim』:

  • 直接打開vim編輯器:

    $ vim

  • 打開已有檔案或建立并編輯檔案:

    $ vim 檔案名

  • 進入指令行模式後輸入

    :e 檔案路徑

    同樣可以打開相應檔案。

『進入插入模式』:

  • i

    :在目前光标處進行編輯
  • I

    :在行首插入
  • A

    :在行末插入
  • a

    :在光标後插入編輯
  • o

    :在目前行後插入一個新行
  • O

    :在目前行前插入一個新行
  • cw

    :替換從光标所在位置後到一個單詞結尾的字元

『退出vim』:

  • :q!

    :強制退出,不儲存
  • :q

    :退出
  • :wq!

    :強制儲存并退出
  • :w <檔案路徑>

    :另存為
  • :saveas 檔案路徑

  • :x

    :儲存并退出
  • :wq

普通模式下輸入

Shift+zz

即可儲存退出vim。

『删除文本』:

進入普通模式,使用下列指令可以進行文本快速删除:

  • x

    :删除遊标所在的字元
  • X

    :删除遊标所在前一個字元
  • Delete

    : 同x
  • dd

    :删除整行
  • dw

    :删除一個單詞(不适用中文)
  • d$或D

    :删除至行尾
  • d^

    :删除至行首
  • dG

    :删除到文檔結尾處
  • d1G

    :删至文檔首部

二、Vim文檔編輯

『vim重複指令』:

1、重複執行上次指令:在普通模式下,

.

(小數點)表示重複上一次的指令操作。例如:普通模式下輸入x,删除第一個字元,輸入

.

(小數點)會再次删除一個字元,除此之外也可以重複dd的删除操作.

2、執行指定次數相同的指令:普通模式下,可以使用

次數+操作

來執行一定次數的某操作。例如:輸入

10x

,删除10個連續字元;輸入

3dd

,将會删除3行文本。

在普通模式下,還可以使用

dw

daw

(delete a word)删除一個單詞,是以可以很容易的聯想到

dnw(n替換為相應數字)

表示删除n個單詞。

『遊标的快速跳轉』:

1、行間跳轉

  • nG(n Shift+g)

    :遊标移動到第 n 行(如果預設沒有顯示行号,請先進入指令模式,輸入

    :set nu

    以顯示行号)
  • gg

    :遊标移動到到第一行
  • G(Shift+g)

    :到最後一行

2、行内跳轉:普通模式下使用下列指令在行内按照單詞為機關進行跳轉

  • w

    :到下一個單詞的開頭
  • e

    :到下一個單詞的結尾
  • b

    :到前一個單詞的開頭
  • ge

    :到前一個單詞的結尾
  • 0或^

    :到行頭
  • $

    :到行尾
  • f<字母>

    :向後搜尋<字母>并跳轉到第一個比對的位置(非常實用)
  • F<字母>

    :向前搜尋<字母>并跳轉到第一個比對的位置
  • t<字母>

    :向後搜尋<字母>并跳轉到第一個比對位置之前的一個字母(不常用)
  • T<字母>

    :向前搜尋<字母>并跳轉到第一個比對位置之後的一個字母(不常用)

『複制粘貼和剪切』:

1、複制及粘貼文本

  • 普通模式中使用

    y

    複制
    • 普通模式中,

      yy

      複制遊标所在的整行(3yy表示複制3行)
    • y^

      複制至行首,或y0。不含光标所在處字元。
    • y$

      複制至行尾。含光标所在處字元。
    • yw

      複制一個單詞。
    • y2w

      複制兩個單詞。
    • yG

      複制至文本末。
    • y1G

      複制至文本開頭。
  • p

    粘貼
    • p(小寫)

      代表粘貼至光标後(下)
    • P(大寫)

      代表粘貼至光标前(上)

2、剪切及粘貼

dd删除指令就是剪切,每次dd删除文檔内容後,便可以使用p來粘貼。

三、查找和替換

1、替換和撤銷(Undo)指令

  • r+<待替換字母>

    :将遊标所在字母替換為指定字母
  • R

    :連續替換,直到按下Esc
  • cc

    :替換整行,即删除遊标所在行,并進入插入模式
  • cw

    :替換一個單詞,即删除一個單詞,并進入插入模式
  • C(大寫)

    :替換遊标以後至行末
  • ~

    :反轉遊标所在字母大小寫
  • u{n}

    :撤銷一次或n次操作
  • U(大寫)

    :撤銷目前行的所有修改
  • Ctrl+r

    :redo,即撤銷undo的操作

2、快速縮進

  • >>

    整行向右縮進
  • <<

    整行向左回退
  • :

    進入指令行模式下對shiftwidth值進行設定可以控制縮進和回退的字元數,例如:

    :set shiftwidth=10

    即設定縮進為10個字元
  • 指令行模式下輸入

    :ce(center)

    指令使本行内容居中
  • :ri(right)

    指令使本行文本靠右
  • :le(left)

    指令使本行内容靠左

3、查找

(1)快速查找

  • /

    然後鍵入需要查找的字元串 按回車後就會進行查找。
  • /

    功能相同,隻不過

    是向上而

    /

    是向下查找。
  • 進入查找之後,輸入

    n

    N

    可以繼續查找
  • n

    表示繼續查找,

    N

    反向查找

(2)進階查找

  • \*

    尋找遊标所在處的單詞
  • \#

    同上,但

    \#

    是向前(上)找,

    \*

    則是向後(下)找
  • g\*

    \*

    ,但部分符合該單詞即可
  • g\#

    \#

四、進階功能入門

1、多檔案編輯

(1)使用vim編輯多個檔案:編輯多個檔案有兩種形式,一種是在進入vim前使用的參數就是多個檔案。另一種就是進入vim後再編輯其他的檔案。

  • 同時建立兩個新檔案并編輯:

    $ vim 1.txt 2.txt

    ,預設進入1.txt檔案的編輯界面
  • :n

    編輯2.txt檔案,可以加!即

    :n!

    強制切換,之前一個檔案的輸入沒有儲存,僅僅切換到另一個檔案
  • :N

    編輯1.txt檔案,可以加!即

    :N!

    強制切換,之前檔案内的輸入沒有儲存,僅僅是切換到另一個檔案

(2)進入vim後打開新檔案

  • :e 3.txt

    打開新檔案3.txt
  • :e#

    回到前一個檔案
  • :ls

    可以列出以前編輯過的文檔
  • :b 2.txt(或者編号)

    可以直接進入檔案2.txt編輯
  • :bd 2.txt(或者編号)

    可以删除以前編輯過的清單中的檔案項目
  • :e! 4.txt

    ,新打開檔案4.txt,放棄正在編輯的檔案
  • :f

    顯示正在編輯的檔案名
  • :f new.txt

    ,改變正在編輯的檔案名字為new.txt

(3)恢複檔案

如果因為斷電等原因造成文檔沒有儲存,可以采用恢複方式,

vim -r

進入文檔後,輸入

:ewcover 1.txt

來恢複

2、可視模式

  • 在普通模式下輸入

    v

    (小寫),進入字元選擇模式,就可以移動光标,光标走過的地方就會選取。再次按下v會後就會取消選取。
  • Shift+v

    (小寫),進入行選擇模式,按下

    V

    之後就會把整行選取,您可以上下移動光标選更多的行,同樣,再按一次

    Shift+v

    就可以取消選取。
  • Ctrl+v(小寫)

    ,這是區域選擇模式,可以進行矩形區域選擇,再按一次

    Ctrl+v

    取消選取。
  • 在可視模式下輸入

    d

    删除選取區域内容
  • y

    複制選取區域内容

3、視窗操作

vim可以在一個界面裡打開多個視窗進行編輯,這些編輯視窗稱為vim的視窗。

打開方法有很多種,例如可以使用在指令行模式下輸入

:new

打開一個新的vim視窗,并進入視窗編輯一個新檔案(普通模式下輸入

Ctrl+w

也可以,但是

Ctrl+w

在chrome下會與chrome關閉标簽頁的快捷鍵沖突,是以使用該快捷鍵你可以在IE或其它浏覽器進行練習),除了

:new

指令,下述列舉的多種方法也可以在指令模式或普通模式下打開新的視窗:

  • :sp 1.txt

    打開新的水準分屏視窗來編輯1.txt
  • :vsp 2.txt

    打開新的垂直分屏視窗來編輯2.txt
  • 普通模式下

    Ctrl-w s

    将目前視窗分割成兩個水準的視窗
  • Ctrl-w v

    将目前視窗分割成兩個垂直的視窗
  • Ctrl-w q

    即 :q 結束分割出來的視窗。如果在新視窗中有輸入需要使用強制符!即:q!
  • Ctrl-w o

    打開一個視窗并且隐藏之前的所有視窗
  • Ctrl-w j

    移至下面視窗
  • Ctrl-w k

    移至上面視窗
  • Ctrl-w h

    移至左邊視窗
  • Ctrl-w l

    移至右邊視窗
  • Ctrl-w J

    将目前視窗移至下面
  • Ctrl-w K

    将目前視窗移至上面
  • Ctrl-w H

    将目前視窗移至左邊
  • Ctrl-w L

    将目前視窗移至右邊
  • Ctrl-w -

    減小視窗的高度
  • Ctrl-w +

    增加視窗的高度

ps:在練習過程中,漸漸體會到vim指令鍵組合和全鍵盤操作的友善之處。不過為什麼要使用hjkl這四個作為方向鍵呢?直接使用上下左右鍵不是更好嗎?

之後去查找維基百科上對于ADM-3A的介紹,發現初創者的鍵盤構造與現在的不完全相同,鍵盤上并沒有上下左右鍵。而hjkl是右手停留的位置,這大概就是選擇這四個鍵的原因吧:)

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

附:參考資料

  • Vim編輯器 實驗樓
  • 做中學之學用學用Vim (婁老師的部落格)
  • vim-adventures遊戲

一、TCP/IP簡介

『TCP/IP 背景和介紹』:

  • TCP/IP(Transmission Control Protocol/Internet Protocol)是傳輸控制協定和網絡協定的簡稱,它定義了電子裝置如何連入網際網路,以及資料如何在它們之間傳輸的标準。
  • TCP/IP 不是一個協定,而是一個協定族的統稱,裡面包括了 IP 協定、ICMP 協定、TCP 協定、以及 http、ftp、pop3 協定等。網絡中的計算機都采用這套協定族進行互聯。
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

1、網絡協定棧架構

TCP/IP 被分為 4 層,每層承擔的任務不一樣,各層的協定的工作方式也不一樣,每層封裝上層資料的方式也不一樣:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

(1)應用層:應用程式通過這一層通路網絡,常見 FTP、HTTP、DNS 和 TELNET 協定;

(2)傳輸層:TCP 協定和 UDP 協定;

(3)網絡層:IP 協定,ARP、RARP 協定,ICMP 協定等;

(4)網絡接口層:是 TCP/IP 協定的基層,負責資料幀的發送和接收。

『預備知識』:

1、IP 位址

  • 網絡上每一個節點都必須有一個獨立的 IP 位址,通常使用的 IP 位址是一個 32bit 的數字,被 . 分成 4 組,例如,

    255.255.255.255

    就是一個 IP 位址。有了 IP 位址,使用者的計算機就可以發現并連接配接網際網路中的另外一台計算機。
  • 在 Linux 系統中,可以用

    ifconfig -a

    指令檢視自己的 IP 位址:
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

2、域名

  • 用 12 位數字組成的 IP 位址很難記憶,在實際應用時,使用者一般不需要記住 IP 位址,網際網路給每個 IP 位址起了一個别名,習慣上稱作域名。
  • 域名與計算機的 IP 位址相對應,并把這種對應關系存儲在域名服務系統 DNS(Domain Name System) 中,這樣使用者隻需記住域名就可以與指定的計算機進行通信了。
  • 常見的域名包括 com、net 和 org 三種頂級域名字尾,除此之外每個國家還有自己國家專屬的域名字尾(比如我國的域名字尾為 cn)。目前經常使用的域名諸如百度(www.baidu.com)、Linux 組織(www.lwn.net)等等。

我們可以使用指令

nslookup

ping

來檢視與域名相對應的 IP 位址,由于實驗樓網絡限制,我們可以使用

ping github.com

檢視。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

3、MAC 位址

  • MAC(Media Access Control)位址,或稱為實體位址、硬體位址,用來定義網際網路中裝置的位置。
  • 在 TCP/IP 層次模型中,網絡層管理 IP 位址,鍊路層則負責 MAC 位址。是以每個網絡位置會有一個專屬于它的 IP 位址,而每個主機會有一個專屬于它 MAC 位址。

4、端口号

  • IP 位址是用來發現和查找網絡中的位址的,但是不同程式如何互相通信呢,這就需要端口号來識别了。
  • 常用協定對應端口号:
    • SSH 22
    • FTP 20 和 21
    • Telnet 23
    • SMTP 25
    • TFTP 69
    • HTTP 80
    • SNMP 161
    • Ping 使用ICMP,無具體端口号

5、封裝和分用

  • 封裝:當應用程式發送資料的時候,資料在協定層次當中從頂向下通過每一層,每一層都會對資料增加一些首部或尾部資訊,這樣的資訊稱之為協定資料單元(Protocol Data Unit,縮寫為PDU),在分層協定系統裡,在指定的協定層上傳送的資料單元,包含了該層的協定控制資訊和使用者資訊。
    • 實體層(一層)PDU指資料位(Bit)
    • 資料鍊路層(二層)PDU指資料幀(Frame)
    • 網絡層(三層)PDU指資料包(Packet)
    • 傳輸層(四層)PDU指資料段(Segment)
    • 第五層以上為資料(data)
  • 分用:當主機收到一個資料幀時,資料就從協定層底向上升,通過每一層時,檢查并去掉對應層次的封包首部或尾部,與封裝過程正好相反。

6、RFC

RFC(Request for Comment)文檔是所有以太網協定的正式标準,并在其官網上面公布,由 IETF 标準協會制定。大量的 RFC 并不是正式的标準,出版的目的隻是為了提供資訊。RFC 的篇幅不一,從幾頁到幾百頁不等。每一種協定都用一個數字來辨別,如 RFC 3720 是 iSCSI 協定的标準,數字越大說是 RFC 的内容越新或者是對應的協定(标準)出現的比較晚。

二、鍊路層介紹

『簡介』:

  • 網絡層協定的資料單元是 IP 資料報 ,而資料鍊路層的工作就是把網絡層交下來的 IP 資料報 封裝為 幀(frame)發送到鍊路上,以及把接收到的幀中的資料取出并上交給網絡層。
  • 為達到這一目的,資料鍊路必須具備一系列相應的功能,主要有:
    • 将資料封裝為幀(frame),幀是資料鍊路層的傳送機關;
    • 控制幀的傳輸,包括處理傳輸差錯,調節發送速率與接收方相比對;
    • 在兩個網絡實體之間提供資料鍊路通路的建立、維持和釋放的管理。
  • 資料幀的結構是這樣的:
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『控制幀的傳輸』:

1、差錯控制

通信系統必須具備發現差錯的能力,并采取措施糾正之,使差錯控制在所能允許的盡可能小的範圍内,這就是差錯控制過程,也是資料鍊路層的主要功能之一。

  • 回報重發

接收方通過對差錯編碼(奇偶校驗碼或 CRC 碼)的檢查,可以判定一幀在傳輸過程中是否發生了差錯。一旦發現差錯,一般可以采用回報重發的方法來糾正。這就要求接受方收完一幀後,向發送方回報一個接收是否正确的資訊,使發送方據此做出是否需要重新發送的決定。發送方僅當收到接收方已正确接收的回報信号後才能認為該幀已經正确發送完畢,否則需要重發直至正确為止。

  • 計時器

如果某一幀發送出現問題,一直不能發送成功,為了避免傳輸過程停滞不前,通常引入 計時器 (Timer) 來限定接收方發回回報消息的時間間隔。當發送方發送一幀的同時也啟動計時器,若在限定時間間隔内未能收到接收方的回報資訊,即計時器逾時(Timeout),則可認為傳出的幀以出錯或丢失,就要重新發送。

  • 序号

由于同一幀資料可能被重複發送多次,就可能引起接收方多次收到同一幀并将其遞交給網絡層的情況。為了防止這種情況,可以采用對發送的幀編号的方法,即賦予每幀一個序号,進而使接收方能從該序号來區分是新發送來的幀還是重發的幀,以此來确定要不要将接收到的幀遞交給網絡層。

2、流量控制

由于收發雙方各自使用的裝置工作速率和緩沖存儲空間的差異,可能出現發送方的發送能力大于接收方接收能力的現象,此時若不對發送方的發送速率做适當的限制,前面來不及接收的幀将被後面不斷發送來的幀“淹沒”,進而造成幀的丢失而出錯。

由此可見,流量控制實際上是對發送方資料流量的控制,使其發送速率不超過接收方的速率。是以需要一些規則使得發送方知道在什麼情況下可以接着發送下一幀,而在什麼情況下必須暫停發送,以等待收到某種回報資訊後再繼續發送。這就是流量控制。

『以太網』:

以太網(Ether-net)是指 DEC 公司、Intel 公司和 Xerox 公司在 1982 年聯合公布的一個标準,這個标準裡面使用了一種稱作 CSMA/CD 的接入方法。而 IEEE802 提供的标準集 802.3(還有一部分定義到了 802.2 中)也提供了一個 CSMA/CD 的标準。

這兩個标準稍有不同,是以鍊路層資料幀的的封裝格式也有所不同(資料幀中的位址為 MAC 位址):

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『PPP(點對點協定)』:

PPP(點到點協定)是為在同等單元之間傳輸資料設計的鍊路層協定。這種鍊路提供全雙工操作,并按照順序傳遞資料。設計目的主要是用來通過 撥号或專線 方式建立 點對點 連接配接發送資料,使其成為各種主機、網橋和路由器之間簡單連接配接的一種共通的解決方案。

點對點協定(PPP)為在點對點連接配接上傳輸多協定資料包提供了一個标準方法。PPP 最初設計是為兩個對等節點之間的 IP 流量傳輸提供一種封裝協定。在 TCP/IP 協定集中它是一種用來同步調制連接配接的資料鍊路層協定。

『SLIP 與 PPP』:

1、SLIP 協定

SLIP 的全稱為 Serial Line IP(串行線路 IP)。它是一種對 IP 資料報進行封裝的簡單形式。

SLIP 協定規定的幀格式規則:

  • IP 資料報以一個稱作 END(0xc0)的特殊字元結束。同時為了防止資料報傳輸之前的線路噪音被誤認為是資料報内容,在資料報開始處添加一個 END 字元;
  • 如果 IP 資料報中含有 END 字元,就連續傳輸 0xdb 和 0xdc 來取代它。0xdb 是 SLIP 的 ESC 字元,但它的值與 ASCⅡ碼中的 ESC(0x1b)不同;
  • 如果 IP 資料報中含有 ESC 字元,就連續傳輸 0xdb 和 0xdd 來取代它。

SLIP 的缺陷:

  • 每一端必須知道對端的 IP 位址,沒有辦法把本端 IP 位址傳遞給對端;
  • 資料幀中無類型字段,當一條串行線路使用 SLIP 時則不能使用其他協定;
  • SLIP 資料幀中無 checksum,隻能依靠上層協定來發現和糾正錯誤。

2、PPP 協定

PPP 協定修改了 SLIP 協定中的缺陷,包括以下三個部分:

  • PPP 封裝 IP 資料報既支援資料為 8 位和無奇偶校驗的異步模式,又支援面向比特的同步連結;
  • 通過 LCP(鍊路控制協定)允許雙方進行協商;
  • 通過 NCP(網絡控制協定)允許雙方在網絡層上進行協商。

PPP 協定的字元規則與 SLIP 有所不同:

  • PPP 幀以标志字元 0x7e 開始和結束,緊接着是一個值為 0xff 的位址位元組,然後是一個值為 0x03 的控制位元組;
  • 由于标志字元是 0x7e,當它出現在資訊字段中時,需要連續傳送 0x7d 和 0x5e 來替代它;
  • 當在資訊字段中遇到 0x7d 時,需要連續傳送 0x7d 和 0x5d 來替代它。
  • 預設情況下,如果字元的值小于 0x20,需要連續傳送 0x7d 和 0x21 來替代它。

PPP 與 SLIP 相比具有下列優點:

  • PPP 支援在單根串行線路上運作多種網絡層協定;
  • 每一幀都有 CRC 校驗;
  • 通信雙方可以用 NCP 進行 IP 位址的動态協商;
  • 可以類似于 CSLIP 對 TCP 和 IP 首部進行壓縮;
  • LCP 可以對多個資料鍊路選項進行設定。

『MTU』:

為了提供足夠快的響應時間,以太網和 IEEE802.3 對資料幀長度都有限制,其最大值分别為 1500 位元組和 1492 位元組,鍊路層的這個特性稱作 MTU ,即** 最大傳輸單元 **。

當網絡層傳下來一個 IP 資料報,并且其長度比鍊路層的 MTU 大,那麼網絡層就需要對資料報進行分片,使每一片都小于 MTU。

MTU 分為接口 MTU 和路徑 MTU:接口 MTU 是所指定的接口所允許發送的最大資料長度;路徑 MTU 指兩台通信主機路徑中最小的 MTU 值。路徑 MTU 是不對稱的,它在兩個方向上不一定一緻。

用指令 netstat -in 可以檢視網絡接口的 MTU:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

三、IP 網際協定

IP 協定位于網絡層,它是 TCP/IP 協定族中最為核心的協定,所有的 TCP、UDP、ICMP 及 IGMP 資料都以 IP 資料報格式傳輸。IP 協定提供的是 不可靠 、 無連接配接 的資料報傳送服務。

  • 不可靠(unreliable):IP 協定不能保證資料報能成功地到達目的地,它僅提供傳輸服務。當發生某種錯誤時,IP 協定會丢棄該資料報。傳輸的可靠性全由上層協定來提供。
  • 無連接配接(connectionless):IP 協定對每個資料報的處理是互相獨立的。這也說明, IP 資料報可以不按發送順序接收。如果發送方向接收方發送了兩個連續的資料報(先是 A,然後是 B),每個資料報可以選擇不同的路線,是以 B 可能在 A 到達之前先到達。

『IP 資料報』:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

如上圖所示,普通的 IP 資料報的報頭長度 20 位元組(除非有選項字段),各個部分的作用:

  • 版本号 :4 位,用于标明 IP 版本号,0100 表示 IPv4,0110 表示 IPv6。目前常見的是 IPv4。
  • 首部長度 :4 位,表示 IP 報頭長度,包括選項字段。
  • 服務類型(TOS) :分别有:最小時延、最大吞吐量、最高可靠性、最小花費 4 種服務,如下圖所示。4 個辨別位隻能有一個被置為 1 :
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • 總長度 :16 位,報頭長度加上資料部分長度,便是資料報的總長度。IP 資料報最長可達 65535 位元組。
  • 辨別 :16 位,接收方根據分片中的辨別字段相不相同來判斷這些分片是不是同一個資料報的分片,進而進行分片的重組。通常每發送一份封包它的值就會加 1。
  • 标志 :3 位,用于辨別資料報是否分片。其中的第 2 位是不分段(DF)位。當 DF 位被設定為 1 時,則不對資料包進行分段處理;第 3 位是分段(MF)位,除了最後一個分段的 MF 位被設定為 0 外,其他的分段的 MF 位均設定為 1。
  • 偏移 :13 位,在接收方進行資料報重組時用來辨別分片的順序。
  • 生存時間(TTL) :8 位,用于設定資料報可以經過的最多的路由器個數。TTL 的初始值由源主機設定(通常為 32 或 64),每經過一個處理它的路由器,TTL 值減 1。如果一個資料報的 TTL 值被減至 0,它将被丢棄。
  • 協定 :8 位,用來辨別是哪個協定向 IP 傳送資料。ICMP 為 1,IGMP 為 2,TCP 為 6,UDP 為 17,GRE 為 47,ESP 為 50。
  • 首部校驗和 :根據 IP 首部計算的校驗和碼。
  • 源 IP 和目的 IP :資料報頭還會包含該資料報的發送方 IP 和接收方 IP。
  • 選項 :是資料報中的一個可變長、可選的資訊,不常用,多用于安全、軍事等領域。

『IP 位址分類』:

為了便于尋址以及階層化構造網絡,每個 IP 位址可被看作是分為兩部分,即 網絡号 和 主機号 。同一個區域的所有主機有相同的網絡号(即 IP 位址的前半部分相同),區域内的每個主機(包括路由器)都有一個主機号與其對應。

IP 位址被分為 A,B,C,D,E 五類,其中 A 類給大型網絡或政府機構等,B 類配置設定給中型網絡、跨國企業等,C 類配置設定給小型網絡,D 類用于多點傳播,E 類用于實驗,各類可容納的位址數目不同。其中我們最常見的為 A,B,C 這三類。

IP 位址用 32 位二進制數字表示的時候,A,B,C 類 IP 的網絡号長度分别為 8 位、16 位、24 位:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • A 類位址
    • A 類位址網絡号範圍:1.0.0.0---127.0.0.0
    • A 類 IP 位址範圍:1.0.0.0---127.255.255.255
    • A 類 IP 的私有位址範圍:10.0.0.0---10.255.255.255 (所謂的私有位址就是在網際網路上不使用,而被用在區域網路絡中的位址)
    • 127.X.X.X 是保留位址,用做循環測試用的
    • 因為主機号有 24 位,是以一個 A 類網絡号可以容納 2^24-2=16777214 個主機号
  • B 類位址
    • B 類位址網絡号範圍:128.0.0.0---191.255.0.0
    • B 類 IP 位址範圍:128.0.0.0---191.255.255.255
    • B 類 IP 的私有位址範圍:172.16.0.0---172.31.255.255
    • 169.254.X.X 是保留位址;191.255.255.255 是廣播位址
    • 因為主機号有 16 位,是以一個 B 類網絡号可以容納 2^16-2=65534 個主機号
  • C 類位址
    • C 類位址網絡号範圍:192.0.0.0---223.255.255.0
    • C 類 IP 位址範圍:192.0.0.0---223.255.255.255
    • C 類 IP 的私有位址範圍:192.168.0.0---192.168.255.255
    • 因為主機号有 8 位,是以一個 C 類網絡号可以容納 2^8-2=254 個主機号

『子網劃分』:

IP 位址如果隻使用 ABCDE 類來劃分,會造成大量的浪費:一個有 500 台主機的網絡,無法使用 C 類位址。但如果使用一個 B 類位址,6 萬多個主機位址隻有 500 個被使用,造成 IP 位址的大量浪費。

是以,可以在 ABC 類網絡的基礎上,進一步劃分子網:占用主機号的前幾個位,用于表示子網号 。

這樣 IP 位址就可看作 IP =** 網絡号** + 子網号 + 主機号

子網号的位數沒有硬性規定,于是我們用 子網路遮罩 來确定一個 IP 位址中哪幾位是主機号,具體使用方法如圖:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

子網路遮罩中的 1 辨別了 IP 位址中相應的網絡号,0 辨別了主機号。将 IP 位址和子網路遮罩進行 邏輯與運算 ,結果就能區分網絡号和子網号。

『IP 路由選擇』:

如果發送方與接收方直接相連(點對點)或都在一個共享網絡上(以太網),那麼 IP 資料報就能直接送達。

而大多數情況則是發送方與接收方通過若幹個路由器(router)連接配接,那麼資料報就需要經過若幹個路由器的轉發才能送達,它是怎麼選擇一個合适的路徑來"送貨"的呢?

IP 層在記憶體中有一個路由表(輸入指令 route -n 可以檢視路由表),當收到一份資料報并進行發送時,都要對該表進行搜尋:

  • 1、搜尋路由表,如果能找到和目的 IP 位址完全一緻的主機,則将 IP 資料報發向該主機;
  • 2、搜尋路由表,如果比對主機失敗,則比對同子網的路由器(這需要子網路遮罩的協助)。如果找到路由器,則将 IP 該資料報發向該路由器;
  • 3、搜尋路由表,如果比對同子網路由器失敗,則比對同網絡号路由器,如果找到路由器,則将該 IP 資料報發向該路由器;
  • 4、如果以上都失敗了,就搜尋預設路由,如果預設路由存在,則發報;
  • 5、如果都失敗了,就丢掉這個包;
  • 6、接收到資料報的路由器再按照它自己的路由表繼續轉發,直到資料報被轉發到目的主機;
  • 7、如果在轉發過程中,IP 資料報的 TTL(生命周期)已經被減為 0,則該 IP 資料報就被抛棄。

『NAT 技術』:

當你用 ifconfig 檢視 IP 位址時,有時你會發現自己的 IP 位址是這樣的———192.168.X.X 或 172.16.X.X

這是 C 類網和 B 類網的私有位址,這就是俗稱的内網 IP。這是因為你的路由器采用了 NAT 技術。

NAT(Network Address Translation,網絡位址轉換)是 1994 年提出的。當在專用網内部的一些主機本來已經配置設定到了内網 IP 位址,但現在又想和網際網路上的主機通信時,NAT 技術将其内網 IP 位址轉換成全球 IP 位址,然後與網際網路連接配接,也就是說,内網的數台主機使用了同一個全球 IP 位址在上網。

NAT 技術實作了寬帶共享,而且有助于緩解 IP 位址空間枯竭的問題。

『IPv6』:

IPv6 的位址長度是 128 位,通常将這 128 位的位址按每 16 位劃分為一個段,将每個段轉換成十六進制數字,并用冒号隔開,比如:2000:0000:0000:0000:0001:2345:6789:abcd 就是一個 IPv6 位址。

單從數量級上來說,IPv6 所擁有的位址容量是 IPv4 的約 8×10^28 倍,達到 2^128(算上全零的)個。這不但解決了網絡位址資源數量的問題,同時也為除電腦外的裝置連入網際網路在數量限制上掃清了障礙。

四、網絡層其它協定

網絡層不僅有 IP 協定,還有其它如 ARP、ICMP、IGMP、ARAR 等其它協定。

『ARP(Address Resolution Protocol)位址解析協定』:

1、功能:當主機通過資料鍊路發送資料的時候, IP 資料報 會先被封裝為一個 資料幀 ,而 MAC 位址 會被添加到資料幀的 報頭 。ARP 便是在這個過程中通過目标主機的 IP 位址,查詢目标主機的 MAC 位址。

2、原理:

在電腦和路由器中都有一個 ARP 緩存表 ,其中儲存的是近期(20 分鐘)與自己有過通信的主機的 IP 位址與 MAC 位址的對應關系。

ARP 緩存表使用過程:

  • 當主機要發送一個 IP 資料報的時候,會首先查詢一下自己的 ARP 緩存表;
  • 如果在 ARP 緩存表中找到對應的 MAC 位址,則将 IP 資料報封裝為資料幀,把 MAC 位址放在幀首部,發送資料幀;
  • 如果查詢的 IP-MAC 值對不存在,那麼主機就向網絡中廣播發送一個 ARP 請求資料幀,ARP 請求中包含待查詢 IP 位址;
  • 網絡内所有收到 ARP 請求的主機查詢自己的 IP 位址,如果發現自己符合條件,就回複一個 ARP 應答資料幀,其中包含自己的 MAC 位址;
  • 收到 ARP 應答後,主機将其 IP - MAC 對應資訊存入自己的 ARP 緩存,然後再據此封裝 IP 資料報,再發送資料幀。

你可以通過指令 arp -a 檢視 ARP 緩存表(表項記錄 20 分鐘逾時),這裡還有其它 ARP 指令可以對緩存表做檢視、修改:

3、ARP 代理

如果 ARP 請求是從一個網絡上的主機發往另一個網絡上的主機,那麼連接配接這兩個網絡的路由器就可以回答該 ARP 請求,這個過程稱作 代理 ARP(Proxy ARP)。

當連接配接這兩個網絡的路由器收到該 ARP 請求時,它會發現自己有通向目的主機的路徑,随後它會将自己(路由器)的 MAC 位址回複給源主機。源主機會認為路由器的 MAC 位址就是目的主機的 MAC 位址,而對于随後發來的資料幀,路由器會轉發到它後面真實 MAC 位址的目的主機。

兩個實體網絡之間的路由器可以使這兩個網絡彼此透明化,在這種情況下,隻要路由器設定成一個 ARP 代理,以響應一個網絡到另一個網絡主機的 ARP 請求,兩個實體網絡就可以使用相同的網絡号。

4、ARP 欺騙

位址解析協定是建立在網絡中各個主機互相信任的基礎上的,它的誕生使得網絡能夠更加高效的運作,但其本身也存在缺陷:

ARP位址轉換表是依賴于計算機中高速緩沖存儲器動态更新的,而高速緩沖存儲器的更新是受到更新周期的限制的,隻儲存最近使用的位址的映射關系表項,這使得攻擊者有了可乘之機,可以在高速緩沖存儲器更新表項之前修改位址轉換表,實作攻擊。ARP請求為廣播形式發送的,網絡上的主機可以自主發送ARP應答消息,并且當其他主機收到應答封包時不會檢測該封包的真實性就将其記錄在本地的MAC位址轉換表,這樣攻擊者就可以向目标主機發送僞ARP應答封包,進而篡改本地的MAC位址表。[5] ARP欺騙可以導緻目标計算機與網關通信失敗,更會導緻通信重定向,所有的資料都會通過攻擊者的機器,是以存在極大的安全隐患。

防禦措施:

  • 不要把網絡安全信任關系建立在IP基礎上或MAC基礎上(RARP同樣存在欺騙的問題),理想的關系應該建立在IP+MAC基礎上。
  • 設定靜态的MAC-->IP對應表,不要讓主機重新整理設定好的轉換表。
  • 除非很有必要,否則停止使用ARP,将ARP做為永久條目儲存在對應表中。
  • 使用ARP伺服器。通過該伺服器查找自己的ARP轉換表來響應其他機器的ARP廣播。確定這台ARP伺服器不被黑。
  • 使用“proxy”代理IP的傳輸。
  • 使用硬體屏蔽主機。設定好路由,確定IP位址能到達合法的路徑(靜态配置路由ARP條目),注意,使用交換集線器和網橋無法阻止ARP欺騙。
  • 管理者定期用響應的IP包中獲得一個RARP請求,然後檢查ARP響應的真實性。
  • 管理者定期輪詢,檢查主機上的ARP緩存。
  • 使用防火牆連續監控網絡。注意有使用SNMP的情況下,ARP的欺騙有可能導緻陷阱包丢失。
  • 若感染ARP病毒,可以通過清空ARP緩存、指定ARP對應關系、添加路由資訊、使用防病毒軟體等方式解決。

『RARP(Reverse Address Resolution Protocol)逆向位址解析協定』:

RARP 與 ARP 是相反的關系,用于将 MAC 位址轉換為 IP 位址。對應于 ARP,RARP 請求以廣播方式傳送,而 RARP 應答一般是單點傳播傳送的。

某些裝置,比如無盤機在啟動時可能不知道自己的 IP 位址,它們可以将自己的 MAC 位址使用 RARP 請求廣播出去,RARP 伺服器就會響應并回複無盤機的 IP 位址。

『ICMP(Internet Control Message Protocol)控制封包協定』:

通信過程中的發生各種問題時,ICMP 将問題回報,通過這些資訊,管理者可以對所發生的問題作出診斷,然後采取适當的措施去解決它。

ICMP 封包由 8 位錯誤類型、8 位條件代碼和 16 位校驗群組成,被封裝在一個 IP 資料報中:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

封包的類型字段可以有 15 個不同的值,以便描述特定類型的 ICMP 封包,代碼字段的值進一步描述不同的條件,各類型的封包及其處理方法如圖所示:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

也有一些出現差錯而不産生 ICMP 封包的情況:

  • 1.ICMP 差錯封包
  • 2.目的位址是廣播或多點傳播位址
  • 3.作為鍊路層廣播的資料報
  • 4.不是 IP 分片的第一片
  • 5.源位址不是單個主機的資料報(源不能為零位址、環回位址、廣播多點傳播位址)

『ping 程式』:

ping

程式和

traceroute

程式是兩個常見的 基于 ICMP 協定 的工具。

1、ping 簡介

ping 程式是對兩台主機之間連通性進行測試的基本工具,它隻是利用 ICMP 回應要求和回應答覆封包,而不用經過傳輸層(TCP/UDP)。

ping 程式通過在 ICMP 封包資料中存放發送請求的時間值來計算往返時間,當應答傳回時,用目前時間減去存放在 ICMP 封包中的時間值,即是往返時間。

ping 程式使用方法為 ping IP 位址 ,ping 指令還可以加上參數,實作更多的功能:

  • -n 隻輸出數值。
  • -q 不顯示任何傳送封包的資訊,隻顯示最後的結果。
  • -r 忽略普通的 Routing Table,直接将資料包送到遠端主機上。通常是檢視本機的網絡接口是否有問題。
  • -R 記錄路由過程。
  • -v 詳細顯示指令的執行過程。
  • -c 數目:在發送指定數目的包後停止。
  • -i 秒數:設定間隔幾秒送一個網絡封包給一台機器,預設值是一秒送一次。
  • -t 存活數值:設定存活數值 TTL 的大小。

2、TTL值

TTL

是 Time To Live的縮寫,該字段指定 IP 包被路由器丢棄之前允許通過的最大網段數量。

TTL 是 IPv4 標頭的一個8 bit 字段,它的作用是限制IP資料包在計算機網絡中的存在的時間,即IP資料包在計算機網絡中可以轉發的最大跳數。

假如沒有TTL字段,網絡中的 IP 包将越來越多造成網絡阻塞,TTL 避免 IP 包在網絡中的無限循環和收發,節省了網絡資源,并能使IP包的發送者能收到告警消息。

3、Ping 指令判斷作業系統

ping 指令會傳回一個 TTL 值,我們可以使用它來判斷目标的作業系統類型。

常見作業系統預設 TTL 值如下:

  • UNIX TTL: 255
  • Linux TTL: 64
  • WINDOWS 95/98 TTL: 32
  • Windows NT 4.0/2000/XP/2003/7/8/10 TTL:128

『traceroute 程式』:

1、traceroute

traceroute 程式是用來偵測主機到目的主機之間所經路由情況的重要工具。剛才 ping 程式中講過,帶

-R

參數的 ping 指令也可以記錄路由過程,但是,因為 IP 資料報頭的長度限制(最多能儲存 9 個 IP 位址),ping 不能完全的記錄下所經過的路由器,traceroute 正好就填補了這個缺憾。

2、traceroute 工作原理

  • 它發送一份 TTL 為 1 的 IP 資料報給目的主機,經過第一個路由器時,TTL 值被減為 0,則第一個路由器丢棄該資料報,并傳回一份逾時 ICMP 封包,于此得到了路徑中第一個路由器的位址;
  • 然後再發送一份 TTL 值為 2 的資料報,便可得到第二個路由器的位址;
  • 以此類推,一直到到達目的主機為止,這樣便記錄下了路徑上所有的路由 IP。
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『IGMP(Internet Group Management Protocol)組管理協定』:

IGMP 是用于管理多點傳播組成員的一種協定,它的作用在于,讓其他所有需要知道自己處于哪個多點傳播組的主機和路由器知道自己的狀态。隻要某一個多點傳播組還有一台主機,多點傳播路由器就會把資料傳輸出去,這樣,接受方就會通過網卡過濾功能來得到自己想要的資料。

為了知道多點傳播組的資訊,多點傳播路由器需要定時的發送 IGMP 查詢,各個多點傳播組裡面的主機要根據查詢來回複自己的狀态。路由器來決定有幾個多點傳播組,自己要對某一個多點傳播組發送什麼樣的資料。

五、傳輸層:UDP 協定

『傳輸層協定』:

從之前介紹的網絡層協定來看,通信的兩端是兩台主機,IP 資料報首部就标明了這兩台主機的 IP 位址。但是從傳輸層來看,是發送方主機中的一個程序與接收方主機中的一個程序在交換資料,是以,嚴格地講,通信雙方不是主機,而是主機中的程序。

主機中常常有多個應用程序同時在與外部通信(比如浏覽器和 QQ 在同時運作),下圖中,A 主機的 AP1 程序在與 B 主機的 AP3 程序通信,同時主機 A 的 AP2 程序也在與 B 主機的 AP4 程序通信。

兩個主機的傳輸層之間有一個灰色雙向箭頭,寫着“傳輸層提供應用程序間的邏輯通信”。 邏輯通信:看起來是資料似乎是沿着雙向箭頭在傳輸層水準傳輸的,但實際上是沿圖中的虛線經多個協定層次而傳輸。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

TCP/IP 協定棧傳輸層有兩個重要協定——UDP 和 TCP,不同的應用程序在傳輸層使用 TCP 或 UDP 之一:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『端口』:

剛才的圖中,AP1 與 AP3 的通信與 AP2 與 AP4 的通信可以使用同一個傳輸層協定來傳輸(TCP 或 UDP),根據 IP 位址或 MAC 位址都隻能是把資料傳到正确的主機,但具體需要傳到哪一個程序,是通過端口來辨認的。比如同時使用浏覽器和 QQ,浏覽器占用 80 端口,而 QQ 占用 4000 端口,那麼發送過來的 QQ 消息便會通過 4000 端口顯示在 QQ 用戶端,而不會錯誤地顯示在浏覽器上。

端口号有 0~65535 的編号,其中:

  • 編号 0~1023 為 系統端口号 ,這些端口号可以在網址 www.iana.org 查詢到,它們被指派給了 TCP/IP 最重要的一些應用程式,以下是一些常見的系統端口号:
應用層協定: FTP TELNET SMTP DNS TFTP HTTP SNMP
系統端口号: 21 23 25 53 69 80 161
  • 編号 1024~49151 為 登記端口号 ,為沒有系統端口号的應用程式使用,使用這類端口号必須在 IANA 按規定手續登記,以防止重複。
  • 編号 49152~65535 為 短暫端口号 ,是留給客戶程序選擇暫時使用的,使用結束後,這類端口号會被放開以供其它程式使用。

『UDP 概述』:

UDP(User Datagram Protocol)使用者資料報協定,它隻在 IP 資料報服務之上增加了很少一點功能,它的主要特點有:

  • (1).UDP 是無連接配接的,發送資料之前不需要建立連接配接(而 TCP 需要),減少了開銷和時延。
  • (2).UDP盡最大努力傳遞,不保證傳遞可靠性。
  • (3).UDP 是面向封包的,對于從網絡層傳遞下來的 IP 資料報,隻做很簡單的封裝(8 位元組 UDP 報頭),首部開銷小。
  • (4).UDP 沒有擁塞控制,出現網絡擁塞時發送方也不會降低發送速率。這種特性對某些實時應用是很重要的,比如 IP 電話,視訊會議等,它們允許擁塞時丢失一些資料,因為如果不抛棄這些資料,極可能造成時延的累積。
  • (5).UDP 支援一對一、一對多、多對一和多對多的互動通信。

從應用層到傳輸層,再到網絡層的各層次封裝:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『UDP 封包』:

UDP 資料報可分為兩部分:UDP 報頭和資料部分。其中資料部分是應用層傳遞下來的資料。UDP 報頭總共 8 位元組,而這 8 位元組又分為 4 個字段:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • (1)源端口 2 位元組 在對方需要回信時可用,不需要時可以全 0;
  • (2)目的端口 2 位元組 必須,也是最重要的字段;
  • (3)長度 2 位元組 長度值包括報頭和資料部分;
  • (4)校驗和 2 位元組 用于檢驗 UDP 資料報在傳輸過程中是否有出錯,有錯就丢棄。

『tcpdump 抓取 UDP 封包』:

以下程式會向 IP 位址 192.168.1.1 的 7777 端口 發送一條 "hello" 消息。

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>

int main(void)
{
        int sockfd;
        struct sockaddr_in server;
        char msg[20]={0};
        
        sockfd = socket(AF_INET,SOCK_DGRAM,0);
        if (sockfd < 0) {
                perror("socket error!\n");
                exit(-1);
        }
        
        memset(&server,0,sizeof(server));
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = inet_addr("192.168.1.1");
        server.sin_port = htons(7777);
        
        strncpy(msg,"hello",sizeof("hello"));
        
        printf("send message:%s\n",msg);
        
        if (sendto(sockfd,msg,20,0,(struct sockaddr *)&server,sizeof(server)) != 20) {
                perror("sendto error!\n");
                exit(-1);
        }        
 
        exit(0);
}
           

安裝并運作 tcpdump,在另一終端編譯運作以上程式:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

傳回剛才運作 tcpdump 的終端檢視抓包結果:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

六、傳輸層:TCP 協定

『概述』:

TCP 和 UDP 處在同一層——運輸層,但是它們有很多的不同。TCP 是 TCP/IP 系列協定中最複雜的部分,它具有以下特點:

  • (1) TCP 提供 可靠的 資料傳輸服務,TCP 是 面向連接配接的 。應用程式在使用 TCP 通信之前,先要建立連接配接,這是一個類似“打電話”的過程,通信結束後還要“挂電話”。
  • (2) TCP 連接配接是 點對點 的,一條 TCP 連接配接隻能連接配接兩個端點。
  • (3) TCP 提供可靠傳輸,無差錯、不丢失、不重複、按順序。
  • (4) TCP 提供 全雙工 通信,允許通信雙方任何時候都能發送資料,因為 TCP 連接配接的兩端都設有發送緩存和接收緩存。
  • (5) TCP 面向 位元組流 。TCP 并不知道所傳輸的資料的含義,僅把資料看作一連串的位元組序列,它也不保證接收方收到的資料塊和發送方發出的資料塊具有大小對應關系。
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『TCP 封包段結構』:

TCP 是面向位元組流的,而 TCP 傳輸資料的單元是 封包段 。一個 TCP 封包段可分為兩部分:報頭和資料部分。資料部分是上層應用傳遞的資料,而報頭則是 TCP 功能的關鍵。

TCP 封包段的報頭有前 20 位元組的固定部分,後面 4n 位元組是根據需要而添加的字段。如圖則是 TCP 封包段結構:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

20 位元組的固定部分,各字段功能說明:

  • 1.源端口和目的端口:各占 2 個位元組,分别寫入源端口号和目的端口号。這和 UDP 報頭有類似之處,因為都是運輸層協定。
  • 2.序号:占 4 位元組序,序号範圍[0,2^32-1],序号增加到 2^32-1 後,下個序号又回到 0。

    TCP 是面向位元組流的,通過 TCP 傳送的位元組流中的每個位元組都按順序編号,而報頭中的序号字段值則指的是本封包段資料的第一個位元組的序号。

  • 3.确認序号:占 4 位元組,期望收到對方下個封包段的第一個資料位元組的序号。
  • 4.資料偏移:占 4 位,指 TCP 封包段的報頭長度,包括固定的 20 位元組和選項字段。
  • 5.保留:占 6 位,保留為今後使用,目前為 0。
  • 6.控制位:共有 6 個控制位,說明本封包的性質,意義如下:
    • URG 緊急:當 URG=1 時,它告訴系統此封包中有緊急資料,應優先傳送(比如緊急關閉),這要與緊急指針字段配合使用。
    • ACK 确認:僅當 ACK=1 時确認号字段才有效。建立 TCP 連接配接後,所有封包段都必須把 ACK 字段置為 1。
    • PSH 推送:若 TCP 連接配接的一端希望另一端立即響應,PSH 字段便可以“催促”對方,不再等到緩存區填滿才發送。
    • RET 複位:若 TCP 連接配接出現嚴重差錯,RST 置為 1,斷開 TCP 連接配接,再重建立立連接配接。
    • SYN 同步:用于建立和釋放連接配接,稍後會詳細介紹。
    • FIN 終止:用于釋放連接配接,當 FIN=1,表明發送方已經發送完畢,要求釋放 TCP 連接配接。
  • 7.視窗:占 2 個位元組。視窗值是指發送者自己的接收視窗大小,因為接收緩存的空間有限。
  • 8.檢驗和:2 個位元組。和 UDP 封包一樣,有一個檢驗和,用于檢查封包是否在傳輸過程中出差錯。
  • 9.緊急指針:2 位元組。當 URG=1 時才有效,指出本封包段緊急資料的位元組數。
  • 10.選項:長度可變,最長可達 40 位元組。具體的選項字段,需要時再做介紹。

『連接配接的建立與釋放』:

TCP 是面向連接配接的,在傳輸 TCP 封包段之前先要建立連接配接,發起連接配接的一方被稱為用戶端,而響應連接配接請求的一方被稱為服務端,而這個建立連接配接的過程被稱為 三次握手 :

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • (1) 用戶端送出請求連接配接封包段,其中報頭控制位 SYN=1,初始序号 seq=x。用戶端進入 SYN-SENT(同步已發送)狀态。
  • (2) 服務端收到請求封包段後,向用戶端發送确認封包段。确認封包段的首部中 SYN=1,ACK=1,确認号是 ack=x+1,同時為自己選擇一個初始序号 seq=y。服務端進入 SYN-RCVD(同步收到)狀态。
  • (3) 用戶端收到服務端的确認封包段後,還要給服務端發送一個确認封包段。這個封包段中 ACK=1,确認号 ack=y+1,而自己的序号 seq=x+1。這個封包段已經可以攜帶資料,如果不攜帶資料則不消耗序号,則下一個封包段序号仍為 seq=x+1。

至此 TCP 連接配接已經建立,用戶端進入 ESTABLISHED(已建立連接配接)狀态,當服務端收到确認後,也進入 ESTABLISHED 狀态,它們之間便可以正式傳輸資料了。

當傳輸資料結束後,通信雙方都可以釋放連接配接,這個釋放連接配接過程被稱為 釋放連接配接 :

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • (1) 此時 TCP 連接配接兩端都還處于 ESTABLISHED 狀态,用戶端停止發送資料,并發出一個 FIN 封包段。首部 FIN=1,序号 seq=u(u 等于用戶端傳輸資料最後一位元組的序号加 1)。用戶端進入 FIN-WAIT-1(終止等待 1)狀态。
  • (2) 服務端回複确認封包段,确認号 ack=u+1,序号 seq=v(v 等于服務端傳輸資料最後一位元組的序号加 1),服務端進入 CLOSE-WAIT(關閉等待)狀态。現在 TCP 連接配接處于半開半閉狀态,服務端如果繼續發送資料,用戶端依然接收。
  • (3) 用戶端收到确認封包,進入 FIN-WAIT-2 狀态,服務端發送完資料後,發出 FIN 封包段,FIN=1,确認号 ack=u+1,然後進入 LAST-ACK(最後确認)狀态。
  • (4) 用戶端回複确認确認封包段,ACK=1,确認号 ack=w+1(w 為半開半閉狀态時,收到的最後一個位元組資料的編号) ,序号 seq=u+1,然後進入 TIME-WAIT(時間等待)狀态。

注意此時連接配接還沒有釋放,需要時間等待狀态結束後(4 分鐘) 連接配接兩端才會 CLOSED。設定時間等待是因為,有可能最後一個确認封包丢失而需要重傳。

『TCP 可靠傳輸的實作』:

  • (1) TCP 封包段的長度可變,根據收發雙方的緩存狀态、網絡狀态而調整。

(2) 當 TCP 收到發自 TCP 連接配接另一端的資料,它将發送一個确認。

(3) 當 TCP 發出一個段後,它啟動一個定時器,等待目的端确認收到這個封包段,如果不能及時收到一個确認,将重發這個封包段。這就是稍後介紹的逾時重傳。

(4) TCP 将保持它首部和資料的檢驗和。如果通過檢驗和發現封包段有差錯,這個封包段将被丢棄,等待逾時重傳。

(5) TCP 将資料按位元組排序,封包段中有序号,以確定順序的正确性。

(6) TCP 還能提供流量控制。TCP 連接配接的每一方都有收發緩存。TCP 的接收端隻允許另一端發送接收端緩沖區所能接納的資料。這将防止較快主機緻使較慢主機的緩沖區溢出。

可見逾時重發機制是 TCP 可靠性的關鍵,隻要沒有得到确認封包段,就重新發送資料報,直到收到對方的确認為止。

『逾時重傳』:

TCP 規定,接收者收到資料封包段後,需回複一個确認封包段,以告知發送者資料已經收到。而發送者如果一段時間内(逾時計時器)沒有收到确認封包段,便重複發送:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

為了實作逾時間重傳,需要注意:

  • 1.發送者發送一個封包段後,暫時儲存該封包段的副本,為發生逾時重傳時使用,收到确認封包後删除該封包段。
  • 2.确認封包段也需要序号,才能明确是發出去的那個資料報得到了确認。
  • 3.逾時計時器比傳輸往返時間略長,但具體值是不确定的,根據網絡情況而變。

『連續 ARQ 協定』:

逾時重傳機制很費時間,每發送一個資料報都要等待确認。

在實際應用中的真實情況是,采用了流水線傳輸:發送方可以連續發送多個封包段(連續發送的資料長度叫做視窗),而不必每發完一段就停下來等待确認。

實際應用中,接收方也不必對收到的每個封包都做回複,而是采用累積确認方式:接收者收到多個連續的封包段後,隻回複确認最後一個封包段,表示在這之前的資料都已收到。

這樣,傳輸效率得到了很大的提升。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • (1) 慢啟動 :初始的視窗值很小,但是按指數規律漸漸增長,直到達到慢開始門限(ssthresh)。
  • (2) 加性增 :視窗值達到慢開始門限後,每發送一個封包段,視窗值增加一個機關量。
  • (3) 乘性減 :無論什麼階段,隻要出現逾時,則把視窗值減小一半。

參考資料

  • TCP/IP網絡協定基礎 實驗樓教程
  • HTTP協定—— 簡單認識TCP/IP協定
  • DNS協定(一)
  • dns協定 百度百科

一、gcc的使用

『編譯一個C程式』:

以這個程式為例:

#include <stdio.h>

int summary(int n);

int main()
{
        int i,result;

        result = 0;
        for(i=1; i<=100; i++){
        result += i;
        }

        printf("Summary[1-100] = %d\n", result);
        printf("Summary[1-450] = %d\n",summary(450));

        return 0;
}

int summary(int n)
{
        int sum = 0;

        int i;
        for(i=1;i<=n;i++){
                sum += i;
        }

        return sum;
}

           

要編譯一個C語言程式,隻需要使用gcc指令後跟一個C源檔案作為參數。

使用

gcc summary.c

編譯上面的程式summary.c,編譯後産生的可執行檔案叫做a.out,位于目前目錄下:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

執行這個程式,得到:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

a.out為預設檔案名。gcc提供了-o選項讓使用者指定可執行檔案的檔案名。可以使用

gcc -o sum summary.c

指令,将summary.c

如果需要得到彙編代碼等等,需要使用以下選項:

選項 功能
-c 隻激活預處理、編譯和彙編,生成擴充名為.o的目标代碼檔案
-S 隻激活預處理和編譯,生成擴充名為.s的彙編代碼檔案
-E 隻激活預處理,并将結果輸出至标準輸出
-g 為調試程式(如gdb)生成相關資訊

使用-E選項時,gcc會在标準輸出顯示其處理結果。是以應該使用重新定向将其輸出到一個檔案中,如:

gcc -E summary.c > pre_sum

二、調試:gdb

『啟動gdb』:

首先使用

gcc -g

指令生成帶有調試資訊的可執行程式,否則調試時看到的将是一堆彙編代碼。

然後就可以使用gdb指令對生成的二進制檔案進行調試了。

啟動gdb的方法很簡單,将二進制檔案作為gdb的參數就可以了:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

gdb首先會在螢幕上列印一些關于它的版本資訊,随後顯示提示符“(gdb)”等待接受使用者指令。

『檢視源代碼』:

list指令(縮寫為l)用于檢視程式的源代碼:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

gdb會自動在源代碼之前加上行号。第一次使用list指令時列出前10行,可以使用回車表示執行上一條指令。

可以給list指令指定行号,列出該行所在位置附近(10行)的代碼:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

search指令可以搜尋特定的内容。隻會顯示符合條件的第一行,再次按Enter鍵找到比對的下一行代碼。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

可見,在20行之後就沒有“int summary”這個字元串了。

需要注意的是,search隻能朝向檔案尾搜尋,這一點與Vim的“/”指令一樣,隻是gdb的search指令不會在到達檔案尾之後再從頭開始搜尋,而是提醒無法找到比對模式。

使用reverse-search可以向檔案頭搜尋。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

search/reverse-search指令支援使用正規表達式進行搜尋。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『設定斷點』:

break指令(縮寫為b)用于設定斷點,此指令接受行号或者函數名作為參數。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

以上設定了兩個斷點,這樣,當程式運作到第10行及summary()函數的入口就會停下來,等待使用者發出指令。使用info break指令可以檢視已經設定的斷點資訊。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『單步調試』:

使用run指令(縮寫為r)運作程式至斷點。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

使用next指令單步執行程式,此指令接受執行行數作為參數。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

由于進入循環,執行兩步後又回到了第11行。可以使用continue指令(縮寫為c),直至遇到下一個斷點。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『監視變量』:

可以使用print指令(縮寫為p)要求gdb提供指定變量的值。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

每次都使用print未免麻煩,gdb提供了watch指令,用于設定觀察點。watch接受變量名(或者表達式)作為參數,一旦參數的值發生變化,就停下程式。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『臨時修改變量』:

gdb允許使用者在運作程式時改變變量的值,通過set var指令實作這一點。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『檢視堆棧情況』:

每次程式調用一個函數,函數的位址、參數、函數内的局部變量都會被壓入“棧”(Stack)中。使用bt指令可以看到目前運作時棧的情況。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『退出gdb』:

調試完畢,使用quit(縮寫為q)指令退出gdb程式。如果程式還沒有運作完,gdb會要求使用者确認退出指令。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

  • Linux系統程式設計 實驗樓
  • gdb 跟蹤調試指令整理

一、第一個程式:Hello World!

以這個基本的Shell程式為例,該程式用于在螢幕上列印一行字元串“Hello World!”。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

其中,

#! /bin/bash

用于指明運作這個腳本時應該使用哪個Shell程式;

以“#”開頭的是注釋,Shell會自動忽略“#”後面的所有内容;

Shell腳本會自動忽略空行,用空行分割一個程式中不同的任務代碼是一個良好的變成習慣;

echo

指令把其參數傳遞給标準輸出,在這裡就是顯示器。如果參數是一個字元串的話,那麼應該用雙引号把它包含起來。echo指令最後會自動加上一個換行符。

要執行這個Shell腳本,首先應該為它加上可執行權限,完成後就可以運作了。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

二、變量和運算符

『變量的指派和使用』:

以下程式将一個字元串賦給變量,并輸出:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

運作結果:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

在Shell中使用變量不需要事先聲明。使用等号“=”将一個變量右邊的值賦給這個變量時,直接使用變量名就可以了(注意在這裡指派變量時,“=”左右兩邊沒有空格)。

當需要存取變量時,就要使用一個字元來進行變量替換。在BASH中,“$”用于對一個變量進行解析。Shell在碰到帶有“$”的變量時會自動将其替換成這個變量的值。

變量隻在其所在的腳本中有效,退出後将無法查詢變量的值。

  • 使用source指令可以強行讓一個腳本影響其父Shell環境。
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • 與之相反的指令是export。export讓腳本可以影響其子Shell環境。
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
  • 使用unset指令可以手動登出一個變量。

『變量替換』:

如果需要輸出“$”時,需要使用轉義字元“\”。

Shell提供了花括号“{}”來限定一個變量的開始和結束。在緊跟變量輸出字母字尾時,就必須使用這個功能。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『位置變量』:

Shell腳本使用位置變量來儲存參數。傳遞給腳本檔案的參數分别存放在“$”符号帶有數字的變量中。也就是說,第一個參數存放在$1,第二個參數存放在$2...以此類推。當存取的參數超過十個的時候,就要用花括号把這個數字括起來,如${13},${20}等。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

下面是這個程式的運作結果。因為沒有第三個參數,是以$3的值是空的。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『BASH引号規則』:

在Shell腳本中可以使用的引号有如下三種:

  • 雙引号:阻止Shell對大多數特殊字元(例如#)進行解釋。但“$”、“`”和“””仍保持其特殊含義。
  • 單引号:阻止Shell對所有字元進行解釋。
  • 倒引号:“`”位于Esc鍵下方。當用倒引号括起一個Shell指令時,這個指令将會被執行,執行後的輸出結果将作為這個表達式的值。倒引号中的特殊字元一般都會被解釋。

如以下腳本可以顯示這3個引号的不同之處:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

以下是運作結果。可以看到雙引号也會對“`”作出解釋。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

三、表達式求值

觀察以下例子:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

可以看到,運作結果并不是3。Shell腳本語言是一種“弱類型”的語言,它并不知道變量num中儲存的是一個數值,是以在遇到num=$num+2這個指令時,Shell隻是簡單地把$num和“+2”連在一起作為新的值賦給變量num。為了讓Shell得到3,可以使用

$ num=$[ $num + 1 ]

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

可以采用

[base#]n

來表示從二到三十六進制的任何一個n值,例如2#10就表示二進制數10(對應于十進制的2)。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

注意:在“1”、“+”和“2”之間要有空格。

另一種指導Shell進行表達式求值的方法是使用let指令。更準确地說,let指令用于計算整數表達式的值。如:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

四、腳本執行指令和控制語句

『if選擇結構』:

if指令判斷條件是否成立,進而決定是否執行相關的語句。如果不成立,直接跳過這段if結構(以fi作為結束标志),繼續執行後面的腳本。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

運作結果如下:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

注意:這裡用于條件測試的語句[ $password = "mypasswd" ],在[、$password、=和"mypasswd"之間必須存在空格。

下面這個例子展示了如何做出“如果...如果...否則...”這樣的判斷:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『case多選結構』:

case用于在一系列模式中比對某個變量的值,這種結構的基本文法如下:

case word in
	pattern-1)
		commands-1
		;;
	pattern-2)
		commands-2
		;;
	...
	pattern-n)
		commands-n
		;;
	*)
		commands-n+1
		;;
esac
           

變量word逐一從pattern-1到pattern-n的模式進行比較,當找到一個比對的模式後,就執行緊跟在後面的指令commands(可以是多條指令);如果沒有找到比對模式,case語句就什麼都不做。

指令“;;”隻在case結構中出現,Shell一旦遇到這條指令就跳轉到case結構的最後。與此類似的是,C語言提供了break語句在switch結構中實作相同的功能。

星号(*)用于比對所有的字元串,是以一般放在最後。

五、條件測試

『if判斷的依據』:

需要注意的是,if語句本身并不執行判斷。它實際上接受一個程式名作為參數,然後執行這個程式,并根據這個程式的傳回值來判斷是否執行相應程式。如果程式的傳回值是0,就表示“真”,if語句進入對應的語句塊;所有非0的傳回值都表示“假”,if語句直接跳過對應的語句塊。

『test指令和空格的使用』:

既然if語句需要接受一個指令作為參數,那麼像"$password" = "john"這樣的表達式就不能直接放在if語句的後面。是以需要額外引入一個指令,用于判斷表達式的真假。test指令的文法如下:

test expr

,如:

test "$password" = "john"

。如果兩者相等,那麼test指令傳回0;否則傳回1。

同樣地,也可以使用方括号“[”進行條件測試,文法為:

[ expr ]

注意:在Shell程式設計中,空格絕不僅僅是程式設計風格這麼簡單!對比以下三條指令:

password="john"
test "$password" = "john"
[ "$password" = "john" ]
           
  • 第一條是指派語句,在password、=和"john"之間沒有空格;
  • 第二條是條件測試指令,在"$password"、=和"john"之間均有空格;
  • 第三條是條件測試指令(是test指令的另一種寫法),在[、"$password"、=、"john"和]之間均有空格。

如果在指派語句的“=”兩邊加上空格,會導緻文法錯誤。

這是因為,Shell首先是一個指令解釋器,而不是一門程式設計語言。空格在Shell這個“指令解釋器”中用于分隔指令和傳遞給它的參數(或者用于分隔指令的兩個參數)。使用whereis指令查找test和“[”可以看到,這兩個程式檔案存放在/user/bin目錄下。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

是以在上面的例子中,"$password"、=和"john"都是test指令和[指令的參數,參數和指令、參數和參數之間必須用空格分隔。而指派語句password="john"沒有空格,因為password是變量名,不是可執行程式。

test和[指令可以對以下三類表達式進行測試:

  • 字元串比較
  • 檔案測試
  • 數字比較

1、 字元串比較:test和[指令的字元串比較主要用于測試字元串是否為空,或者兩個字元串是否相等。相關選項如下表:

描述
-z str 當字元串str長度為0時傳回真
-n str 當字元串str長度大于0時傳回真
str1 = str2 當字元串str1和str2相等時傳回真
str1 != str2 當字元串str1和str2不相等時傳回真

2、檔案測試:用于判斷一個檔案是否滿足特定的條件。相關選項如下表:

-e 檢查檔案是否存在
-d 檢查檔案是否存在以及該檔案是否是目錄檔案
-f 檢查檔案是否存在以及該檔案是否是普通檔案(不是目錄)
-r 檢查檔案是否存在以及該檔案是否可讀
-w 檢查檔案是否存在以及該檔案是否可寫
-x 檢查檔案是否存在以及該檔案是否可執行
-s 檢查檔案是否存在以及該檔案是否大于0位元組

3、數字比較:test和[指令在數字比較方面隻能用來比較整數(包括負整數和正整數),基本文法為:

test int1 option int2

[ int1 option int2 ]

。其中的option表示比較選項,常用的選項如下表:

英文全稱
-eq 等于 equal
-gt 大于 greater than
-lt 小于 less than
-ne 不等于 not equal
-ge 大于等于 greater or equal
-le 小于等于 less or equal

4、複合表達式:組合使用幾個條件表達式。test和[指令本身内建了操作符來完成條件表達式的組合,如下表:

操作符
!expr “非”運算,當expr為假時傳回真
expr1 -a expr2 “與”運算,當expr1和expr2同時為真時才傳回真
expr1 -o expr2 “或”運算,當expr1或expr2為真時傳回真

六、循環結構

Shell中的循環結構有:while、until和for

『while語句』:

while語句重複執行指令,直到測試條件為假。比如以下這個程式,計算1-100的和:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

運作結果為:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

『until語句』:

until語句是while語句的另一種寫法,隻是測試條件相反而已。

上面的腳本用until語句完成,應該為:

#!/bin/bash

sum=0
number=1

#while test $number -le 100
until ! test $number -le 100
do
	sum=$[ $sum + $number ]
	let number=$number+1
done

echo "The summary is $sum"
           

『for語句』:

如果希望從清單中逐一取一系列的值,此時使用while和until就顯得不太友善。Shell提供了for語句,這個語句在一個值表上疊代執行。for的基本文法如下:

for variable [in list]
do
	commands
done
           

這裡的“值表”是一系列以空格分割的值。Shell每次從這個清單中取出一個值,運作do/done之間的指令,直到取完清單中的所有的值。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習
《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

如果清單中的數字特别多,則需要使用其他方法。Shell本身帶了一個叫做seq的工具,該指令接受一個數字範圍,并把它轉換為一個清單。如果要生成1~9的數字清單,可以:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

七、讀取使用者輸入

read指令可以從标準輸入接收一行資訊。read指令接受一個變量名作為參數,把從标準輸入接收到的資訊存放在這個變量中。如果沒有提供變量名,那麼讀取的資訊将存放在變量REPLY中。比如下面這個例子:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

可以給read指令提供多個變量名作為參數。在這種情況下,read指令會将接收到的行“拆開”分别賦予這些變量。預設情況下,Bash根據空格、制表符和換行符進行拆分。比如下面這個腳本将使用者輸入拆分為兩個單詞分别放在變量first和second中。

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

輸出結果如下:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

如果有多個空格,則按照第一個空格分隔:

《資訊安全系統設計基礎》——預備作業:實驗樓教程學習

  • 進階Bash腳本程式設計指南 實驗樓
  • 玩轉Bash腳本:test測試語句

——————TO BE CONTINUED...——————

  1. A-Z ↩︎