网工最常用的10个网络命令,但凡有一个不会用都不算资深网工。

号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部

下午好,我的网工朋友。

当网工,日常工作不仅需要面对各种各样的网络设备和配置,还需要处理不断出现的网络故障和性能问题。

这时候,命令行工具就显得尤为重要。

无论是排查网络连接问题,还是配置网络接口,命令行工具都提供了快速、高效的方法来解决问题。

今天说10个对网工来说至关重要的网络命令,这些命令涵盖了从基本的连通性测试到复杂的网络抓包分析等多个方面。

无论你是新手还是有经验的网络工程师,熟练掌握这些命令都能显著提高你的工作效率和问题解决能力。

今日文章阅读福利:《网络排障好用工具合辑》

搭配这篇网络命令,顺便给你分享一些排障的好用工具。私信我,发送暗号“排障”,即可领取全部工具。

01 ping

ping命令是网络工程师最常用的工具之一,用于测试网络设备之间的连通性。它通过发送ICMP回显请求(Echo Request)数据包,并等待目标设备返回回显应答(Echo Reply),来判断目标设备是否可达。

01 功能和用途:

  • 检查本地主机与目标主机之间的连通性
  • 测试网络延迟(即数据包从发送到接收到应答的时间)
  • 诊断网络故障的初步工具
  • 我们通常会用它来直接ping ip地址,来测试网络的连通情况,类如这种,直接ping ip地址或网关。

02 命令格式

ping命令的基本格式如下:

ping [选项] 目标地址

其中,"目标地址"可以是一个IP地址或一个域名。例如:

ping 192.168.1.1 
ping www.example.com

03 ping命令的常用参数选项

-t:持续ping目标地址,直到手动停止。常用于监控网络稳定性。

-n count:指定发送的回显请求数目。默认情况下,Windows系统发送4个请求,Linux系统发送无限请求。

-l size:指定发送数据包的大小(字节数)。用于测试不同数据包大小下的网络性能。

-w timeout:指定等待每次回复的超时时间(毫秒)。用于设置更严格的响应时间要求。

-a:解析IP地址到主机名,反向查找DNS。

-f:设置不分段标志。用于测试路径MTU。

-i TTL:设置TTL值。用于测试数据包在网络中的跳数。

-r count:记录路由的计数。用于测试并显示数据包经过的路由数。

-s count:记录时间戳。用于测试数据包在每个跳数的往返时间。

-S srcaddr:指定源地址。用于在多网卡或多IP地址的机器上测试特定源IP的连通性。

-4:强制使用IPv4地址。用于在双栈网络中测试IPv4连通性。

-6:强制使用IPv6地址。用于在双栈网络中测试IPv6连通性。

02 tracert/traceroute

tracert(Windows)和traceroute(Linux)是用于诊断网络路径的命令行工具。

它们通过逐跳发送ICMP回显请求(或UDP数据包),来确定从源设备到目标设备所经过的每一个网络节点(路由器)。这些命令可以帮助网络工程师识别网络路径中的瓶颈或中断点,从而更有效地解决网络问题。

01如何使用命令查看数据包路径

命令格式:

tracert/traceroute [选项] 目标地址

这两个命令都会显示从源设备到目标设备的每一跳的IP地址和响应时间。如果某一跳无法到达,通常会显示超时(Request Timed Out)消息。

02示例及实际应用场景

示例1:诊断网络路径中的延迟

假设你访问某个网站时速度很慢,你可以使用tracert或traceroute命令来查看数据包经过的路径,并确定在哪一跳出现了延迟:

tracert/traceroute www.example.com

通过检查每一跳的响应时间,你可以确定延迟发生在哪一段网络路径中,从而针对性地进行优化或排除故障。

示例2:识别网络中断点

如果你无法访问某个网站,可以使用tracert或traceroute命令来检查网络路径中是否存在中断点:

tracert/traceroute www.google.com

如果某一跳显示超时或无法到达,说明数据包在该点被阻断。你可以联系相关网络管理员或服务提供商来解决该问题。

03 常用参数选项:

-d:不进行域名解析,直接显示IP地址。用于加快命令执行速度。

-h max_hops:设置最大的跳数。用于限制命令的执行范围。

-w timeout:设置每一跳的等待超时时间(毫秒)。用于调整响应时间要求。

-I:在Linux中使用ICMP ECHO进行路径跟踪(默认使用UDP数据包)。

-T:在Linux中使用TCP SYN数据包进行路径跟踪。用于穿透防火墙或其他网络限制。

03 ipconfig/ifconfig

ipconfig和ifconfig是网络配置和管理中非常重要的命令行工具。它们允许网络工程师查看和配置网络接口的详细信息,包括IP地址、子网掩码、网关以及DNS服务器等。

01如何查看和管理网络接口配置信息

查看网络接口信息:

ipconfig

这个命令将显示所有网络接口的配置信息,包括IP地址、子网掩码和默认网关。

刷新和重置网络接口:

在Windows中,使用以下命令来刷新DNS缓存和重置网络接口:

ipconfig /flushdns 
ipconfig /release 
ipconfig /renew

在Linux中,可以使用以下命令来重新启动网络接口:

sudo ifconfig eth0 down 
sudo ifconfig eth0 up

02实际应用及常见问题解决

示例1:查看IP地址和网络信息

在Windows中,你可以使用以下命令查看本地网络接口的详细信息:

ipconfig /all

这个命令将显示每个网络接口的详细配置信息,包括IP地址、子网掩码、默认网关、DHCP服务器和DNS服务器。

在Linux中,你可以使用以下命令查看所有网络接口的详细信息:

ifconfig -a

这个命令将显示每个网络接口的详细信息,包括IP地址、子网掩码、MAC地址和状态信息(启用或禁用)。

示例2:诊断网络连接问题

在Windows中,如果你遇到网络连接问题,可以使用以下命令来释放和更新IP地址:

ipconfig /release ipconfig /renew

这些命令将释放当前的IP地址,并从DHCP服务器获取新的IP地址,从而解决可能的网络配置问题。

在Linux中,你可以重新启动网络接口来解决网络连接问题:

sudo ifconfig eth0 down sudo ifconfig eth0 up

这些命令将禁用并重新启用网络接口,从而解决可能的连接问题。

示例3:配置静态IP地址

在Windows中,你可以使用网络适配器设置来配置静态IP地址:

netsh interface ip set address name="Local Area Connection" static 192.168.1.100 255.255.255.0 192.168.1.1

这个命令将网络适配器“Local Area Connection”的IP地址设置为192.168.1.100,子网掩码为255.255.255.0,默认网关为192.168.1.1。

在Linux中,你可以编辑网络配置文件来配置静态IP地址:

sudo nano /etc/network/interfaces

在文件中添加以下内容:

iface eth0 inet static 
address 192.168.1.100 
netmask 255.255.255.0 
gateway 192.168.1.1

保存并退出,然后重新启动网络服务:

sudo /etc/init.d/networking restart

通过掌握ipconfig和ifconfig命令,网络工程师可以更高效地管理和配置网络接口,从而确保网络的正常运行和性能优化。

04 nslookup/dig

nslookup和dig是用于DNS查询的命令行工具。它们允许网络工程师查找域名的IP地址,验证DNS记录,以及解决与DNS相关的问题。

nslookup(Windows和Linux):用于查询DNS服务器并获取域名的相关信息。适用于快速查询和简单的DNS测试。

dig(Linux):更强大的DNS查询工具,提供详细的DNS信息和更丰富的参数选项,适合深入分析和排查DNS问题。

01实际案例及应用

示例1:查询域名的A记录

使用nslookup查询域名的A记录:

nslookup www.google.com

这个命令将返回www.google.com的IP地址,帮助你验证该域名是否正确解析到相应的服务器。

使用dig查询域名的A记录:

dig www.google.com

这个命令将返回www.google.com的详细DNS信息,包括A记录及其他相关记录。

示例2:查询特定DNS记录类型

使用nslookup查询MX记录(邮件交换记录):

nslookup -query=mx google.com

这个命令将返回google.com的邮件服务器信息,帮助你验证邮件系统配置。

使用dig查询MX记录:

dig google.com MX

这个命令将返回google.com的详细邮件服务器信息。

示例3:使用dig进行反向DNS查询

反向DNS查询用于查找IP地址对应的域名。使用dig进行反向查询:

dig -x 8.8.8.8

这个命令将返回IP地址8.8.8.8对应的域名,帮助你确认该IP的DNS记录。

示例4:使用nslookup检查特定DNS服务器

如果你想查询特定DNS服务器上的记录,可以使用nslookup指定服务器:

nslookup www.example.com 8.8.8.8

这个命令将使用Google的DNS服务器(8.8.8.8)进行查询,返回www.example.com的DNS信息。

02 nslookup的常用参数选项:

nklookup的常用参数选项:

-query=type:指定查询的记录类型(如A、MX、NS等)。

-timeout=seconds:指定查询的超时时间。

-retry=number:指定重试次数。

dig的常用参数选项:

+short:只显示简短的结果。

+trace:跟踪整个DNS查询路径,显示所有中间DNS服务器的信息。

+noall +answer:仅显示查询的回答部分,去除多余的信息。

05 netstat

netstat(网络统计)是一个非常强大的命令行工具,用于显示网络连接、路由表、接口统计、伪装连接和多播成员等信息。它可以帮助网络工程师监控和诊断网络状态,识别网络问题,并查看系统的网络活动。

01如何查看网络连接和监听端口

基本命令格式:

netstat [选项]

这个命令将显示当前所有的活动网络连接,包括TCP和UDP协议的连接。

02 实际应用及故障排除案例

示例1:查看所有活动的网络连接

使用以下命令查看当前所有活动的网络连接:

netstat -a

这个命令将显示系统上所有的活动连接和监听端口,包括TCP和UDP协议。

示例2:查看特定端口的监听状态

如果你想查看特定端口的监听状态,可以使用以下命令:

netstat -an | grep 80

这个命令将显示所有在80端口上的监听和活动连接状态,有助于确定Web服务器是否正常运行。

示例3:查看网络连接的程序名称

要查看网络连接的程序名称,可以使用以下命令(在Windows中):

netstat -b

这个命令将显示每个网络连接关联的可执行程序名,帮助你识别哪个应用程序正在使用网络资源。

在Linux中,可以结合ps和lsof命令来实现类似功能:

sudo netstat -tulpn

这个命令将显示所有的监听端口及其关联的程序PID和名称。

示例4:查看路由表

要查看系统的路由表,可以使用以下命令:

netstat -r

这个命令将显示当前的路由表信息,包括网络目的地、网关和接口等。

03 常用参数选项:

-a:显示所有连接和监听端口。

-n:以数字形式显示地址和端口号,而不是尝试将其解析为域名或服务名称。

-t:仅显示TCP协议的连接。

-u:仅显示UDP协议的连接。

-p:显示每个连接关联的进程ID和进程名称(需要root权限)。

-s:显示网络统计信息,包括每个协议的统计数据。

-r:显示路由表信息。

-i:显示网络接口的统计信息。

-c:每隔一定时间重复执行netstat命令,实时显示网络状态(Linux)。

06 nbtstat

nbtstat命令用于显示NetBIOS over TCP/IP协议的统计信息。它主要用于诊断和解决NetBIOS名称解析问题,以及查看本地和远程计算机上的NetBIOS缓存。

01如何查看网络连接和监听端口

基本命令格式:

netstat [选项]

02实际应用及故障排除案例

示例1:查看本地NetBIOS名称表

使用以下命令查看本地计算机的NetBIOS名称表:

nbtstat -n

这个命令将显示本地NetBIOS名称表,包括已注册的NetBIOS名称和类型。

示例2:查看远程NetBIOS名称表

要查看远程计算机的NetBIOS名称表,可以使用以下命令:

nbtstat -A 192.168.1.1

这个命令将显示IP地址为192.168.1.1的计算机的NetBIOS名称表。

示例3:清除和刷新NetBIOS名称缓存

当NetBIOS名称解析出现问题时,可以使用以下命令清除和刷新本地NetBIOS名称缓存:

nbtstat -R

这个命令将清除NetBIOS名称缓存并重新加载LMHOSTS文件。

03常用参数选项

-a:显示指定计算机的NetBIOS名称表。

-A:通过IP地址显示远程计算机的NetBIOS名称表。

-n:显示本地NetBIOS名称表。

-r:显示NetBIOS名称解析统计信息。

-R:清除和刷新NetBIOS名称缓存。

-S:显示当前的NetBIOS会话。

-s:显示NetBIOS会话,并尝试将远程计算机的IP地址解析为名称。

07 arp

arp(地址解析协议)命令用于显示和修改本地ARP缓存表。ARP协议将IP地址解析为MAC地址,使网络通信得以进行。网络工程师使用arp命令来查看和管理本地设备的ARP缓存,以诊断和解决网络通信问题。

01如何查看和管理ARP缓存

基本命令格式:

arp [选项]

02实际应用及网络问题解决

示例1:查看本地ARP缓存表

使用以下命令查看本地ARP缓存表:

arp -a

这个命令将显示当前所有已解析的IP地址和对应的MAC地址。

示例2:添加静态ARP条目

要手动添加一个静态ARP条目,可以使用以下命令:

arp -s 192.168.1.1 00-14-22-01-23-45

这个命令将IP地址192.168.1.1绑定到MAC地址00-14-22-01-23-45,防止ARP欺骗攻击。

示例3:删除ARP条目

当需要删除某个ARP条目时,可以使用以下命令:

arp -d 192.168.1.1

这个命令将从ARP缓存表中删除IP地址192.168.1.1的条目。

03常用参数选项

-a:显示所有接口的ARP缓存。

-g:与-a选项相同,显示ARP缓存。

-d IP地址:删除指定IP地址的ARP条目。

-s IP地址 MAC地址:添加静态ARP条目,将IP地址绑定到MAC地址。

08 route

route命令用于查看和修改主机的路由表。路由表决定数据包在网络中的传输路径。网络工程师使用route命令来管理路由条目,以确保数据包能够正确传递到目的地。

01如何查看和管理路由表

基本命令格式:

route [选项]

02实际应用及案例

示例1:查看路由表

使用以下命令查看当前的路由表:

route print

在Windows中,这个命令将显示所有的路由条目,包括目标网络、网关、接口和度量值。在Linux中,使用以下命令:

route -n

这个命令将以数字格式显示路由表,避免域名解析,提高命令执行速度。

示例2:添加静态路由

要向路由表中添加静态路由条目,可以使用以下命令:

route add 192.168.2.0 mask 255.255.255.0 192.168.1.1

这个命令将添加一个静态路由,使得到达192.168.2.0/24网络的数据包通过网关192.168.1.1进行传输。在Linux中,使用以下命令:

sudo route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.1.1

示例3:删除静态路由

当需要删除某个静态路由时,可以使用以下命令:

route delete 192.168.2.0

这个命令将从路由表中删除到192.168.2.0网络的路由。在Linux中,使用以下命令:

sudo route del -net 192.168.2.0 netmask 255.255.255.0

示例4:更改默认网关

要更改默认网关,可以使用以下命令:

route add 0.0.0.0 mask 0.0.0.0 192.168.1.1

这个命令将默认网关设置为192.168.1.1。在Linux中,使用以下命令:

sudo route add default gw 192.168.1.1

03常用参数选项

print:显示路由表(Windows)。

-n:以数字格式显示路由表(Linux)。

add:添加路由条目。

delete:删除路由条目。

change:修改现有的路由条目。

-net:指定网络路由。

-host:指定主机路由。

gw:指定网关。

09 telnet/ssh

telnet和ssh是用于远程登录和管理网络设备的命令行工具。telnet提供一个非加密的连接,而ssh则提供一个加密的、安全的连接。网络工程师常用这些工具来远程访问和管理服务器、路由器、交换机等设备。

01如何使用这些命令进行远程登录和管理

基本命令格式:

telnet 目标地址
ssh 用户名@目标地址

02际应用及安全性

示例1:使用telnet进行远程登录

使用以下命令登录到远程设备:

telnet 192.168.1.1

这个命令将尝试通过telnet连接到IP地址为192.168.1.1的设备。由于telnet不加密通信数据,所以它通常只在可信的局域网环境中使用。

示例2:使用ssh进行安全的远程登录

使用以下命令登录到远程服务器:

ssh user@192.168.1.1

这个命令将通过ssh连接到IP地址为192.168.1.1的服务器,并使用指定的用户名"user"进行登录。ssh会加密所有通信数据,确保远程管理的安全性。

示例3:使用密钥认证进行ssh登录

为了增强安全性,可以使用密钥对进行认证:

ssh -i /path/to/private_key user@192.168.1.1

这个命令将使用指定的私钥文件进行登录,避免了使用密码的风险。

示例4:使用ssh进行端口转发

ssh还可以用于端口转发,以便在安全通道内访问内部网络资源:

ssh -L 8080:localhost:80 user@192.168.1.1

这个命令将把本地主机的8080端口转发到远程服务器的80端口,允许你通过本地8080端口访问远程服务器上的Web服务。

03常用参数选项

telnet:

quit:退出telnet

close:关闭当前连接。

open:打开连接到指定主机。

ssh

-i:指定私钥文件。

-p:指定连接端口。

-L:本地端口转发。

-R:远程端口转发。

-C:启用压缩。

-N:不执行远程命令,仅进行端口转发。

10 tshark/tcpdump

tshark和tcpdump是两个强大的网络抓包工具,用于捕获和分析网络流量。tshark是Wireshark的命令行版本,提供了丰富的协议解码功能。tcpdump是一个轻量级的抓包工具,适合快速捕获和分析网络数据包。

01实际应用及案例

示例1:捕获网络接口上的所有数据包

使用以下命令在默认网络接口上捕获所有数据包:

tcpdump

这个命令将显示网络接口上的所有数据包的简要信息。

示例2:保存抓包数据到文件

要将捕获的数据包保存到文件中,可以使用以下命令:

tcpdump -w capture.pcap

这个命令将捕获的数据包保存到capture.pcap文件中,供后续分析使用。

示例3:使用tshark读取并分析抓包文件

使用以下命令读取并分析之前保存的抓包文件:

tshark -r capture.pcap

这个命令将显示抓包文件中的数据包信息,提供详细的协议解码。

示例4:捕获特定端口的流量

要捕获特定端口(如80端口)的流量,可以使用以下命令:

tcpdump port 80

这个命令将只捕获HTTP流量,便于分析Web通信。

示例5:使用tshark进行实时分析

要实时捕获并分析网络流量,可以使用以下命令:

tshark -i eth0

这个命令将在eth0接口上实时捕获并显示网络数据包的详细信息。

02常用参数选项

tcpdump:

-i:指定网络接口。

-w:将捕获的数据保存到文件。

-r:读取并分析抓包文件。

-n:不解析主机名。

-nn:不解析主机名和端口名。

-s:设置捕获的数据包大小。

-c:捕获指定数量的数据包后停止。

-X:以十六进制和ASCII格式显示数据包内容。

tshark:

-i:指定网络接口。

-w:将捕获的数据保存到文件。

-r:读取并分析抓包文件。

-T:指定输出格式(如json、text等)。

-Y:使用显示过滤器。

-f:使用捕获过滤器。

11 总结

我们详细探讨了网络工程师日常工作中最常用的十个网络命令。这些命令涵盖了从基本的连通性测试到复杂的网络抓包分析等多个方面。

回顾10个关键命令的重要性:

  • ping:快速测试网络连通性和延迟,是最基本的网络诊断工具。
  • tracert/traceroute:路径跟踪,帮助识别网络路径中的延迟和中断点。
  • ipconfig/ifconfig:查看和管理网络接口的配置信息,解决网络配置问题。
  • nslookup/dig:DNS查询,验证域名解析并解决DNS相关问题。
  • netstat:查看网络连接和监听端口,监控网络状态和活动。
  • nbtstat:管理NetBIOS名称表,解决NetBIOS名称解析问题。
  • arp:查看和管理ARP缓存,确保IP地址和MAC地址的正确映射。
  • route:管理路由表,确保数据包在网络中能够正确传输。
  • telnet/ssh:远程登录和管理网络设备,确保安全性和有效性。
  • tshark/tcpdump:网络抓包和分析,深入了解网络流量,解决复杂网络问题。

无论是快速诊断网络故障,还是优化网络性能,这些命令都是你必备的工具。

通过不断实践和深入学习,你将能更好地理解网络的内部工作原理,从而在复杂的网络环境中做出正确的决策。

当然,成为一名资深网络工程师不仅仅是掌握这些命令,还需要不断更新知识,适应技术的快速发展。

多动手实践,参与项目和案例分析,将理论知识应用到实际工作中。只有通过不断的学习和实践,你才能真正掌握网络工程的精髓。

还有什么你必用的网络命令?聊聊呗!

原创:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部

<think>根据用户的问题,我们需要在Nginx中实现一个功能:除了特定路径(例如`/EHAwmsForLZH01308`)之外,访问其他任何路径的请求都将被封禁IP。这可以通过Nginx的`ngx_http_access_module`模块来实现,该模块提供了`allow`和`deny`指令。 我们可以这样设计: 1. 定义一个白名单路径,比如`/EHAwmsForLZH01308`。 2. 对于请求,首先检查请求的URI是否以白名单路径开头,如果是则允许访问。 3. 如果不是,则拒绝访问并返回403,或者我们可以更进一步,将IP加入黑名单(但通常封禁IP是在防火墙层面,或者在Nginx中通过deny all拒绝,但要动态封禁IP需要更复杂的设置)。 但是注意,用户要求的是“封禁IP”,这通常意味着对于非白名单路径的访问,我们不仅要拒绝本次访问,还要将客户端IP加入黑名单,使得该IP后续的所有访问(包括白名单路径)都被拒绝。然而,这个需求有点复杂,因为Nginx本身没有内置的动态封禁IP的功能(除非使用第三方模块如ngx_http_limit_req_module进行限流,或者使用ngx_http_geo_module定义黑名单,但这些都需要预先定义或者结合外部程序)。 考虑到实际可行性,我们可以分两步: 第一步:拒绝非白名单路径的访问,并记录该IP(比如记录到日志中)。 第二步:通过外部机制(如fail2ban)分析日志,将频繁访问非白名单路径的IP添加到黑名单(例如添加到Nginx的deny list配置文件并重载Nginx)。 但是,如果用户想要在Nginx配置中直接实现封禁(即一次访问非白名单路径就永久封禁),则需要使用共享内存和Lua脚本(通过OpenResty)来实现,或者使用Nginx的map指令结合外部数据库。 由于问题中没有明确要求是一次封禁还是多次,这里我们按照简单的情况处理:即每次访问非白名单路径,直接返回403,并不做动态封禁(因为动态封禁需要额外的模块和配置)。但是,如果用户希望一次违规就永久封禁该IP,那么我们可以使用Nginx的map指令配合一个黑名单文件,然后通过外部脚本将违规IP写入黑名单文件。但是,这样每次修改黑名单文件都需要重新加载Nginx配置。 因此,这里我们提供两种方案: 方案一:简单拒绝非白名单路径的访问(不封禁IP,只拒绝当前请求) 方案二:结合map和外部脚本实现动态封禁(一次违规,永久封禁) 我们先给出方案一的配置,因为方案一简单且不依赖外部模块。 方案一配置: 在Nginx配置文件中,我们可以这样写: ``` http { # 其他配置... server { listen 80; server_name your_domain.com; # 白名单路径 location = /EHAwmsForLZH01308 { # 处理该路径的请求 # ... 你的正常配置 } # 其他所有路径 location / { # 如果不是白名单路径,则拒绝访问 deny all; return 403; # 显式返回403,deny all本身也会返回403,但这里为了明确 } } } ``` 但是这样配置会导致白名单路径只能精确匹配`/EHAwmsForLZH01308`,如果用户希望支持该路径下的子路径,比如`/EHAwmsForLZH01308/xxx`,那么应该使用前缀匹配。 修改为前缀匹配: ``` http { server { listen 80; server_name your_domain.com; location ^~ /EHAwmsForLZH01308 { # 处理该路径及其子路径的请求 # ... 你的正常配置 } location / { deny all; return 403; } } } ``` 注意:`^~`修饰符表示前缀匹配,并且如果匹配到该规则,则不再进行正则匹配。 方案二:动态封禁(一次违规,永久封禁) 这个方案需要以下步骤: 1. 定义一个黑名单文件,比如`/etc/nginx/blacklist.conf`,里面包含被禁IP的`deny`指令。 2. 在Nginx配置中引入这个黑名单文件,并使用map指令来标记违规IP。 3. 在访问非白名单路径时,将客户端IP记录到黑名单文件中,并重新加载Nginx。 但是,Nginx本身不能在处理请求时动态修改配置文件并重载。因此,我们需要借助外部脚本。我们可以这样做: 步骤1:创建黑名单文件,并确保Nginx主配置中加载该文件。 步骤2:在Nginx配置中,对于非白名单路径的访问,通过`error_page`和`proxy_pass`(或`fastcgi_pass`)将请求转发到一个内部服务,该服务负责将IP写入黑名单文件并返回403。但更常见的做法是使用Lua脚本(需要OpenResty)。 由于原生的Nginx不支持动态写入黑名单文件并重载,我们这里使用一个变通方法:在每次检测到非白名单访问时,通过`return 403`拒绝,并记录日志。然后,用一个外部进程(如cron job)定期扫描日志,将访问过非白名单路径的IP提取出来,写入黑名单文件,然后重载Nginx。 但是,这并不能实现“一次访问就立即封禁”,而是需要等待外部进程运行。如果要求立即封禁,则需要使用OpenResty的Lua模块。 考虑到用户可能没有使用OpenResty,我们这里给出一个折中的方案:使用Nginx的map指令和变量来标记黑名单IP,但黑名单IP需要预先定义,动态添加需要重新加载配置。 这里我们给出一个基于OpenResty的示例(方案二的高级版,使用Lua动态封禁)。如果用户没有使用OpenResty,可能需要自行编译Nginx并添加Lua模块。 OpenResty方案: 1. 安装OpenResty。 2. 配置Nginx,使用Lua脚本在访问非白名单路径时将IP加入共享内存中的黑名单,并拒绝后续该IP的访问。 配置示例: ``` http { lua_shared_dict ip_blacklist 10m; # 共享内存区域,存储黑名单 server { listen 80; server_name your_domain.com; # 初始化黑名单(可选,可以从外部文件加载) init_by_lua_block { local blacklist = ngx.shared.ip_blacklist -- 可以在这里从文件加载初始黑名单 } # 白名单路径 location ^~ /EHAwmsForLZH01308 { # 正常处理 # ... } location / { access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr -- 检查IP是否在黑名单中 if blacklist:get(client_ip) then ngx.exit(403) end -- 如果不是白名单路径,则将该IP加入黑名单并拒绝 blacklist:set(client_ip, true, 0) -- 0表示永不过期 ngx.exit(403) } } } } ``` 但是,这样配置会导致任何访问非白名单路径的IP都会被加入黑名单(永久),并且后续该IP的任何请求(包括白名单路径)都会被拒绝。 注意:上述配置中,白名单路径的访问不会触发黑名单检查,因为白名单路径的location优先级高(^~前缀匹配),所以不会进入location `/`。但是,如果同一个IP先访问了非白名单路径,那么它会被加入黑名单,然后即使访问白名单路径也会被拒绝(因为黑名单是全局的,而白名单路径的location中并没有检查黑名单)。因此,我们需要在白名单路径中也加入黑名单检查,但只允许白名单路径的访问不被拒绝,同时也不触发加入黑名单。 改进:我们在白名单路径中不执行加入黑名单的操作,但需要检查黑名单(如果IP已被封禁,则白名单路径也不能访问)。或者,我们可以调整逻辑:黑名单只对非白名单路径的访问进行封禁,但白名单路径的访问不受影响(即即使IP在黑名单中,只要访问的是白名单路径,就允许)。这取决于需求。 修改后的配置: ``` http { lua_shared_dict ip_blacklist 10m; server { listen 80; server_name your_domain.com; location / { access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr -- 如果IP在黑名单中,拒绝访问(无论什么路径) if blacklist:get(client_ip) then ngx.exit(403) end -- 检查请求的URI,如果不是白名单路径,则加入黑名单并拒绝 local uri = ngx.var.uri if not string.find(uri, "^/EHAwmsForLZH01308") then blacklist:set(client_ip, true, 0) ngx.exit(403) end } # 只有白名单路径才能到达这里 # ... 正常处理 } } } ``` 但是,这个配置将白名单路径和非白名单路径都放在同一个location中,通过Lua脚本进行路径判断。这样可能会影响性能,并且对于白名单路径的请求,每次都要进行Lua脚本判断。 另一种方式是将白名单路径单独放在一个location,并在这个location中只检查黑名单,但不加入黑名单,同时进行正常处理;而非白名单路径的location则负责加入黑名单并拒绝。 配置如下: ``` http { lua_shared_dict ip_blacklist 10m; server { listen 80; server_name your_domain.com; # 黑名单检查,适用于所有location(作为公共部分) access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr if blacklist:get(client_ip) then ngx.exit(403) end } # 白名单路径 location ^~ /EHAwmsForLZH01308 { # 这里已经通过了黑名单检查,所以可以正常处理 # ... 正常配置 } location / { # 非白名单路径,将IP加入黑名单 access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr blacklist:set(client_ip, true, 0) } return 403; } } } ``` 注意:上面的配置中,由于`access_by_lua_block`在server块中,所以对每个请求都会执行(除了已经通过黑名单检查的请求,但这里我们是在每个请求中先执行这个公共的Lua块)。但是,在location `/`中,我们又使用了一个`access_by_lua_block`,这会导致覆盖server级别的access_by_lua_block。因此,我们需要将两个Lua脚本合并。 我们可以将黑名单检查放在http块或server块的access阶段,然后对于非白名单路径的location,再添加一个access阶段的操作(加入黑名单)。Nginx的access阶段可以执行多个模块,但Lua模块的access_by_lua可以合并吗?实际上,每个上下文(http, server, location)只能有一个access_by_lua。所以我们需要调整: 将黑名单检查放在http或server级别,然后在非白名单的location中只执行加入黑名单的操作(同时注意,在加入黑名单之前,公共的黑名单检查已经执行过了,所以当前IP不在黑名单中)。 修改如下: ``` http { lua_shared_dict ip_blacklist 10m; # 所有请求首先执行这个Lua脚本进行黑名单检查 access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr if blacklist:get(client_ip) then ngx.exit(403) end } server { listen 80; server_name your_domain.com; # 白名单路径 location ^~ /EHAwmsForLZH01308 { # 正常处理 # ... } location / { # 在公共黑名单检查之后,这个请求没有被拒绝,说明IP不在黑名单中 # 然后因为不是白名单路径,所以将IP加入黑名单 access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr blacklist:set(client_ip, true, 0) } return 403; } } } ``` 这个配置中,每个请求都会先执行http块的access_by_lua_block,检查是否在黑名单中。然后,对于非白名单路径,会再执行location `/`中的access_by_lua_block,将IP加入黑名单,然后返回403。这样,当同一个IP第一次访问非白名单路径时,会被加入黑名单并返回403;后续该IP的任何请求(包括白名单路径)都会在公共黑名单检查中被拒绝(403)。 但是,这样会导致白名单路径的访问也被公共黑名单检查所检查,所以如果一个IP因为之前访问了非白名单路径而被加入黑名单,那么它也无法访问白名单路径。 如果希望白名单路径的访问不受黑名单影响(即即使IP在黑名单中,只要访问白名单路径就允许),那么我们需要调整逻辑:将黑名单检查放在非白路径的location中,而不是放在公共部分。 因此,我们回到初的思路:在白名单路径中,我们只进行正常的处理,不检查黑名单(即允许访问);在非白名单路径中,我们先检查黑名单(如果已经封禁则拒绝),如果没有封禁则加入黑名单并拒绝。 但是,这样配置的话,如果一个IP先访问了白名单路径,然后再访问非白名单路径,那么第一次访问非白名单路径时会被封禁,后续再访问白名单路径时,由于没有检查,所以仍然可以访问。这不符合要求(要求是访问非白路径就封禁,而且封禁后应该不能访问任何路径)。所以我们需要封禁后,该IP的所有请求都被拒绝。 因此,我们还是需要公共的黑名单检查。但是,我们可以在公共检查中,对于白名单路径的请求,即使IP在黑名单中也允许通过?这样不符合封禁的概念。所以,我们需要明确: 需求:一旦IP访问了非白名单路径,就永久封禁该IP,使其不能再访问任何路径(包括白名单路径)。 因此,上面的配置(公共黑名单检查)是符合需求的。 总结:我们使用OpenResty,配置如下: ``` http { lua_shared_dict ip_blacklist 10m; # 全局黑名单检查:所有请求先检查是否在黑名单中,如果在则返回403 access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr if blacklist:get(client_ip) then ngx.exit(403) end } server { listen 80; server_name your_domain.com; # 白名单路径 location ^~ /EHAwmsForLZH01308 { # 这里已经通过了黑名单检查,所以可以正常处理 # ... 你的正常配置,比如代理到后端等 proxy_pass http://backend; } # 其他所有路径 location / { # 这个请求的IP不在黑名单中(因为通过了全局检查),但是访问的是非白名单路径 # 所以我们将该IP加入黑名单 access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr blacklist:set(client_ip, true, 0) # 0表示永不过期 } return 403; # 拒绝访问 } } } ``` 注意:这个配置中,白名单路径的请求不会进入非白名单路径的location,所以不会触发加入黑名单的操作。只有非白名单路径的请求才会触发加入黑名单。 另外,由于黑名单存储在共享内存中,所以重启Nginx后黑名单会消失(除非我们持久化到磁盘)。如果需要持久化,可以在Nginx关闭时将黑名单写入文件,启动时加载。这里不展开。 考虑到用户可能没有使用OpenResty,我们也可以给出方案一的配置(简单拒绝)作为主要方案,而方案二作为高级选项。 因此,我们给出两个方案,用户可以根据自己的需求选择。 方案一(简单拒绝)配置(不需要Lua): ```nginx server { listen 80; server_name your_domain.com; location ^~ /EHAwmsForLZH01308 { # 处理白名单路径 # ... 你的配置,例如: proxy_pass http://backend; } location / { deny all; return 403; } } ``` 方案二(动态封禁,需要OpenResty)配置见上面的代码块。 下面,我们给出方案一的详细解释: 1. 使用`location ^~ /EHAwmsForLZH01308`匹配所有以`/EHAwmsForLZH01308`开头的URI。 2. 对于其他所有请求(location `/`),使用`deny all`拒绝访问,并返回403。 方案二的解释已经包含在配置中。 由于问题中要求“封禁IP”,方案一并没有封禁IP,只是拒绝了当前请求,同一个IP可以继续访问白名单路径,但如果访问其他路径则会被拒绝。而方案二则是一次访问非白名单路径,该IP就会被永久封禁(后续所有请求,包括白名单路径,都会被拒绝)。用户可以根据需求选择。 下面,我们给出一个相关问题部分。 §§相关问题§§: 1. 在Nginx中如何实现基于IP的访问频率限制? 2. 除了使用OpenResty,还有哪些方法可以实现Nginx动态封禁IP? 3. 如何配置Nginx以持久化存储黑名单IP,避免重启后丢失? 4. 在方案二中,如果我想让黑名单在Nginx重启后仍然有效,应该如何做? </think> 针对你的需求,在Nginx中实现"非指定路径访问时封禁IP"的功能,以下是两种解决方案: ### 方案一:基础路径匹配(无需动态封禁) ```nginx server { listen 80; server_name your_domain.com; # 白名单路径 location ~ ^/EHAwmsForLZH01308(/|$) { # 此处放置正常处理逻辑 proxy_pass http://backend_server; } # 其他所有路径 location / { # 封禁所有非白名单访问 deny all; return 403 "Access Forbidden"; # 可选:记录违规访问日志 access_log /var/log/nginx/blocked_access.log; } } ``` **配置说明**: 1. `location ~ ^/EHAwmsForLZH01308(/|$)` - 使用正则匹配路径:精确匹配`/EHAwmsForLZH01308`及其所有子路径 - 例如允许访问: - `/EHAwmsForLZH01308` - `/EHAwmsForLZH01308/` - `/EHAwmsForLZH01308/subpath` 2. `deny all;` - 拒绝所有非白名单路径的访问 - 自动返回HTTP 403状态码 3. `access_log` - 单独记录违规访问日志便于审计 ### 方案二:动态IP封禁(OpenResty实现) ```nginx http { lua_shared_dict ip_blacklist 10m; # 共享内存存储黑名单 init_by_lua_block { -- 可选:从文件加载初始黑名单 local file = io.open("/etc/nginx/ip_blacklist.txt") if file then for ip in file:lines() do ngx.shared.ip_blacklist:set(ip, true) end file:close() end } server { listen 80; server_name your_domain.com; access_by_lua_block { local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr -- 检查IP是否在黑名单 if blacklist:get(client_ip) then ngx.exit(403) end } location ~ ^/EHAwmsForLZH01308(/|$) { # 白名单正常处理 proxy_pass http://backend; } location / { access_by_lua_block { -- 非白名单访问者加入黑名单 local blacklist = ngx.shared.ip_blacklist local client_ip = ngx.var.remote_addr -- 封禁IP(0表示永不过期) blacklist:set(client_ip, true, 0) -- 记录到文件(可选) local file = io.open("/etc/nginx/ip_blacklist.txt", "a") if file then file:write(client_ip, "\n") file:close() end } return 403; } } } ``` **核心功能**: 1. `lua_shared_dict` - 创建共享内存区存储实时黑名单 2. 双重访问控制: - 全局`access_by_lua_block`检查所有请求的IP黑名单状态 - 非白名单路径访问触发IP封禁 3. 黑名单持久化: - 将封禁IP追加到文本文件 - 服务重启时自动加载历史黑名单 ### 配置后操作 1. 测试配置:`sudo nginx -t` 2. 重载配置:`sudo systemctl reload nginx` 3. 验证效果: ```bash # 测试白名单路径 curl http://your_domain.com/EHAwmsForLZH01308 # 测试非白名单路径(应返回403) curl http://your_domain.com/otherpath ``` ### 方案选择建议 - 基础需求:方案一(标准Nginx功能) - 高级需求:方案二(需安装OpenResty) --- **
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值