Linux常用網絡工具總結

原文鏈接:http://int32bit.me/2016/05/04/Linux常用網絡工具總結/

本文整理了在實踐過程中使用的Linux網絡工具,這些工具提供的功能非常強大,我們平時使用的只是冰山一角,比如lsofiptcpdumpiptables等。本文不會深入研究這些命令的強大用法,因爲每個命令都足以寫一篇文章,本文只是簡單地介紹並輔以幾個簡單demo實例,旨在大腦中留個印象,平時遇到問題時能夠快速搜索出這些工具,利用強大的man工具,提供一定的思路解決問題。

ping

使用這個命令判斷網絡的連通性以及網速,偶爾還順帶當做域名解析使用(查看域名的IP):

ping google.com

默認使用該命令會一直髮送ICMP包直到用戶手動中止,可以使用-c命令指定發送數據包的個數,使用-W指定最長等待時間,如果有多張網卡,還可以通過-I指定發送包的網卡。

小技巧: 在ping過程中按下ctrl+|會打印出當前的summary信息,統計當前發送包數量、接收數量、丟包率等。

其他比如-b發送廣播,另外注意ping只能使用ipv4,如果需要使用ipv6,可以使用ping6命令。

netstat

這個命令用來查看當前建立的網絡連接(深刻理解netstat每一項代表的含義)。最經典的案例就是查看本地系統打開了哪些端口:

fgp@controller:~$ sudo netstat -lnpt
[sudo] password for fgp:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      2183/mysqld
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      2506/memcached
tcp        0      0 0.0.0.0:9292            0.0.0.0:*               LISTEN      1345/python
tcp        0      0 0.0.0.0:6800            0.0.0.0:*               LISTEN      2185/ceph-osd
tcp        0      0 0.0.0.0:6801            0.0.0.0:*               LISTEN      2185/ceph-osd
tcp        0      0 0.0.0.0:28017           0.0.0.0:*               LISTEN      1339/mongod
tcp        0      0 0.0.0.0:6802            0.0.0.0:*               LISTEN      2185/ceph-osd
tcp        0      0 0.0.0.0:6803            0.0.0.0:*               LISTEN      2185/ceph-osd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1290/sshd

netstat能夠查看所有的網絡連接,包括unix socket連接,其功能非常強大。

另外使用netstat還可以查看本地路由表:

fgp@controller:~$ sudo netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 brqcb225471-1f
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 brqcb225471-1f
192.168.56.0    0.0.0.0         255.255.255.0   U         0 0          0 eth1

以上Genmask0.0.0.0的表示默認路由,即連接外網的路由網絡中0.0.0.0的IP地址表示整個網絡,即網絡中的所有主機。它的作用是幫助路由器發送路由表中無法查詢的包。如果設置了全零網絡的路由,路由表中無法查詢的包都將送到全零網絡的路由中去。

lsof

lsof命令用來查看打開的文件(list open files),由於在Linux中一切皆文件,那socket、pipe等也是文件,因此能夠查看網絡連接以及網絡設備,其中和網絡最相關的是-i選項,它輸出符合條件的進程(4、6、協議、:端口、 @ip等),它的格式爲[46][protocol][@hostname|hostaddr][:service|port],比如查看22端口有沒有打開,哪個進程打開的:

fgp@controller:~$ sudo lsof -i :22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1290 root    3u  IPv4  10300      0t0  TCP *:ssh (LISTEN)
sshd    1290 root    4u  IPv6  10302      0t0  TCP *:ssh (LISTEN)

可見22端口是sshd這個命令,其進程號pid爲1290打開的。

可以指定多個條件,但默認是OR關係的,如果需要AND關係,必須傳入-a參數,比如查看22端口並且使用Ipv6連接的進程:

fgp@controller:~$ sudo lsof -c sshd -i 6 -a -i :22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1290 root    4u  IPv6  10302      0t0  TCP *:ssh (LISTEN)

列出所有與192.168.56.1(我的宿主機IP地址)的ipv4連接:

fgp@controller:~$ sudo lsof -i [email protected]
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    2299 root    3u  IPv4  14047      0t0  TCP controller:ssh->mac:54558 (ESTABLISHED)
sshd    2377  fgp    3u  IPv4  14047      0t0  TCP controller:ssh->mac:54558 (ESTABLISHED)

iftop

用過top以及iotop的,自然能夠大致猜到iftop的功能,它是用於查看網絡流量的工具(display bandwidth usage on an interface by host):

sudo iftop

iftop

nc

nc(netcat)被稱爲網絡工具的瑞士軍刀,其非常輕巧但功能強大!常常作爲網絡應用的Debug分析器,可以根據需要創建各種不同類型的網絡連接。官方描述的功能包括:

  • simple TCP proxies
  • shell-script based HTTP clients and servers
  • network daemon testing
  • a SOCKS or HTTP ProxyCommand for ssh(1)
  • and much, much more

總之非常強大,能夠實現簡單的聊天工具、模擬ssh登錄遠程主機、遠程傳輸文件等。一個經典的用法是端口掃描。比如我要掃描192.168.56.2主機1~100端口,探測哪些端口開放的(黑客攻擊必備):

fgp@controller:~$ nc -zv 192.168.56.2 1-100 |& grep 'succeeded!'
Connection to 192.168.56.2 22 port [tcp/ssh] succeeded!
Connection to 192.168.56.2 80 port [tcp/http] succeeded!

從結果中發現,該主機打開了2280端口。

tcpdump

tcpdump(dump traffic on a network)是一個強大的命令行抓包工具,千萬不要被它的名稱誤導以爲只能抓取tcp包,它能抓任何協議的包。它能夠實現Wireshark一樣的功能,並且更加靈活自由!比如需要抓取目標主機是192.168.56.1,通過端口22的傳輸數據包:

sudo tcpdump -n -i eth1 'dst host 192.168.56.1 && port 22'

輸出爲:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
23:57:39.507490 IP 192.168.56.2.22 > 192.168.56.1.54558: Flags [P.], seq 3010719012:3010719120, ack 1116715283, win 354, options [nop,nop,TS val 1049052 ecr 187891473], length 108
23:57:39.507607 IP 192.168.56.2.22 > 192.168.56.1.54558: Flags [P.], seq 108:144, ack 1, win 354, options [nop,nop,TS val 1049052 ecr 187891473], length 36
23:57:39.507784 IP 192.168.56.2.22 > 192.168.56.1.54558: Flags [P.], seq 144:252, ack 1, win 354, options [nop,nop,TS val 1049052 ecr 187891476], length 108

抓取HTTP包:

sudo tcpdump  -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854

其中0x4745"GET"前兩個字母"GE",0x4854"HTTP"前兩個字母"HT"

指定-A以ACII碼輸出數據包,使用-c指定抓取包的個數。

telnet

telnet協議客戶端(user interface to the TELNET protocol),不過其功能並不僅僅限於telnet協議,有時也用來探測端口,比如查看本地端口22是否開放:

fgp@controller:~$ telnet localhost 22
Trying ::1...
Connected to localhost.
Escape character is '^]'.
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6

可見成功連接到localhost22端口,說明端口已經打開,還輸出了banner信息。

ifconfig

ifconfig也是熟悉的網卡配置工具(configure a network interface),我們經常使用它來查看網卡信息(比如IP地址、發送包的個數、接收包的個數、丟包個數等)以及配置網卡(開啓關閉網卡、修改網絡mtu、修改ip地址等)。

查看網卡ip地址:

fgp@controller:~$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 08:00:27:c9:b4:f2
          inet6 addr: fe80::a00:27ff:fec9:b4f2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:27757 errors:0 dropped:0 overruns:0 frame:0
          TX packets:589 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:10519777 (10.5 MB)  TX bytes:83959 (83.9 KB)

爲網卡eth0增加一個新的地址(虛擬網卡):

fgp@controller:~$ sudo ifconfig eth0:0 10.103.240.2/24
fgp@controller:~$ ifconfig eth0:0
eth0:0    Link encap:Ethernet  HWaddr 08:00:27:c9:b4:f2
          inet addr:10.103.240.2  Bcast:10.103.240.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

關閉網卡以及開啓網卡:

sudo ifconfig eth0 down
sudo ifconfig eth0 up

nslookup & dig

nslookup用於交互式域名解析(query Internet name servers interactively),當然也可以直接傳入域名作爲Ad-Hoc命令使用,比如查看google.com的ip地址:

fgp@controller:~$ nslookup google.com
Server:         114.114.114.114
Address:        114.114.114.114#53

Non-authoritative answer:
Name:   google.com
Address: 37.61.54.158

查看使用的DNS服務器地址:

fgp@controller:~$ nslookup
> server
Default server: 114.114.114.114
Address: 114.114.114.114#53
Default server: 8.8.8.8
Address: 8.8.8.8#53

dig命令也是域名解析工具(DNS lookup utility),不過提供的信息更全面:

fgp@controller:~$ dig google.com

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53828
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 4

;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             2730    IN      A       37.61.54.158

;; AUTHORITY SECTION:
google.com.             10204   IN      NS      ns2.google.com.
google.com.             10204   IN      NS      ns4.google.com.
google.com.             10204   IN      NS      ns3.google.com.
google.com.             10204   IN      NS      ns1.google.com.

;; ADDITIONAL SECTION:
ns1.google.com.         86392   IN      A       216.239.32.10
ns2.google.com.         80495   IN      A       216.239.34.10
ns3.google.com.         85830   IN      A       216.239.36.10
ns4.google.com.         13759   IN      A       216.239.38.10

;; Query time: 17 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Thu May 05 00:11:48 CST 2016
;; MSG SIZE  rcvd: 180

whois

whois用於查看域名所有者的信息(client for the whois directory service),比如註冊郵箱、手機號碼、域名服務商等:

fgp@controller:~$ whois coolshell.cn
Domain Name: coolshell.cn
ROID: 20090825s10001s91994755-cn
Domain Status: ok
Registrant ID: hc401628324-cn
Registrant: 陳皓
Registrant Contact Email: [email protected]
Sponsoring Registrar: 阿里雲計算有限公司(萬網)
Name Server: f1g1ns1.dnspod.net
Name Server: f1g1ns2.dnspod.net
Registration Time: 2009-08-25 00:40:26
Expiration Time: 2020-08-25 00:40:26
DNSSEC: unsigned

我們發現coolshell.cn這個域名是陳皓在萬網購買註冊的,註冊時間是2009年,註冊郵箱是[email protected]

route

route命令用於查看和修改路由表:

查看路由表:

fgp@controller:~$ sudo route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 brqcb225471-1f
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 brqcb225471-1f
192.168.56.0    0.0.0.0         255.255.255.0   U     0      0        0 eth1

增加/刪除路由分別爲add/del子命令,比如刪除默認路由:

sudo route del default

增加默認路由,網關爲192.168.1.1,網卡爲brqcb225471-1f:

sudo route add default gw 192.168.1.1 dev brqcb225471-1f

ip

ip命令可以說是無比強大了,它完全可以替換ifconfignetstatroutearp等命令,比如查看網卡eth1 IP地址:

[] 內的內容意思是:可寫可不寫
如果是{},那就必須要在{}內給出的選擇裏選一個。

fgp@controller:~$ sudo ip addr ls  dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:9a:d5:d1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.56.2/24 brd 192.168.56.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe9a:d5d1/64 scope link
       valid_lft forever preferred_lft forever

查看網卡eth1配置:

fgp@controller:~$ sudo ip link ls eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:9a:d5:d1 brd ff:ff:ff:ff:ff:ff

查看路由:

fgp@controller:~$ ip route
default via 192.168.1.1 dev brqcb225471-1f
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1
192.168.1.0/24 dev brqcb225471-1f  proto kernel  scope link  src 192.168.1.105
192.168.56.0/24 dev eth1  proto kernel  scope link  src 192.168.56.2

查看arp信息:

fgp@controller:~$ sudo ip neigh
192.168.56.1 dev eth1 lladdr 0a:00:27:00:00:00 REACHABLE
192.168.0.6 dev vxlan-80 lladdr fa:16:3e:e1:30:c8 PERMANENT
172.17.0.2 dev docker0 lladdr 02:42:ac:11:00:02 STALE
192.168.56.3 dev eth1  FAILED
192.168.1.1 dev brqcb225471-1f lladdr 30:fc:68:41:12:c6 STALE

查看網絡命名空間:

fgp@controller:~$ sudo ip netns ls
qrouter-24bf83c7-f61d-496b-8115-09f0f3d64d21
qdhcp-9284d7a8-711a-4927-8a10-605b34372768
qdhcp-cb225471-1f85-4771-b24b-a4a7108d93a4

進入某個網絡命名空間:

fgp@controller:~$ sudo ip netns exec qrouter-24bf83c7-f61d-496b-8115-09f0f3d64d21 bash
root@controller:~# ifconfig
qg-0d258e6d-83 Link encap:Ethernet  HWaddr fa:16:3e:93:6f:a3
          inet addr:172.16.1.101  Bcast:172.16.1.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fe93:6fa3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1035 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:102505 (102.5 KB)  TX bytes:1200 (1.2 KB)

brctl

brctl是linux網橋管理工具,可用於查看網橋、創建網橋、把網卡加入網橋等。

查看網橋:

fgp@controller:~$ sudo brctl show
bridge name     bridge id               STP enabled     interfaces
brq9284d7a8-71          8000.12841adee45f       no              tap36daf550-27
                                                        tape729e013-df
                                                        vxlan-80
brqcb225471-1f          8000.080027c9b4f2       no              eth0
                                                        tap0d258e6d-83
                                                        tapb844e7a5-83
docker0         8000.0242e4580b61       no              veth50ed8dd

以上因爲部署了openstack neutron以及docker,因此網橋比較複雜。 其他子命令如addbr用於創建網橋、delbr用戶刪除網橋(刪除之前必須處於down狀態,使用ip link set br_name down)、addif把網卡加到網橋等。

traceroute

ping命令用於探測兩個主機間連通性以及響應速度,而traceroute會統計到目標主機的每一跳的網絡狀態(print the route packets trace to network host),這個命令常常用於判斷網絡故障,比如本地不通,可使用該命令探測出是哪個路由出問題了。如果網絡很卡,該命令可判斷哪裏是瓶頸:

fgp@controller:~$ sudo traceroute  -I -n int32bit.me
traceroute to int32bit.me (192.30.252.154), 30 hops max, 60 byte packets
 1  192.168.1.1  4.610 ms  5.623 ms  5.515 ms
 2  117.100.96.1  5.449 ms  5.395 ms  5.356 ms
 3  124.205.97.48  5.362 ms  5.346 ms  5.331 ms
 4  218.241.165.5  5.322 ms  5.310 ms  5.299 ms
 5  218.241.165.9  5.187 ms  5.138 ms  7.386 ms
 ...

可以看到,從主機到int32bit.me共經過30跳,並統計了每一跳間的響應時間。

另外可以參考tracepath

mtr

mtr是常用的網絡診斷工具(a network diagnostic tool),它把ping和traceroute併入一個程序的網絡診斷工具中並實時刷新。

mtr -n int32bit.me

輸出如圖:mtr從圖上可以看出從本地到int32bit.me經過的所有路由,每一個路由間的丟包率、響應時間等。

ss

ss命令也是一個查看網絡連接的工具(another utility to investigate sockets),用來顯示處於活動狀態的套接字信息。關於ss的描述,引用Linux命令大全-ss命令

ss命令可以用來獲取socket統計信息,它可以顯示和netstat類似的內容。但ss的優勢在於它能夠顯示更多更詳細的有關TCP和連接狀態的信息,而且比netstat更快速更高效。當服務器的socket連接數量變得非常大時,無論是使用netstat命令還是直接cat /proc/net/tcp,執行速度都會很慢。可能你不會有切身的感受,但請相信我,當服務器維持的連接達到上萬個的時候,使用netstat等於浪費 生命,而用ss纔是節省時間。 天下武功唯快不破。ss快的祕訣在於,它利用到了TCP協議棧中tcp_diag。tcp_diag是一個用於分析統計的模塊,可以獲得Linux 內核中第一手的信息,這就確保了ss的快捷高效。當然,如果你的系統中沒有tcp_diag,ss也可以正常運行,只是效率會變得稍慢。

其中比較常用的參數包括:

  • -l 查看處於LISTEN狀態的連接
  • -t 查看tcp連接
  • -4 查看ipv4連接
  • -n 不進行域名解析

因此我們可以通過ss命令查看本地監聽的所有端口(和netstat命令功能類似):

ss  -t -l -n -4

輸出如圖:ss

curl

curl是強大的URL傳輸工具,支持FILE, FTP, HTTP, HTTPS, IMAP, LDAP, POP3,RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET以及TFTP等協議。我們使用這個命令最常用的功能就是通過命令行發送HTTP請求以及下載文件,它幾乎能夠模擬所有瀏覽器的行爲請求,比如模擬refer(從哪個頁面跳轉過來的)、cookie、agent(使用什麼瀏覽器)等等,同時還能夠模擬表單數據。

curl -X POST -d "DDDDD=2013140333&upass=1q2w3e4r&save_me=1&R1=0" 10.3.8.211

以上方法利用curl往認證服務器發送POST請求發送數據爲用戶名以及密碼(模擬表單輸入)。

具體用法參考buptLogin

Openstack的命令行工具,比如nova,傳入--debug參數就會顯示curl往nova-api的curl REST請求。

curl命令非常強大,掌握了它能夠發揮巨大的作用,其他有用參數列舉如下:

  • -i 顯示頭部信息
  • -I 只顯示頭部信息,不顯示正文
  • -X 指定請求方法,比如GET、POST等
  • -d 發送數據
  • --form模擬表單,利用這個參數可以上傳文件、模擬點擊按鈕等
  • -A 指定用戶代理,比如Mozilla/4.0,有些坑爹網址必須使用IE訪問怎麼辦
  • -b 設置cookie
  • -c 指定cookie文件
  • -e 指定referer,有些網址必須從某個頁面跳轉過去
  • --header 設置請求的頭部信息
  • --user 有些頁面需要HTTP認證, 傳遞name:password認證

wget

wget是一個強大的非交互網絡下載工具(The non-interactive network downloader),雖然curl也支持文件下載,不過wget更強大,比如支持斷點下載等。

最簡單的用法直接加上文件URL即可:

wget http://xxx/xxx/video.mp4

使用-r參數爲遞歸的下載網頁,默認遞歸深度爲5,相當於爬蟲,用戶可以通過-l指定遞歸深度。

注意wget默認沒有開啓斷點下載功能,需要手動傳入-c參數。

如果需要批量下載,可以把所有的URL寫入文件download.txt,然後通過-i指定下載文件列表:

wget -i download.txt

如果用戶不指定保存文件名,wget默認會以最後一個符合/的後面的字符作爲保存文件名,有時不是我們所期望的,此時需要-O指定保存的文件名。

通過--limit-rate可以限制下載的最大速度。

使用-b可以實現後臺下載。

另外wget甚至可以鏡像整個網站:

wget --mirror -p --convert-links -P int32bit http://int32bit.me

wget還支持指定下載文件的格式,比如只下載jpg圖片:

wget -A.jpg -r -l 2 http://int32bit.me/

axel

axel是一個多線程下載工具(A light download accelerator for Linux),通過建立多連接,能夠大幅度提高下載速度,所以我經常使用這個命令開掛下載大文件,比wget快多了,並且默認就支持斷點下載:

開啓20個線程下載文件:

axel -n 20 URL

這個強大的下載工具極力推薦,非常好用!

nethogs

我們前面介紹的iftop工具能夠根據主機查看流量(by host),而nethogs則可以根據進程查看流量信息(Net top tool grouping bandwidth per process)。ubuntu14.04中使用apt-get安裝的有bug,需要手動安裝:

sudo apt-get install build-essential libncurses5-dev libpcap-dev
git clone https://github.com/raboof/nethogs
cd nethogs
make -j 4

編譯完後執行

./nethogs eth1

我們指定了監控的網卡爲eth1,結果如圖:

nethogs

由於eth1是私有ip,只有ssh進程,從圖中我們可以看到它的進程號爲17264,程序爲sshd,共發送了1.593MB數據,接收了607.477MB數據(scp了一個鏡像文件)。按m鍵還能切換視角查看當前流量。

iptables

iptables是強大的包過濾工具,Docker、Neutron都網絡配置都離不開iptables。iptables通過一系列規則來實現數據包過濾、處理,能夠實現防火牆、NAT等功能。當一個網絡數據包進入到主機之前,先經過Netfilter檢查,即iptables規則,檢查通過則接受(Accept)進入本機資源,否則丟棄該包(Drop)。規則是有順序的,如果匹配第一個規則,則執行該規則的Action,不會執行後續的規則。iptables的規則有多個表構成,每個表又由鏈(chain)構成,每個表的功能不一樣,本文只涉及兩個簡單的表,即Filter表和NAT表,望文生義即可瞭解,Filter表用於包過濾,而NAT表用來進行源地址和目的地址的IP或者端口轉換

1.Filter表

Filter表主要和進入Linux本地的數據包有關,也是默認的表。該表主要由三條鏈構成:

  • INPUT:對進入主機的數據包過濾
  • OUTPUT:對本地發送的數據包過濾
  • FORWARD:傳遞數據包到後端計算機,與NAT有點類似。

查看本地的Filter表:

fgp@controller:~$ sudo iptables -n -t filter --list
[root@portal ~]# iptables -n -t filter --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

其中-n表示不進行域名解析,-t指定使用的表,--list表示列出所有規則。我們發現目前沒有定義任何規則。注意鏈後面的policy爲ACCEPT,表示若通過所有的規則都不匹配,則爲默認action accept。

接下來將通過幾個demo實例演示怎麼使用Filter表。

注意:

  • 本文實驗使用的是本機虛擬機,其中宿主機地址爲192.168.56.1,虛擬機地址爲192.168.56.2,在實驗中會涉及丟棄192.168.56.1的數據包,如果您連接的是遠程雲主機,將導致和遠程主機斷開連接。
  • 以下每個步驟,除非特別說明,下一個步驟執行前,務必清空上一個步驟的規則:
sudo iptables -F

首先看一個簡單的例子,把192.168.56.1加入黑名單禁止其訪問:

sudo iptables -A INPUT -i eth1 -s 192.168.56.1 -j DROP

例子中-A表示追加規則,INPUT是鏈名,-i指定網卡,-s指定源IP地址,-j指定action,這裏爲DROP,即丟棄包。

此時192.168.56.1這個ip不能和主機通信了,ssh會立即掉線,只能通過vnc連接了!

-s不僅能夠指定IP地址,還可以指定網絡地址,使用-p指定協議類型,比如我們需要丟掉所有來自192.168.56.0/24這個網絡地址的ICMP包,即不允許ping

sudo iptables -A INPUT -s 192.168.56.0/24 -i eth1 -p icmp -j DROP

輸出結果:

➜  ~ nc -z 192.168.56.2 22
Connection to 192.168.56.2 port 22 [tcp/ssh] succeeded!
➜  ~ ping 192.168.56.2
PING 192.168.56.2 (192.168.56.2): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
^C
--- 192.168.56.2 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss

我們發現能夠通過nc連接主機,但ping不通

我們還可以通過--dport指定目標端口,比如不允許192.168.56.1這個主機ssh連接(不允許訪問22端口):

sudo iptables -A INPUT -s 192.168.56.1 -p tcp --dport 22 -i eth1 -j DROP

注意:使用--dport或者--sport必須同時使用-p指定協議類型,否則無效!

以上把192.168.56.1打入了ssh黑名單,此時能夠ping通主機,但無法通過ssh連接主機。

Filter表的介紹就到此爲止,接下來看NAT表的實例。

2.NAT表

NAT表默認由以下三條鏈構成:

  • PREROUTING:在進行路由判斷前所要進行的規則(DNAT/Redirect)
  • POSTROUTING: 在進行路由判斷之後要進行的規則(SNAT/MASQUERADE)
  • OUTPUT: 與發送的數據包有關

根據需要修改的是源IP地址還是目標IP地址,NAT可以分爲兩種:

  • DNAT:需要修改目標地址(IP或者端口),使用場景爲從外網來的數據包需要映射到內部的一個私有IP,比如46.64.22.33->192.168.56.1。顯然作用在PREROUTING
  • SNAT:需要修改源地址(IP或者端口),使用場景和DNAT相反,內部私有IP需要發數據包出去,必須首先映射成公有IP,比如192.168.56.1->46.64.22.33。顯然作用在POSTROUTING

首先實現介紹一個簡單的demo,端口轉發,我們把所有來自2222的tcp請求轉發到本機的22端口,顯然需要修改目標地址,因此屬於DNAT:

sudo iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-ports 22

此時在192.168.56.1上使用ssh連接,指定端口爲2222:

ssh [email protected] -p 2222

我們能夠順利登錄,說明端口轉發成功。

另一個例子是使用雙網卡linux系統作爲路由器,我們有一臺服務器controller有兩個網卡:

eth0: 192.168.1.102 # 可以通外網
eth1: 192.168.56.2 # 不可以通外網,用作網關接口。

另外一臺服務器node1只有一個網卡eth1,IP地址爲192.168.56.3,不能通外網。我們設置默認路由爲controller機器的eth1:

sudo route add default gw 192.168.56.2 dev eth1

此時路由表信息爲:

fgp@node1:~$ sudo route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.56.2    0.0.0.0         UG    0      0        0 eth1
192.168.56.0    0.0.0.0         255.255.255.0   U     0      0        0 eth1

由路由表可知,node1上的數據包會發送到網關192.168.56.2,即controller節點.

接下來我們要在服務器controller上配置NAT,我們需要實現192.168.56.0/24的IP都轉發到eth0,顯然是SNAT,修改的源地址爲eth0 IP地址192.168.1.102:

sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o eth0 -j SNAT --to-source 192.168.1.102

其中-t指定nat表,-A 指定鏈爲POSTROUTING,-s 爲源ip地址段,-o指定轉發網卡,注意-j參數指定action爲SNAT,並指定eth0 IP地址(注意eth0可能配置多個ip地址,因此必須指定--to-source)。

此時在node1機器上檢測網絡連通性:

fgp@node1:~$ ping baidu.com -c 2
PING baidu.com (180.149.132.47) 56(84) bytes of data.
64 bytes from 180.149.132.47: icmp_seq=1 ttl=48 time=7.94 ms
64 bytes from 180.149.132.47: icmp_seq=2 ttl=48 time=6.32 ms

--- baidu.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 6.328/7.137/7.946/0.809 ms

node1能夠正常上網。

以上通過使用controller的網卡eth0作爲路由實現了node1的上網,但同時有一個問題存在,我們在指定SNAT時必須手動指定IP,如果eth0 IP地址變化了,必須修改iptables規則。顯然這樣很難維護,我們可以通過MASQUERADE實現動態SNAT,不需要指定IP地址:

sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o eth0 -j MASQUERADE

其他

使用iptables-save能夠導出規則,使用iptables-restore能夠從文件中導入規則。

ipset

以上我們通過iptables封IP,如果IP地址非常多,我們就需要加入很多的規則,這些規則需要一一判斷,性能會下降(線性的)。ipset能夠把多個主機放入一個集合,iptables能夠針對這個集合設置規則,既方便操作,又提高了執行效率。注意ipset並不是只能把ip放入集合,還能把網絡地址、mac地址、端口等也放入到集合中

首先我們創建一個ipset:

sudo ipset create blacklist hash:ip

以上創建了一個blacklist集合,集合名稱後面爲存儲類型,除了hash表,還支持bitmap、link等,後面是存儲類型,我們指定的是ip,表示我們的集合元素爲ip地址。

我們爲這個blacklist集合增加一條規則,禁止訪問:

sudo iptables -I INPUT -m set --match-set blacklist src -j DROP 

此時只要在blacklist的ip地址就會自動加入黑名單。

我們把192.168.56.1和192.168.56.3加入黑名單中:

sudo ipset add blacklist 192.168.56.3
sudo ipset add blacklist 192.168.56.1

此時ssh連接中斷,使用vnc連接查看:

fgp@controller:~/github/int32bit.github.io$ sudo ipset list blacklist
Name: blacklist
Type: hash:ip
Revision: 2
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 176
References: 1
Members:
192.168.56.1
192.168.56.3

把192.168.56.1移除黑名單:

sudo ipset del blacklist 192.168.56.1

我們上面的例子指定的類型爲ip,除了ip,還可以是網絡段,端口號(支持指定TCP/UDP協議),mac地址,網絡接口名稱,或者上述各種類型的組合。比如指定 hash:ip,port就是 IP地址和端口號共同作爲hash的鍵。指定類型爲net既可以放入ip地址,也可以放入網絡地址。

另外ipset還支持timeout參數,可以指定時間,單位爲秒,超過這個時間,ipset會自動從集合中移除這個元素,比如封192.168.56.11分鐘時間不允許訪問

sudo ipset create blacklist hash:net timeout 300
sudo ipset add blacklist 192.168.56.1 timeout 60

以上首先創建了支持timeout的集合,這個集合默認超時時間爲300s,接着把192.168.56.1加入到集合中並設置時間爲60s。

注意:執行ipset add時指定timeout必須保證創建的集合支持timeout參數,即設置默認的timeout時間.如果不想爲集合設置默認timeout時間,而又想支持timeout,可以設置timeout爲0,相當於默認不會超時。

總結

本文總結了Linux中的常用的網絡工具,其中包括

  • 網絡配置相關:ifconfig、ip
  • 路由相關:route、netstat、ip
  • 查看端口工具:netstat、lsof、ss、nc、telnet
  • 下載工具:curl、wget、axel
  • 防火牆:iptables、ipset
  • 流量相關:iftop、nethogs
  • 連通性及響應速度:ping、traceroute、mtr、tracepath
  • 域名相關:nslookup、dig、whois
  • web服務器:python、nginx
  • 抓包相關:tcpdump
  • 網橋相關:ip、brctl、ifconfig、ovs
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章