本文整理了在实践过程当中使用的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中的经常使用的网络工具,其中包括