本文整理了在實踐過程當中使用的Linux網絡工具,這些工具提供的功能很是強大,咱們平時使用的只是冰山一角,好比lsof
、ip
、tcpdump
、iptables
等。本文不會深刻研究這些命令的強大用法,由於每一個命令都足以寫一篇文章,本文只是簡單地介紹並輔以幾個簡單demo實例,旨在大腦中留個印象,平時遇到問題時可以快速搜索出這些工具,利用強大的man
工具,提供必定的思路解決問題。node
使用這個命令判斷網絡的連通性以及網速,偶爾還順帶當作域名解析使用(查看域名的IP):python
ping google.com
默認使用該命令會一直髮送ICMP包直到用戶手動停止,可使用-c
命令指定發送數據包的個數,使用-W
指定最長等待時間,若是有多張網卡,還能夠經過-I
指定發送包的網卡。mysql
小技巧: 在ping過程當中按下ctrl+|
會打印出當前的summary信息,統計當前發送包數量、接收數量、丟包率等。linux
其餘好比-b
發送廣播,另外注意ping只能使用ipv4,若是須要使用ipv6,可使用ping6
命令。nginx
這個命令用來查看當前創建的網絡鏈接(深入理解netstat每一項表明的含義)。最經典的案例就是查看本地系統打開了哪些端口:git
fgp@controller:~$ sudo netstat -lnpt
github
[sudo] password for fgp:
web
Active Internet connections (only servers)
sql
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
docker
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
以上Genmask
爲0.0.0.0
的表示默認路由,即鏈接外網的路由。網絡中0.0.0.0的IP地址表示整個網絡,即網絡中的全部主機。它的做用是幫助路由器發送路由表中沒法查詢的包。若是設置了全零網絡的路由,路由表中沒法查詢的包都將送到全零網絡的路由中去。
lsof
命令用來查看打開的文件(list open files),因爲在Linux中一切皆文件,那socket、pipe等也是文件,所以可以查看網絡鏈接以及網絡設備,其中和網絡最相關的是-i
選項,它輸出符合條件的進程(四、六、協議、:端口、 @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 4@192.168.56.1
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)
用過top
以及iotop
的,天然可以大體猜到iftop
的功能,它是用於查看網絡流量的工具(display bandwidth usage on an interface by host):
sudo iftop
nc(netcat)被稱爲網絡工具的瑞士軍刀,其很是輕巧但功能強大!經常做爲網絡應用的Debug分析器,能夠根據須要建立各類不一樣類型的網絡鏈接。官方描述的功能包括:
總之很是強大,可以實現簡單的聊天工具、模擬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!
從結果中發現,該主機打開了22
和80
端口。
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協議客戶端(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
可見成功鏈接到localhost
的22
端口,說明端口已經打開,還輸出了banner
信息。
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用於交互式域名解析(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用於查看域名全部者的信息(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: haoel@hotmail.com
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年,註冊郵箱是haoel@hotmail.com
。
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命令能夠說是無比強大了,它徹底能夠替換ifconfig
、netstat
、route
、arp
等命令,好比查看網卡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
是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
把網卡加到網橋等。
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是經常使用的網絡診斷工具(a network diagnostic tool),它把ping和traceroute併入一個程序的網絡診斷工具中並實時刷新。
mtr -n int32bit.me
輸出如圖:從圖上能夠看出從本地到int32bit.me
通過的全部路由,每個路由間的丟包率、響應時間等。
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也能夠正常運行,只是效率會變得稍慢。
其中比較經常使用的參數包括:
所以咱們能夠經過ss
命令查看本地監聽的全部端口(和netstat命令功能相似):
ss -t -l -n -4
輸出如圖:
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是一個強大的非交互網絡下載工具(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是一個多線程下載工具(A light download accelerator for Linux),經過創建多鏈接,可以大幅度提升下載速度,因此我常用這個命令開掛下載大文件,比wget快多了,而且默認就支持斷點下載:
開啓20個線程下載文件:
axel -n 20 URL
這個強大的下載工具極力推薦,很是好用!
咱們前面介紹的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,結果如圖:
因爲eth1是私有ip,只有ssh進程,從圖中咱們能夠看到它的進程號爲17264,程序爲sshd,共發送了1.593MB數據,接收了607.477MB數據(scp了一個鏡像文件)。按m
鍵還能切換視角查看當前流量。
iptables是強大的包過濾工具,Docker、Neutron都網絡配置都離不開iptables。iptables經過一系列規則來實現數據包過濾、處理,可以實現防火牆、NAT等功能。當一個網絡數據包進入到主機以前,先通過Netfilter檢查,即iptables規則,檢查經過則接受(Accept)進入本機資源,不然丟棄該包(Drop)。規則是有順序的,若是匹配第一個規則,則執行該規則的Action,不會執行後續的規則。iptables的規則有多個表構成,每一個表又由鏈(chain)構成,每一個表的功能不同,本文只涉及兩個簡單的表,即Filter表和NAT表,望文生義便可瞭解,Filter表用於包過濾,而NAT表用來進行源地址和目的地址的IP或者端口轉換。
Filter表主要和進入Linux本地的數據包有關,也是默認的表。該表主要由三條鏈構成:
查看本地的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表。
注意:
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表的實例。
NAT表默認由如下三條鏈構成:
根據須要修改的是源IP地址仍是目標IP地址,NAT能夠分爲兩種:
46.64.22.33->192.168.56.1
。顯然做用在PREROUTING
。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 fgp@192.168.56.2 -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
可以從文件中導入規則。
以上咱們經過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.1
1分鐘時間不容許訪問
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中的經常使用的網絡工具,其中包括