Go-知识测试-模糊测试

Go-知识测试-模糊测试

  • 1. 定义
  • 2. 例子
  • 3. 数据结构
  • 4. tesing.F.Add
  • 5. 模糊测试的执行
  • 6. testing.InternalFuzzTarget
  • 7. testing.runFuzzing
  • 8. testing.fRunner
  • 9. FuzzXyz
  • 10. RunFuzzWorker
  • 11. CoordinateFuzzing
  • 12. 总结

建议先看:https://blog.csdn.net/a18792721831/article/details/140062769

Go-知识测试-工作机制

1. 定义

模糊测试(Fuzzing)是一种通过构造随机数据对代码进行测试的测试方法,相比于单元测试,
它能提供更为全面的测试覆盖,从而找出代码中的潜在漏洞。
从1.18开始,Go开始正式支持模糊测试。
模糊测试要保证测试文件以_test.go结尾。
测试方法必须以FuzzXxx开头。
模糊测试方法必须以*testing.F作为参数。

2. 例子

假设有个函数,根据输入内容,将输入进行翻转然后在和输入拼接,从而返回一个回文串(不一定是严格意义下的回文串)
函数如下:

func PalindromeStr(in string) string {b := []byte(in)for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {b[i], b[j] = b[j], b[i]}return in + string(b)
}

接着使用单元测试

func TestPalindromeStr(t *testing.T) {testCase := []struct{ in, out string }{{"abc", "abccba"},{"abcdef", "abcdeffedcba"},{"abcdefg", "abcdefggfedcba"},{" ", "  "},}for _, c := range testCase {o := PalindromeStr(c.in)if o != c.out {t.Error("Not equal", c.out, "got:", o)}}
}

使用go test -v 执行示例测试,-v 表示控制台输出结果
在这里插入图片描述

接着使用模糊测试

func FuzzPalindromeStr(f *testing.F) {testCase := []string{"abc", "def", " ", "a", "aaa", "aaaaaaaaaaaaaaaaaaaa"}for _, c := range testCase {f.Add(c) // 输入测试种子}f.Fuzz(func(t *testing.T, a string) {b := PalindromeStr(a)// 返回结果进行判断,回文串的规则就是第一个字符和最后一个字符相同,依次类推for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {if b[i] != b[j] {t.Error("Not palindrome")}}})
}

使用go test -fuzz=Fuzz -fuzztime=100s启动模糊测试,-fuzz表示执行模糊测试,-fuzztime表示持续时间
在这里插入图片描述

发现执行了100s,也没法问题。
那么我们就自动构造一个错误,如果是utf-8字符,返回回文串,否则返回输入内容,模拟异常逻辑:

func PalindromeStr(in string) string {b := []byte(in)if !utf8.Valid(b) {return in}for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {b[i], b[j] = b[j], b[i]}return in + string(b)
}

因为单元测试中没有中文字符,所以单元测试通过,但是模糊测试呢:
在这里插入图片描述

报错了,同时testdata目录中有相应的输入和输出
在这里插入图片描述

非utf8字符串,触发了错误逻辑

3. 数据结构

由于模糊测试可以覆盖人类经常忽略的边界用例,因此模糊测试对于发现安全漏洞特别有价值。
模糊测试的结构如下:
在这里插入图片描述

看起来很像单元测试的扩展。
一个模糊测试可以分为两部分,一是通过 f.Add 添加随机种子,二是通过 f.Fuzz 函数开始随机测试。标记测试结果的方法与之前的单元测试是通用的。
模糊测试的testing.F结构:
go在1.18中,在testing的包中增加了fuzz.go文件,支持模糊测试:

type F struct {common // 通用测试结构,更多见 https://blog.csdn.net/a18792721831/article/details/140062769fuzzContext *fuzzContext // 与 testContext 类似,用于控制执行testContext *testContextinFuzzFn bool // 标记 fuzz 是否在运行中corpus []corpusEntry // 种子,语料库result     fuzzResult // 模糊测试结果fuzzCalled bool // 是否启动
}

通用测试结构 common 提供了诸如标记测试结果的能力,而增加的 corpus 则用于保存通过 f.Add 添加的种子和测试过程中生成的随机输入。
每次执行 f.Add 都会生成一个 corpusEntry 对象,然后加入 corpus 语料库中。
corpusEntry 结构用于保存待测函数的所有输入:

type corpusEntry = struct {Parent     stringPath       stringData       []byteValues     []any // Values 要与待测函数索旭耀的参数完全一致Generation intIsSeed     bool
}

f.Add 每次添加的种子个数需要与待测函数所需要的参数完全一致,因为测试执行时,每次取出一组种子作为函数的入参。

4. tesing.F.Add

func (f *F) Add(args ...any) {// 将输入的参数加入到数组中var values []anyfor i := range args {// 模糊测试只能支持基本数据类型,对于复杂类型是不支持的if t := reflect.TypeOf(args[i]); !supportedTypes[t] {panic(fmt.Sprintf("testing: unsupported type to Add %v", t))}values = append(values, args[i])}f.corpus = append(f.corpus, corpusEntry{Values: values, IsSeed: true, Path: fmt.Sprintf("seed#%d", len(f.corpus))})
}

支持模糊测试的参数类型:

var supportedTypes = map[reflect.Type]bool{reflect.TypeOf(([]byte)("")):  true,reflect.TypeOf((string)("")):  true,reflect.TypeOf((bool)(false)): true,reflect.TypeOf((byte)(0)):     true,reflect.TypeOf((rune)(0)):     true,reflect.TypeOf((float32)(0)):  true,reflect.TypeOf((float64)(0)):  true,reflect.TypeOf((int)(0)):      true,reflect.TypeOf((int8)(0)):     true,reflect.TypeOf((int16)(0)):    true,reflect.TypeOf((int32)(0)):    true,reflect.TypeOf((int64)(0)):    true,reflect.TypeOf((uint)(0)):     true,reflect.TypeOf((uint8)(0)):    true,reflect.TypeOf((uint16)(0)):   true,reflect.TypeOf((uint32)(0)):   true,reflect.TypeOf((uint64)(0)):   true,
}

除了这些之外的类型都不支持。

5. 模糊测试的执行

src/tesing/fuzz.goinitFuzzFlags中定义了模糊测试的参数:

func initFuzzFlags() {matchFuzz = flag.String("test.fuzz", "", "run the fuzz test matching `regexp`")flag.Var(&fuzzDuration, "test.fuzztime", "time to spend fuzzing; default is to run indefinitely")flag.Var(&minimizeDuration, "test.fuzzminimizetime", "time to spend minimizing a value after finding a failing input")fuzzCacheDir = flag.String("test.fuzzcachedir", "", "directory where interesting fuzzing inputs are stored (for use only by cmd/go)")isFuzzWorker = flag.Bool("test.fuzzworker", false, "coordinate with the parent process to fuzz random values (for use only by cmd/go)")
}

首先使用-fuzz=reg触发模糊测试,-fuzztime=30s指定模糊测试持续的时间,如果不指定,则一直运行。
-fuzzminimizetime最小失败时间,默认一分钟,-fuzzcachedir缓存目录,默认是命令执行目录,fuzzworker工作目录,默认是命令执行目录。

6. testing.InternalFuzzTarget

testing.M中,对于单元测试,示例测试和性能测试,都有一个内部类型用于存储编译生成的执行参数。模糊测试也有:
在这里插入图片描述

在1.18中三种内部类型增加成4种了。
在编译的时候,load操作也增加了 Fuzz开头的模糊测试函数
在这里插入图片描述

在渲染测试的main入口中,也增加了模糊测试的模板
在这里插入图片描述

在testing.M.Run中,增加了模糊测试的支持
在这里插入图片描述

InternalFuzzTarget的结构:

type InternalFuzzTarget struct {Name stringFn   func(f *F)
}

很简单,和单元测试等的结构非常类似,name和对应的func,func 的参数是 *testing.F

7. testing.runFuzzing

在runFuzzing中首先对全部的模糊测试进行匹配,找到本次期望执行的模糊测试case
在这里插入图片描述

接着构造testing.F对象,调用testing.fRunner执行case
在这里插入图片描述

8. testing.fRunner

在testing.fRunner中启动执行,类似于单元测试的 testing.tRunner。
在这里插入图片描述

性能测试是 testing.runN
示例测试是 testing.runExample
单元测试是 testing.tRunner

第一个defer函数主要处理这几个事情:失败后资源清理,保证测试报告完成,失败退出,等待子测试完成,成功输出报告。
第二个defer函数是等待所有的子测试完成后,发送信号,表示子测试结束。

9. FuzzXyz

接着回到模糊测试中:

func FuzzPalindromeStr(f *testing.F) {testCase := []string{"abc", "def", " ", "a", "aaa", "你好"}for _, c := range testCase {f.Add(c) // 输入测试种子}f.Fuzz(func(t *testing.T, a string) {b := PalindromeStr(a)// 返回结果进行判断,回文串的规则就是第一个字符和最后一个字符相同,依次类推for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {if b[i] != b[j] {t.Error("Not palindrome")}}})
}

模糊测试可以认为是两部分,第一部分是输入测试种子,第二部分是判决模糊的参数执行是否成功。
在testing.F.Add中,将参数种子放到了testing.F.corpus里面,并且要求输入的种子参数的数量,每次Add的时候,必须和被测试方法的入参一致。
在第二部分的Fuzz中,首先对入参进行了校验:
在这里插入图片描述

入参是一个func类型的参数,并且第一个参数是*testing.T的参数,后面是可变参数。
第一个*testing.T主要是复用了单元测试的测试管理能力,比如报告输出,成功失败的标记等等。
后面的可变参数则是被模糊测试的函数入参列表。
接着对可变参数列表进行类型判断,只有基本类型才能模糊测试,如果入参中存在复杂类型,那么是无法模糊测试的。
在这里插入图片描述

接下来就是模糊的核心逻辑了,如何根据输入的参数种子,派生更多的入参用例:
在这里插入图片描述

模糊测试的goroutine分为三种
在这里插入图片描述

这三种的含义先存疑。
在CheckCorpus中,对入参种子和可变参数进行校验,确保种子数组中每一组都符合要求。
在ReadCorpus中,则是随机取出本次执行的参数,如果是指定fuzz的目录和id,那么会使用指定的目录下的指定参数去执行
在这里插入图片描述

ReadCorpus调用了internal的fuzz实现
在这里插入图片描述

在ReadCorpus中调用了readCorpusData
在这里插入图片描述

不过上面都是执行特定的模糊case 。
在前面已知模糊测试的goroutine中有三种:

const (seedCorpusOnly fuzzMode = iotafuzzCoordinatorfuzzWorker
)

第一种 seedCorpusOnly 是 testing.runFuzzTests 中创建的,由testing.M调用
在这里插入图片描述

第二种 fuzzCoordinator 是 默认的,如果执行的go命令中没有指定 test.fuzzworker , 默认是 false
在 testing.runFuzzing 中创建的
在这里插入图片描述

第三种 fuzzWorker 是由 命令行参数指定的。

在这里插入图片描述

根据这里的逻辑,基本上可以看出,seedCorpusOnly 是读取指定模糊case, fuzzCoordinator是生成模糊case,fuzzWorker是执行case。
在这里插入图片描述

接着创建一个 testing.T 的对象,然后调用 testing.tRunner 执行case 。
在这里插入图片描述

testing.tRunner执行case的参数是 corpusEntry 类型的输入。

也就是说,对于模糊测试,会先直接调用测试种子执行,然后会根据执行情况,在进行随机参数。

如果是 fuzzCoordinator 类型的,那么执行 CoordinateFuzzing
在这里插入图片描述

如果是 fuzzWorker ,执行 RunFuzzWorker
在这里插入图片描述

如果是 seedCorpusOnly ,执行 run func,相当于直接用测试种子运行
在这里插入图片描述

在 fuzzWorker中,对于输出做了重定向。

10. RunFuzzWorker

RunFuzzWorker方法是在internal中实现的
在这里插入图片描述

如果一个case经过了10还没有被执行,就认为是饿死了
在serve方法中调用了workerServer.Fuzz 方法
在这里插入图片描述

并且是持续性调用的
在workerServer.fuzz中进行模糊测试
在workerServer.fuzz中,第一次调用直接使用种子
在这里插入图片描述

接着就是持续性测试了
在这里插入图片描述

在 mutator.mutate 中根据种子进行随机
在这里插入图片描述

会对一次随机的多个参数,随机选择一个参数,然后对这个参数进行随机
比如对于整型,会随机加或者减一个数
在这里插入图片描述

对于字符串,对字节码随机加减
在这里插入图片描述

也就是说,如果你的种子里面有中文,才会随机中文。

contains
accepts
calls
calls
passes
returns
TestDeps
RunFuzzWorker
fn
workerServer.fuzz
mutator.mutate
fuzz.CorpusEntry
error

11. CoordinateFuzzing

CoordinateFuzzing方法在internal中实现的
在这里插入图片描述

首先会对并发数,缓存目录,日志等进行初始化
在这里插入图片描述

根据并发数,创建多个 worker 执行模糊测试
在这里插入图片描述

在coordinate中也是持续测试
在这里插入图片描述

如果没有启动,那么就调用启动初始化等操作,如果收到了退出信号,那么就退出
如果随机输入已经生成,那么就使用随机输入调用
在这里插入图片描述

接着是for-select进行持续性测试,除非模糊测试失败,或者执行模糊测试的时候,有设置超时时间,或者主动退出等
在这里插入图片描述

在workerClient.fuzz中执行
在这里插入图片描述

也是调用 mutator.mutate 进行随机
在这里插入图片描述

同时,在调用FuzzXyz后,会记录case的执行情况,用于分析执行的覆盖率等等
在这里插入图片描述

12. 总结

Go 1.18 的 Fuzz 测试使用了一种称为 “coverage-guided fuzzing” 的技术来生成随机输入。这种技术的基本思想是通过监视被测试代码的覆盖率来引导输入的生成。

具体来说,Fuzz 测试首先使用你提供的种子值(seed values)来运行测试。然后,它会监视这些测试运行过程中哪些代码被执行了,以及输入值如何影响代码的执行路径。

接着,Fuzz 测试会尝试修改种子值或者组合种子值,生成新的输入,以尝试覆盖更多的代码路径。例如,如果你的种子值是字符串,Fuzz 测试可能会改变字符串的长度,添加、删除或修改字符,等等。

如果新的输入导致了更多的代码被执行,或者触发了新的代码路径,那么这个输入就会被保存下来,用作后续测试的种子值。这样,Fuzz 测试就可以逐渐 “学习” 如何生成能够触发更多代码路径的输入。

这种方法可以有效地发现一些难以预见的边界情况,特别是那些可能导致程序崩溃或者行为异常的情况。

需要注意的是,虽然 Fuzz 测试可以自动生成大量的输入,但是它并不能保证完全覆盖所有可能的输入。因此,你仍然需要编写单元测试和集成测试,以确保你的代码在预期的输入下能够正确工作。

Coverage-Guided Fuzzing 相关论文和链接

Coverage-guided fuzzing 是一种基于代码覆盖率的模糊测试技术,通过生成输入数据并监控代码覆盖率来发现潜在的错误和漏洞。这种方法的核心思想是通过最大化代码覆盖率来提高测试的有效性。

  1. “American Fuzzy Lop (AFL)”
    AFL 是一种流行的 coverage-guided fuzzing 工具,由 Michał Zalewski 开发。虽然 AFL 本身不是一篇论文,但它的设计和实现对该领域有着重要影响。
  • 链接: AFL GitHub Repository
  1. “Fuzzing: Brute Force Vulnerability Discovery”
    这篇论文由 Michael Sutton, Adam Greene, 和 Pedram Amini 撰写,详细介绍了模糊测试的基本概念和技术,包括 coverage-guided fuzzing。
  • 链接: Fuzzing: Brute Force Vulnerability Discovery
  1. “Coverage-based Greybox Fuzzing as Markov Chain”
    这篇论文由 Marcel Böhme, Van-Thuan Pham, 和 Abhik Roychoudhury 撰写,提出了一种基于覆盖率的灰盒模糊测试方法,并将其建模为马尔可夫链。
  • 链接: Coverage-based Greybox Fuzzing as Markov Chain
  1. “AFLFast: A Framework for Extremely Fast Fuzzing”
    这篇论文由 Marcel Böhme, Van-Thuan Pham, Manh-Dung Nguyen, 和 Abhik Roychoudhury 撰写,介绍了 AFLFast,这是一种改进的 AFL 版本,通过优化输入生成策略来提高模糊测试的效率。
  • 链接: AFLFast: A Framework for Extremely Fast Fuzzing
  1. “LibFuzzer: A Library for Coverage-Guided Fuzz Testing”
    LibFuzzer 是 LLVM 项目的一部分,提供了一个用于覆盖率引导模糊测试的库。虽然没有正式的论文,但其设计和实现文档非常详细。
  • 链接: LibFuzzer Documentation
  1. “Fuzzing with Code Fragments”
    这篇论文由 Patrice Godefroid, Hila Peleg, 和 Rishabh Singh 撰写,提出了一种基于代码片段的模糊测试方法,通过组合代码片段来生成新的测试输入。
  • 链接: Fuzzing with Code Fragments
  1. “Evaluating Fuzz Testing”
    这篇论文由 Marcel Böhme, Van-Thuan Pham, Manh-Dung Nguyen, 和 Abhik Roychoudhury 撰写,评估了不同模糊测试工具和技术的有效性,包括 coverage-guided fuzzing。
  • 链接: Evaluating Fuzz Testing
  1. “Fuzzing: Art, Science, and Engineering”
    这篇论文由 Patrice Godefroid 撰写,全面介绍了模糊测试的艺术、科学和工程,包括 coverage-guided fuzzing 的技术细节和应用。
  • 链接: Fuzzing: Art, Science, and Engineering

这些论文和资源提供了关于 coverage-guided fuzzing 的深入理解和最新研究成果。通过阅读这些文献,你可以更好地理解这种技术的原理、实现和应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/45212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文入门【NestJs】Providers

Nest学习系列 ✈️一文入门【NestJS】 ✈️一文入门【NestJs】Controllers 控制器 &#x1f6a9; 前言 在NestJS的世界里&#xff0c;理解“Providers”是构建健壮、可维护的后端服务的关键。NestJS&#xff0c;作为Node.js的一个现代框架&#xff0c;采用了Angular的一些核…

Redis的安装配置及IDEA中使用

目录 一、安装redis&#xff0c;配置redis.conf 1.安装gcc 2.将redis的压缩包放到指定位置解压 [如下面放在 /opt 目录下] 3.编译安装 4.配置redis.conf文件 5.开机自启 二、解决虚拟机本地可以连接redis但是主机不能连接redis 1.虚拟机网络适配器网络连接设置为桥接模式…

VSCode上通过C++实现单例模式

单例模式实际上就是为了确保一个类最多只有一个实例&#xff0c;并且在程序的任何地方都可以访问这个实例&#xff0c;也就是提供一个全局访问点&#xff0c;单例对象不需要手动释放&#xff0c;交给系统来释放就可以了&#xff0c;单例模式的设计初衷就是为了在整个应用程序的…

vue 下拉菜单树形结构——vue-treeselect的组件使用

参考&#xff1a; https://www.cnblogs.com/syjtiramisu/p/17672866.htmlhttps://www.cnblogs.com/syjtiramisu/p/17672866.html vue-treeselect的使用 - 简书下载依赖 使用https://www.jianshu.com/p/459550e1477d 实际项目使用&#xff1a;

uni-app iOS上架相关App store App store connect 云打包有次数限制

相册权限 uni-app云打包免费有次数 切换一个账号继续

华为手机联系人不见了怎么恢复?3个解决方案

华为手机联系人列表就像是我们精心编织的社交网络之网。然而&#xff0c;有时&#xff0c;这张网可能会因为各种原因而意外破损&#xff0c;联系人信息消失得无影无踪&#xff0c;让我们陷入“人脉孤岛”的困境。华为手机联系人不见了怎么恢复&#xff1f;别担心&#xff0c;我…

构建高质量数据集与智能数据工程平台:播客AI Odyssey深度对话实录

对话整数智能联创和前IDEA研究员&#xff1a;构建高质量数据集与智能数据工程平台 - AI Odyssey | 小宇宙 - 听播客&#xff0c;上小宇宙 人工智能技术的日益深远发展&#xff0c;对人工智能的性能提升与技术迭代提出了新的要求。在大模型训练中&#xff0c;已有的研究和实践表…

【操作系统】进程管理——用信号量机制解决问题,以生产者-消费者问题为例(个人笔记)

学习日期&#xff1a;2024.7.10 内容摘要&#xff1a;利用信号量机制解决几个经典问题模型 目录 引言 问题模型 生产者-消费者问题&#xff08;经典&#xff09; 多生产者-多消费者问题 吸烟者问题 读者写者问题&#xff08;难点&#xff09; 哲学家进餐问题&#xff0…

解决POST请求中文乱码问题

解决POST请求中文乱码问题 1、乱码原因2、解决方法3、具体步骤 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Web开发中&#xff0c;处理POST请求时经常遇到中文乱码问题&#xff0c;这主要是由于服务器在接收到POST请求的数据后&#x…

BUG解决:postman可以请求成功,但Python requests请求报403

目录 问题背景 问题定位 问题解决 问题背景 使用Python的requests库对接物联数据的接口之前一直正常运行&#xff0c;昨天突然请求不通了&#xff0c;通过进一步验证发现凡是使用代码调用接口就不通&#xff0c;而使用postman就能调通&#xff0c;请求参数啥的都没变。 接口…

SSL 证书错误:如何修复以及错误发生的原因

SSL证书可以提升网站的可信度。然而&#xff0c;如果您的SSL证书出现错误&#xff0c;您可能会得到一个“不安全”的标签&#xff0c;这可能会导致访问者失去对您网站的信任并转向竞争对手。 本文将介绍SSL证书错误的原因及其对用户的潜在影响。随后&#xff0c;我们将提供详细…

MybatisPlus 核心功能

MybatisPlus 核心功能 文章目录 MybatisPlus 核心功能1. 条件构造器1.1 QueryWrapper1.2 LambdaQueryWrapper&#xff08;推荐&#xff09;1.3 UpdateWrapper1.4 LambdaUpdateWrapper 2. 自定义SQL3. Service接口 1. 条件构造器 当涉及到查询或修改语句时&#xff0c;MybatisP…

界面组件Kendo UI for React 2024 Q2亮点 - 生成式AI集成、设计系统增强

随着最新的2024年第二季度发布&#xff0c;Kendo UI for React为应用程序开发设定了标准&#xff0c;包括生成式AI集成、增强的设计系统功能和可访问的数据可视化。新的2024年第二季度版本为应用程序界面提供了人工智能(AI)提示&#xff0c;从设计到代码的生产力增强、可访问性…

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序 SSM 图书管理系统小程序 功能介绍 用户 登录 注册 首页 图片轮播 图书信息推荐 图书详情 赞 踩 评论 收藏 系统公告 公告详情 用户信息修改 我的待还 图书归还 催还提醒 我的收藏管理 意见反馈 管理员 登录 个人中心…

绝地求生PUBG奇幻大乱斗怎么玩 奇幻大乱斗什么时候回归

《绝地求生》(PUBG) 是由韩国开发的一款战术竞技型射击类沙盒游戏&#xff0c;游戏中我们需要和队友组队乘坐飞机跳伞到达一座空岛&#xff0c;之后我们需要搜索一切我们可以用到的物资&#xff0c;之后我们于敌人进行对战&#xff0c;期间不断躲避毒圈的追击&#xff0c;最后当…

Redis+Caffeine 实现两级缓存实战

RedisCaffeine 实现两级缓存 背景 ​ 事情的开始是这样的&#xff0c;前段时间接了个需求&#xff0c;给公司的商城官网提供一个查询预计送达时间的接口。接口很简单&#xff0c;根据请求传的城市仓库发货时间查询快递的预计送达时间。因为商城下单就会调用这个接口&#xff…

防火墙安全策略及用户认证实验

目录 一、实验拓扑 二、实验要求 三、实验思路 四、实验配置 1、配置vlan 2、配置路由器、防火墙IP地址&#xff0c;划分区域 3、配置安全策略 ​策略一&#xff1a; 策略二&#xff1a; 策略三&#xff1a; 4、配置用户认证 策略一&#xff1a; 策略二&#xff1a…

WebGIS基础原理

该部分内容与部分插图、学习框架的主要参考的网站与博主如下&#xff08;也趁机分享给大家&#xff09;&#xff1a; OSGeo开源WebGIS在线教程&#xff1a;http://webgis.cn/ OSGeo《地理信息系统原理》&#xff1a;https://www.osgeo.cn/gis-tutorial/index.html OSGeo《Pyth…

DSC主备归档报错

先看一个报错&#xff1a; 2024-07-10 22:12:21.725 [ERROR] database P0000003511 T0000000000000003696 rafil_list_overlap_consecutive_check failed, rfil(DMDATA/data/DSC02/arch/ARCHIVE_LOCAL1_0x57843343_EP1_2024-07-10_20-44-40.log)->next_seq(2901) > nex…

部署Harbor仓库

本章内容&#xff1a; 安装docker-ce部署harbor仓库上传和拉取 1.安装docker 1&#xff09;拉取源码 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 2&#xff09;安装docker-ce yum -y install docker-ce 3&#…