-
1. 概述 1.1 ICMPv4介绍 ICMPv4是IPv4协议族中的一个重要协议,它主要用于传递网络层的控制和错误信息。与IP数据报不同,ICMPv4报文并不直接用于传输用户数据,而是辅助IP协议更好地完成数据传输任务。 ICMPv4报文封装在IP数据报中进行传输。报文主要由两部分组成:报头和数据部分。报头包含了类型、代码和校验和等重要信息,用于识别报文的类型和检测传输错误,数据部分携带了与具体报文类型相关的信息。 根据功能,ICMPv4报文可以分为两大类:差错报告报文和查询报文。 (1) 差错报告报文用于告知源主机在数据传输过程中遇到的各种错误情况: 目标不可达,数据包无法送达目标地址。 超时,数据包在网络中存在的时间超过限制。 重定向,通知源主机有更优的路由路径。 (2) 查询报文则用于网络探测和管理: 回显请求和应答,对应ping工具,用于连通性测试。 时间戳请求和应答,用于进行时间同步。 常用的网络诊断工具如ping、traceroute都是基于ICMPv4实现的,可以利用它们快速判断网络状态,定位故障点。 1.2 相关RFC文档 以下是与ICMPv4相关的主要RFC文档列表: RFC 792 - Internet Control Message Protocol (1981),定义了ICMPv4协议的基本规范,包括报文格式、类型和代码等。 RFC 950 - Internet Standard Subnetting Procedure (1985),引入了子网编址的概念,通过子网掩码实现IP地址的划分。 RFC 1122 - Requirements for Internet Hosts – Communication Layers (1989),定义了互联网主机在实现TCP/IP协议栈时需要遵循的各项要求。 RFC 1191 - Path MTU Discovery (1990),提出了路径MTU发现机制,用于确定到达目标主机路径上的最小MTU。 RFC 1256 - ICMP Router Discovery Messages (1991),引入了ICMPv4路由器发现报文,用于主机动态地发现本地网络上的路由器。 RFC 1393 - Traceroute Using an IP Option (1993),描述了使用IP选项实现traceroute的方法。 RFC 1812 - Requirements for IP Version 4 Routers (1995),定义了IPv4路由器的各项需求,其中包括对ICMPv4的处理要求。 RFC 2463 - Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification (1998),定义了ICMPv6协议,作为IPv6协议族中与ICMPv4相对应的协议。 RFC 4443 - Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification (2006),更新了ICMPv6协议的规范,取代了RFC 2463。 RFC 4884 - Extended ICMP to Support Multi-Part Messages (2007),扩展了ICMPv4和ICMPv6,支持多部分消息,增加了对大型诊断消息的传输能力。 RFC 5837 - ICMP Extensions for Multiprotocol Label Switching (2010),定义了用于MPLS的ICMPv4和ICMPv6扩展,支持MPLS网络的错误报告和诊断。 RFC 5508 - NAT Behavioral Requirements for ICMP (2009),定义了网络地址转换(NAT)设备处理ICMPv4报文的行为要求,以保证NAT环境下ICMP的正确工作。 2. 报文格式 2.1 ICMPv4首部 ICMPv4报文格式由类型、代码和校验和三个固定字段组成,后面紧跟与具体报文类型相关的数据部分。 字段说明: IPv4报文首部协议(proto)字段值为1,表示其携带了ICMPv4报文数据。 Type(类型,8位)标识ICMPv4报文的类型,不同的类型对应不同的报文格式和用途,如0表示回显应答,8表示回显请求等。 Code(代码,8位)与类型字段一起标识ICMPv4报文的具体含义,同一类型的报文可能有多个代码值,表示不同的错误原因或附加信息。 Checksum(校验和,16位)用于检测报文在传输过程中是否出现错误,计算时需要将校验和字段置零,然后对整个ICMP报文进行16位二进制反码求和。 Message Body(消息体,长度可变)携带与具体报文类型相关的数据,如错误信息、回显数据等,不同类型的报文有不同的消息体格式。 2.2 ICMPv4报文类型 常见的ICMPv4报文类型如下: 类型 名称 RFC文档 差错or查询 用途描述 0 Echo Reply RFC792 查询 响应Echo Request,用于确认连通性和RTT测量 3 Destination Unreachable RFC792 差错 通知源主机目标不可达,具体原因在Code字段中说明 4 Source Quench RFC792 差错 通知源主机降低发送速率,避免拥塞(已废弃) 5 Redirect RFC792 差错 通知源主机有更好的路由,优化路由路径 8 Echo Request RFC792 查询 请求目标主机回应,用于确认连通性和RTT测量 9 Router Advertisement RFC1256 查询 路由器定期或应请求发送,公告自身作为默认网关的可用性 10 Router Solicitation RFC1256 查询 主机发送该报文,请求路由器立即发送Router Advertisement 11 Time Exceeded RFC792 差错 当TTL耗尽或分片重组超时时,告知源主机 12 Parameter Problem RFC792 差错 IP首部存在问题导致无法处理时,告知源主机 13 Timestamp RFC792 查询 请求目标主机回送时间戳,用于时间同步(已废弃) 14 Timestamp Reply RFC792 查询 Timestamp查询的应答报文(已废弃) 15 Information Request RFC792 查询 请求目标主机提供IP地址信息(已废弃) 16 Information Reply RFC792 查询 Information Request的应答报文(已废弃) 17 Address Mask Request RFC1256 查询 请求子网掩码信息(已废弃) 18 Address Mask Reply RFC1256 查询 Address Mask Request的应答报文(已废弃) 类型3、4、5、11、12属于差错报文,用于通知源主机存在的问题。 类型0、8、13、14、15、16属于查询报文,用于诊断连通性、测量时延等。 有些类型如Source Quench、Timestamp等已经被废弃不再使用。 2.3 ICMPv4常见代码 ICMPv4中类型3、5、9、11、12的常见代码号如下: 类型 代码 名称 描述 3 0 Net Unreachable 目标网络不可达 3 1 Host Unreachable 目标主机不可达 3 2 Protocol Unreachable 目标协议不可达 3 3 Port Unreachable 目标端口不可达 3 4 Fragmentation Needed and Don’t Fragment was Set 需要分片但设置了不分片位 3 5 Source Route Failed 源路由失败 3 6 Destination Network Unknown 目标网络未知 3 7 Destination Host Unknown 目标主机未知 3 8 Source Host Isolated 源主机被隔离 3 9 Communication with Destination Network is Administratively Prohibited 与目标网络的通信被管理员禁止 3 10 Communication with Destination Host is Administratively Prohibited 与目标主机的通信被管理员禁止 3 11 Destination Network Unreachable for Type of Service 对于此类服务,目标网络不可达 3 12 Destination Host Unreachable for Type of Service 对于此类服务,目标主机不可达 3 13 管理禁止通信 被过滤策略禁止的通信 3 14 违反主机优先级 src/dest/port不准许的优先级 3 15 优先级终止生效 在最小Tos之下(RFC1812) 5 0 Redirect Datagram for the Network 对特定网络重定向 5 1 Redirect Datagram for the Host 对特定主机重定向 5 2 Redirect Datagram for the Type of Service and Network 对特定类型服务和网络重定向 5 3 Redirect Datagram for the Type of Service and Host 对特定类型服务和主机重定向 9 0 Normal Router Advertisement 正常路由器通告 9 16 Does Not Route Common Traffic 不路由普通流量 11 0 Time to Live exceeded in Transit 传输过程中超过生存时间 11 1 Fragment Reassembly Time Exceeded 分片重组超时 12 0 Pointer indicates the error 参数问题,错误由指针指出 12 1 Missing a Required Option 缺少必需的选项 12 2 Bad Length 长度错误 2.4 ICMPv4差错报文限制 在某些情况下,网络设备不会产生ICMPv4差错报文,以避免网络拥塞、安全问题或无用的错误报告: 广播或组播地址,当IP数据报的目标地址是广播或组播地址时,通常不会产生ICMPv4差错报文,如"目标不可达"或"超时"等。 分片,当接收到IP分片时,如果出现错误(如超时、目标不可达等),通常不会为每个分片生成单独的ICMPv4差错报文,而是等到全部分片到达后再生成一个差错报文。 ICMP差错报文,为了避免无限循环,当一个ICMP差错报文触发另一个差错时,通常不会再生成新的ICMP差错报文。 源地址不可达,当源IP地址不可达时(零地址、环回地址、广播地址或组播地址),通常不会生成ICMPv4差错报文,以避免网络拥塞和广播风暴。 作为链路层广播的数据报,避免产生大量的差错报文。 安全策略,根据网络管理员的安全策略,某些类型的ICMPv4报文可能会被禁用或过滤,如ping请求、重定向等。 2.5 ICMPv4目的不可达(类型3) ICMPv4的目的不可达报文(Destination Unreachable Message)是类型3的差错报文,用于在数据包无法送达目标时,由路由器或主机向源端发送,告知其发生了不可达的情况。 RFC 792报文的格式如下: Destination Unreachable Message(RFC 792) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | unused | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internet Header + 64 bits of Original Data Datagram | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 字段说明如下: Type(8位),值为3,表示目的不可达报文。 Code(8位),表示不可达的具体原因,取值范围0~15。 Checksum(16位),ICMPv4头部和数据部分的校验和。 unused(32位),未使用字段,必须置0。 Internet Header + 64 bits of Original Data Datagram,数据部分,包含引发差错报文的原始IP数据报的IP头部和至少64位数据。在不超过576字节的情况下,应尽量的多包涵原始数据。 RFC 4884报文格式如下(支持扩展数据结构): Destination Unreachable Message(RFC 4884) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | unused | Length | Next-Hop MTU* | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internet Header + leading octets of original datagram | | | | // | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ICMP扩展头部以及零个或多个关联对象 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type、Code、Checksum、unused字段与原有格式相同。 Original IPv4 Header + data,数据部分,包含引发差错报文的原始IP数据报的IP头部和数据。与原有格式不同,该字段长度可变,不再限于64位,至少应包含128字节。 Length,指示Original IPv4 Header + data字段的长度,单位为4字节(IPv4和IPv6单位不一样)。 代码为4(报文太大)时,Next-Hop MTU字段用于记录下一跳的MTU,并被PMTUD使用。 当路由器或主机无法转发或处理接收到的数据包时,就会向源端发送一个相应的目的不可达报文。源端收到该报文后,可以根据Code值判断具体的不可达原因,并结合数据部分携带的原始报文信息进行问题的定位和调整。 Code字段表示不可达的具体原因,常见取值如下: Net Unreachable(0),网络不可达。 Host Unreachable(1),主机不可达。 Protocol Unreachable(2),协议不可达。 Port Unreachable(3),端口不可达。 Fragmentation Needed and Don’t Fragment was Set(4),需要分片但禁止分片。 Source Route Failed(5),源路由失败。 Destination Network Unknown(6),目标网络未知。 Destination Host Unknown(7),目标主机未知。 Source Host Isolated(8),源主机被隔离。 Communication with Destination Network Administratively Prohibited(9),目标网络通信被管理员禁止。 Communication with Destination Host Administratively Prohibited(10),目标主机通信被管理员禁止。 Destination Network Unreachable for Type of Service(11),对于当前服务类型,目标网络不可达。 Destination Host Unreachable for Type of Service(12),对于当前服务类型,目标主机不可达。 数据部分包含了引发该差错报文的原始IP数据报的IP头部和前64位数据,用于帮助源端定位和诊断问题。如果原始数据报小于64位,则截断后填充0。 ICMPv4定义了"Packet Too Big"(PTB)报文,用于在网络中发现和调整数据包的大小,以适应不同链路的MTU限制,这种机制称为"Path MTU Discovery"(PMTUD),对于优化网络性能和避免分片非常重要。 在ICMPv4中,PTB报文属于目的不可达报文(类型3)的一种特例,使用代码4表示。当一个路由器收到一个数据包,其大小超过了下一跳链路的MTU,且该数据包设置了"Don’t Fragment"(DF)标志时,路由器会丢弃该数据包,并向源主机发送一个PTB报文。 PTB报文的格式与普通的目的不可达报文类似,但在未使用字段中携带了下一跳链路的MTU值。源主机收到PTB报文后,会将该报文中指示的MTU值作为目标地址的Path MTU(PMTU),并据此调整后续数据包的大小。 如果源主机无法缩减数据包大小,则会中止发送并向上层应用报告错误。 2.6 ICMPv4重定向(类型5) ICMPv4的重定向报文(Redirect Message)是一种特殊的ICMP报文,用于通知主机更优的路由路径。当主机发送数据包时,如果路由器发现主机使用了次优的路由路径,则会向主机发送重定向报文,建议主机更新其路由表,以便后续数据包可以直接发送到更优的下一跳路由器。 Redirect Message(5) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Gateway Internet Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internet Header + 64 bits of Original Data Datagram | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type(8位),值为5,表示重定向报文。 Code(8位),表示重定向的具体原因,取值范围0~3。 Checksum(16位),ICMP报文的校验和。 Gateway Internet Address(32位),建议的更优下一跳路由器的IP地址。 Internet Header + 64 bits of Original Data Datagram,触发重定向报文的原始IP数据报的IP头部和前64位数据。 重定向类型(Code): Network Redirect(0),表示对特定网络的重定向。 Host Redirect(1),表示对特定主机的重定向。 Network Redirect for TOS(2),表示对特定网络和服务类型(TOS)的重定向。 Host Redirect for TOS(3),表示对特定主机和服务类型(TOS)的重定向。 2.7 ICMPv4超时(类型11) ICMPv4的超时报文(Time Exceeded Message)是一种重要的差错报文,用于通知源主机在数据包传输过程中发生了超时。这种超时通常分为两种情况: 传输过程中超过了IP头部中的生存时间(TTL)。 分片重组超时,相当于整个数据报被丢弃。 下面是ICMPv4超时报文的格式: Time Exceeded Message(11) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | unused | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internet Header + 64 bits of Original Data Datagram | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 字段说明: Type(8位),值为11,表示超时报文。 Code(8位),表示超时的具体原因,取值范围0~1。 Checksum(16位),ICMP报文的校验和。 unused(32位),未使用字段,置0。 Internet Header + 64 bits of Original Data Datagram,触发超时报文的原始IP数据报的IP头部和前64位数据。 超时代码(Code): Time to Live exceeded in Transit(0),表示数据包在传输过程中超过了IP头部中的TTL值。每经过一个路由器,IP头部的TTL值就会减1,当TTL减为0时,路由器会丢弃该数据包,并向源主机发送一个Code 0的超时报文。 Fragment Reassembly Time Exceeded(1),表示分片重组超时。当一个数据包被分片传输时,目标主机需要在一定时间内收到所有分片并重组,如果超过了设定的时间阈值,就会触发Code 1的超时报文。 超时报文用于通知源主机在数据包传输过程中发生了异常,帮助源主机诊断和调试网络问题: Code 0的超时报文通常表明网络路径过长或存在路由环路,源主机可以据此调整TTL值或检查路由配置。Code 0的超时报文也被用于traceroute等网络诊断工具,以发现网络路径上的路由器。 Code 1的超时报文提示分片重组过程出现了问题,可能是因为网络拥塞、分片丢失或目标主机资源不足等原因。 2.8 ICMPv4参数问题(类型12) ICMPv4的参数问题报文(Parameter Problem Message)是一种重要的差错报文,用于通知源主机在数据包的首部中发现了错误或不完整的信息。当路由器或主机在处理数据包时检测到头部字段存在问题,无法正确解析或处理时,就会向源主机发送参数问题报文。 Parameter Problem Message(12) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Pointer | unused | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Internet Header + 64 bits of Original Data Datagram | 字段说明: Type(8位),值为12,表示参数问题报文。 Code(8位),表示错误的具体原因,取值范围0~2。 Checksum(16位),ICMP报文的校验和。 Pointer(8位),指向数据包首部中发生错误的字节位置。 unused(24位),未使用字段,置0。 Internet Header + 64 bits of Original Data Datagram,触发参数问题报文的原始IP数据报的IP头部和前64位数据。 错误代码(Code): Pointer indicates the error(0),表示Pointer字段指向了数据包首部中发生错误的具体位置。 Missing a Required Option(1),表示数据包缺少了某个必需的选项。 Bad Length(2),表示数据包的长度存在问题,可能是总长度与首部长度和数据长度之和不一致,或者超过了网络的MTU限制。 参数问题报文用于通知源主机在发送数据包时出现了首部错误,帮助源主机诊断和调试网络问题: Code 0的参数问题报文通常表明数据包的某个首部字段存在无法识别或不合法的值,Pointer字段会指明具体的错误位置,源主机可以据此检查和修正数据包的构造过程。 Code 1的参数问题报文提示数据包缺少了某个必需的首部选项,例如安全选项、源路由选项等,源主机需要检查上层协议和应用的设置,确保包含所有必需的选项。 Code 2的参数问题报文表示数据包的长度字段存在问题,可能是上层协议计算错误或者数据包在传输过程中被截断,源主机需要检查数据包的封装和传输过程。 2.9 ICMPv4回显请求/应答(类型0/8) ICMP回显请求和应答是我们日常网络应用中最常见的两种ICMP报文。它们构成了Ping程序的基础,让我们能够方便地检测网络的连通性和延迟。 Echo(8) or Echo Reply(0) Message 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identifier | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data ... +-+-+-+-+- 一个完整的ICMP回显请求或应答报文由以下几个字段依次组成: 类型(Type,8位),回显请求的类型值为8,而回显应答的类型值则为0。 代码(Code,8位),对于回显请求和应答报文,代码字段的值通常都为0,表示这是一个标准的查询和响应过程。 校验和(Checksum,16位),ICMP报文的前4个字节和数据部分一起被用于计算校验和。 标识符(Identifier)和序号(Sequence Number),这两个字段各占2字节,它们的值由发送方任意指定,但在请求和应答报文中必须保持一致。 数据部分,在回显请求和应答中,这部分内容是完全一样的。数据的具体内容由请求方定义,应答方只需原封不动地返回即可。 最常见的应用莫过于Ping程序了。当我们在命令行中输入"ping 目标IP地址"时,源主机就会构造一系列ICMP回显请求报文,填入适当的标识符和序号,然后连续发送给目标主机。 目标主机收到请求后,会提取报文中的标识符和序号,构造对应的ICMP回显应答报文,再发送回源主机。源主机根据收到的ICMP应答,计算往返时间和丢包率,评估与目标主机之间的网络质量。 另一个常见的应用是traceroute程序,它通过逐步增加IP包的生存时间(TTL),结合ICMP超时错误和到达目标时的ICMP端口不可达错误,一跳一跳地探测到目标主机的网络路径。 2.10 ICMPv4路由器请求和通告(类型9/10) ICMPv4 路由器请求和通告报文帮助主机自动发现附近的路由器,获取必要的配置信息。 路由器请求报文的ICMP类型值为 9,当一台主机希望自动获取路由器的信息时,它会在本地网络上广播一个路由器请求报文。这个报文的目标地址通常为受限广播地址255.255.255.255或本地网段的广播地址。 路由器请求报文的格式非常简洁,除了公共的 ICMP 报头外,没有其他特殊字段: ICMP Router Solicitation Message(9) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 路由器通告报文的ICMP类型值为10,当路由器收到一个路由器请求报文或者自身的通告时间间隔到期时,它就会主动向本地网络发送一个路由器通告报文。这个报文通常以组播的形式发送,目标地址为 224.0.0.1。 ICMP Router Advertisement Message(10) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Num Addrs |Addr Entry Size| Lifetime | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Router Address[1] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Preference Level[1] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Router Address[2] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Preference Level[2] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | . | | . | | . | 相比请求报文,通告报文的内容就丰富多了,除了ICMP报头,它还包含以下重要信息: 地址数(Num Addrs),表示通告报文中包含的路由地址条目数量,每个块包含一个IPv4地址和相应的优先水平(Preference level)。 地址条目大小(Addr Entry Size),说明每个地址条目的大小,以 32 位字为单位。 生存周期(Lifetime),告知主机在收到下一个通告报文之前,本报文中的信息有效的时间,单位为秒。 路由器地址(Router Address),路由器拥有的一个或多个 IP 地址。 优先水平(Preference level),一个32位的有符号二进制补码整数,其值越大代表优先级越高。默认的优先水平是0,特殊值0x80000000表示这个地址不应该作为有效的默认路由。 主机收到路由器通告报文后,会提取出路由器的IP地址,并根据报文中的生存时间设置老化定时器。在定时器到期之前,主机就可以使用通告的路由器地址作为默认网关,将目标不在本地网段的数据报文转发给路由器处理。 3. ICMP攻击 3.1 洪泛攻击 ICMP协议作为网络层的重要协议之一,在网络管理、故障诊断等方面发挥着关键作用。然而,由于其设计的开放性和灵活性,ICMP也常常被恶意利用,成为网络攻击的工具。 (1) ICMP洪泛攻击(ICMP Flood)是一种典型的拒绝服务(DoS)攻击方式。攻击者通过向目标主机或网络发送大量的ICMP请求报文(如Echo请求、时间戳请求等),耗尽目标的网络带宽和系统资源,导致其无法正常提供服务。 攻击者通常采用伪造源IP地址的方式,隐藏自己的真实身份,并利用僵尸网络放大攻击流量。当大量的ICMP请求同时到达目标时,网络设备的处理能力和带宽很快被耗尽,合法用户的请求无法得到及时响应,网络服务质量严重下降。 (2) **ICMP路由重定向攻击(ICMP Redirect)**用于路由器通知主机更优的路由路径。然而,恶意攻击者可以伪造ICMP重定向报文,引诱主机将数据报文发送到错误的路由器或恶意主机,造成数据泄露或中间人攻击。 攻击者通常在与目标主机相同的本地网络内,伪装成合法的路由器,向目标主机发送虚假的ICMP重定向报文。如果主机没有对报文来源进行严格验证,就可能误认为攻击者是可信的路由器,从而将敏感数据发送给攻击者,或者陷入恶意主机设置的"陷阱"。 (3) **ICMP目的不可达攻击(ICMP Destination Unreachable)**用于告知源主机目标主机或端口无法到达。攻击者可以利用这一机制,向目标主机发送伪造的目的不可达报文,导致目标主机错误地中断与合法主机的通信。 例如,攻击者监听到目标主机与某个合法服务器之间的通信后,就伪造一个源IP为该服务器、目标IP为目标主机的ICMP目的不可达报文,并声称服务器的某个端口不可达。目标主机收到报文后,可能会误认为服务器主动断开了连接,从而中断与服务器的通信。当攻击者持续发送这类报文时,目标主机与合法服务器之间的通信就会不断受到干扰。 (4) Ping of Death攻击,早期的一些操作系统和网络设备在处理超大的ICMP回显请求报文时存在缓冲区溢出漏洞。攻击者利用这一漏洞,构造一个超过最大允许长度(65535字节)的ICMP请求报文,在目标主机上引发系统崩溃或重启,造成拒绝服务。 为了防范ICMP报文攻击,网络管理员可以采取以下措施: 在网络边界和主机上启用ICMP报文过滤,仅允许必要的ICMP报文通过。 对ICMP报文进行速率限制,避免少量主机占用过多网络资源。 对ICMP报文的合法性进行验证,丢弃可疑的伪造报文。 及时更新系统和设备,修复已知的ICMP相关漏洞。 部署抗DDoS设备,实时监测和清洗恶意ICMP流量。 ICMP报文攻击是网络安全领域的一大挑战,攻击者利用ICMP的开放性和灵活性,通过多种手段破坏网络通信和服务。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/Once_day/article/details/139426408
-
一、Jenkins是什么 Jenkins可以简单理解为一个自动化工具,它帮助软件开发团队实现了持续集成和持续交付的过程。持续集成是指将不同开发者的代码合并到主干之前,自动进行构建、测试等操作,以确保代码质量和稳定性。持续交付则是指在每次代码变更后,自动进行打包和部署,以便快速将新功能或修复发布给用户。 使用Jenkins,你可以设置一个任务或流水线,在其中定义一系列需要执行的步骤。比如,当有新的代码提交到版本控制系统(如Git)时,Jenkins会检测到变更,并触发相应的构建任务。它会自动下载最新的代码、编译项目、运行各种测试(单元测试、集成测试等),甚至还能进行静态代码分析来找出潜在问题。 如果构建和测试成功,Jenkins可以进一步将生成的软件包部署到目标服务器上,使其能够被用户访问到。这样做的好处是节省了手动操作的时间和错误风险,并确保了每次更新都经过验证并可靠地发布。 总之,Jenkins是一个强大且灵活的工具,通过自动化执行构建、测试和部署等任务,提高了开发团队的效率和代码质量,同时降低了出错的可能性。 二、常见的部署Jenkins的方法 最常见的部署 Jenkins 的方法有以下几种: 独立安装:可以从 Jenkins 官网上下载适合你操作系统的安装包,然后按照官方文档的步骤进行安装。这种方式比较灵活,可以在本地服务器或云服务器上进行安装。 容器化部署:Jenkins 提供了官方的 Docker 镜像,可以通过 Docker 来运行 Jenkins。只需安装好 Docker 环境,在命令行中执行相应指令即可拉取镜像并运行 Jenkins 容器。 三、为什么选择容器化部署 容器化部署通常使用 Docker 镜像来实现。Docker 是一种流行的容器化平台,它提供了一种打包应用程序及其依赖项的方法,并将其封装在一个可移植和隔离的环境中,即容器。这个容器可以在任何支持 Docker 的主机上运行,而不需要额外的配置或依赖项。 在容器化部署 Jenkins 中,可以使用 Docker 镜像来创建一个独立的 Jenkins 容器,该容器包含了所有所需的软件、库和配置文件。这样就可以轻松地在各个环境中部署 Jenkins,保证环境一致性,并且能够快速进行部署和升级操作。 选择容器化部署 Jenkins 的好处主要有以下几点: 灵活性:容器化部署可以将 Jenkins 及其依赖项打包到一个独立的容器中,使其更加独立、可移植和易于管理。您可以轻松地在不同的环境中进行部署,例如开发环境、测试环境或生产环境。 隔离性:每个 Jenkins 容器都是相互隔离的,这意味着它们之间的运行不会相互干扰。这种隔离性能够提供更高的安全性和稳定性,确保一个容器中出现问题不会影响到其他容器。 快速部署和升级:由于容器镜像具备轻量级和可复制的特点,因此可以快速地进行部署和升级。只需创建新的容器实例,并替换旧版本即可完成升级过程,而无需手动配置。 环境一致性:通过容器化部署,您可以确保在不同的环境中(开发、测试、生产)运行的 Jenkins 实例是一致的。这有助于减少因环境差异引起的问题,并提供更可靠的构建和部署过程。 容器化部署能够提供更灵活、隔离和快速部署的 Jenkins 环境,更加便捷地管理和使用 Jenkins。 四、容器化部署Jenkins步骤 1、安装 Docker 首先,需要在目标服务器上安装 Docker。 安装步骤见:linux环境安装docker-CSDN博客 2、获取 Jenkins 镜像 从 Docker Hub 上获取 Jenkins 的官方镜像。可以使用以下命令拉取最新版本的 Jenkins 镜像: docker pull jenkins/jenkins 3、创建并运行容器 创建一个基于 Jenkins 镜像的容器实例,并将其运行起来。 docker run -d -u root -p 8080:8080 -p 50000:50000 -v /home/test:/var/jenkins_home --name my_jenkins jenkins/jenkins 这个命令是用来在 Docker 中运行 Jenkins 镜像,并将容器的端口映射到主机的 8080 和 50000 端口,同时将主机的 /home/test 目录挂载到容器内部的 /var/jenkins_home 目录。容器名称被指定为 my_jenkins。 解释每个选项的含义: -d:以后台模式运行容器。 -u root:以 root 用户身份运行容器。 -p 8080:8080 -p 50000:50000:将容器内部的 8080 和 50000 端口映射到主机上相同的端口。 -v /home/test:/var/jenkins_home:将主机上的 /home/test 目录挂载到容器内部的 /var/jenkins_home 目录。 --name my_jenkins:给容器设置一个名称为 my_jenkins。 通过运行该命令,您可以在本地访问 Jenkins Web UI,使用 localhost:8080 访问 Jenkins 主界面,并使用 Docker 容器中 /var/jenkins_home 存储数据。 注:为啥要进行主机目录挂载到容器 假设我们正在使用一个容器来运行 Jenkins 服务器,而在主机上,我们希望将 Jenkins 的数据目录存储在 /home/test 目录下。为了实现这一目的,我们可以将主机上的 /home/test 目录挂载到容器内部的 /var/jenkins_home 目录。 通俗地讲,挂载的作用是将主机上的某个目录与容器内部的某个目录建立连接,以实现数据共享和持久化。在这种情况下,我们选择将 Jenkins 数据目录挂载到主机上的 /home/test 目录,并映射到容器内部的 /var/jenkins_home 目录。 4、访问 Jenkins 在浏览器中访问 http://<服务器IP地址>:8080 来打开 Jenkins Web UI。按照提示完成初始化设置,获取管理员密码并创建管理员账号。 4.1 查看初始密码问题 直接cat 给出的路径 提示找不到文件 因为我们是在docker里部署的,所以需要进到容器中才能访问这个文件,使用如下命令进入容器 docker exec -it my_jenkins /bin/bash 这个命令是使用Docker来在正在运行的名为"my_jenkins"的Jenkins容器中执行一个交互式的bash终端会话。解释如下: docker exec: 用于在正在运行的容器中执行命令。 -it: 表示以交互式方式运行命令,并分配一个伪终端(TTY)。 my_jenkins: 指定要执行命令的容器名称或ID。 /bin/bash: 指定要在容器中执行的bash shell。 通过这个命令,您可以进入正在运行的Jenkins容器内部,以便进行一些特定操作或调试。这将打开一个与Jenkins容器关联的bash终端,允许您在容器内部进行命令行操作。 进入到容器内部后再查看初始密码,就可以正常查看到了 密码复制过来 5、配置 Jenkins 5.1 安装插件 点击安装推荐的插件即可,然后等待安装完成 5.2 创建管理员用户 一定牢记账号密码 5.3 实例配置 默认即可 这样就可以使用Jenkins了 五、简单使用Jenkins配置SSH远程操作服务器 进入Jenkins主页面 linux服务器上我们有一个shell文件,文件和内容如下: 我们通过Jenkins的构建任务的方式去执行这个文件 在Jenkins中进行构建时,需要首先SSH登录到一个远程服务器以执行必要的脚本,然后再执行构建。这时,需要安装SSH Plugin,并进行如下配置。 1、安装SSH Plugin 在Jenkins界面,系统管理->管理插件->安装SSH Plugin 说明,SSH Plugin的目的就是支持SSH到远程服务器,然后执行Shell命令。 可以先去已安装里搜索看有没有已经安装SSH Plugin,没有的话去未安装里去搜索安装 2、配置凭据 凭据管理中添加配置凭据 3、SSH相关配置 SSH remote hosts 配置SSH服务器站点,ip,账号,密码以及刚刚创建的凭证,保存 Hostname: SSH服务器的地址 Port: 22 Credentials:选择刚才添加的凭据 4、新建任务 输入任务名称,选择第一个自由风格的项目,确定 构建环境 选择 Execute shell script on remote host using ssh SSH站点配置默认就是刚刚配置的凭证 然后填写执行前和执行后的Shell脚本 5、构建任务 点击立即构建 6、查看构建结果 点击查看构建历史,点击控制台输出,就可以看到执行结果 SUCCESS 与直接在linux服务器上执行结果一致 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/m0_59681797/article/details/135882908
-
1、检查防火墙状态: Ubuntu 18.04及更高版本使用的是ufw(Uncomplicated Firewall)。您可以使用以下命令检查ufw是否已安装并处于运行状态: sudo ufw status 1 如果ufw已安装并正在运行,则会显示防火墙的状态(如活动、已停止等)以及开放的端口。 2、检查已开放的端口: 使用以下命令查看当前ufw防火墙规则及已开放的端口: sudo ufw show added 1 这将显示已添加的防火墙规则,包括已开放的端口。 如果ufw未安装或未启用,可能是因为使用的Ubuntu版本未默认安装该防火墙。在这种情况下,可以通过以下命令安装ufw并启用防火墙: sudo apt update sudo apt install ufw sudo ufw enable ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
-
探索GoServer:高效、易用的Golang服务器框架 项目地址:https://gitcode.com/ecdiy/goserver GoServer 是一个由Golang编写的高性能网络服务器框架,它旨在简化开发过程,提供稳定且高效的网络服务实现。本文将深入探讨GoServer的核心特性、技术亮点及应用案例,帮助开发者更好地理解和利用这一强大的工具。 项目简介 GoServer是一个轻量级但功能丰富的框架,它集成了常见的服务器功能,如HTTP/HTTPS、TCP/UDP服务、WebSocket支持,还提供了模块化的中间件系统,使得扩展和定制变得简单。对于需要快速构建网络服务的开发团队,GoServer是一个理想的选择。 技术分析 1. 基于Golang的并发模型 GoServer充分利用了Golang的goroutine和channel特性,实现了高并发处理能力。通过协程间的通信,它可以有效地管理大量连接,保证了系统的响应速度。 2. 模块化设计 该框架采用了模块化设计,包括路由、中间件、日志等核心组件,都可以方便地进行扩展和替换。这意味着你可以根据自己的需求调整或定制任何部分,保持代码的灵活性和可维护性。 3. 中间件系统 GoServer支持自定义中间件,可以用于处理请求前后的逻辑,例如认证、日志记录、限速等。这种设计使得复杂的功能可以分解为一系列小的、独立的处理步骤,降低了代码耦合度。 4. 高性能网络库 GoServer底层使用的是Golang标准库net/http和net,经过优化,能够处理大量的并发连接,确保服务的稳定性和效率。 5. 易于上手 尽管功能强大,但GoServer的API设计简洁直观,新用户可以很快熟悉并开始编写服务器应用程序。 应用场景 Web服务 - 快速搭建HTTP/HTTPS服务,支持RESTful API。 实时通信 - 利用WebSocket构建实时数据推送的应用,如聊天室、股票交易通知等。 物联网(IoT) - 可以作为设备通信服务器,处理TCP/UDP数据包,实现设备控制和监控。 游戏服务器 - 支持高并发连接,适用于网络游戏、多人在线游戏的后端架构。 特点总结 高性能 - 利用Golang原生并发机制,轻松处理大量并发请求。 灵活性 - 模块化设计使扩展和定制变得更加简单。 易于使用 - 简洁的API和丰富的文档,降低学习成本。 稳定可靠 - 基于成熟的标准库,保证服务稳定性。 总的来说,无论是新手还是经验丰富的开发者,GoServer都是构建高性能服务器应用的理想选择。如果你正在寻找一个既高效又灵活的Golang服务器框架,不妨尝试一下GoServer,让开发变得更简单、更高效。 项目地址:https://gitcode.com/ecdiy/goserver ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/gitblog_00017/article/details/137221159
-
在服务器管理和维护中,准确的系统时间对于保证服务器正常运行和数据一致性至关重要。 而有时候,我们可能需要手动修改服务器上的系统时间,以调整时区、修复时间漂移等问题。 本文将介绍如何使用Linux命令来修改服务器时间。 一、检查当前时间 首先,我们需要使用命令来检查服务器的当前时间。在终端中输入以下命令: date 1 显示出当前的日期和时间,以及所设置的时区。确认当前时间和时区是否符合预期,可用作后续操作的比对标准。 二、修改时间日期 修改日期:要修改服务器的日期,可以使用date命令并指定日期格式,例如: date -s "2023-12-12" 1 将日期设置为指定的日期(年-月-日)。请注意,您可能需要具有管理员权限才能更改日期。 修改时间:要修改服务器的时间,同样可以使用date命令并指定时间格式,例如: date -s "21:57:12" 1 将时间设置为指定的时间(时:分:秒)。 同时修改日期和时间:如果要同时修改日期和时间,可以将日期和时间合并到一个命令中,例如: date -s "2023-12-12 21:57:12" 1 同时修改日期和时间。 三、设置时区 查看当前时区:要查看当前的时区设置,可以使用以下命令: timedatectl show --property=Timezone 1 显示出当前的时区。 修改时区:要修改服务器的时区,可以使用以下命令,并将"Asia/Shanghai"替换为所需的时区标识符: timedatectl set-timezone Asia/Shanghai 1 将时区设置为指定的时区。 四、验证修改结果 完成以上操作后,我们可以再次使用date命令来验证是否成功修改了服务器的时间和时区。确认系统时间以及时区是否与预期一致。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/warmspace2008/article/details/134960098
-
文章目录 说明 恢复笔记 待恢复的数据库文件所在目录与文件层级如下 检查事项 具体操作 修改3: mv recovery.conf recovery.done 需要重置 wal 日志然后启库 检查效果 补充笔记(2024-02-07更新) pg_rman 安装与使用参考: pg_rman 编译安装与使用 说明 需求是能启库就行, 可以接受数据丢失, 恢复步骤有偷懒, 本文仅供个人记录笔记使用, 请不要完全照抄 规范合理的步骤是需要使用 recovery.conf 文件, 写清楚目标环境上的归档日志路径(当前提前得将源库中的wal日志拷贝到目标环境归档路径下) 来启动并恢复 恢复笔记 以 db_test 为例: 待恢复的数据库文件所在目录与文件层级如下 /data/restore/pg_restore/backups/db_test20231216/014025/backup.ini 检查事项 0.目录级别与生产环境保持一致,如果不一致, 需要自己手动创建确保一致, 1.最上级目录(20231216同级目录)存在 pg_rman.ini 2.20231216/014025下存在 file_database.txt 3.文件 20231216/014025/backup.ini 中的 STATUS=OK -bash-4.2$ cat backup.ini # configuration BACKUP_MODE=FULL WITH_SERVERLOG=false COMPRESS_DATA=true # result TIMELINEID=5 START_LSN=4bb/4e000028 STOP_LSN=4bb/7e81c420 START_TIME='2023-02-15 01:35:03' END_TIME='2023-02-15 07:42:53' RECOVERY_XID=181372900 RECOVERY_TIME='2023-02-15 06:04:45' TOTAL_DATA_BYTES=233395485133 READ_DATA_BYTES=233408059346 READ_ARCLOG_BYTES=32782681011 WRITE_BYTES=35758753390 BLOCK_SIZE=8192 XLOG_BLOCK_SIZE=8192 STATUS=OK 具体操作 创建恢复目录(你要将 数据库备份集恢复到哪里去), 相当于是执行了 pg_rman -B $BACKUP_PATH init mkdir -p /data/restore/2023_pg_restore/db_test/data 1 检查待恢复的数据库文件集合是否正常, 如果显示 OK 则可以继续操作, 如果显示 RUNNING或者ERROR 则说明备份文件集合有问题, 需要重新弄一份新的 pg_rman -B /data/restore/pg_restore/backups/db_test show 具体恢复命令 (-D 指向你要将数据库文件集合恢复到哪里去) pg_rman -B /data/restore/pg_restore/backups/db_test restore -D /data/restore/2023_pg_restore/db_test/data 这里如果报 ARC_PATH 相关的错误(ERROR), 需要手动创建该目录 ,如果只是报 warning 可以先忽略 比如: mkdir -p /data/restore/2023_pg_restore/db_test/arc_log mkdir -p /data/restore/2023_pg_restore/db_test/srv_log 更新 /data/restore/pg_restore/backups/db_test/pg_rman.ini 文件 修改 配置文件 /data/restore/2023_pg_restore/db_test/data/postgresql.conf 与 /data/restore/2023_pg_restore/db_test/data/backup_label(如果存在的话) 修改1: 禁用 archive_mode 修改2: 修改 log_directory 与 data_directory 与 hba_file 配置项中的 data 值 与 /data/restore/2023_pg_restore/db_test/data 保持一致 修改3: mv recovery.conf recovery.done 修改4: mv backup_label backup_label_lxm 修改5: 将 listen_addresses= ‘10.33.45.110’ 改为 listen_addresses = ‘*’ 手动启动数据库 (-D 启动哪个目录对应的数据库实例 ) pg_ctl start -D /data/restore/2023_pg_restore/db_test/data 如果还报错, 查看日志文件 -bash-4.2$ tailf /data/restore/2023_pg_restore/db_test/data/pg_log/postgresql-25.*csv 2023-12-25 15:44:37.909 HKT,,,119321,,658932e5.1d219,4,,2023-12-25 15:44:37 HKT,,0,FATAL,XX000,"could not locate required checkpoint record",,"If you are not restoring from a backup, try removing the file ""/data/restore/2023_pg_restore/db_test/data/backup_label"".",,,,,,,"" 2023-12-25 15:44:37.910 HKT,,,119317,,658932e5.1d215,1,,2023-12-25 15:44:37 HKT,,0,LOG,00000,"startup process (PID 119321) exited with exit code 1",,,,,,,,,"" 2023-12-25 15:44:37.910 HKT,,,119317,,658932e5.1d215,2,,2023-12-25 15:44:37 HKT,,0,LOG,00000,"aborting startup due to startup process failure",,,,,,,,,"" 2023-12-25 15:49:10.374 HKT,,,136964,,658933f6.21704,1,,2023-12-25 15:49:10 HKT,,0,LOG,00000,"database system was interrupted; last known up at 2023-12-16 02:17:39 HKT",,,,,,,,,"" 2023-12-25 15:49:10.375 HKT,,,136964,,658933f6.21704,2,,2023-12-25 15:49:10 HKT,,0,LOG,00000,"could not open tablespace directory ""pg_tblspc/0/PG_9.4_201409291"": No such file or directory",,,,,,,,,"" 2023-12-25 15:49:10.459 HKT,,,136964,,658933f6.21704,3,,2023-12-25 15:49:10 HKT,,0,LOG,00000,"invalid primary checkpoint record",,,,,,,,,"" 2023-12-25 15:49:10.459 HKT,,,136964,,658933f6.21704,4,,2023-12-25 15:49:10 HKT,,0,LOG,00000,"invalid secondary checkpoint record",,,,,,,,,"" FATAL,XX000,"could not locate required checkpoint record", 需要重置 wal 日志然后启库 Report bugs to <pgsql-bugs@postgresql.org>. -bash-4.2$ pg_resetxlog -f /data/restore/2023_pg_restore/db_test/data Transaction log reset -bash-4.2$ -bash-4.2$ pg_ctl start -D /data/restore/2023_pg_restore/db_test/data server starting -bash-4.2$ 2023-12-25 15:50:13 HKT::@:[138504]: LOG: redirecting log output to logging collector process 2023-12-25 15:50:13 HKT::@:[138504]: HINT: Future log output will appear in directory "/data/restore/2023_pg_restore/db_test/data/pg_log". 检查效果 -bash-4.2$ netstat -anp |grep 5472 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:5472 0.0.0.0:* LISTEN 138504/postgres tcp6 0 0 :::5472 ::: * LISTEN 138504/postgres unix 2 [ ACC ] STREAM LISTENING 2208435216 138504/postgres /tmp/.s.PGSQL.5472 unix 3 [ ] STREAM CONNECTED 154721 - unix 3 [ ] STREAM CONNECTED 154720 - -bash-4.2$ psql -p 5472 psql (9.4.14) Type "help" for help. postgres=# \l+ List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description -----------+----------+----------+-------------+-------------+-----------------------+---------+------------+-------------------------------------------- db_test | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | 69 GB | pg_default | repmgr | repmgr | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | 687 MB | pg_default | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +| 6729 kB | pg_default | unmodifiable empty database | | | | | postgres=CTc/postgres | | | template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +| 8697 kB | pg_default | default template for new databases | | | | | postgres=CTc/postgres | | | 补充笔记(2024-02-07更新) 1. 修改 /postgresql/hq/bk/restore/pg_restore/backups/iobs/pg_rman.ini 将 ARCLOG_PATH 值改为一个新路径, 例如/postgresql/hq/bk/restore/2023_pg_restore/iobs_new_arc_log, 需要先手动创建该路径并授予 postgres的属主权限 2. 执行 pg_rman -B /postgresql/hq/bk/restore/pg_restore/backups/iobs/ restore -D /postgresql/hq/bk/restore/2023_pg_restore/iobs_new_lxm2 >> ./res.log 2>&1 & 进行恢复 3. 检查恢复结果 tail res.log -bash-4.2$ tail res.log LOG: (16485/16492) 00000009000010B800000014 LOG: (16486/16492) 00000009000010B800000015 LOG: (16487/16492) 00000009000010B800000016 LOG: (16488/16492) 00000009000010B800000017 LOG: (16489/16492) 00000009000010B800000018 LOG: (16490/16492) 00000009000010B800000019 LOG: (16491/16492) 00000009000010B80000001A LOG: (16492/16492) 00000009000010B80000001B LOG: backup 2024-02-24 01:35:25 is valid INFO: restore complete. Recovery starts automatically when the PostgreSQL server is started. 4.进入新的 data目录 cd /postgresql/hq/bk/restore/2023_pg_restore/iobs_new_lxm2 cp postgresql.conf postgresql.conf_bak_`date +%F` cp recovery.conf recovery.conf_bak_`date +%F` vim recovery.conf 将 recovery_target_timeline 值改为 'latest' vim postgresql.conf 修改里面的相关路径 包括如下配置 -bash-4.2$ diff postgresql.conf postgresql.conf_bak_20240311 2,3c2,3 < data_directory ='/postgresql/hq/bk/restore/2023_pg_restore/iobs_new_lxm2' < hba_file ='/postgresql/hq/bk/restore/2023_pg_restore/iobs_new_lxm2/pg_hba.conf' --- > data_directory ='/postgresql/pg5472/data' > hba_file ='/postgresql/pg5472/data/pg_hba.conf' 7c7 < listen_addresses = '*' --- > listen_addresses = '10.33.45.110' 57,58c57,58 < #archive_command = 'test ! -f /postgresql/pgbackup/iobs/archlog/%f && cp %p /postgresql/pgbackup/iobs/archlog/%f' < archive_command = 'test ! -f /postgresql/hq/bk/restore/2023_pg_restore/iobs_new_arc_log/%f && cp %p /postgresql/hq/bk/restore/2023_pg_restore/iobs_new_arc_log/%f' --- > archive_command = 'test ! -f /postgresql/pgbackup/iobs/archlog/%f && cp %p /postgresql/pgbackup/iobs/archlog/%f' > 67c67 < log_directory = '/postgresql/hq/bk/restore/2023_pg_restore/iobs_new_lxm2/pg_log' --- > log_directory = '/postgresql/pg5472/data/pg_log' -bash-4.2$ 5. 启动数据库 postmaster -D /postgresql/hq/bk/restore/2023_pg_restore/iobs_new_lxm2 & 6. 登录(根据配置文件中 listen_port 为 5472 -bash-4.2$ psql -p 5472 psql (9.4.14) Type "help" for help. postgres=# show data_directory ; data_directory --------------------------------------------------- /postgresql/hq/bk/restore/2023_pg_restore/iobs_new_lxm2 (1 row) 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/yueludanfeng/article/details/137179651
-
在 Linux 中,管理用户和权限是一个重要的方面,因为它决定了用户可以访问和修改哪些文件和程序。以下是一些关于用户和权限管理的基本命令和常见问题的解答: 如何切换用户? 使用 su (switch user) 命令可以切换用户。 示例:切换到用户 username。 su - username 如果你没有指定用户(即只输入 su),默认会切换到超级用户(root)。在切换用户时,系统通常会要求输入目标用户的密码。 如何查看当前用户? whoami whoami 命令显示当前用户的用户名。 whoami id id 命令显示当前用户的 UID(用户 ID)、GID(组 ID)和所属的用户组。 id 如何查看和修改文件权限? ls -l 使用 ls -l 可以查看文件的权限。 ls -l filename 输出会显示文件的权限、所有者和所属组。 chmod chmod (change mode) 命令用于修改文件或目录的权限。 示例:给 file.txt 文件所有者添加执行权限。 chmod u+x file.txt 示例:给 file.txt 设置具体权限(所有者读写执行,组读执行,其他用户读)。 chmod 754 file.txt 如何添加或删除用户? useradd useradd 命令用于创建新用户。 示例:添加新用户 newuser。 sudo useradd newuser userdel userdel 命令用于删除用户。 示例:删除用户 olduser。 sudo userdel olduser 如何修改用户密码? 使用 passwd 命令可以修改用户的密码。 示例:修改当前用户的密码。 passwd 如果你是超级用户,可以为其他用户设置密码。 sudo passwd username 没有文件运行权限怎么办? 如果你试图运行一个没有执行权限的文件,你可以使用 chmod 命令为该文件添加执行权限,如上面 chmod 的例子所示。 如何查看用户所属的用户组? groups groups 命令显示当前用户所属的所有用户组。 groups 若要查看特定用户所属的用户组: groups username id id 命令也可以用来查看用户所属的用户组。 id username 如何修改文件的所有者或所属组? chown chown (change owner) 命令用于修改文件或目录的所有者。 示例:将 file.txt 的所有者更改为 newowner。 sudo chown newowner file.txt chgrp chgrp (change group) 命令用于修改文件或目录的所属组。 示例:将 file.txt 的所属组更改为 newgroup。 sudo chgrp newgroup file.txt 如何切换到 root 用户? 使用 su 命令可以切换到 root 用户。 su - 你需要输入 root 用户的密码。如果你使用的是 sudo,可以使用以下命令切换到 root 用户: sudo -i 或 sudo su - 在使用 sudo 时,你需要输入自己的密码,而不是 root 的密码。 这些命令和概念是 Linux 用户和权限管理的基础。管理员通常需要熟练 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/hebtu666/article/details/139309127
-
在Linux服务器上查看硬件配置信息,可以使用一系列命令行工具。以下是一些常用命令来获取不同硬件组件的详细信息: 查看CPU信息: cat /proc/cpuinfo:显示处理器类型、型号、频率、核心数等详细信息。 lscpu:提供更为人性化的CPU架构和核心数量等信息。 查看内存信息: free -h 或 free -m:显示当前系统中内存的使用情况(以合适的单位如GB或MB显示)。 dmidecode -t memory:获取更详细的内存条信息,包括插槽数量、大小、速度等。 查看硬盘信息: fdisk -l 或 lsblk -f:列出所有磁盘及其分区情况。 hdparm -I /dev/sda(替换 /dev/sda 为你的磁盘设备名):获取SATA硬盘的详细参数。 smartctl -a /dev/sda(适用于S.M.A.R.T.支持的磁盘):获取硬盘健康状况和详细信息。 查看网络接口信息: ip addr show 或 ifconfig(部分新系统已弃用 ifconfig):显示网络接口及IP地址配置。 ethtool eth0(替换 eth0 为你的网卡设备名):查看网络接口的详细信息,如速度、双工模式等。 查看主板、BIOS以及其他硬件信息: lshw:全面展示系统硬件结构,包括主板、显卡、声卡等各种设备信息。 dmidecode:从DMI表中读取系统硬件信息,例如制造商、产品序列号、BIOS版本等。 查看RAID阵列信息: 对于软RAID,可以查看 /proc/mdstat 来了解MDADM管理的RAID状态。 对于硬RAID,可能需要特定厂商提供的工具,如HP Smart Array阵列则使用 hpacucli 命令。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/weixin_72186894/article/details/136240066
-
环境信息:ABC_20.3环境问题一句话总结:在进行ABC运行环境巡检时,发现下图的目录空间的使用率已达到100%,是否会影响业务系统的正常运行?此目录下的tmpfs是什么文件?能否删除?。问题现象截图:使用场景或目的:不涉及。操作步骤:无希望优化的地方或希望实现的效果:租户账号:nxx项目名称: 天津xx
-
说到 Linux 定时任务,大家用得最多的就是 crond 服务,但其实 systemd 也有类似的功能。我们不但可以通过 systemd 来管理服务,还能设置定时任务,那就是 systemd timer。与 crond 相比,systemd 定时任务具有以下优点:更高的精度:systemd 定时任务可以精确到秒,而 crond 只能精确到分钟。可以限制资源使用:使用 systemd 定时任务可以设置内存和 CPU 的使用限制,比如最多使用 50% 的 CPU。更灵活的配置:systemd 定时任务可以通过条件、依赖关系等进行配置,以控制任务的执行。相比之下,crond 的配置相对简单,灵活性较低。举个例子,假设我们要通过 crond 配置多个大文件的远程备份(使用 scp、rsync 或 ftp 的方式),但由于大文件的网络传输时间不确定,因此下一个文件的备份任务开始时间几乎都是按照经验估计的。这可能导致上一个任务的网络传输尚未完成,下一个任务已经开始,同时占用网络带宽,然后又启动了下一个任务,形成恶性循环。而使用 systemd timer 可以建立任务之间的依赖关系,例如在第一个备份任务完成后再启动第二个备份任务,以此类推。systemd timer 原理systemd 定时任务基于 systemd 的单元管理器。它使用两种类型的单元来管理定时任务:.timer 单元和 .service 单元。.timer 单元:.timer 单元定义了定时规则,包括启动时间、间隔时间等。每个 .timer 单元都对应一个或多个关联的 .service 单元。.service 单元:.service 单元定义了要在计时器触发时运行的服务或命令。当 .timer 触发时,相关联的 .service 单元将被启动。systemd 定时任务原理是:systemd 定期检查每个 .timer 单元中定义的定时规则,以确定是否触发相应的定时器。一旦定时器触发,systemd 将启动与该定时器关联的 .service 单元,从而执行预定的任务。在正式介绍 systemd 定时任务之前,我们先要了解什么是单元(unit)。systemd 单元简单来讲,单元就是 systemd 的最小管理单位,是单个进程的描述。一个个单元相互调用和依赖,组成一个庞大的任务管理系统。systemd 中的 unit 有很多类型,下面是一些常见的 unit 类型:.service:service 单元,也就是我们常说的系统服务.target:target 单元,其实就是一堆 unit 的集合,比如常见的 multi-user.target.timer:timer 单元,负责定时任务。.slice:slice 单元,负责资源的分配。每个 unit 都有一个描述文件(unit 负责干什么、怎么干...),它们分散在三个目录:/lib/systemd/system:系统默认的 unit 文件/etc/systemd/system:包含用户自定义的 unit 文件,如果设置了开机自启动,则该目录下的 unit 描述文件会创建一个符号链接。/usr/lib/systemd/system:用户自己定义的 unit 文件,也会包含一些系统默认的 unit 文件大多数 linux 发行版中 /lib 是 /usr/lib的软链接,所以 1 和 3 其实是同一目录,作用自然应该是相同的。其实可以简单分成两类:/etc/systemd/system:用户自定义的 unit 文件/usr/lib/systemd/system:系统默认的 unit 文件和用户安装软件的 unit 文件# 查看所有 unit $ systemctl list-unit-files # 查看所有 Service unit $ systemctl list-unit-files --type service # 查看所有 Timer unit $ systemctl list-unit-files --type timer关于 systemd unit 相关的内容这里就不细讲了,大家可以看我之前的文章:《systemctl 命令设置开机自启动失败 》设置 systemd 定时任务有一个检查 https 证书是否过期的脚本 check_https.sh,我们现在需要系统定期执行这个脚本,除此之外,系统在开机之后也会执行这个脚本。首先创建一个 service unit[root@localhost ~]# cat /usr/lib/systemd/system/check-https.service [Unit] Description=check https certificates [Service] Type=oneshot ExecStart=check_https.sh [Install] WantedBy=multi-user.targetType=oneshot 表示 service 以一次性(Oneshot)方式运行。这意味着当启动 service 时,它将执行一次,并在完成后退出。然后我们创建一个 timer unitService unit 只是定义了如何执行任务,要定时执行这个 Service,还必须定义 Timer unit[root@localhost ~]# cat /usr/lib/systemd/system/check-https.timer [Unit] Description=Runs check https every day [Timer] OnUnitActiveSec=24h Unit=check-https.service [Install] WantedBy=multi-user.target我们着重来看下 [Timer] 部分:OnActiveSec:定时任务生效后,多少时间开始执行任务OnBootSec:系统启动后,多少时间开始执行任务OnStartupSec:Systemd 进程启动后,多少时间开始执行任务OnUnitActiveSec:该 unit 上次执行后,等多少时间再次执行OnUnitInactiveSec: 定时任务上次关闭后多少时间,再次执行OnCalendar:基于绝对时间,而不是相对时间执行AccuracySec:如果因为各种原因,任务必须推迟执行,推迟的最大秒数,默认是60秒Unit:真正要执行的任务,默认是同名的带有.service 后缀的 unitPersistent:如果设置了该字段,即使定时任务到时没有启动,也会自动执行相应的 unitWakeSystem:如果系统休眠,是否自动唤醒系统上面的 timer 文件里,OnUnitActiveSec=24h 表示 24 小时执行一次任务。下面是其他的写法:1、在系统启动 15 分钟后执行,并在系统运行时,每周执行一次[Timer] OnBootSec=15min OnUnitActiveSec=1w Unit=check-https.service2、每周周一执行,如果到时定时任务没有启动,会立即执行[Timer] OnCalendar=weekly Persistent=true Unit=check-https.service3、每周日凌晨三点执行(时间格式:Year-Month-Day Hour:Minute:Second)[Timer] OnCalendar=Sun *-*-* 03:00:00 Unit=check-https.service官方文档:cid:link_1然后我们启动这个定时任务,并设置开机自启动# 重新加载配置 systemctl daemon-reload systemctl start check-https.timer systemctl enable check-https.timer其他一些定时任务命令:# 查看所有正在运行的定时任务 systemctl list-timers # 关闭定时任务 systemctl stop check-https.timer # 查看定时任务状态 systemctl status check-https.timer
-
Linux启动过程Linux启动需要经历一些步骤,这些步骤确保系统能够在各种不同的硬件和配置条件下可靠地启动和运行,并且具有足够的灵活性以适应不同的使用场景和需求,具体步骤如下:BIOS/UEFI初始化(硬件初始化):执行基本输入输出系统(BIOS)或统一可扩展接口(UEFI)中的初始化程序。这些程序负责硬件的自检、加载引导程序等操作,这确保了系统能够正确地与硬件交互,并且提供了基本的硬件支持。引导加载程序(Boot Loader):BIOS/UEFI初始化后,控制权被传递给引导加载程序,从而加载操作系统的内核映像和必要的初始化RAM磁盘映像,以及传递启动参数给内核;这个过程是系统启动的关键一步,确保了正确的内核被加载并且系统启动参数被正确传递。Linux内核启动:引导加载程序将控制权交给Linux内核。内核启动时,会初始化硬件、加载必要的驱动程序以及创建第一个用户进程(init进程);这确保了系统能够正确地与硬件交互,并且能够访问存储在磁盘上的文件系统。init进程启动:init 进程是 Linux 系统的第一个用户空间进程,它负责启动系统的其他进程和服务;通过 init 进程,系统可以在启动时根据需要启动不同的服务,并且提供了系统运行级别的管理和切换功能。运行级别初始化:根据系统的默认运行级别,init 进程会启动相应的运行级别。每个运行级别都定义了一组需要启动的系统服务和进程。通过运行级别,管理员可以根据需要轻松地切换系统的运行状态,并且可以根据需要启动或停止不同的服务。系统初始化和用户登录:一旦系统处于适当的运行级别并启动了所需的服务,系统就会初始化各种设置和环境。如果是多用户环境,系统会等待用户登录。登录后,用户可以开始使用系统。Linux中的7种运行级别通过设置不同的运行级别,管理员可以实现系统启动时的自定义配置,例如启用或禁用特定服务、加载特定的内核模块等。这种灵活性使得 Linux 系统可以更好地适应不同的使用场景和需求。单用户模式(runlevel 1):也称为救援模式,系统在此模式下只启动最基本的服务和进程,通常用于系统修复和维护。多用户模式(runlevel 2、3、4):这些运行级别通常用于多用户环境下,系统启动基本的网络服务,但不包含图形用户界面。多用户图形界面模式(runlevel 5):系统启动图形用户界面和相关服务,适用于桌面系统或需要图形界面的服务器环境。关机(runlevel 0):系统关闭所有服务并停止运行;重新启动(runlevel 6):系统重新启动;与运行级别相关的 Bash 指令通常用于管理系统的运行级别以及执行与运行级别相关的操作。以下是一些常用的与运行级别相关的 Bash 指令:runlevel #显示当前系统的运行级别 telinit <运行级别> #用于改变系统的运行级别 init <运行级别> #传统的系统初始化程序,也可用来改变系统的运行级别 chkconfig --list # 显示所有系统服务及其在各个运行级别下的启用情况 chkconfig <服务名> on # 将指定服务在启动时自动启用 chkconfig <服务名> off # 将指定服务在启动时取消自动启用
-
在CentOS上安装SFTP服务通常是通过安装OpenSSH来实现的,因为OpenSSH默认提供了SFTP功能。以下是在CentOS上安装SFTP的步骤:一、安装OpenSSH服务器:sudo yum install openssh-server启动SSH服务:sudo systemctl start sshd确保SSH服务随系统启动而启动:sudo systemctl enable sshd检查SSH服务状态:sudo systemctl status sshd这将显示SSH服务是否正在运行以及其他相关信息。现在,你的CentOS服务器上应该已经安装并运行了SFTP服务。你可以使用任何支持SFTP的客户端(如WinSCP、FileZilla等)连接到服务器。确保使用SSH协议(端口22)进行连接,并使用具有适当权限的用户凭据进行身份验证。二、配置sftp用户、访问目录等下面是一个完整的例子,假设我们要创建一个名为sftpuser的用户,限制他只能访问/sftp目录,并且使用特定的SSH配置文件。创建SFTP用户:sudo useradd -m -s /sbin/nologin sftpuser设置用户密码:sudo passwd sftpuser创建用户的SFTP根目录:sudo mkdir /sftp设置根目录的权限(根目录必须是root用户,否则sftp连接不上):sudo chown root:root /sftpsudo chmod 755 /sftp在根目录下层建立子目录方可以写入(根目录只能读取不能写入,因为根目录必须是root用户,而sftp访问的用户却是我们新建的sftpuser)mkdir /sftp/sharedatachown sftpuser:sftpuser /sftp/sharedata创建新用户自定义ssh配置简单点直接修改/etc/ssh/sshd_config也可以,这样服务启动选项sshd.service就不用改了创建用户的SSH配置文件目录:sudo mkdir /home/sftpuser/.ssh复制系统SSH配置文件到用户目录:sudo cp /etc/ssh/sshd_config /home/sftpuser/.ssh/sshd_config编辑用户的SSH配置文件:sudo vi /home/sftpuser/.ssh/sshd_config在这个文件中,确保你有适当的配置,例如使用ChrootDirectory限制用户访问,以及其他任何你想要自定义的配置。注意将这个配置节放到最后,否则老是报错: "Directive 'UseDNS' is not allowed within a Match block" 表明在 Match 块中不允许使用 UseDNS 这个指令。Match User sftpuser ChrootDirectory /sftp ForceCommand internal-sftp AllowTcpForwarding noX11Forwarding no给新用户的用户目录递归设置归属chown -R sftpuser:sftpuser /home/sftpuser给配置文件设置读取权限chmod 755 /home/sftpuser/.ssh/sshd_config修改SSH服务启动选项打开SSH服务的启动选项文件,可以使用systemctl status sshd查看找到(通常在 /etc/systemd/system/sshd.service 或 /etc/init.d/sshd 或/usr/lib/systemd/system/sshd.service),并修改为:ExecStart=/usr/sbin/sshd -f /home/sftpuser/.ssh/sshd_config -D $OPTIONS或者/usr/sbin/sshd -f /home/sftpuser/.ssh/sshd_config $OPTIONS重新加载SSH服务:systemctl daemon-reloadsystemctl restart sshd现在,用户sftpuser被限制在sftp目录下,并且只能使用SFTP进行文件传输。他们的SSH配置文件位于/home/sftpuser/.ssh/sshd_config,这样他们可以自定义他们的SSH行为而不影响其他用户或系统级别的配置。查看错误日志:检查系统日志:如果问题仍然存在,请查看系统日志文件,如 /var/log/auth.log 或 /var/log/secure,以获取有关写入文件失败的详细信息。日志文件中可能会提供关于出现问题的原因的线索。三、多SFTP用户如何配置SSH服务启动选项只能指定一个配置文件。如果你想要为多个用户指定不同的配置,你需要为每个用户创建单独的配置文件,并在启动选项中指定这些文件。例如,如果你有两个用户 sftpuser1 和 sftpuser2,你可以为他们分别创建不同的配置文件,然后在SSH服务的启动选项中指定这些文件。为每个用户创建配置文件:sudo cp /etc/ssh/sshd_config /home/sftpuser1/.ssh/sshd_configsudo cp /etc/ssh/sshd_config /home/sftpuser2/.ssh/sshd_config编辑每个用户的配置文件并根据需要进行自定义:sudo vi /home/sftpuser1/.ssh/sshd_configMatch User sftpuser1 ChrootDirectory /sftp ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding nosudo vi /home/sftpuser2/.ssh/sshd_configMatch User sftpuser2 ChrootDirectory /sftp/other_directory ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no修改SSH服务的启动选项,分别指定每个用户的配置文件:ExecStart=/usr/sbin/sshd -f /home/sftpuser1/.ssh/sshd_config -f /home/sftpuser2/.ssh/sshd_config -D $OPTIONS或者/usr/sbin/sshd -f /home/sftpuser1/.ssh/sshd_config -f /home/sftpuser2/.ssh/sshd_config $OPTIONS这样配置后,每个用户将使用自己的配置文件,可以分别定制他们的SSH行为。
-
第一步:查看Docker Root目录docker info | grep 'Docker Root'第二步:查到容器的长id(container id)方式一:docker inspect pdmaas | grep "Id"方式二:docker ps -a --no-trunc | grep pdmaas第三步:停止容器docker stop [容器名|容器id]第四步:编辑修改环境变量env建议:修改前先备份!!!vim ${Docker Root}/containers/${container-id}/config.v2.json 或 vim ${Docker Root}/containers/${container-id}/config.jsonjson文件代码是压缩的,可以使用sz path命令下载下来格式化后再编辑,再用rz -y命令上传覆盖第五步:重载服务的配置文件systemctl daemon-reload第六步:重启docker转载自https://www.cnblogs.com/bgyb/p/18191197systemctl restart docker
-
要在Nginx中配置允许跨域(Cross-Origin Resource Sharing, CORS),你需要修改Nginx的配置文件(通常是nginx.conf或者某个包含在nginx.conf中的单独的配置文件)。下面是一个基本的例子,展示了如何在Nginx中设置CORS:打开你的Nginx配置文件。这通常是/etc/nginx/nginx.conf或者/etc/nginx/conf.d/default.conf,或者一个特定站点的配置文件在/etc/nginx/sites-available/或/etc/nginx/conf.d/目录下。在你想要允许跨域请求的server块或location块中添加add_header指令。下面是一个简单的例子,它允许来自任何源的跨域请求,并允许所有的请求方法(GET, POST, PUT, DELETE等)和请求头:server { listen 80; server_name your.domain.com; location / { # ... 其他的配置 ... # 允许跨域请求 if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # 自定义的头部可能需要额外的配置 # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # 告诉客户端,实际请求可以预检,并返回一个非简单请求的预检结果且缓存该结果 # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST' || $request_method = 'GET' || $request_method = 'PUT' || $request_method = 'DELETE') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; # # 如果需要处理跨域Cookie,请取消下面的注释 # # add_header 'Access-Control-Allow-Credentials' 'true'; } # ... 其他的代理或静态文件配置 ... } }注意:* 允许来自任何源的请求,但在生产环境中,出于安全考虑,你应该明确指定允许的源。如果你需要处理跨域Cookie(即withCredentials设置为true的XHR/Fetch请求),则必须设置Access-Control-Allow-Credentials为true,并且Access-Control-Allow-Origin不能设置为*,而应该是一个具体的源(如http://example.com)。在处理OPTIONS预检请求时,Nginx直接返回204状态码,这告诉浏览器请求是允许的,并且不需要实际发送请求体。请根据你的实际需求调整允许的HTTP方法和请求头。修改完Nginx配置文件后,重新加载或重启Nginx服务以使更改生效:sudo nginx -s reload # 或者 sudo systemctl reload nginx # 或者完全重启Nginx服务 sudo systemctl restart nginx本文来自博客园,作者:dashery,转载请注明原文链接:cid:link_0
-
一、逻辑地址和物理地址1.1 含义:逻辑地址和物理地址是计算机内存管理中的两个核心概念,它们在计算机系统中扮演着不同的角色。逻辑地址(Logical Address),也称为虚拟地址(Virtual Address),是由操作系统提供给程序使用的地址。这些地址是在程序中使用的,但并不是实际存在的地址。逻辑地址的大小和位数取决与处理器的架构和操作系统的设计,通常是一个定长的二进制数值。在执行指令时,CPU会将逻辑地址转换未物理地址来取数据。物理地址(Physical Address),是指内存中实际的地址,他表示内存模块中每个存储的单元(通常是字节)的唯一标识符,因此具有唯一性,且直接与内存相关联。物理地址通常是以一个十六进制表示的数字,他确定了计算机中的实际内存位置。总结来说,逻辑地址是虚拟的,而物理地址是实际的。逻辑地址是程序中使用的地址,它需要经过转换后才能访问到实际的物理地址。在内存管理中,操作系统根据自己的算法将逻辑地址转换为物理地址,使得程序能够正常地读取和写入内存中的数据。逻辑地址与物理地址之间存在着映射关系,但它们并不相等,还需要经过地址映射的过程。Top二、逻辑磁盘和物理磁盘2.1含义逻辑磁盘和物理磁盘的关系可以通过LVM(Logical Volume Manager)系统来理解。在LVM中,物理存储设备如硬盘分区或整个硬盘被转换为物理卷(Physical Volume,简称PV),这些物理卷然后聚集形成卷组(Volume Group,简称VG)。在卷组之上,可以创建逻辑卷(Logical Volume,简称LV)。这些逻辑卷是标准的块设备,可以在其上建立文件系统,相当于非LVM系统中的分区。具体来说,物理卷对应的是硬件存储,是磁盘或者磁盘分区,是物理存在。而卷组和逻辑卷则是逻辑上的存在。逻辑卷是在卷组上建立的,可以根据业务需求扩展或收缩,提供更大的灵活性和管理便利。此外,逻辑磁盘也可以在逻辑上再次进行划分,例如,有多个物理磁盘通过RAID和技术组成一个虚拟磁盘后,还可以将这个虚拟磁盘划分为多个逻辑磁盘。这些逻辑磁盘可能并不一定位于同一块物理磁盘上,它们可能是跨多个物理磁盘的,这样可以提高I/O效率。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签