curl
-L
跟随重定向,自动跳转-s
静默模式- 一旦发生错误,不会显示错误信息
-S
如果出错, 则显示错误信息- 一般与
-s
一起使用
- 一般与
curl -sSL <url>
-v
输出通信过程- 包括具体链接的IP和端口,HTTPS协议的握手过程
-I
只显示首部信息- 发送HEAD请求
-i
显示首部和body-o
保存数据到文件中- 相当于
wget
命令- 对应的,
wget -O- <url>
相当于curl
命令
- 对应的,
- 相当于
curl -o <path/to/file> <url>
-O
按照源文件名自动保存-u
提供用户名和密码
curl -u <name:password> <url>
-H
提供首部信息- 例如设置请求设备
user-agent
参数- 因为返回内容可能根据设备不同而不同
- 例如设置请求设备
curl 'https://ifconfig.me/' -H \
'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
-x
使用代理
curl -x <proxy_addr:port> <url>
- curl默认为GET方法,使用
-X
支持其他方法 -d
提供POST数据body-F "upload=@"
上传文件
curl -X POST http://github.com
curl -X DELETE http://github.com
# 注意-d后的json信息用单引号而不是反引号
curl -X POST localhost:8000/search -H "Content-Type:application/json" -d '{"key":123, "val":456}'
# @用文件代替命令行输入(-d等价--data)
curl -X POST localhost:8000/search -H "Content-Type:application/json" --data @filename.json
# -F "upload=@"上传文件
curl -X POST http://localhost:8000/upload -F "upload=@/Users/ghost/Desktop/pic.jpg" -H "Content-Type: multipart/form-data"
# 上传多个文件
curl -X POST http://localhost:8000/multi/upload -F "upload=@/Users/ghost/Desktop/pic.jpg" -F "upload=@/Users/ghost/Desktop/journey.png" -H "Content-Type: multipart/form-data"
--limit-rate <200k>
用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境--trace-time
显示curl过程每一步的时间戳,用于查看时间耗在哪步--cert <cert_file> --key <key_file>
用来进行mTLS认证-k
跳过检查服务器的 SSL 证书是否正确- 一般用于服务端证书为自签名时
- 一般用于服务端证书为自签名时
--resolve host:port:address
在HTTPS协议下指定访问的IP- https下指定IP不能通过更改Host头部实现,因为TLS握手时拿不到Host
- 一般用于测试CDN加速
- 参考:
dig
dig <域名>
查询DNS包括CNAME记录,A记录等相关信息的工具dig @<dns ip> <域名>
指定DNS查询- 例如指定谷歌的
8.8.8.8
DNS服务器 - 如果不指定 DNS 服务器,dig 会依次使用
/etc/resolv.conf
里的地址作为 DNS 服务器
- 例如指定谷歌的
dig +short <域名>
只显示CNAME和IPdig +trace <域名>
显示递归查询的详细过程dig <域名> [A\CNAME\NS\AAAA]
指定要查询的信息dig命令默认的输出信息可以分为 5 个部分
- 显示 dig 命令的版本和输入的参数
- 显示服务返回的一些技术详情
- 如果
status
的值为NOERROR
则说明本次查询成功结束
- 如果
QUESTION SECTION
显示我们要查询的域名和字段- 默认请求
A
字段
- 默认请求
ANSWER SECTION
是查询到的结果- 第一列为域名
- 第二列为TTL
- 缓存时间,单位秒
- 第三列为要查询信息的类别
- IN代表类别为IP协议,即Internet
- 由于现在都是互联网,所以其它基本不用
- 第四列为要查询的记录类型
- 第五列为域名对应的结果
- IP或另一个域名
- 本次查询的一些统计信息
- 比如用了多长时间,查询了哪个 DNS 服务器,在什么时间进行的查询等
ping
- 用来探测本机与网络中另一主机之间是否可达的命令, 是定位网络通不通的一个重要手段
- 如果两台主机之间ping不通,则表明这两台主机不能建立起连接
- 还可以检测往返耗时(延迟),往返时间反映连接质量
ping -6 www.google.com
可以使用IPv6来pingping -s 1000 www.google.com
指定发送的数据包大小为1000Byte
- 最大能发送65507byte大小的包,避免DDoS攻击
- 利用了ICMP协议
- 基于IP协议实现,不基于TCP或UDP
- 能ping通不一定tcp或udp通
traceroute
可以定位从源主机到目标主机之间经过了哪些路由器,以及到达各个路由器的耗时
一般直接使用命令行测试
- 出现星号(
*
)一般是防火墙封掉了 ICMP 的返回信息- 避免DDoS攻击,或者不想暴露IP地址
-n
避免网关IP的DNS解析-q
指定探测包的数量-I
使用ICMP ECHO代替默认的UDP探测-T
使用TCP SYN代替默认的UDP探测--sport=<num>
指定源port- 参考:https://einverne.github.io/post/2017/06/traceroute.html
- 出现星号(
一次只发一个包来追踪,默认解析IP到域名
可以采用ICMP代替默认的UDP来追踪,且固定源端口
默认一次发3个包追踪,三个包路由转发的路径很可能不同
- 原因是运营商或者server端的负载均衡
- 影响因素一般有源端口、协议(ICMP、UDP、TCP)等
直接追踪域名,会先解析出其中的一个IP地址
除了直接使用命令行测试外,也可以使用网页:http://tools.ipip.net/traceroute.php
mtr
mtr(my traceroute) = ping + traceroute
- 先使用 traceroute 将两个 IP 之间需要经过的 hop 找出来,然后依次去 ping 这些 hop
相对于traceroute命令只会做一次链路跟踪测试,mtr命令会对链路上的相关节点做持续探测并给出相应的统计信息
- mtr命令能避免节点波动对测试结果的影响
一般情况下 mtr 前几跳都是本地 ISP,后几跳属于服务商,中间跳数则是中间节点
- 如果发现前几跳异常,需要联系本地 ISP 服务提供上,相反如果后几跳出现问题,则需要联系服务提供商(比如腾讯数据中心),中间几跳出现问题,则需要联系运营商进行处理
- 如果发现前几跳异常,需要联系本地 ISP 服务提供上,相反如果后几跳出现问题,则需要联系服务提供商(比如腾讯数据中心),中间几跳出现问题,则需要联系运营商进行处理
经常会看到中间某些节点丢包率比后面的节点还要高,这种情况下,永远相信后面的节点
- 这可能是中间节点对 ICMP 协议限速,导致中间节点可能看到 Loss 比后面多
- 并不是真正地丢包,只是对你的 ping 丢了包,实际的包没有丢
- 因为假如中间某个节点真的发生了丢包,那么它后面的节点一定会丢包,因为后面节点要可达必须经过中间的节点
发送过去的包的路由,和返回的包的路由,并不总是一致的
- 很多时候问题是数据包可以成功的到达目的主机,但是返回过程中遇到“困难”了
- 如果有条件的话,最好从两端都使用 mtr 进行诊断
Last, Avg, Best 和 Wrst 列都标识数据包往返的时间
- 使用的是毫秒( ms )单位表示
- Last 表示最后一个数据包所用的时间, Avg 表示平均时间, Best 和 Wrst 表示最小和最大时间
- StDev 提供了数据包在每个主机的标准偏差
- 如果标准偏差越高,说明数据包在这个节点的延时越不相同
- 此时使用最好和最坏的延迟来确定平均延迟是一个较好的方案
- ICMP 速率限制可能会增加延迟
- 一般可以查看最后一条的时间延迟来判断是否是上述情况
netstat
netstat -a # 所有活动的监听和非监听端口
netstat -at # 全部TCP端口
netstat -au # 全部UDP端口
netstat -l # 所有监听的端口
netstat -p # 显示端口占用的任务名,需要root权限
netstat -r # 查看路由表
netstat -n # 以数字而不是别名显示IP地址
# 统计TCP各个连接状态的数量(SYN_SENT、TIME_WAIT、ESTABLISHED)
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
# 查看有哪些IP通过SSH连接了服务器
sudo netstat -anp | grep ESTABLISHED | grep ssh | awk '{print $5}'
# 查看ssh服务是否在运行
netstat -aple | grep ssh
# 查看端口被占用情况,及其进程编号、进程名称
sudo netstat -tulnp | grep <port>
网络瓶颈
端口状态分类
- LISTEN:侦听来自远方的TCP端口的连接请求
- ESTABLISHED:代表一个打开的连接
- SYN-SENT:再发送连接请求后等待匹配的连接请求(如果有大量这样的状态包,检查是否中招了)
- SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认(如有大量此状态,估计被flood攻击了)
- FIN-WAIT-1:等待远程TCP连接中断请求,或先前的连接中断请求的确认
- FIN-WAIT-2:从远程TCP等待连接中断请求
- CLOSE-WAIT:等待从本地用户发来的连接中断请求
- CLOSING:等待远程TCP对连接中断的确认
- LAST-ACK:等待原来的发向远程TCP的连接中断请求的确认(不是什么好东西,此项出现,检查是否被攻击
- TIME-WAIT:等待足够的时间以确保远程TCP接收到连接中断请求的确认CLOSED:没有任何连接状态
路由表
netstat -rn
显示路由表
字段含义
- Destination
- 目标网段或者主机
- Gateway
- 网关地址
0.0.0.0
或者*
表示当前记录对应的Destination
跟本机在同一个网段,通信时不需要经过网关(路由器)转发
- Flags
U
表示路由是可用的H
表示目标是一个主机G
表示gateway是一个网关- 即目标地址位于不同子网,需要经过路由器
- Iface
- 表示对应的输出网卡
路由种类
- 主机路由
- 指向单个IP地址的路由记录
- 此时
Genmask
字段为255.255.255.255
- 网络路由
- 指向主机可以到达的网段
- 指向主机可以到达的网段
- 默认路由
- 当主机不能在路由表中查找到目标主机的IP地址或网络路由时,数据包就被发送到默认网关上
- 此时
Destination
字段为default
或0.0.0.0
,Genmask
字段为0.0.0.0
ip
ip link show # 显示网络接口信息
ip link set eth0 up # 开启网卡
ip link set eth0 down # 关闭网卡
ip addr show # 显示网卡IP信息
ip addr add 192.168.0.1/24 dev eth0 # 设置eth0网卡IP地址192.168.0.1
ip addr del 192.168.0.1/24 dev eth0 # 删除eth0网卡IP地址
ip route show # 显示系统路由
ip route add default via 192.168.1.254 # 设置系统默认路由
ip route add default via 192.168.0.254 dev eth0 # 设置eth0的默认网关为192.168.0.254
ip route add 192.168.4.0/24 via 192.168.0.254 dev eth0 # 设置192.168.4.0网段的网关为192.168.0.254,数据走eth0接口
ip route del default # 删除默认路由
ip route delete 192.168.1.0/24 dev eth0 # 删除eth0的路由
iptables
规则
- 格式:
iptables [-t table] COMMAND chain CRETIRIA -j ACTION
table
指定规则- 若省略此部分,则使用默认的
filter
filter
:定义允许或者不允许的,用来过滤数据nat
:定义地址转换, 主要用来修改数据包的 IP 地址、端口号信息mangle
: 修改报文原数据, 用来修改数据包的服务类型,生存周期,为数据包设置标记,实现流量整形、策略路由等
- 若省略此部分,则使用默认的
COMMAND
指定如何对规则进行管理-L
:列出某规则链中的所有规则-A
:在指定链的末尾添加一条新的规则-F
:删除指定链中的所有规则-D
:删除指定链中的某一条规则-P
:设置指定链的默认规则-R
:修改、替换指定链中的某一条规则-I <num>
:在指定链中插入一条新规则- 允许同时制定添加规则的顺序号,未指定序号时默认作为第一条规则
- 规则的次序非常关键,谁的规则越严格,应该放的越靠前
- 检查规则的时候,是按照从上往下的方式进行检查的
chain
:规则到底在哪个chain上操作- 包括
INPUT
,FORWARD
,OUTPUT
,PREROUTING
和POSTROUTING
- 包括
CRETIRIA
: 指定匹配条件-p 协议名
匹配数据包协议,例如tcp,udp,icmp等-s 源地址
: 匹配源地址或者网段- 可以使用
!
进行反向比对,例如-s ! 192.168.0.0/24
- 可以使用
--sport/dport 端口号
: 匹配源/目的端口:
可以匹配区间,例如--sport 22:80
表示匹配 22 到 80 端口- 该参数必须和
-p
参数一起指定
-d 目标地址
: 匹配目标地址-i 入网卡
: 匹配进入网卡,例如eth0
- 可以使用通配字符
+
来做大范围比对- 例如
eth+
表示所有的 ethernet 网卡
- 例如
- 也以使用
!
进行反向比对
- 可以使用通配字符
-o 出网卡
: 匹配出网卡
-j ACTION
:指定如何进行处理ACCEPT
允许数据包DROP
丢弃数据包,且不给任何回应信息REJECT
拒绝数据包,必要时会给数据发送端一个响应信息log
在/var/log/messages
文件中记录日志信息,然后将数据包传递给下一个规则
- iptables设定的规则需要通过
service iptables save && service iptables restart
来固化- 否则重启服务器还是会恢复原来的状态
例子
# 查看所有iptables规则
iptables -n -L [--line-numbers]
# 删除某个chain上的规则,不填删除所有规则
iptables -F [INPUT]
# 服务器只打开22端口的TCP连接
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# 允许防转发除ICMP协议以外的所有数据包
iptables -A FORWARD -p !icmp -j ACCEPT
# 丢弃所有通过 tcp 协议访问本机 21 端口的数据包
iptables -A INPUT -p tcp --dport 21 -j DROP
# 丢弃来自 192.168.1.0/24 的 1024:65535 端口的访问本机 ssh 端口的数据包
iptables -A INPUT -p tcp -s 192.168.1.0/24 --sport 1024:65535 --dport ssh -j DROP
# 断网3分钟
iptables -P INPUT DROP
iptables -P OUTPUT DROP
echo 'iptables -P INPUT ACCEPT; iptables -P OUTPUT ACCEPT' | at now +3 minutes
原理
- iptables其实是一个命令行工具,位于用户空间,我们可以把它理解成一个客户端代理
- 用户通过iptables这个代理,将用户的安全设定执行到对应的”安全框架”中,这个框架的名字叫netfilter
- netfilter是真正 Linux 内核空间里挡在 “网卡”和“用户态进程”之间的一道“防火墙”
- iptables可以完成封包过滤、封包重定向和网络地址转换(NAT) 等功能
- IP 包“一进一出”的两条路径上,有几个关键的“检查点”, 在 iptables 中,这些“检查点”被称为:链(Chain)
- “检查点”实际上就是内核网络协议栈代码里的 Hook
- iptables 表的作用,就是在某个具体的“检查点”上,按顺序执行几个不同的检查动作
- 当一个 IP 包通过网卡进入主机之后,要经过路由表路由来决定下一步的去向
- 路由前需要通过
PRERROUTING
检查点
- 路由前需要通过
- 经过路由之后,IP 包的去向就分为了两种:
- 继续在本机处理
- 对应
INPUT
检查点 - 进入本机传输层协议栈
- 对应
- 被转发到其他目的地
- 对应
FORWARD
检查点 - 不会进入传输层,而是会继续在网络层流动
- 对应
- 继续在本机处理
- input 链 和 output 链主要用在主机型防火墙,是针对服务器本机进行保护的防火墙
- forward 链、prerouting 链、postrouting 链主要用在网络型防火墙,是针对公司内网与 Internet 之间进行安全控制
tc(traffic control)
- tc 是 Linux 系统中的一个工具,可以用来控制 netem 的工作模式
- 每一个物理网卡都会和一个qdisc关联,然后通过netem添加不同设置参数以实现对网络的控制
- netem是Linux内核提供的网络模拟功能模块
- 可以在性能良好的局域网中模拟出复杂的互联网传输性能
- 例如低带宽、传输延迟、丢包、乱序、重复等情况
- 主要是通过在输出端口处建立一个队列来实现流量控制
- 只能控制发包动作,不能控制收包动作
- 即只能控制出流量
- 直接对物理网卡生效
- 如果控制了物理的 eth0,那么逻辑网卡(比如 eth0:1)也会受到影响
- 反之如果在逻辑网卡上做控制,该控制可能是无效的
- 但虚拟机中的多个网卡可以在虚拟机中视为多个物理网卡
- tc命令需要
root
权限来执行
# 出eth0网卡的网络流量丢包率50%
sudo /sbin/tc qdisc add dev eth0 root netem loss 50%
# 出eth0网卡的网络流量丢包率修改成20%, 且后一个包的丢弃的可能性和前一个的可能性的30%相关
sudo /sbin/tc qdisc change dev eth0 root netem loss 20% 30%
# 出eth0网卡的网络流量RTT增加100ms
sudo /sbin/tc qdisc add dev eth0 root netem delay 100ms
# 出eth0网卡的网络流量RTT增加修改成200ms± 10ms
sudo /sbin/tc qdisc change dev eth0 root netem delay 200ms 10ms
# 出eth0网卡的网络流量随机产生1%的重复数据包
sudo /sbin/tc qdisc add dev eth0 root netem duplicate 1%
# 出eth0网卡的网络流量随机产生0.2%的损坏据包
sudo /sbin/tc qdisc add dev eth0 root netem corrupt 0.2%
# 出eth0网卡的网络流量有25%的数据包会被立即发送,其他的延迟10 秒
sudo /sbin/tc qdisc add dev eth0 root netem delay 10ms reorder 25%
# 出eth0网卡且目的IP是106.54.224.114的网络流量RTT增加200ms, 丢包率50%
sudo /sbin/tc qdisc add dev eth0 root handle 1: prio && \
sudo /sbin/tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 200ms loss 50% && \
sudo /sbin/tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 106.54.224.114 flowid 1:1
# 出eth0网卡且目的网段是106.54.224.0/24的网络流量丢包率50%
sudo /sbin/tc qdisc add dev eth0 root handle 1: prio && \
sudo /sbin/tc qdisc add dev eth0 parent 1:1 handle 10: netem loss 50% && \
sudo /sbin/tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 106.54.224.0/24 flowid 1:1
# 出eth0网卡且目的IP是106.54.224.114的 UDP 流量丢包率50%
# 17是UDP的协议号;如果要限制TCP流量,改成6即可
sudo /sbin/tc qdisc add dev eth0 root handle 1: prio && \
sudo /sbin/tc qdisc add dev eth0 parent 1:1 handle 10: netem loss 50% && \
sudo /sbin/tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip protocol 17 0xff match ip dst 106.54.224.114 flowid 1:1
# 删除eth0网卡相关的所有规则
sudo /sbin/tc qdisc del dev eth0 root
# 删除ifb0网卡的ingress规则
sudo /sbin/tc qdisc del dev ifb0 ingress
# 查看eth0网卡相关的所有规则
sudo /sbin/tc qdisc show dev eth0
- 如果需要控制进入的流量,需要在网卡前附加一个虚拟网卡,然后让流量先从虚拟进入物理网卡,此时我们可以通过控制虚拟网卡的出流量间接控制实际物理网卡的入流量
# 设置规则
modprobe ifb
ip link set dev ifb0 up
sudo /sbin/tc qdisc add dev eth0 ingress
sudo /sbin/tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
sudo /sbin/tc qdisc add dev ifb0 root netem loss 20%
sudo /sbin/tc qdisc add dev eth0 root netem loss 20%
# 只控制进出的UDP流量
modprobe ifb
ip link set dev ifb0 up
sudo /sbin/tc qdisc add dev eth0 ingress
sudo /sbin/tc filter add dev eth0 parent ffff: protocol ip u32 match ip protocol 17 0xff flowid 1:1 action mirred egress redirect dev ifb0
sudo /sbin/tc qdisc add dev ifb0 root netem loss 20%
sudo /sbin/tc qdisc add dev eth0 root handle 1: prio
sudo /sbin/tc qdisc add dev eth0 parent 1:1 handle 10: netem loss 20%
sudo /sbin/tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip protocol 17 0xff flowid 1:1
# 删除规则
sudo /sbin/tc qdisc del dev ifb0 root
sudo /sbin/tc qdisc del dev eth0 ingress
sudo /sbin/tc qdisc del dev eth0 root
ip link set dev ifb0 down
modprobe -v -r ifb
- 参考:
iperf3
- 报告带宽,延迟抖动和数据包丢失
- 可以用来测试一些网络设备如路由器,防火墙,交换机等的性能
测试TCP带宽
- sender代表clien向server发送的数据总和,而receiver代表server接受到的数据总和
- 默认是客户端发送,服务器端接收: 即测试是服务端上行带宽
- 通过client端的
-R
参数可以进行反向测试,即测试服务端下行带宽
- 通过client端的
iperf3 -s -p 50050 -i 1 # 服务端指定的端口需要和客户端一致
iperf3 -c 10.227.4.57 -p 50050 -t 10 -i 2 # 一共测试10秒,每2秒报告一次
测试UDP丢包和抖动
- 默认是客户端发送,服务器端接收: 即测试是上行丢包和抖动
- 通过client端的
-R
参数可以进行反向测试,即测试服务端下行丢包和抖动
- 通过client端的
- 必须通过
-b
限制最大带宽,否则超过服务端带框的话,丢包率等指标会大幅上涨
iperf3 -s -B 10.227.4.57 -i 2 # 以UDP模式监听;-B可以指定绑定的网卡IP,因为有些机器有多个网卡
iperf3 -c 10.227.4.57 -p 5201 -u -b 10M # 使用UDP带宽为10M;默认端口为5201
nc(netcat)
- 检测IP端口是否打开
# 默认检测TCP协议,-u 检查UDP协议
nc -z -v [-u] <host> <port>
# 扫描一段端口,扫描超时3秒
nc -z -v -w3 <host> <port1>-<port2>
- 传输文件
- 速度一般比scp, rsync快
- scp 和 rsync 都用 ssh 的话,本身流量会被加密,所以会慢一点
- 并且由于加密的缘故,跨国传输还会被限速
- 明文传输,适合内网安全的环境下传输
- 默认使用TCP协议传输,可以使用
-u
指定UDP协议传输
- 速度一般比scp, rsync快
# 接收端(先)
nc -l 8080 > image.jpg
# 发送端(后)
nc 192.168.1.2 8080 < image.jpg
ufw (防火墙)
apt install ufw 安装防火墙
sudo ufw enable|disable|status 开启/关闭/查看防火墙状态
sudo ufw allow 22/tcp 开通22端口
sudo ufw allow 80/tcp 开通80端口
sudo ufw allow 3306/tcp 开通3306端口
sudo ufw allow from 192.168.1.100 允许此ip访问本机的所有端口
sudo ufw delete allow from 192.168.1.25 禁止这个ip访问本机
sudo ufw allow 80/tcp from 192.168.1.0/24 设置本机80端口访问的白名单:只允许192.168.1.0网段的ip访问本机80端口
sudo ufw delete allow 80/tcp 禁用本机的80端口
版权声明:本文为winter_wu_1998原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。