SNMPv3 - 用户安全模型

2023-05-16

SNMPv3 - 用户安全模型
这是描述SNMP协议第三版安全特征的两篇文章中的第一篇. SNMPv3 RFCs描述了一个新的框架用于定义SNMP第一, 第二和第三版规范之间的关系. 这个框架以模块的方式划分并且绝大部分依赖以前的工作 (例如 SNMPv1, SNMPv2c, SNMPv2u, 和 SNMPv2*).
在这个框架内的两个核心模块是基于用户的安全模型 (USM) 和基于视图的访问控制模型 (VACM). USM 负责 SNMP 包的认证/加密/解密, VACM 负责管理MIB数据的访问. 本文概述了 USM, 下个月我们会看一下 VACM.
USM 的规范定义在 RFC 2574. 以前版本的SNMP有一个众所周知的弱点是缺乏一个坚固的, 一致的安全方案. 在设计 USM 的时候, 这些典型的安全威胁必须被解决:
      * 信息修改 (数据完整性)
         确保数据在传输中没有被未认证的实体恶意修改.
      * 伪装 (数据来源认证)
         确保准确的知道数据来自谁以及来自哪里, 防止未认证的实体假装认证用户的身份.
      * 泄露 (数据机密性)
         确保未认证的实体不能偷听数据交换.
      * 消息流修改 (消息及时性)
         确保数据及时接收, 防止未认证的实体恶意重组数据. 
USM 能保护SNMPv3包不受以上威胁, 它利用多用户中每一个用户提供私钥来认证和保证私密性. 指定使用的认证协议是 HMAC-MD5 和 HMAC-SHA. 指定的私密性协议是 CBC-DES. RFC 指出安全协议在该RFC被制定的时候被认为安全性对于USM是可接受的. 然而, 未来如果有需要模型允许指定新的认证和私密性协议.
概念
SNMPv3 介绍了许多新的概念. 大部分概念被框架中的多个模块用到. 这里是一些USM用到的概念:
      * snmpEngineID
         一个可管理的域名内的一个SNMP引擎的唯一标识. 这个八进制字符串的值不能是0长度, 全为 '0x00'H, 或 全为 '0xFF'H. snmpEngineID 通常是由企业数字, IP 或 MAC 地址, 以及一个用于管理而分配的字符串组合计算出来的.
      * snmpEngineBoots
         自从snmpEngineID最后一次设定以来SNMP引擎重启或重新初始化的次数. 这个计数器被初始化为0.
      * snmpEngineTime
         自从snmpEngineBoots计数器最后一次增加以来的秒数. 这个计数器被初始化为0. 如果snmpEngineTime达到最大值 (2147483647), 那么snmpEngineBoots加一并且snmpEngineTime再次从0开始计数.
      * snmpSecurityLevel
         有三个可能的安全级别: noAuthNoPriv, authNoPriv, 和 authPriv. noAuthNoPriv 级别指明了没有认证或私密性被执行. authNoPriv 级别指明了认证被执行但没有私密性被执行. authPriv 级别指明了认证和私密性都被执行. noAuthPriv 安全级别不存在的一个原因是需要一个消息认证摘要来确保安全参数的完整性, 也就是私密性参数 (例如. DES salt).
      * 授权SNMP引擎
         为了保护消息不被重发, 延迟发送, 和重定向, 一个通讯SNMP引擎被设计作为授权SNMP引擎. 授权SNMP引擎负责接收需要响应的 SNMP 消息. 它是一个代理并且管理器总是与之通讯. 
SNMPv3 包格式
                              SNMPv3 包格式
                           -------------------------
      /|\                | msgVersion                  |
        |                  |-----------------------|
        |                  | msgID                         |
        |                  |-----------------------|             USM Security Parameters
        |                  | msgMaxSize                  |
        |                  |-----------------------|      /-------------------------------
        |                  | msgFlags                     |    / | msgAuthoritativeEngineID       |
   scope of            |-----------------------|   /   |-----------------------------|
authentication      | msgSecurityModel         | /    | msgAuthoritativeEngineBo ots |
        |                  |-----------------------|/      |-----------------------------|
        |                  |                                  |       | msgAuthoritativeEngineTi me   |
        |                  | msgSecurityParameters |       |-----------------------------|
        |                  |                                  |       | msgUserName                         |
        |                  |-----------------------|\      |-----------------------------|
        |       /|\      |                                  | \    | msgAuthenticationParamet ers |
        |         |       |                                  |   \   |-----------------------------|
        |         |       |                                  |    \ | msgPrivacyParameters            |
        |   scope of   | scopedPDU                   |      \-------------------------------
        | encryption |                                  |
        |         |       |                                  |
        |         |       |                                  |
        |         |       |                                  |
      \|/      \|/      |                                  |
                           -------------------------
SNMP第三版的包结构为了适应像USM之类的安全模型做了改变.
      * msgVersion
         SNMP版本 (例如 1, 2 或 3).
      * msgID
         msgID 用于协调管理器和代理之间的请求和响应. 响应中的msgID必须和接收到的请求中的msgID相同.
      * msgMaxSize
         msgMaxSize 传递发送者能够从其他SNMP引擎接受的最大消息大小.
      * msgFlags
         msgFlags 是一个单独的八位组用于表示如何处理消息. 例如, msgFlags 中的两个位用于指定包是否被认证和是否被加密.
      * msgSecurityModel
         SNMPv3 被设计为使用多个同时存在的安全模型. msgSecurityModel 字段指定了产生消息的安全模型. 因此, 接收者知道使用那个安全模型来对接收到的消息执行安全处理.
      * msgSecurityParameters
         msgSecurityParameters 是一个包含安全模型指定数据的八位组字符串. 该数据仅被 msgSecurityModel 指定的安全模型定义和使用.
      * scopedPDU
         scopedPDU 包含普通的 PDU 以及为了处理该 PDU 的用于识别唯一上下文的信息. 
USM 安全参数
USM 使用 msgSecurityParameters 存放五个值. 这些值被用于认证模块来确保数据完整性和数据源认证, 被用于时序模块来保护消息延迟或重传, 以及被用于私密性模块来保护消息不被泄露.
      * msgAuthoritativeEngineID
         授权引擎的snmpEngineID总是放在这个字段内而不管包是由哪一边产生的.
      * msgAuthoritativeEngineBo ots
         授权引擎的snmpEngineBoots.
      * msgAuthoritativeEngineTi me
         授权引擎的snmpEngineTime.
      * msgUserName
         用户名, 他的私钥将被用于可能的认证和包加密.
      * msgAuthenticationParamet ers
         如果包是认证过的, 那么这个字段包含计算好的该包的 HMAC-MD5 或 HMAC-SHA 消息摘要.
      * msgPrivacyParameters
         如果包的 scopedPDU 是被加密过的, 那么这个字段包含用于DES算法输入的 salt (例如 随机变量). 
代理发现
正如上面提到的, USM 要求授权引擎的 snmpEngineID, snmpEngineBoots, 和 snmpEngineTime 被放置在 msgSecurityParameters 中. 这要求未认证引擎 (例如. 管理器) 在GET, NEXT, 或 SET操作完成以前为认证引擎 (例如 代理) 准备这些值.
有一个发现过程来达到这个目的. 这里会遇到有两个发现事务. 第一个是发现代理的 snmpEngineID. 第二个是发现 snmpEngineBoots 和 snmpEngineTime. 管理器仅仅在安全级别为authNoPriv或authPriv时需要第二个事务. 这是因为 msgAuthoritativeEngineBo ots 和 msgAuthoritativeEngineTi me 被时序模块使用而该模块只是认证过程的一部分.
第一个发现事务被发送SNMPv3包的管理器初始化, 这个包的msgAuthoritativeEngineID 包含一个伪造的值. 当代理接收到一个跟它拥有的 msgAuthoritativeEngineID  不同的包, 这个包会被丢弃并且一个发现包被返回给管理器. 返回的发现包包含正确的 snmpEngineID, 管理器必须使用这个 snmpEngineID.
第二个发现机制要求一个认证过的包被发送给代理. 这意味着认证标志被设置在 msgFlags, 并且 msgAuthenticationParamet ers 包含计算过的该包的消息摘要. 用于认证该包的私钥来自 msgUserName 指定的用户. 当 msgAuthoritativeEngineBo ots 和 msgAuthoritativeEngineTi me 包含伪造的值时这是一个发现包. 当代理接收到这样的包, 首先做认证. 一旦认证完成, msgAuthoritativeEngineBo ots 和 msgAuthoritativeEngineTi me 值被检查. 由于值是伪造的, 该包被丢弃并且第二个发现包被返回给管理器. 返回的发现包是认证过的, 使用相同的用户, 包含正确的 snmpEngineBoots 和 snmpEngineTime 值, 管理器必须使用它们.
及时性
一旦管理器得知了代理的 snmpEngineBoots 和 snmpEngineTime, 管理器必须在本地维护这些值应该是多少. 这要求管理器每一秒都增加 snmpEngineTime 这样这个值会非常接近代理维护的主值. 如果 snmpEngineTime 溢出了, 那么 snmpEngineBoots 必须增加. 管理器必须为每一个它想要与之通讯的代理在本地维护这些值.
代理进行及时性检查被认为是认证过程的一部分并且在接收到的包被认证过之后立刻进行. 如果 msgAuthoritativeEngineBo ots 跟代理的当前 snmpEngineBoots 值不同, 该包被丢弃并且一个发现包被发送回管理器. 如果检查通过, 那么 msgAuthoritativeEngineTi me 被用于跟代理的 snmpEngineTime 值做检查. 如果两个值的差异多于150秒, 这个包被丢弃并且一个发现包被发送回管理器. 如果两个检查都通过, 那么该包被认为被及时接收到并且继续处理.
+/- 150 秒这个用于比较 snmpEngineTime 的值是RFC默认指定. 这个值可以根据你的网络的速度和大小进行合适的修改.
认证
USM 指定使用消息摘要5 (MD5) 和安全哈希算法1 (SHA-1) 算法来认证 SNMPv3 包. 这些算法用于为可变长度的消息创建唯一固定大小的消息摘要, 也称为消息签名或指纹. MD5 创建 128 位的摘要 (16 字节) 而 SHA-1 创建 160 位的摘要 (20 字节). MD5 和 SHA-1 都不能直接用于消息认证代码因为他们不使用私钥作为输入来导出计算过的消息摘要. 这就是为什么使用消息认证密钥哈希   (HMAC) 算法跟 MD5 和 SHA-1 组合使用来计算消息摘要. HMAC 算法定义了一个过程会在数据中加入私钥然后计算 MD5 或 SHA-1 消息摘要. 这保证了要为同样的数据计算等同消息摘要必须共享一个公共的私钥. 这里是发送和接收认证过的 SNMPv3 包要采取的步骤:
发送认证的 SNMPv3 包:
     1. 整个包被创建. 认证标志在 msgFlags 上打开, 并且 msgAuthenticationParamet ers 置零.
     2. 使用 msgUserName 指定用户的私钥认证密钥为该包计算消息摘要. 使用什么算法(例如 HMAC-MD5 或 HMAC-SHA)由用户表中的用户使用的认证协议指定.
     3. 计算过的消息摘要被插入 msgAuthenticationParamet ers.
     4. 包被发送. 
接收认证的 SNMPv3 包:
     1. 包被接收.
     2. 如果 msgFlags 中认证标志被打开, 继续第三步的认证过程. 如果该包没有被发送者认证, 认证被跳过.
     3. 保存 msgAuthenticationParamet ers.
     4. msgAuthenticationParamet ers 置零.
     5. 使用 msgUserName 指定用户的私钥认证密钥为该包计算消息摘要. 使用什么算法(例如 HMAC-MD5 或 HMAC-SHA)由用户表中的用户使用的认证协议指定. 如果用户在用户表中不存在那么该包不能被认证并被丢弃.
     6. 比较计算过的消息摘要和之前保存的 msgAuthenticationParamet ers 中的值. 如果不同该包不是认证的并被丢弃. 如果相同, 该包是认证的并且可以继续处理. 
私密性
USM 指定使用 Cipher Block Chaining mode to the Data Encryption Standard (CBC-DES) 算法来加密和解密 SNMPv3 包. 加密的范围仅仅覆盖包含scopedPDU, 其中包含 PDU 和用于VACM的上下文数据. DES 算法接受三个输入. 这些输入是要被加密的数据, 一个 56 位的私钥, 和一个 56 位的随机产生的 salt 用于确保两个不同的初始化向量被用于用相同私钥加密的两个输入的不同数据. 通讯中使用加密的双方必须共享同一个私钥和 salt 用于推导初始化向量. 私钥存储在用户表, salt 随着包的 msgPrivacyParameters 传递. 这里是发送和接收加密包的步骤.
发送加密的 SNMPv3 包:
     1. 整个包被创建, 并且认证和私密性标志在 msgFlags 中被打开.
     2. 计算一个随机的 salt 值.
     3. scopedPDU 被使用 salt 和 msgUserName 指定的用户的私钥加密.
     4. salt 被插入 msgPrivacyParameters.
     5. 如前所述认证该包.
     6. 发送该包. 
接收加密的 SNMPv3 包:
     1. 包被接收.
     2. 如果 msgFlags 中认证标志被打开, 那么该包必须如前所述进行认证并继续步骤 3. 如果msgFlags中认证标志被关闭那么跳过解密.
     3. 如果msgFlags中私密性标志被打开, 那么继续步骤4的解密过程. 如果包未被发送者加密那么跳过解密.
     4. 使用msgSecurityParameters中指定的salt和 msgUserName 指定的用户的私钥解密 scopedPDU.
     5. 继续处理包. 
用户表
每一个代理维护一个用户表用于存储所有能够通过SNMP访问系统的用户. 表中的每一个用户项包含下列信息, 所有这些都可以通过对USM MIB的SNMP操作来修改:
      * 用户名
         人可读的字符串表示用户的名字.
      * 认证协议
         指示代表该用户发送或接收的消息是否认证以及使用哪一个认证协议. 对这个字段当前可以使用的值是: usmNoAuthProtocol, usmHMACMD5AuthProtocol, 以及 usmHMACSHAAuthProtocol.
      * 认证密钥
         用于认证消息的认证协议使用的本地私钥.
      * 私密性协议
         指示代表该用户发送或接收的消息是否加密以及使用哪一个私密性协议. 对这个字段当前可以使用的值是: usmNoPrivProtocol 和 usmDESPrivProtocol.
      * 私密性密钥
         用于加解密消息的私密性协议使用的本地私钥. 
用户表有一个相关联的叫做usmUserSpinLock的自旋锁. 自旋锁是一个建议性锁用于允许几个 SNMP 管理器协同尝试修改一个 MIB 表. 概念很简单. 任何是有有一个代理要对用户表做修改, 管理器必须通过GET命令获取 usmUserSpinLock 的值. 管理器发送SET命令给代理, 其中包含设置 usmUserSpinLock PDU以及用户表中要被修改的变量. SET命令中 usmUserSpinLock 的值必须是之前通过GET命令取得的. 一旦代理接收到包含SET命令的消息, usmUserSpinLock 立刻被处理. 如果当前 usmUserSpinLock 的值跟SET命令中的指定的值不一样, SET 操作失败并返回错误. 如果两个值相同, SET命令的PDU指定的用户表的变量被设置. 当代理处理完整个PDU, usmUserSpinLock 的值加1. 正如你所见, 如果 usmUserSpinLock 的值跟设置的时候不同, 那么用户表从初次获得 usmUserSpinLock 的值以后被修改过.
本地密钥
本地私钥的概念是允许在许多不同的代理对一个用户使用相同的密码. 强迫每个代理为存在的用户记住不同的密码是非常不灵活的. 本地密钥通过一个哈希函数(例如 MD5 或 SHA-1)根据一个私有的密码和用户存在的代理的 snmpEngineID 来计算. 结果是每个代理的密钥都完全不同, 尽管它们使用了相同的密码.
改变密钥
USM 引入了 KeyChange 类型来描述使用私钥的习惯. KeyChange 定义提供了一个安全的方法来通过网络发送本地密钥这样允许用户改变他们的密钥. 当用户要改变他们的密钥时会碰到以下步骤:
管理器:
     1. 用户数一个新密码.
     2. 本地密钥通过新密码和要改变用户密码的代理的 snmpEngineID 重新计算.
     3. 一个单向的函数用于从老的密钥产生一个值.
     4. 这个值跟新的密钥异或 (XOR).
     5. 最终的 KeyChange 通过一个SET命令发送到代理. 
代理: (接收到 KeyChange SET 操作以后)
     1. 跟管理器使用的同样的单向函数从老的密钥产生一个值.
     2. 这个值跟接收到的KeyChange异或 (XOR) 产生新的密钥.
     3. 新的密钥被设置到用户表. 
创建/克隆 用户
在代理的用户表创建一个新的用户是可能的. 这通过克隆一个存在的用户来实现. 所有的数据从被克隆的用户拷贝到新创建用户的项中. 一旦新的项被创建, 建议立刻改变密钥. 注意你只能通过克隆另一个已存在的用户来创建新的用户. 这要求该代理的用户表必须被初始化为包含你的环境中需要的最小的用户集合.
Using your SNMPv3 manager of choice, 这里有个例子关于如何从已存在的名叫foo的用户创建一个新用户并改变密钥. 注意被创建的新用户的实际名字没有显示在这里, 因为这个名字由被设置的变量的OID索引指定. 用户表通过用户名来查找.
首先获得自旋锁的值然后创建用户. 为了确保新用户项不能被立刻使用, 设置它的状态为 createAndWait.
      sValue = GET (usmUserSpinLock)
      SET((usmUserSpinLock = sValue),
            (usmUserCloneFrom = foo),
            (usmUserStatus = createAndWait))
下一步, 改变私密性密钥. 注意你必须知道foo的私钥用于计算 KeyChange. privKeyChange 值通过被克隆的用户的私钥计算并且新的私钥用于新的用户. 确认使用自旋锁. 同时, usmUserPublic 变量可以被写下作为该包用户密钥的过程的一部分, 随后可以读取这个值来确定密钥改变是否完成.
      sValue = GET(usmUserSpinLock)
      SET((usmUserSpinLock = sValue),
            (usmUserPrivKeyChange = privKeyChange),
            (usmUserPublic = randomValue))
      if (randomValue != GET(usmUserPublic)) then try again
如果新用户不再使用加密, 那么你可以设置 privProtocol 为 usmNoPrivProtocol 并且不再修改私密性密钥.
      sValue = GET(usmUserSpinLock)
      SET((usmUserSpinLock = sValue),
            (usmUserPrivProtocol = usmNoPrivProtocol))
现在改变认证私钥. 注意你必须知道foo的认证私钥用于计算 KeyChange. authKeyChange 值通过被克隆的用户的认证密钥和用于新用户的密钥计算. 再一次确认使用自旋锁.
      sValue = GET(usmUserSpinLock)
      SET((usmUserSpinLock = sValue),
            (usmUserAuthKeyChange = authKeyChange),
            (usmUserPublic = randomValue))
      if (randomValue != GET(usmUserPublic)) then try again
如果新用户不再使用认证, 那么你可以设置 authProtocol 为 usmNoAuthProtocol 并且不再改变认证密钥.
      sValue = GET(usmUserSpinLock)
      SET((usmUserSpinLock = sValue),
            (usmUserAuthProtocol = usmNoAuthProtocol))
最后, 通过设置状态激活这个用户.
      sValue = GET(usmUserSpinLock)
      SET((usmUserSpinLock = sValue),
            (usmUserStatus = active))
结论
这个USM的概述应该使你理解SNMPv3包的认证和加密/解密涉及哪些东西. 另外, 你可以开始考虑当你部署支持SNMPv3的路由器, 交换机和服务器时如何配置你的环境中的代理. 下个月我将会看一下VACM以及展示它如何用于管理到MIB数据的访问.
参考
      * SNMPv3: RFCs 2570, 2571, 2572, 2573, 2574, 2575
      * SNMP, SNMPv2, SNMPv3, and RMON 1 and 2 (Third Edition) by William Stallings. Addison-Wesley Publishing Company.
      * Understanding SNMP MIBs by David Perkins and Evan McGinnis. Prentice Hall PTR. 
转自: http://blog.sina.com.cn/s/blog_63ec20a10101icnj.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SNMPv3 - 用户安全模型 的相关文章

  • 嵌入式软件面试题整理

    基础试题 1 用预处理指令 define 声明一个常数 xff0c 用以表明1年中有多少秒 xff08 忽略闰年问 define SECONDS PER YEAR 60 60 24 365 UL 说明 xff1a define 语法的基本知
  • 硬件在环仿真(HiL)测试介绍

    一 HiL是什么 xff1f 硬件在环仿真 xff08 Hardware in the Loop xff0c 简称HIL xff09 是真 的控制器连接假 的被控对象 xff0c 以一种高效低成本的方式对控制器进行全面测试 它是一种用于复杂
  • Docker Dockerfile详解

    dockerfike快速创建自定义的Docker镜像 一 目录 1 docker典型结构 2 指令介绍 3 创建docker镜像 二 结构 DockerFile分为四部分组成 xff1a 基础镜像信 维护者信息 镜像操作指令和容器启动时执行
  • 树莓派3B+(Raspberry Pi 3 Model B+)安装Ubuntu MATE 18.04及简单配置

    树莓派3B 43 安装Ubuntu MATE 18 04及简单配置 安装Ubuntu18 04 MATE下载Ubuntu 18 04 MATE准备Raspberry Pi Imager镜像烧录工具开机启动 简单配置设置root密码更新列表配
  • OpenCV之getOptimalNewCameraMatrix

    去畸变后的图像四周会出现黑色区域 xff0c 如果畸变较大 xff0c 如鱼眼镜头 xff0c 四周黑色区域将会更大 opencv中给我们提供了一个函数getOptimalNewCameraMatrix xff0c 用于去除畸变矫正后图像四
  • 【深度学习小常识】什么是mAP?

    目录 一 mAP相关概念 1 正例与负例 2 P xff08 精确率 xff09 3 R xff08 召回率 xff09 4 ACC xff08 准确率 xff09 5 AP xff08 平均精确度 xff09 6 示例 二 mAP 1 m
  • STM32CubeMX 下载和安装 详细教程

    HAL库 STM32CubeMX开发 STM32F407 目录 STM32CubeMX安装包 Win 6 6 1 下载链接 STM32CubeMX 下载 步骤1 xff1a 点击官网链接下载 官网下载地址 xff1a https www s
  • Keil5----跳转定义和查找功能

    一 Keil5 跳转定义 跳转定义 鼠标左键点击要查找的变量 方法1 xff1a 点击鼠标右键 xff0c 功能栏中有跳转定义的选项 方法2 xff1a 按快捷键 F12 具体操作如下图所示 xff1a 跳转结果 二 Keil5 查找功能
  • 使用WIFI模块AT指令进行MQTT协议通信

    劢领系列模组 xff0c 经过1年多的演化后 xff0c 已存在多套标准的固件程序 如果用户需要使用MQTT方式进行通信 xff0c 则需要选择标准AT指令 43 MQTT的版本 此版本不仅可以支持标准AT指令的SOCKET通信 xff0c
  • ActiveMQ配置wss

    最近把前端页面由原来的http升级为了https xff0c 发现之前ActiveMQ提供的ws不能强求了 xff0c https服务下要求升级到wss 全网搜索了下 xff0c 没有找到一个靠谱的文档 一 证书准备 使用wss连接服务必须
  • stm32使用HAL库快速编写智能寻迹避障小车(附代码)

    最近学校安排了一节用stm32编写寻迹避障小车的课 xff0c 但无奈学校老师教的方法让作者觉得无法理解 xff0c 但课程答辩时间快到了 xff0c 组内小组成员又做的磕磕绊绊 xff0c 于是身为组长的我就决定尝试一下用刚学的cubem
  • [hal库]使用 CubeMX 快速生成 FreeRTOS 系统并实现多任务处理

    由于项目需求 xff0c 需要使用FREERTOS搭载轻量系统 xff0c 因此写此博客给大家提供一个快速搭建RTOS系统的方法 xff0c 通过cubemx快速生成 以下内容包括 xff1a FreeRTOS 简介 程序框图所需要的元器件
  • Windows C/C++ CLion 开发环境搭建

    博文目录 文章目录 IDE CLion安装设置MinGW 插件测试 特殊配置 使用 CLion 开发 C 43 43 CUDA 应用注意不要走如下弯路 IDE CLion 安装 官网 官方全版本下载 CLion 2021 2 3 exe 或
  • git常见报错解决办法,fatal: the remote end hung up unexpectedly

    问题一 xff1a 上传GIT项目报fatal the remote end hung up unexpectedly错误 上传项目报fatal the remote end hung up unexpectedly的错误 xff0c 应该
  • AtCoder从小白到大神的进阶攻略

    摘自https www cnblogs com LHYLHY p 11572011 html 在此对作者表示感谢 AtCoder从小白到大神的进阶攻略 前言 现在全球最大的编程比赛记分网站非CodeForces和AtCoder莫属了 xff
  • 2020java面试总结

    博主背景 xff1a 92年生 xff0c 渣本毕业 xff0c java岗 xff0c 经验接近6年 xff0c base上海 本文宗旨 xff1a 本文旨在将博主最近的面试经历分享给大家 xff0c 并作些总结 xff0c 尽量为在准备
  • odroid上mavros指定版本安装

    mavros 安装 指定版本 xff1a 0 16 0 https github com mavlink mavros 以下是可能出现的错误 error1 can t find mavlinkConfig cmake solution ht
  • FreeRTOS源码解析 -> vTaskDelete()

    vTaskDelete API 函数 任务可以使用API函数vTaskDelete 删除自己或其它任务 任务被删除后就不复存在 xff0c 也不会再进入运行态 空闲任务的责任是要将分配给已删除任务的内存释放掉 因此有一点很重要 xff0c
  • 设置华为交换机使用账号密码方式进行SSH登录

    1 创建rsa本地密钥对与创建账号 Huawei rsa local key pair create The key name will be Huawei Host The range of public key size is 512
  • java中反射有什么作用?

    前言 反射blog有很多 xff0c 不再赘述 xff0c 但是反射的作用具体实现场景就会比较少 xff0c 这里举个例子 一个需求 使用参数的方式传入需要执行的类名 xff0c 然后执行相应类的同名方法 普通的实现方法 静态加载 因为需要

随机推荐