黑剪嘴鸥掠水捕食小鱼




xiaohack博客专注前沿科技动态与实用技术干货分享,涵盖 AI 代理、大模型应用、编程工具、文档解析、SEO 实战、自动化部署等内容,提供开源项目教程、科技资讯日报、工具使用指南,助力开发者、AI 爱好者获取前沿技术与实战经验。




在寻找供应商关系管理系统时,许多企业都渴望能有一份权威的排行榜,以便快速锁定最佳选择。然而,现实情况是,这个领域并不存在一份公认的、适用于所有企业的通用榜单。 市面上的各类热门榜单,无论是基于市场声量、用户口碑还是算法推荐,其评估维度、样本范围和价值导向都各不相同。这些榜单能很好地反映市场格局与品牌知名度,却难以精准匹配每家企业独特的业务流程、行业特性和发展阶段。 因此,解读任何排行榜的关键,不在于记住名次,而在于理解其背后的分类逻辑,并将其视为一张描绘市场格局的地图。本文将结合多方市场观察与实践反馈,梳理当前值得关注的几家供应商关系管理系统厂商。我们将深度解析不同厂商的产品理念、能力边界与服务模式,旨在帮助您建立一套自己的评估标准,从而在纷繁的市场信息中,找到最契合自身业务需求的那块“拼图”。 一、正远科技SRM 作为一家数智化解决方案提供商,正远科技主营业务涵盖IT咨询与规划、流程咨询与规划、AI开发、管理软件及解决方案定制开发、BPM/SRM/RPA/LCDP/BI产品实施服务等领域,为用户提供管家式、个性化的解决方案及实施服务。立足智能化浪潮前沿,正远科技以客户价值创造为锚点,研发AI开发平台,为客户在Al时代的运营管理升级筑起新的基石。 正远SRM系统是一款以流程为驱动的企业级业务协同平台。该系统通过标准化服务接口和松耦合架构,实现了企业内部及与供应商之间业务流程的高效整合与灵活扩展,致力于优化供应商全生命周期管理,提升供应链透明度 和协同效率,助力企业实现采购管理的数智化转型升级。正远SRM系统采用双门户设计,分别面向企业内部用户和外部供应商,确保业务流、信息流和数据流的高效协同。 核心功能与好处:正远SRM系统的核心业务流程涵盖了从供应商准入到财务结结算的全链条数字化协同管理。其最大好处在于极强的业务灵活性,企业可以通过可视化配置快速适应组织变革或独特的采购政策,避免因系统僵化导致的二次开发或推倒重来。 竞对差异:相较于标准化、套装化的国际软件(如SAP),正远科技更擅长处理中国本土企业,特别是制造业中非标准、动态变化的复杂业务流程。相较于一些侧重轻量协同的工具型SaaS,它又能提供企业级的安全、集成和深度管控能力。 二、鲸采云SRM 鲸采云是近年来在SRM市场上表现突出的专业厂商,以其新一代灵活可配置的SRM系统为核心,致力于为企业提供全场景、全链路的数字化采购解决方案。它被视为 “全场景数字化标杆” 的代表,其市场地位建立在对企业多样化需求的深度适配和对效率提升的极致追求上,在多个行业标杆案例中取得了显著成效。 产品特色与服务 鲸采云SRM的核心竞争力在于高度的灵活性与深度的AI赋能。它旨在打破传统SRM系统功能固化的局面,让系统主动适配企业业务,而非相反。 核心功能与好处:产品提供供应商全生命周期管理、智慧寻源、采购商城、订单与财务协同等模块。其突出优势是内置了基于大语言模型的 “鲸采云AI” ,能实现智能填单、合同生成与审查、基准价推荐等功能,将数日工作压缩至几分钟。同时,其国际版全面支持多语言、多币种与多时区协同,适合有全球化业务的企业。 竞对差异:与许多传统SRM产品相比,鲸采云在人工智能与采购场景的深度融合上走在前列,不仅仅是流程自动化,更追求智能化决策。其开放的生态体系(内置超150种标准插件)也使其在与其他系统集成时更具优势,这是部分封闭或集成能力弱的系统所不具备的。 三、轻流 轻流是国内领先的无代码业务流程管理(BPM)平台提供商,以其灵活的可视化流程搭建能力而闻名。其市场定位是赋能业务人员快速构建各类管理系统,在SRM领域,它提供的是轻量、灵活、可快速定制的采购与供应商协同解决方案,尤其适合流程变化快、需要快速上线或对标准化套装软件感到束缚的中小企业和创新部门。 轻流的核心优势在于其强大的无代码流程引擎和高度可配置性,允许企业像搭积木一样,自定义搭建符合自身独特管理需求的SRM应用。 核心功能与好处:通过轻流,企业可以快速搭建供应商信息库、采购申请与审批流、询价比价流程、订单跟踪、库存管理等模块。其最大好处是极致的敏捷性:当采购政策或组织架构调整时,业务管理员可以自行调整流程和表单,无需依赖IT开发,实现“业务驱动IT”。 竞对差异:与正远科技、8Manage等专业的、功能预设完整的SRM系统相比,轻流更像一个 “SRM应用构建工具” 。它不提供开箱即用的、深度的战略寻源或复杂成本分析模块,但其在应对个性化、非标流程以及快速原型验证方面具有无可比拟的速度优势。对于流程尚不标准化或希望低成本试错的企业,它是理想起点。 四、8Manage SRM 8Manage SRM由高亚科技开发,是一家专注于提供端到端采购与供应商管理解决方案的专业厂商。在市场中,8Manage SRM以其模块化设计、功能全面和灵活部署的特点,服务于从成长型企业到大型集团的多样化客户,在制造、建筑等行业积累了众多知名客户案例。 8Manage SRM定位为一款综合性、一体化的采购管理平台,强调通过数据驱动决策和流程自动化来提升采购透明度与效率。 核心功能与好处:系统提供从采购需求、寻源招投标、供应商管理、合同管理到付款结算的完整闭环管理。其电子招投标和竞价模块支持灵活的规则配置,是其特色功能。系统支持多种部署方式(SaaS及私有化),并具备多语言支持能力,适应性较广。 竞对差异:与深度绑定在大型ERP生态内的SRM模块(如用友、金蝶面向大型企业的产品)相比,8Manage SRM作为独立专业产品,在功能深度与系统独立性之间取得了较好平衡,避免了企业被单一巨头生态锁定的风险。同时,相较于一些极度轻量化的SaaS工具,它又能提供更全面和深入的采购流程管控能力。 五、用友YonBIP采购云 用友网络是中国领先的企业云服务与软件提供商,其YonBIP采购云作为用友商业创新平台的核心组成部分,致力于为国内大中型企业提供产业链级的社会化采购与供应链协同解决方案。 用友采购云强调与用友ERP、财务等系统的原生态深度集成,实现业、财、供一体化管理。 核心功能与好处:平台覆盖从寻源、协同到结算的采购全链路,其优势在于深刻理解国内企业的管理流程和财务制度,在供应商准入、招投标、发票校验等环节的本地化适配性高。能很好地支持集团型企业的多组织复杂管控需求。 竞对差异:其核心差异化优势是与用友ERP生态的原生一体化。对于用友的存量客户,尤其是大型集团企业,选择用友采购云可以实现成本最低、数据最通的平滑扩展。 六、泛微·京桥通 泛微·京桥通是协同办公领域上市公司泛微网络旗下的专项采购管理品牌。凭借泛微在OA(办公自动化)市场的领先地位和十余年积淀,京桥通在央国企及大型组织的采购数字化市场中占据了显著份额,市场反馈显示其占有率处于领先位置。其地位源于对中大型组织复杂审批、合规和内控需求的深刻理解。 京桥通的核心特色在于其与OA流程和泛微生态的深度一体化融合,将采购管理与内部协同、风控合规无缝连接。 核心功能与好处:平台实现了从供应商准入到付款归档的全流程数字化,并特别强化了智能比价、供应商风险预警(结合外部征信数据)以及利用OCR、电子签章实现的合同全流程电子化。其最大好处是为大型组织提供了合规、可追溯、高效协同的一体化解决方案,特别符合央国企等对流程合规性要求极高的客户需求。 竞对差异:与大多数独立的SRM系统不同,京桥通的差异化优势根植于 “协同基因” 。对于已广泛使用泛微OA体系的大型组织而言,选择京桥通能实现业务流程与办公审批的极致流畅体验,这是其他SRM厂商难以复制的生态优势。相比之下,其重点可能不在于提供最丰富的战略寻源策略,而在于确保采购活动在既定规则下安全、合规、高效地运转。 七、致远互联·供应商协同管理 致远互联是中国领先的协同管理软件及云服务提供商,其核心产品为AI-COP智能协同运营平台。该公司长期服务于政务及大中型企业市场,在协同办公、流程管理及数字化运营领域占据重要地位。其供应商协同管理方案并非独立单品,而是基于统一协同平台构建的专项场景应用,这使其在满足组织内部流程与外部协作一体化方面具备先天架构优势。 该方案的核心特色在于 “基于统一协同平台的业管一体化融合” ,旨在打通内部管理流程与外部供应商协作的壁垒。 核心功能与好处:方案覆盖供应商全生命周期管理、寻源采购、订单协同、财务对账等核心环节。其最大好处在于能够将SRM流程与内部的预算控制、合同审批、付款申请等环节在同一个平台上无缝衔接,实现数据不落地流转。例如,采购申请可直接触发预算校验,中标结果可自动生成合同审批流,有效解决了跨系统数据孤岛问题,提升了端到端的流程效率与管控力度。 竞对差异:与SAP Ariba或Coupa等独立的、侧重外部网络化的SRM平台相比,致远互联的方案更侧重于组织内部复杂管理流程与外部供应商协同的深度集成。与同为协同厂商的泛微·京桥通相比,两者思路类似,均强调“协同+管理”,但具体的平台技术架构、流程引擎能力及行业化方案侧重有所不同,共同构成了国内“协同生态型”SRM的典型路径。 总结与选型建议 通过以上分析可以看出,所谓“排行榜”上的领先者,实则是各自赛道的专家。对SRM系统的选择不应基于一个笼统的名次,而应始于一次清晰的自我审视: 明确定位与核心诉求:首先问自己,企业是大型集团/跨国企业、快速成长的中型企业,还是预算有限的初创/小微型企业?核心诉求是满足全球合规与复杂集成、优化深度制造协同、实现业财供一体化,还是仅仅快速解决供应商在线协同的燃眉之急? 识别关键差异化能力:接着,将您的核心诉求与厂商的差异化能力对齐。若追求业务的高度灵活与深度定制,正远科技的“双轮驱动”架构值得探究;若青睐AI深度赋能与全场景智能,可重点考察鲸采云;若急需低成本、快上线的轻量化工具,金蝶AI星辰是典型代表;若需要独立且全面的端到端管理,8Manage SRM是可靠选项;若处于强合规、重流程的泛微OA生态内,京桥通则是自然延伸。 超越榜单的实践验证:最后,请记住榜单仅是信息入口。建议基于以上分析,筛选出2-3家最契合的供应商,推动一场深入的 “概念验证(PoC)” 。围绕企业最核心、最复杂的1-2个采购场景进行实际搭建与测试,亲身感受系统的灵活性、易用性以及供应商的响应速度与服务深度。唯有通过实践验证的方案,才是对企业而言真正的“榜首”之选。






大家好,我是拖更博主r0leG3n7。本文将简单介绍frp这款隧道代理工具的项目结构和代码运行流程以及如何通过对frp二次开发(后面简称"二开")来消除其静态特征和流量特征从而规避杀软以及EDR的检测。如有任何错误和不足欢迎各位师傅指正,转载请注明文章出处。
致敬伟大的原项目:https://github.com/fatedier/frp,我选择的是较新版本0.65.0的frp。(我写这篇文章的时候frp刚刚更新到0.66.0,但应该不影响我当时二开的就是最新版的frp[狗头])。
先问大家一个问题,如果我需要对某个开源项目进行二开,我有必要把这个开源项目里所有的代码结构都分析得明明白白的嘛?那当然是没那个必要,对于这种大型的开源项目,我们需要很明确自己想要把这个项目改成什么样子,确定自己的需求,确定项目有哪些对于你来说是"缺陷"的地方,这样就不会在庞大的代码海洋里迷失自己。
1、首先来到我们软件生命周期最重要的需求分析阶段,我的大致的需求就是要改frp的静态特征和流量特征来绕过EDR检测达到免杀的效果,确定大致的需求以后我需要知道frp有哪些特征。
原版的frp有如下几个典型特征:
1)frp的服务端和客户端启动时都会默认读取同目录名为frpc.ini或者frps.ini的配置文件。
2)frp的客户端与服务端发起TCP连接时会发送诸如版本号、架构、token、run id等信息进行登录认证。
3)frp的客户端与服务端在连接成功或者失败时都会在控制台输出一些debug信息或者提示信息。
4)frp的客户端与服务端在TCP连接建立后的第一个应用层数据包会发送一个自定义的字节,这个字节的值为0x17。
5)frp的客户端与服务端在TCP连接建立成功后,服务端可以通过对某些API接口发起get请求、post请求或者put请求去控制客户端,比如/api/reload、/api/stop等。
2、确定大致的需求并且定位"缺陷"以后,我要明确我的需求,明确我要把它改成什么样子。
我明确的需求:
1)对于frp的服务端和客户端在本地读取配置文件的行为,我可以把配置文件信息想象成shellcode,按照loader加载shellcode那样处理。我想到的是将配置文件硬编码在程序里面;或者将配置文件加密后通过命令行传入frp,frp客户端与服务端尝试建立连接时再进行解密;或者通过远程URL加载;还有最重要的是去除通过文件路径读取配置文件的功能。
2)对于frp的服务端和客户端建立连接失败时的输出的错误信息,我要进行删除或者修改;对于建立连接成功时发送的登录信息或者代理信息,我要进行TLS加密或者将默认变量名、键值对修改;对于TLS建立连接的默认自定义字节以及服务端控制客户端的api默认接口名也是一样地做修改处理。
1、程序所需的依赖写在了项目的go.mod文件中,在GoLand的IDEA可以按"Alt键+回车键"自动下载对应的依赖。

2、项目的Makefile是编译命令文件,在这里可以找到服务端代码入口/cmd/frps以及客户端的代码入口/cmd/frpc。

3、我们可以直接定位到客户端/cmd/frpc/mian.go,编译时会自动搜索该目录下的mian.go文件作为编译的入口,重点关注sub.Execute()。

4、按alt跟进sub.Execute(),它的主要功能是rootCmd.Execute()这行 。

5、按alt跟进rootCmd.Execute(),rootCmd.Execute()会执行rootCmd中的RunE,RunE中包含两个关键的函数runMultipleClients()和runClient(),这两个函数主要的功能就是加载配置文件然后建立与服务端的链接。我们主要看runClient()函数,一般情况下一个frpc客户端只加载一个配置文件,所以不用怎么去考虑改runMultipleClients(),我二开的时候索性直接删掉了命令行配置文件路径的输入。runClient()传入一个名为cfgFile的全局变量,它是frp客户加载配置文件的路径。

6、纵观整个rootCmd.Execute()过程,我们都没有看到给cfgFile全局变量赋值的地方。但是我们知道原版的frpc客户端是从命令行输入配置文件路径的,我们可以从包的init()函数看到程序是怎么从命令行中获取用户输入的配置文件路径赋值cfgFile变量的。init()函数是 Go 语言中的一个特殊函数,通常用于资源、包和变量的初始化。它的特点是每个包的 init() 在程序运行期间只执行一次;init()无需手动调用,会在main()之前自动执行,导入包的 init() 先于当前包的 init() 执行。

7、回到rootCmd.Execute(),按alt跟进runClient()函数,我们来到了这次二开中最重要的函数config.LoadClientConfig(),它是我们修改配置文件传参关键。从返回值我们可以知道,它会返回配置文件的基本配置信息、代理配置信息、配置文件格式等。config.LoadClientConfig()的传入参数是配置文件路径,这个函数是需要完全改写的,我上面的需求已经说的很明确了,我会从硬编码、远程URL输入或者命令行输入去读取配置文件,不会有从文件路径读取配置文件的行为,减少文件落地。

8、虽然说要完全改写config.LoadClientConfig(),但是我们还是要按alt跟进看一下它的内部逻辑以便我们更精确无误地对它进行修改,config.LoadClientConfig()存在读取并转换配置文件的legacy.ParseClientConfig()方法。

9、按alt跟进legacy.ParseClientConfig(),legacy.ParseClientConfig()函数通过文件读取函数GetRenderedConfFromFile()以及传入的文件路径来读取配置文件信息并将其赋值content变量,然后将content的类型转化为字节数组后将其作为参数传给UnmarshalClientConfFromIni()方法,UnmarshalClientConfFromIni()将转换后的基础配置文件信息赋值给cfg。

10、同样地,legacy.ParseClientConfig()通过legacy.LoadAllProxyConfsFromIni(),将转换后的代理配置文件信息等赋值给变量proxyCfgs和visitorCfgs。这时候我们知道配置文件信息主要是靠UnmarshalClientConfFromIni()和LoadAllProxyConfsFromIni()两个函数进行转换的,到时候我们二开的时候就照着这两个函数简单修改一下就行了。

11、了解完它是怎么读取并转化配置文件信息后,我们再回到上面的runClient()函数,再大致了解一下它是怎么通过startService方法以及转化后的配置文件信息启动服务的,这里注意startService方法第五个参数cfgFile为配置文件路径,到时候服务端调用/api/reload接口重新加载配置文件时候会用到。因为我二开时将通过文件路径读取配置文件信息这个行为删除了,这个参数到时候会变成空值,这个参数置空以后服务端调用该接口可能会报错。


12、service.go的NewService创建服务对象方法。

13、service.go的Run运行服务对象方法。

本节我将介绍如何对frp原项目进行二开改造隐藏其静态特征和流量特征,包括修改传参方式,修改frp默认输出,修改frp静态字符串,修改frp的TLS流量特征等。相信看过四大名著《三国演义》的都知道赵云在长坂坡七进七出,单骑救主的故事,我第一次了解到这个故事的时候我就觉得不可思议,真的有人能从这么多的魏军人马中带着个婴儿死里逃生吗?在二开了frp之后,我就悟到了。frp客户端就是赵云,配置文件就是阿斗,单骑救主护送阿斗回蜀就是frp客户端与服务端建立连接的通信过程。赵云之所以会被在茫茫人海中被魏军检测到,并不只是因为他喊了那句"我乃常山赵子龙",更多的是因为他有对阿斗进行明目张胆地"取餐"这个行为,不过好在他能及时调整,将阿斗硬编码到自己的怀里,才做到了七进七出。我觉得单骑救主这个故事可以有更多opsec的改进方案让他变得更加合理更加地叫人信服,至于怎么改,请看下面听我娓娓道来。
传参方式的修改在上面需求的第一条已经提出来了,我的最终方案是去除通过文件路径读取配置文件的部分;如果frp收到命令行传入的加密配置文件,就解密该配置文件进行连接;如果读取不到命令行传入的加密配置文件,就读取硬编码的配置文件进行连接。
1、首先去除init()函数中接收对配置文件路径的输入,新增一个全局变量eStr,用于接收用户控制台输入的加密后的配置文件信息,使用示例"-e <加密的配置文件信息>"。
rootCmd.PersistentFlags().StringVarP()方法参数说明:
第一个参数为接收控制台输入的指针
第二个参数为参数名称
第三个参数为传入参数的简写,比如"-c ./frpc.ini"
第四个参数为参数的默认值(StringVarP就必须为字符串类型,BoolVarP就必须为布尔类型,以此类推)
第五个参数为参数介绍说明

2、修改rootCmd.Execute()逻辑,当eStr变量不为空(也就说收到来自用户在命令行输入的加密配置文件内容),就对传入的加密配置文件内容进行解密,将它解密后的明文传给一个自定义的cfgContent变量;如果eStr变量为空,就将硬编码的配置文件信息传给cfgContent变量。cfgContent变量最终会作为参数传给修改后的runClient()函数。

3、修改runClient()函数运行逻辑,之前runClient传入第一个参数是配置文件路径,我现在将这个参数改成配置文件内容,到时候硬编码的配置文件或者解密后的配置文件可以直接作为参数调用这个函数,修改的地方主要是config.LoadClientConfig()这个部分,将其修改为了一个新的函数config.LoadClientConfigFromContent(),用于接收传入的配置文件内容并将其转换。

4、config.LoadClientConfigFromContent()第一个传入参数为配置文件内容的字符串,返回值与之前一致。
func LoadClientConfigFromContent(content string, strict bool) (
*v1.ClientCommonConfig,
[]v1.ProxyConfigurer,
[]v1.VisitorConfigurer,
bool, error,
) {
var (
cliCfg *v1.ClientCommonConfig
proxyCfgs = make([]v1.ProxyConfigurer, 0)
visitorCfgs = make([]v1.VisitorConfigurer, 0)
isLegacyFormat bool
)
contentBytes := []byte(content)
// Render template with values
renderedContent, err := RenderWithTemplate(contentBytes, GetValues())
if err != nil {
return nil, nil, nil, false, fmt.Errorf("render template error: %v", err)
}
if DetectLegacyINIFormat(renderedContent) {
// Parse legacy INI format
legacyCommon, err := legacy.UnmarshalClientConfFromIni(renderedContent)
if err != nil {
return nil, nil, nil, true, err
}
// Parse all proxy and visitor configs from the same content
legacyProxyCfgs, legacyVisitorCfgs, err := legacy.LoadAllProxyConfsFromIni(legacyCommon.User, renderedContent, legacyCommon.Start)
if err != nil {
return nil, nil, nil, true, err
}
cliCfg = legacy.Convert_ClientCommonConf_To_v1(&legacyCommon)
for _, c := range legacyProxyCfgs {
proxyCfgs = append(proxyCfgs, legacy.Convert_ProxyConf_To_v1(c))
}
for _, c := range legacyVisitorCfgs {
visitorCfgs = append(visitorCfgs, legacy.Convert_VisitorConf_To_v1(c))
}
isLegacyFormat = true
} else {
allCfg := v1.ClientConfig{}
if err := LoadConfigure(renderedContent, &allCfg, strict); err != nil {
return nil, nil, nil, false, err
}
cliCfg = &allCfg.ClientCommonConfig
for _, c := range allCfg.Proxies {
proxyCfgs = append(proxyCfgs, c.ProxyConfigurer)
}
for _, c := range allCfg.Visitors {
visitorCfgs = append(visitorCfgs, c.VisitorConfigurer)
}
}
if len(cliCfg.Start) > 0 {
startSet := sets.New(cliCfg.Start...)
proxyCfgs = lo.Filter(proxyCfgs, func(c v1.ProxyConfigurer, _ int) bool {
return startSet.Has(c.GetBaseConfig().Name)
})
visitorCfgs = lo.Filter(visitorCfgs, func(c v1.VisitorConfigurer, _ int) bool {
return startSet.Has(c.GetBaseConfig().Name)
})
}
proxyCfgs = lo.Filter(proxyCfgs, func(c v1.ProxyConfigurer, _ int) bool {
enabled := c.GetBaseConfig().Enabled
return enabled == nil || *enabled
})
visitorCfgs = lo.Filter(visitorCfgs, func(c v1.VisitorConfigurer, _ int) bool {
enabled := c.GetBaseConfig().Enabled
return enabled == nil || *enabled
})
if cliCfg != nil {
if err := cliCfg.Complete(); err != nil {
return nil, nil, nil, isLegacyFormat, err
}
}
for _, c := range proxyCfgs {
c.Complete(cliCfg.User)
}
for _, c := range visitorCfgs {
c.Complete(cliCfg)
}
return cliCfg, proxyCfgs, visitorCfgs, isLegacyFormat, nil
}
5、将config.LoadClientConfigFromContent()返回的cfg, proxyCfgs, visitorCfgs作为参数传给startService(),传参方式这部分就修改完成了。注意startService()的第五个参数为配置文件路径,我修改frp的传参方式以后这个配置文件路径的值就不存在了,所以我把它的值置空了,这个参数在后面调用/api/reload重新加载配置文件时候会用到,如果仍需要调用这个api建议将其修改为一个系统默认路径,不然调用时可能会导致frp客户端异常。

6、运行效果就是先用加密程序将frpc配置文件加密后的字节数组以base64编码的字符串输出。

7、frpc客户端启动时如果接收到-e 传入的Base64编码的字符串,frpc客户端就会解密该字符串并转化配置文件;如果接收不到-e 传入的Base64编码的字符串,frpc客户端就会读取代码内硬编码的配置文件。从这里我们也可以看到frp客户端在连接到服务端时会输出一些诸如"client/service.go:331"的信息,这些都是要做处理的。

上面讲frp特征的时候提到frp的客户端与服务端在TCP连接建立后的第一个应用层数据包会发送一个值为0x17的自定义字节,这个是frp在流量层面最显著的特征之一,就好像赵云的武器"龙胆亮银枪"以及坐骑"照夜玉狮子",使得赵云在茫茫魏军人马中被一眼认出。
我们先用wireshark看下frp原味的通信流量,下图是frp的TLS的握手流量,可以从"Client Hello"和"Server Hello"这几个关键字快速定位,点击"Transport Layer Security",我们可以看到这部分的第一个字节是0x16。

再看frp部分的应用流量,点击"Transport Layer Security",我们可以看到这部分的第一个字节是0x17。

再通过搜索0x17和0x16定位到项目中/pkg/util/net/tls.go和/server/server.go,我们看到自定义字节变量FRPTLSHeadByte的值为0x17,以及判断0x16和x017 switch逻辑,似乎就能跟上面wireshark看到的流量特征扯上一些联系?我之前听有些卖frp免杀课的人说修改了这个变量FRPTLSHeadByte(旧版的frp好像是另一个变量名)的值,就能消除上面wireshark看到的frp的0x17流量特征。


事实真的是这样的吗?其实他们只说对了一半,修改变量FRPTLSHeadByte确实能消除frp一部分的流量特征。但无论你怎么改FRPTLSHeadByte的值,如果像上面那样看frp的TLS的握手流量和frp的应用流量,无论你怎么改,看到的还是0x17。因为上面看到的那部分就是TLS的正常流量,TLS记录协议头固定为5字节,第一个字节0x17代表应用数据,如果是0x16代表TLS握手数据;第二第三个字节代表TLS版本;第四第五个字节代表数据长度。

他们错误地把FRP自定义字节理解为TLS记录协议头固定字节的第一个字节,因为FRP自定义字节默认值刚刚好就是0x17,和应用数据的TLS记录协议头第一个字节一样。但实际上FRP自定义字节是客户端与服务端在TCP连接建立后的第一个应用层数据包发送的第一个字节,为了方便大家理解,我把FRP自定义字节从默认值0x17改成了0x18,这个字节会在TLS握手之前发送,可以结合下图去理解。

在wireshark内,我们右键frp的tcp流量,选择"追踪流",再选择"TCPStream"

再选择显示为"Hex转储",我们就能看到frp自定义字节修改前的样子:

frp自定义字节修改后的样子:

但其实仅修改这一个字节还是不够,有部分厂商的流量设备已经能自动识别这类单字节修改后的流量,要想在流量层面隐藏得更好需要修改/pkg/util/net/tls.go的CheckAndEnableTLSServerConnWithTimeout()函数,在TLS握手之前多填充几个自定义字节。

在修改完自定义字节以后,需要frpc配置文件中[common]下面添加这一行,不然客户端连接到服务端会报错。
disable_custom_tls_first_byte = false
因为从frp的0.50.0版本开始,frp就将禁用发送自定义字节的默认值设置为true,如果使用了frp自定义字节就需要加上这一行

最后一定要记得服务端frps的配置文件加上强制TLS连接。
tls_only = True
客户端frpc的配置文件也加上使用TLS加密,不然前面做的一切都白费。
tls_enable = true
这一步主要是防止赵云有事没事就喊一句"我乃常山赵子龙"。其实就是简单改一些frp默认控制台输出,减少被检测识别的概率。
/client/server.go



/client/control.go

/pkg/auth/token.go

/cmd/frpc/sub/root.go

/pkg/msg/msg.go中有frp客户端与服务端通信时的登录信息以及代理信息,在使用了TLS加密以后这个不修改其实也不会有很大影响,但是改了总比没改会好点。


client/service.go和server/service.go存在默认盐值crypto.DefaultSalt,frp身份认证过程不是直接交换密码或者token,而是进行带盐值的hash计算和比较,不修改默认盐值可能存在被爆破的风险。

/cmd/frpc/sub/verify.go
这里也有一个包含校验读取配置文件方法的go文件,它也会有个读取本地文件的行为,这里可以直接删除掉/cmd/frpc/sub/verify.go,对编译和运行没影响,不删除反而在读取不到本地配置文件时会输出一些frp的特征,还能缩小编译后的文件体积。

/pkg/util/version/version.go中存在frp的版本信息

/cmd/frpc/sub/admin.go
1、frp服务端提供了三个api接口控制frp客户端,这三个接口的功能分别是重新加载配置文件、查看代理状态、停止frp客户端运行。

2、重新加载配置文件接口会读取frp首次与客户端连接时输入的配置文件路径。

3、svr.configFilePath的来源于startService()方法传入的第五个参数,这部分要在runClient方法内修改。

/client/admin_api.go

市面上常用的go语言工具混淆有三种,分别是:go-strip、cross-file-obfuscator和garble。附上项目地址:
https://github.com/boy-hack/go-strip
https://github.com/burrowers/garble
https://github.com/masterqiu01/cross-file-obfuscator
大家现在千万别用go-strip去混淆,go-strip前两年生存环境还可以,现在的杀软很容易识别到go-strip,并且只要是go-strip混淆就判定为恶意软件。我现在使用的最多的是garble,它能混淆一些类名以及字符串,并且能较好地压缩文件体积,garble需要go语言1.25.0以上的版本才能使用,下面简单介绍一下Kali怎么安装1.25.0以上的go语言以及garble。
1、下载解压go
wget https://mirrors.aliyun.com/golang/go1.25.4.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.25.4.linux-amd64.tar.gz
nano ~/.zshrc
2、配置环境变量,~/.zshrc末尾追加如下
export GOROOT=/usr/local/go
export GOPATH=$HOME/go # 推荐设置工作目录
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
3、使配置生效
source ~/.zshrc
export GOPROXY=https://goproxy.io
go install mvdan.cc/garble@latest
1、在kali使用garble编译前建议先使用原生的go编译器编译一次,主要是让其下载对应的依赖
go build -o ./frpc.exe ./cmd/frpc
2、然后再用garble编译(在kali上编译需要指定目标架构,我这里编译的是windows的amd64)
export GOOS=windows
export GOARCH=amd64
garble build -o ./frpc-1.exe ./cmd/frpc
3、garble压缩效果,原生的go编译器编译出来的大小为23Mb左右,garble编译出来的为18Mb左右

4、garble的混淆效果如下:
原生的go编译器

garble

5、如果kali不想指定目标架构,也可以使用如下命令跨平台编译
make -f Makefile.cross-compiles
客户端在卡巴斯基和核晶环境下通过frp代理做端口扫描能稳定运行

在没有签名没有做反沙箱状态下上传至VT,只有ESET-NOD32识别出来了是frp客户端

frp在做完传参方式修改、流量改造以及garble混淆后基本就能bypass大部分杀软了。传参方式修改是必须做的,它不仅可以减少文件落地,更是一种针对frp特定的反沙箱操作,某些沙箱提供带有特定文件(比如frpc.ini和frps.ini)的环境来针对性地检测frp。在此基础再加上一些比如延迟执行等反沙箱操作就更好了,如果能把frp做成BOF插件从内存加载那就更opsec了。流量改造方面除了修改frp自定义字符,frp客户端与服务端连接时尽量以域名进行连接,不要直接暴露原生IP,服务端的域名要做cdn防护或者使用云平台PaaS进行转发,然后配置好自定义的TLS证书(最好TLS证书也像配置文件那样内嵌到程序里面,减少文件落地),这样能减少被溯源的概率。静态特征方面,除了garble混淆以外,如果在确定了是目标环境是什么杀软以后,可以考虑使用UPX对frp进行加壳,某些杀软对UPX并不敏感,加壳可以解决百分之90的静态特征问题,但是加壳以后UPX也成为了它的静态特征,不过UPX的静态特征也是可以处理的,其他静态特征处理可以翻看我公众号之前的文章,此处就不再赘述了。除了以上这些二开的点,我们还可以把frp做成系统服务进行权限维持、添加ICMP隧道类型等。
frp的优点就是稳定,但是缺点也很明显,当你需要搭建二级代理或者三级代理的时候,你就不得不把frp二级或三级代理的服务端也上传上去,这意味着你要上传很多个客户端以及服务端,而且对他们都要做免杀处理。隧道代理工具我目前用的比较多的除了frp还有Stowaway,项目地址:https://github.com/ph4ntonn/Stowaway,它也是一个很值得去二开的一个项目,Stowaway的优点是它既能做客户端也能做服务端,往往搭建二级代理或者三级代理上传一个可执行程序就足够了。
给你⼀根⻓度为 n 的绳⼦,请把绳⼦剪成整数⻓的 m 段( m 、 n 都是整数, n > 1 并且 m > 由于答案过⼤,请对 998244353 取模。 自底向上计算最优解 在上面版本上优化状态转移方程,提高代码效率,直接比较 dp[i] = max(max(j × (i-j), j × dp[i-j])) 其中 1 ≤ j < i 我们仔细观察就会发现:要想乘积⽐较⼤,在没有1的前提下,优先使⽤3,如果出现1,那么优先使⽤2 ⽐如: 结果很不幸:运⾏超时:您的程序未能在规定时间内运⾏结束,请检查是否循环有错或算法复杂度过⼤。 于是我们需要想到其他的⽅式,如何快速计算 3 的 n 次⽅,这是我们需要解决的问题,因为在尽量凑 3的前提下,有以下三种情况: 也就是说,当n≥5时,优先剪出长度为3的段;剩余4时剪成2×2 为什么选择3? 执行过程示例(n=10): 在计算幂次⽅的时候,为了避免溢出,在每次相乘的时候,都需要除以998244353 ,为了计算快,每次以⾃身相乘的⽅式计算,代码如下:题⽬描述
1 , m <= n ),每段绳⼦的⻓度记为 k[1] ,..., k[m] 。请问 k[1] k[2] ... * k[m] 可能的最⼤乘积是多少?例如,当绳⼦的⻓度是 8 时,我们把它剪成⻓度分别为 2 、3 、3 的三段,此时得到的最⼤乘积是 18 。思路解答
动态规划
public class Solution {
private static final int MOD = 998244353;
public int cutRope(int n) {
if (n < 2) return 0;
if (n == 2) return 1;
if (n == 3) return 2;
// dp[i]表示长度为i的绳子剪裁后的最大乘积
long[] dp = new long[n + 1];
// 基础情况:这些值不是乘积,而是长度本身(因为可以不剪)
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
// 从长度为4开始计算
for (int i = 4; i <= n; i++) {
long max = 0;
// 遍历所有可能的分割点,j <= i/2 避免重复计算
for (int j = 1; j <= i / 2; j++) {
// 比较各种分割方案的乘积
long product = dp[j] * dp[i - j];
if (product > max) {
max = product;
}
}
dp[i] = max % MOD;
}
return (int) dp[n];
}
}优化动态规划
j*(i-j)和j*dp[i-j]的最大值public class Solution {
private static final int MOD = 998244353;
public int cutRope(int n) {
if (n < 2) return 0;
if (n == 2) return 1;
if (n == 3) return 2;
long[] dp = new long[n + 1];
dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j < i; j++) {
// 三种情况取最大值:不剪、剪一刀、剪多刀
long temp = Math.max(j * (i - j), j * dp[i - j]);
dp[i] = Math.max(dp[i], temp);
}
dp[i] %= MOD;
}
return (int) dp[n];
}
}贪心算法(最优解)
2 = 1 + 1
3 = 1 + 2
4 = 2 + 2
5 = 2 + 3
6 = 3 + 3
7 = 3 + 2 + 2
8 = 3 + 3 + 2
9 = 3 + 3 + 3
10 = 3 + 3 + 2 + 2
11 = 3 + 3 + 3 + 2
12 = 3 + 3 + 3 + 3public class Solution {
public long cutRope(long number) {
if (number == 2) return 1;
if (number == 3) return 2;
long res = 1;
while (number > 4) {
res *= 3;
res = res % 998244353;
number -= 3;
}
return res * number % 998244353;
}
}10 ÷ 3 = 3段...剩余1
调整:2段3 → 剩余4 → 剪成2×2
结果:3² × 2² = 9 × 4 = 36public class Solution {
private static final int MOD = 998244353;
public int cutRope(int n) {
// 特殊情况处理
if (n <= 3) return n - 1;
// 计算可以剪出多少段长度为3的绳子
int countOf3 = n / 3;
// 处理剩余部分:当剩余长度为1时,调整策略
if (n - countOf3 * 3 == 1) {
countOf3--; // 减少一段3,与剩余的1组成4
}
// 计算剩余部分能剪出多少段长度为2的绳子
int countOf2 = (n - countOf3 * 3) / 2;
// 计算结果:3的countOf3次方 × 2的countOf2次方
long result = pow(3, countOf3) * pow(2, countOf2);
return (int) (result % MOD);
}
/**
* 快速幂算法计算a的b次方取模
*/
private long pow(long a, long b) {
long result = 1;
while (b > 0) {
if ((b & 1) == 1) {
result = (result * a) % MOD;
}
a = (a * a) % MOD;
b >>= 1;
}
return result;
}
}
最近在官网充值了一些 Kimi 2.5 的 API ,感觉很好用,想订阅下会员,Kimi 对会员权益说明很模糊。之前按次数,被喷后,改成按额度,但是多少额度也不说清楚?

只宣传限时扩容三倍。。。还有就是 Kimi Code 和 Kimi 会员有什么区别?
Kimi Code 显示 [购买以上任意套餐,还会获得其他 Kimi 会员权益]

Kimi 会员界面显示 [ Kimi Code 2 倍额度]

感情是在这打哑谜是吧,什么档次会员多少 token 是什么不能说的秘密吗? Kimi Code 送 Kimi 会员,Kimi 会员送 Kimi Code 在这套娃呢? Kimi Code 宣传限时扩容三倍,Kimi 会员宣传 Kimi Code 2 倍额度,真太乱了...
因自己有广告拦截和安全的需求自己建了 doh ,都是自己的服务器和可靠上游(国外是 controld+cf+google ,国内用的是阿里和腾讯的 doh),自建的都没有限速(部分 doh 有 qps 限速)。
自己手机是安卓系统,设置里面只有 dot 选项,没有 doh ,这就让我头疼了,于是让 codex 开发了这个 app ,已经经过测试,没有什么大问题。
当然也可以自定义其他的 doh (这是功能之一)
自建的 doh 国内的是上海的机(带宽很小),国外是 ovh ,当然也可能会增加更多机器(未来),还有一个 cf 反代的。
国内可直连 https://rvv.amd.pub/ix
套 cf cdn 的是 https://int.amd.pub/ix
位于上海的国内 doh: https://amd.pub/ix
app 可通过下面方式下载
https://rvv.amd.pub/mica.apk
https://drive.google.com/file/d/1sEWKBsVhRDxkA-osAUXML0IPeKZaQbd0/view?usp=sharing
app 截图: https://rvv.amd.pub/umr/Screenshot_20260203_063742.jpg
欢迎大家使用,有不足之处请多包涵!
吾身 (Diarum) - 取自"吾日三省吾身",一款零负担、快记录、怡复盘的日记应用,记录独一无二的人生。
零负担,软件使用非常简单,登陆后打开首页即跳转到今日日记。快记录,打开立刻开始记录,自动保存。怡复盘,可以愉快的完成复盘、总结分析。轻松实现现代化 AI 加持的“吾日三省吾身”。
配置 AI Key 之后自动触发日记向量化,后续可以跟 AI LLM 结合日记开展对话 。自然快速地完成:
基于 PocketBase 和现代 Web 技术构建,简洁、优雅、可自托管。
开发这款软件的初衷源自自己对日记的需求。现在市面上已经有很多优秀的日记和笔记软件。但都多少有点无法满足自己的需求。我期望的一个日记软件,是打开后立刻可以开始记录,不需要纠结文件名、标题、目录结构。最好是网页的,这样在各种设备都可以使用。我自己的设备涉及 MacBook 、HarmonyOS NEXT 、Android 、Arch Linux 、Windows 。只有网页应用能够很好的快速兼容这些平台。最好是可以很方便的自托管的,确保我自己对数据的掌控,且方便搬家。
于是就做了这样一款软件,英文名叫 Diarum ,中文名叫 “吾身”。使用 go+svelte 开发,轻快好用。花费了大量心思打磨移动端和桌面端的日记体验。现在我个人感觉使用体验已经比较丝滑,可以愉快的记录一天的各种事情。
在核心功能的基础上,集成了一个简单的 RAG 系统,配置好 AI KEY 和 MODEL 之后,会自动触发向量数据库的构建。这样一来跟内置的 AI 助手对话时,就可以将向量匹配到的日记放入上下文,方便的进行分析总结等。此外还提供了一个简单的 API 系统,可以方便的将日记数据对接到 n8n 这样的平台,实现自动化的周报、月报生成等灵活的工作流。
软件我自己已经使用了一段时间,感觉不错,记日记几乎是零心智负担。想到什么打开就可以立刻开始记录。迭代了几个版本,现在功能基本稳定可用了。分享出来,希望听听大家的看法。
软件已经开源,欢迎提 issue 和 PR 。提供一个 demo ,可以快速注册体验,期待大家使用。
事情要从一个本来很简单的念头说起。
我想做一个行情类应用。
目标朴素得不能再朴素了:
用户自己配个 API Key ,
就能看 A 股 / 港股 / 美股 / 汇率 / 指数 / 加密货币 的实时行情和历史曲线。
于是我开干了。
应用很快写完了,逻辑清晰,代码优雅,README 看起来还行。
https://www.v2ex.com/t/1187033
设计初衷也非常“程序员式正义”:
听起来是不是特别合理?
我当时也觉得自己是个天才。
应用一交到用户手里,问题就来了:
总结一句话:为了用我的 App ,用户得先修完一门《全球金融数据 API 导论》。
本来是看行情,
结果变成了 配置行情。
功能是有的,
但体验极其反人类。
我终于意识到一个残酷的事实:
用户根本不想折腾。
问题的本质其实很简单:
既然如此,那干脆一步到位。
我干了件看起来有点“本末倒置”的事:
我去改了一个开源库
项目名叫 Aktools,原本就很强,
但我对它下手更狠了一点,加缓存,加数据源:
https://github.com/johnny-peters/aktools-change
我改造后的 Aktools ,目标只有一个:
用户什么都不用配置
只需要:
docker run / deploy aktools
然后就能直接用。
你能拿到什么?
没有 API Key
没有平台选择
没有额度焦虑
没有配置地狱
一句话:
Aktools 部署完,数据就自己长出来了。
回头看这件事,特别有意思:
真正实现了:
“为了这碟醋,我包了顿饺子,
结果发现饺子比醋香多了。”
如果你是:
那你直接访问 https://price.btc-reborn.com/ ,可以订阅行情,配置持仓;
也可以在项目地址 https://github.com/johnny-peters/financial-dashboard 下载 exe,拥有一个无广告绿色的可开机启动的控件(仿 mac 做的)
如果你是:
那你可以直接从这里开始:
🔗 Aktools (改良版):
https://github.com/johnny-peters/aktools-change
技术人常犯的错是:
把“可配置性”当成“用户友好”。
但后来我才想明白:
真正好的体验,
是让用户连“配置”这个概念都不需要知道。
这当然不会是奥数题

插件成功上架谷歌插件商店了,之前分享过一次,但是上次使用比较麻烦,现在可以直接从谷歌插件商店安装
CloseTab 是一款强大的浏览器标签页管理插件,帮助你轻松管理大量标签页,提升浏览器性能和工作效率。支持一键保存、恢复、搜索和批量管理标签组。
Chrome / Edge 浏览器
直接访问 Chrome 应用商店 点击"添加至 Chrome"即可一键安装。
适用于想要体验最新功能或进行二次开发的用户。
下载地址: Gitee 仓库
chrome://extensions/edge://extensions/保存标签组
恢复标签组
管理标签组
如果一个系统存在路径穿越漏洞,外部可能读取到正在使用的 swapfile 。
测试发现,虽然是概率性的,但 swapfile 中确实可能存在账号和应用的明文密码。似乎与近期是否有成功登录的行为有关。
进一步推论,如果攻击者采用一些手段推高内存占用,可能会导致更多信息外溢到 swapfile 从而被截获。
去年国庆左右在 88code 购买了半年的会员,当时 298 每天可以用 140 刀很划算,后面双 12 又搞活动,我又囤了好久,结果今年年初,因为 A 社加大封号力度,结果现在导致他们成本覆盖不了,结果一直停到今天,之前还以为可以恢复,结果一个月了都没消息。
本来之前去申请退款的,客服说我的套餐很划算,就没退,结果上周再去退,说一周退,到现在都没退会回来,问客服就是耐心等,然后据说客服工资都发不出来了,请问要咋维权呢
由于是使用机场自己的客户端,没有 tun 模式,网上搜了一下可以使用 Proxifier 解决 Antigravity 的登录问题,正好之前用 OBS 直播油管的时候安装过 Proxifier ,于是直接设置了一个规则,顺利登录 Antigravity 。
但是马上遇到一个棘手的问题,agent 加载不出来,也就是对话框和模型都加载不出来,我以为是跟 cursor 一样需要在设置里面配置 proxy ,结果设置了也不行,重启几次 IDE 都是加载不出来。
搜了一下公众号文章,都讲的不清不楚,Proxifier 规则里面要增加好几个 exe ,不止是 antigravity.exe ,直接复制别人公众号文章里面提供的文件名,行不通,于是在任务管理器里面,把 Antigravity 相关的所有 exe 都找到所在文件夹,通过手动添加进去,就搞定了。
需要添加的几个 exe 的文件夹路径(其中 XXX 需要换成你的用户名):
C:\Users\xxx\AppData\Local\Programs\Antigravity
C:\Users\xxx\AppData\Local\Programs\Antigravity\resources\app\extensions\antigravity
我添加进规则的几个 EXE:antigravity.exe; inno_updater.exe; language_server_windows_x64.exe; fd.exe
记得要通过 browser 这个按钮添加才有效。
附赠 Proxifier 注册码 5EZ8G-C3WL5-B56YG-SCXM9-6QZAP
rt ,好奇为什么
我的二个普通 vps 都丢包 50%以上,但有中国优化的 DMIT 没事。
试了下 Vultr 的几个测试 ip 如 https://lax-ca-us-ping.vultr.com/, 也是丢 50%以上。
用普通的机子 fq 简直没法用了。
最新频繁看到神吹联想笔记本的相关推送,B 站也有多名 UP 主在推。
联想小新 Pro 16 GT AI 元启版,续航超 27 小时,真实办公使用 20 小时。。。
之前是联想 ThinkPad E14 AI 元启版续航 26 小时。。。
这些拿钱的营销号,完全不说实话。大家理智选择,不要被带偏。
今天给大家分享一下,我们星球开发的底层操作系统内核项目的面经,看看大家对于此项目是否感兴趣,如果感兴趣,可以加入星球进行学习。 关于此项目的介绍,可以看下面链接的文章内容: https://mp.weixin.qq.com/s/jWvq9YAF52Mm57TmhT3qow 1.性能监控项目,解析/proc文件下meminfo去获取内存的一些使用情况,说说这里面有哪些资源的一些使用参数 2.仅仅是做了一个性能的采集吗,有没有参与一些性能的优化,比如内存优化呀? 1.有没有通过一些渠道去考虑或者了解,比如像cpu负载过高,内存可用比较少,这些情况我该怎么去优化? 2.linux监控项目,说说使用ebpf进行网络流量统计的流程,ebpf在网络协议栈里面如何工作 3.性能监控项目,读取到了哪些内存指标,读取到之后如何去做一个分析(定位内存问题) 4.cpu负载如何去做一个分析,怎么判断具体系统是哪里的问题 5.cpu具体各个指标怎么去做一个分析 6.采集的优化是怎么做的,降至毫秒级的操作 7.stress、iperf工具怎么使用的,平时还有用其他的一些验证工具吗 8.性能采集这块有涉及哪些模块,包括涉及哪些代码逻辑,整体偏向技术的summary的东西讲讲 9.性能采集这块有涉及哪些模块,包括涉及哪些代码逻辑,整体偏向技术的summary的东西讲讲 10.性能监控用到了grpc、protobuf,你讲一下grpc它的一个底层原理 11.看你有做这个网络流量统计,你对协议栈这块了解吗?比如内核协议栈或者其他的一些协议栈 12.linux系统监控的话,网络流量统计用的ebpf,你简单介绍一下这个ebpf它是如何实现一个网络流量统计的一个功能的 13.你用ebpf的这个它走的是内核协议栈吗还是什么 14.对于linux分布式性能监控这个项目,在我不熟悉这个系统的情况下,你给我介绍一下这个系统,可以用各种不同的维度或者方法来给我介绍一下 15.对于这个性能监控项目,你觉得从技术上来讲,这个系统最关键的几个点是什么 16.在这个性能监控系统里面,再稳定性方面,你是怎么涉及或考虑的? 17.内核模块用什么代码编写的? 18.本来可以用proc方式获取数据,为什么要用内核模块? 本文由mdnice多平台发布前言
面经分享
(说了各种采集方式的调研与选择和优缺点,迭代,做的采集方式的优化)
飞牛这事给所有人上了一课,你作为用户永远不知道厂家会犯什么错误,即便是你购买的付费服务也有可能成为黑客的工具,那我们有哪些方案可以在厂家之外能保护我们自己呢。
直接把 NAS 暴露在公网我觉得是不合理的,我觉得至少要套一层隧道。
我目前方案是使用 OPENVPN+证书登录,
具体的方案是用了一个虚拟机专门跑 OPENVPN ,然后路由器上端口转发虚拟机,所有的操作都需要 OPENVPN 之后才能进行,并且每隔一段时间对虚拟机进行更新。
但这个方案并不适合小白,一是我有 V4 公网,二是对于小白用户来说用专门的虚拟机并且按照自己的需求去搭一个 OPENVPN 难度不低。
那么有什么可以增加安全性又对于小白用户比较友好的方案呢?