1. 程式人生 > 程式設計 >npm淘寶映象修改講解

npm淘寶映象修改講解

防火牆設定iptables

目錄

iptables簡介

iptables和netfilter的關係

iptables其實不是真正的防火牆,我們可以把它理解成一個客戶端代理,一個Linux防火牆的管理工具,使用者通過iptables這個代理,將使用者的安全設定執行到對應的”安全框架”中,這個”安全框架”才是真正的防火牆,這個框架的名字叫netfilter
netfilter才是防火牆真正的安全框架(framework),netfilter位於核心空間。iptables其實是一個命令列工具,位於使用者空間,我們用這個工具操作真正的框架。
iptables對應在核心中的模組應該是ip_tables,我們檢視系統核心中ip_tables的資訊的時候可以看到ip_tables.ko這個模組是在netfilter這個目錄下的。
netfilter/iptables(下文中簡稱為iptables)組成Linux平臺下的包過濾防火牆,與大多數的Linux軟體一樣,這個包過濾防火牆是免費的,它可以代替昂貴的商業防火牆解決方案,完成封包過濾、封包重定向和網路地址轉換(NAT)等功能。

iptables規則概念

規則(rules) 其實就是網路管理員預定義的條件,規則一般的定義為“如果資料包頭符合這樣的條件,就這樣處理這個資料包”。規則儲存在核心空間的資訊包過濾表中,這些規則分別指定了源地址、目的地址、傳輸協議(如TCP、UDP、ICMP)和服務型別(如HTTP、FTP和SMTP)等。
當資料包與規則匹配時,iptables就根據規則所定義的方法來處理這些資料包,如放行(accept),拒絕(reject)和丟棄(drop)等。配置防火牆的主要工作是新增,修改和刪除這些規則。
其中:

  • 匹配(match):符合指定的條件,比如指定的 IP 地址、埠、協議等。一條命令可以有多個匹配(條件),必須同時滿足才會執行目標。
  • 丟棄(drop):當一個包到達時,簡單地丟棄,不做其它任何處理。
  • 接受(accept):和丟棄相反,接受這個包,讓這個包通過。
  • 拒絕(reject):和丟棄相似,但它還會向傳送這個包的源主機發送錯誤訊息。這個錯誤訊息可以指定,也可以自動產生。
  • 目標(target):指定的動作,說明如何處理一個包,比如:丟棄,接受,或拒絕。只有匹配的資料包才會執行目標。
  • 跳轉(jump):和目標類似,不過它指定的不是一個具體的動作,而是另一個鏈,表示要跳轉到那個鏈上。
  • 規則(rule):一個或多個匹配及其對應的目標。iptables設定一條命令就是設定一條規則。

iptables的四表五鏈

表(tables):提供特定的功能,iptables內建了4個表,即filter表、nat表、mangle表和raw表,分別用於實現包過濾,網路地址轉換、包重構(修改)和資料跟蹤處理。
鏈(chains):是資料包傳播的路徑,每一條鏈其實就是眾多規則中的一個檢查清單,每一條鏈中可以有一條或數條規則。當一個數據包到達一個鏈時,iptables就會從鏈中第一條規則開始檢查,看該資料包是否滿足規則所定義的條件。如果滿足,系統就會根據 該條規則所定義的方法處理該資料包;否則iptables將繼續檢查下一條規則,如果該資料包不符合鏈中任一條規則,iptables就會根據該鏈預先定義的預設策略來處理資料包。
Iptables採用“表”和“鏈”的分層結構,在Linux中現在是四張表五個鏈。下面羅列一下這四張表和五個鏈(注意一定要明白這些表和鏈的關係及作用)。

規則表

  • filter表——三個鏈:INPUT、FORWARD、OUTPUT
     作用:過濾資料包。
     核心模組:iptables_filter。
  • Nat表——三個鏈:PREROUTING、POSTROUTING、OUTPUT
     作用:用於網路地址轉換(IP、埠)
     核心模組:iptable_nat
  • Mangle表——五個鏈:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
     作用:修改資料包的服務型別、TTL、並且可以配置路由實現QOS
     核心模組:iptable_mangle(別看這個表這麼麻煩,咱們設定策略時幾乎都不會用到它)
  • Raw表——兩個鏈:OUTPUT、PREROUTING
     作用:決定資料包是否被狀態跟蹤機制處理
     核心模組:iptable_raw

規則鏈

1)INPUT——進來的資料包應用此規則鏈中的策略
2)OUTPUT——外出的資料包應用此規則鏈中的策略
3)FORWARD——轉發資料包時應用此規則鏈中的策略
4)PREROUTING——對資料包作路由選擇前應用此鏈中的規則
(記住!所有的資料包進來的時侯都先由這個鏈處理)
5)POSTROUTING——對資料包作路由選擇後應用此鏈中的規則
(所有的資料包出來的時侯都先由這個鏈處理)

iptables傳輸資料包的過程

從網上找了兩個流程圖。


1)當一個數據包進入網絡卡時,它首先進入PREROUTING鏈,核心根據資料包目的IP判斷是否需要轉送出去。
2)如果資料包就是進入本機的,它就會沿著圖向下移動,到達INPUT鏈。資料包到了INPUT鏈後,任何程序都會收到它。
3)如果資料包是要轉發出去的,且核心允許轉發,資料包就會如圖所示向右移動,經過FORWARD鏈,然後到達POSTROUTING鏈輸出。
4)本機上執行的程式可以傳送資料包,這些資料包會經過OUTPUT鏈,然後到達POSTROUTING鏈輸出。

注意每一個鏈對應的表都是不完全一樣的,表和鏈之間是多對多的對應關係。但是不管一個鏈對應多少個表,它的表都是按照下面的優先順序來進行查詢匹配的。
表的處理優先順序:raw>mangle>nat>filter。

iptables命令

語法規則

iptables [-t table] COMMAND [chain] CRETIRIA -j ACTION

-t table,是指操作的表,filter、nat、mangle或raw, 預設使用filter
COMMAND,子命令,定義對規則的管理,包括:增加,刪除,插入,替換,顯示等
chain, 指明鏈路,可以是五鏈,也可以是自定義的鏈
CRETIRIA, 匹配的條件或標準,包括協議、IP、埠、介面等條件
ACTION,操作動作,ACCEPT、DROP、REJECT

命令選項輸入順序

iptables [-t table] <-A/I/D/R> 規則鏈名 [規則號] <-i/o 網絡卡名> -p 協議名 <-s 源IP/源子網> --sport 源埠 <-d 目標IP/目標子網> --dport 目標埠 -j 動作

鏈管理

  • -N,--new-chain chain  新建一個自定義的規則鏈;
  • -X, --delete-chain [chain]  刪除使用者自定義的引用計數為0的空鏈;所以,在刪除前要清空鏈。
  • -F, --flush [chain]  清空指定的規則鏈上的規則;
  • -E, --rename-chain old-chain new-chain  重新命名鏈;
  • -Z, --zero [chain [rulenum]]  置零計數器;
  • -P, --policy chain target  設定鏈路的預設策略

注意:“,”分隔了兩種用法,比如:新建鏈可以用命令-N,也可以用--new-chain。

規則管理

  • -A, --append chain rule-specification:追加新規則於指定鏈的尾部;
  • -I, --insert chain [rulenum] rule-specification:插入新規則於指定鏈的指定位置,預設為首部;
  • -R, --replace chain rulenum rule-specification:替換指定的規則為新的規則;
  • -D, --delete chain rulenum:根據規則編號刪除規則;

檢視規則

  • -L, --list [chain]:列出規則;
  • -v, --verbose:詳細資訊;
  • -vv, -vvv 更加詳細的資訊
  • -n, --numeric:數字格式顯示主機地址和埠號;
  • -x, --exact:顯示計數器的精確值;
  • --line-numbers:列出規則時,顯示其在鏈上的相應的編號;
  • -S, --list-rules [chain]:顯示指定鏈的所有規則;

匹配條件

匹配條件包括通用匹配條件和擴充套件匹配條件
通用匹配條件是指標對源地址、目標地址的匹配,包括單一源IP、單一源埠、單一目標IP、單一目標埠、資料包流經的網絡卡以及協議。
擴充套件匹配條件指通用匹配之外的匹配條件。
當一條規則裡面有多個條件時,多個條件之間是與的關係,資料包只有滿足所有的條件才會生效。

通用匹配條件

  • [!] -s, --source address[/mask][,...]:檢查報文的源IP地址是否符合此處指定的範圍,或是否等於此處給定的地址;
  • [!] -d, --destination address[/mask][,...]:檢查報文的目標IP地址是否符合此處指定的範圍,或是否等於此處給定的地址;
  • [!] -p, --protocol protocol:匹配報文中的協議,可用值tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh 或者 "all", 亦可以數字格式指明協議;
  • [!] -i, --in-interface name:限定報文僅能夠從指定的介面流入;only for packets entering the INPUT, FORWARD and PREROUTING chains.
  • [!] -o, --out-interface name:限定報文僅能夠從指定的介面流出;only for packets entering the FORWARD, OUTPUT and POSTROUTING chains.

注意:“!”表示取反,比如 "! -p tcp" 表示匹配非TCP協議。

擴充套件匹配條件-隱含擴充套件匹配

1. -p tcp:TCP協議的擴充套件

  • [!] --destination-port,--dport port[:port]:指定目標埠,不能指定多個非連續埠,只能指定單個埠,比如--dport 21 (表示埠21) 或者 --dport 21:23 (此時表示21,22,23)
  • [!] --source-port,--sport port[:port]:指定源埠
  • --tcp-fiags mask [comp]:TCP的標誌位(SYN,ACK,FIN,PSH,RST,URG)
    mask:要檢查的FLAGS list,以逗號分隔;
    comp:在mask給定的諸多的FLAGS中,其值必須為1的FLAGS列表,餘下的其值必須為0;

2. -p udp:可直接使用udp協議擴充套件模組的專用選項:

  • [!] --source-port,--sport port[:port]
  • [!] --destination-port,--dport port[:port]

擴充套件匹配條件-顯示擴充套件匹配

顯示擴充套件匹配必須用-m

-m option
1. 多埠匹配

multiport以離散或連續的方式定義多埠匹配條件,最多15個

  • [!] --source-ports,--sports port[,port,port:port]...:指定多個源埠,以逗號分隔
  • [!] --destination-ports,--dports port[,port|,port:port]...:指定多個目標埠
iptables -I INPUT -d 172.16.0.7 -p tcp -m multiport --dports 22,80,139,445,3306 -j ACCEPT
2. 多IP地址匹配

iprange以連續地址塊的方式來指明多IP地址匹配條件

  • [!] --src-range from[-to]
  • [!] --dst-range from[-to]
iptables -I INPUT -d 172.16.0.7 -p tcp -m multiport --dports 22,80,139,445,3306 -m iprange --src-range 172.16.0.61-172.16.0.70 -j REJECT
3. 字串匹配

string擴充套件模組對報文中的應用層資料做字串模式匹配檢測
字元匹配可以用來做URL過濾

  • --algo {bm|kmp}:字串匹配檢測演算法。bm:Boyer-Moore;kmp:Knuth-Pratt-Morris
  • [!] --string pattern:要檢測的字串模式,只能處理明文資料
  • [!] --hex-string pattern:要檢測的字串模式,16進位制格式
iptables -A OUTPUT -m string --string "baidu"  --algo bm -j DROP
4. time擴充套件模組

time擴充套件模組,根據時間段區匹配報文,如果報文到達的時間在指定的時間範圍以內,則符合匹配條件。

  • --timestart hh:mm[:ss]
  • --timestop hh:mm[:ss]
  • [!] --weekdays day[,day...]
  • [!] --monthdays day[,day...]
  • --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
  • --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
  • --kerneltz:使用核心配置的時區而非預設的UTC;
# 週末早上9點到下午6點不能瀏覽網頁
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --weekdays 6,7 --timestart 09:00:00 --timestop 18:00:00 -j REJECT
5. connlimit:限制同一IP的連線數

使用connlimit擴充套件模組,可以限制每個IP(或網段)地址同時連結到server端的連結數量,注意:我們不用指定IP,其預設就是針對”每個客戶端IP”,即對單IP的併發連線數限制。

[!] --connlimit-above n    # 連線上限超過n個則匹配
[!] --connlimit-mask n     # 這組主機的掩碼,預設是connlimit-mask 32 ,即每個IP。
[!] --connlimit-upto n    # 連線上限未達到n個則匹配

# 每個客戶端IP的ssh併發連線數不能高於2
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-avove 2 -j REJECT
6. limit:限速
  • --limit rate[/second|/minute|/hour|/day] # 每秒/分鐘/小時/天允許通過的資料包個數。
  • --limit-burst number # 最初的令牌數,預設是5個

想要理解limit模組的工作原理,我們需要先了解一下”令牌桶”演算法,因為limit模組使用了令牌桶演算法。
我們可以這樣想象,有一個木桶,木桶裡面放了5塊令牌,而且這個木桶最多也只能放下5塊令牌,所有報文如果想要出關入關,都必須要持有木桶中的令牌才行,這個木桶有一個神奇的功能,就是每隔6秒鐘會生成一塊新的令牌,如果此時,木桶中的令牌不足5塊,那麼新生成的令牌就存放在木桶中,如果木桶中已經存在5塊令牌,新生成的令牌就無處安放了,只能溢位木桶(令牌被丟棄),如果此時有5個報文想要入關,那麼這5個報文就去木桶裡找令牌,正好一人一個,於是他們5個手持令牌,快樂的入關了,此時木桶空了,再有報文想要入關,已經沒有對應的令牌可以使用了,但是,過了6秒鐘,新的令牌生成了,此刻,正好來了一個報文想要入關,於是,這個報文拿起這個令牌,就入關了,在這個報文之後,如果很長一段時間內沒有新的報文想要入關,木桶中的令牌又會慢慢的積攢了起來,直到達到5個令牌,並且一直保持著5個令牌,直到有人需要使用這些令牌,這就是令牌桶演算法的大致邏輯。
那麼,就拿剛才的”令牌桶”理論類比我們的命令,”–limit”選項就是用於指定”多長時間生成一個新令牌的”,”–limit-burst”選項就是用於指定”木桶中最多存放幾個令牌的”。

限制每分鐘最多放行10個icmp包
iptables -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
但是我測試發現ping命令的資料包一直可以通過。為什麼會這樣呢?原來是預設策略是放行,報文會匹配鏈中的每一條規則,如果沒有任何一條規則能夠匹配到,則匹配預設動作(鏈的預設策略)。所以我們需要把預設策略設定成REJECT。
正確的命令:

iptables -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
iptables -A INPUT -p icmp -j REJECT
7. state:收發包的狀態

[!] --state state

state的值可以是:INVALID, ESTABLISHED, NEW, RELATED or UNTRACKED.
NEW: 新連線請求;
ESTABLISHED:已建立的連線;
INVALID:無法識別的連線,包沒有辦法被識別,或者這個包沒有任何狀態
RELATED:相關聯的連線,當前連線是一個新請求,但附屬於某個已存在的連線;
UNTRACKED:未追蹤的連線;當報文的狀態為Untracked時通常表示無法找到相關的連線

state模組用在什麼地方呢?
我們試想一下這麼一個場景,我們只允許區域網中的某臺PC(192.168.0.100)訪問外部的網站,其餘的PC不允許訪問外網,那我們應該如何設定呢?如果只對源IP進行匹配,放行源IP是192.168.0.100的PC,但是我們訪問外網是一個互動的過程,即當192.168.0.100發起連線或者請求時,server會有響應,如果只設置源IP是192.168.0.100,很顯然無法完成互動的,需要把server的IP也設定為允許,但是我們把外網的源IP也加入accept中也不現實,因為外網很多,我們不能把所有的都加進去吧,而且,我們想要允許接收的是外網的響應報文,過濾掉外網主動發起的報文。
那麼,用–tcp-flags去匹配tcp報文的標誌位,把外來的”第一次握手”的請求拒絕,是不是也可以呢?顯然也不可以,因為如果對方使用的是UDP協議或者ICMP協議呢?
所以,我們需要解決的問題是:怎樣判斷這些報文是為了迴應我們之前發出的報文,還是主動向我們傳送的報文呢?
我們可以通過iptables的state擴充套件模組解決上述問題。

state模組的“連線”和TCP/IP協議簇的連線不是一個概念,在TCP/IP中,TCP是面向連線的,有3次握手和4次揮手,UDP和ICMP是無連線的。但是對於state來說,只要兩臺裝置(更精確來說是兩個socket)有“你來我往”的通訊就算是建立連線了,所以對state模組來說TCP/UDP/ICMP都是有連線的。
對於state模組的連線而言,”連線”其中的報文可以分為5種狀態,報文狀態可以為NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED。
NEW:連線中的第一個包,狀態就是NEW,我們可以理解為新連線的第一個包的狀態為NEW。
ESTABLISHED:我們可以把NEW狀態包後面的包的狀態理解為ESTABLISHED,表示連線已建立。

RELATED是相關聯的連線,舉個例子:比如FTP服務,FTP服務端會建立兩個程序,一個命令程序,一個數據程序。命令程序負責服務端與客戶端之間的命令傳輸(我們可以把這個傳輸過程理解成state中所謂的一個”連線”,暫稱為”命令連線”)。資料程序負責服務端與客戶端之間的資料傳輸 ( 我們把這個過程暫稱為”資料連線” )。但是具體傳輸哪些資料,是由命令去控制的,所以,”資料連線”中的報文與”命令連線”是有”關係”的。那麼,”資料連線”中的報文可能就是RELATED狀態,因為這些報文與”命令連線”中的報文有關係。
注:如果想要對ftp進行連線追蹤,需要單獨載入對應的核心模組nf_conntrack_ftp,如果想要自動載入,可以配置/etc/sysconfig/iptables-config檔案

回到上面的問題,如果只放行響應報文?
iptables -t filter -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

參考:iptables詳解(8):iptables擴充套件模組之state擴充套件

易錯點

預設丟棄只允許某些通過

iptables要只允許某些IP,切記先放行這些IP,最後拒絕所有IP,順序不能亂,且拒絕規則不可少
iptables是按照規則順序進行匹配的,一旦遇到匹配的規則(拒絕或者允許),對這個埠/服務的規則就不往下走了。

參考

linux iptables man
iptables命令使用詳解
IPtables之三:顯式擴充套件規則
iptables的四表五鏈與NAT工作原理
centos下iptables防火牆規則用法和概述
iptables命令的使用
iptables詳解(5):iptables匹配條件總結之二(常用擴充套件模組)