现在每年都不想回家,但是每年都回家,类似的 V 友们是怎么处理的?
这种复杂的情绪,好难排解,大家有什么想法?
觉得只要爸妈还在,就很难真的说出口「今年我不回」。
内心也会有愧疚感,春节的氛围和习俗,就很难彻底做那个「过年不回家的人」。
每年都要和自己谈判拉扯,这种无力感好无奈。
xiaohack博客专注前沿科技动态与实用技术干货分享,涵盖 AI 代理、大模型应用、编程工具、文档解析、SEO 实战、自动化部署等内容,提供开源项目教程、科技资讯日报、工具使用指南,助力开发者、AI 爱好者获取前沿技术与实战经验。
这种复杂的情绪,好难排解,大家有什么想法?
觉得只要爸妈还在,就很难真的说出口「今年我不回」。
内心也会有愧疚感,春节的氛围和习俗,就很难彻底做那个「过年不回家的人」。
每年都要和自己谈判拉扯,这种无力感好无奈。
最近看到飞牛 NAS爆出的漏洞,路径遍历漏洞,NAS 只要放在 WAF 后面其实不会受到漏洞影响的。于是特来分享这篇 WAF 部署教程。
该文适合有一台小主机,性能还可以,有ipv4/6公网地址,并设置了DDNS。或者有公网 ip的用户
相信大家跟我一样有all in one小主机,家里也部署了几套应用(群晖 NAS、飞牛 NAS、emby等),害怕哪天被黑客入侵了,丢失了数据,损失了时间。
本次部署的 WAF 是使用的长亭家的雷池 WAF,官方推荐使用 docker 安装,所以想使用 WAF 先安装 docker,docker 安装教程请自行百度
下面是我家里的网络拓扑,如果有类似或者一样的可以抄作业了。我的all in one的配置是ESXI+OpenWrt+Windows10+Linux,底层使用的ESXI 系统作为虚拟机,大家也可以使用PVE,这个是不影响的,也不是本次的重点,重点是安装docker的那台Linux。
WAF 是 Web Application Firewall 的缩写,也被称为 Web 应用防火墙。区别于传统防火墙,WAF 工作在应用层,对基于 HTTP/HTTPS 协议的 Web 系统有着更好的防护效果,使其免于受到黑客的攻击。
注:WAF 并不能对非 HTTP 协议的流量进行防护哦,例如 SSH、FTP 等
也就是说如果我们的部署了 web 服务就可以使用 WAF 来拦截非法请求,保护我们的系统,WAF 官网地址是
。
Linux 镜像,这里使用的是Debian 系统
爱折腾的你和你的小手
安装 Linux 系统步骤省略,如有不会的可以自行百度即可,配置这块最好是给 2C4G,40G
安装命令,需使用 root 权限安装,这里我的 Linux 的 ip 为10.10.10.164,这台机器只是用户演示怎么安装流程,后续会用我已经使用的机器去配置如何设置 WAF。bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/manager.sh)"

当看到这个的时候雷池就部署好了
访问 https://10.10.10.164:9443 端口进行登录访问
登录后的页面是这样的,后面我就用我现在使用的雷池,用于配置防护
在配置站点防护前,请大家阅读长亭 waf 的配置手册,以下是我的配置流程,如果你们的设置和我一样,可以进行抄作业,如果不一样,请大家结合 配置手册 ,进行配置。
在没有部署 waf 之前我们想要通过公网访问我们内网的应用需要做端口映射(转发),其网络拓扑是这样的

需要在路由器上配置 10.10.10.198 的 5000 端口,进行端口映射(转发),才能访问到我们内网的群晖系统。
注:每个家用路由器配置页面都不一样,请根据自己的路由器型号自行配置,其原理都是一致的。

现在我们给群晖配置 WAF,其工作流程就是先把流量引到 WAF 上检测,然后 WAF 再用 Nginx 将流量转发到群晖上。其网络拓扑如下:

1.了解工作流程后我们来配置 WAF ,首先上传我们的 SSL 证书,不上传证书也可以正常使用,证书上传不是必须。防护站点-证书管理-添加证书

2.添加我们需要防护的站点,比如添加我们的群晖 NAS。防护站点-站点管理-添加站点

上游服务器填写真实群晖 NAS 的访问地址,格式为http://ip+端口或者https://ip+端口
域名填写你的域名即可,这里的端口我们需要记录下来,因为群晖默认端口是 5000,这里我们也使用 5000
如果勾选 SSL 的话,就会出现中间下拉框选中证书,选择你上传后的证书即可。
这样我们就部署好了一个 web 应用的 waf 防护站点。接下来我们还需要设置端口映射(转发)
设置端口转发,在上面我们说了,没有配置 waf 时,我们只需要直接填写 NAS 的地址+ip 就可以直接访问,现在我们部署了 waf,需要更改配置。
只需要更改内网地址为 WAF 的地址即可。其中内部端口要和 WAF 中配置的端口要一致,因为 WAF 上我们配置时使用的是 5000 端口,所以这里我们也是要设置 5000 端口,如果上面设置的是 6000 端口,这里内部端口就要设置为 6000。外部端口可以随便设置,这个端口就是你域名+这个端口,就可以访问到群晖 NAS。
注:每个家用路由器配置页面都不一样,请根据自己的路由器型号自行配置,其原理都是一致的。

现在我们已经配置好了 WAF,我们就去试试有没有效果,在设置之前,我们需要更改一些 WAF 的配置,推荐配置如下,如果不配置的话,WAF 会经常拦截我们正常的应用,导致无法使用。
防护配置-频率设置

访问到这个页面就说明 WAF 已经部署成功,Ps.在部署的时候勾选了 SSL 证书,这里我们也是使用 https 访问的,因为 WAF 的作用类似 Nginx,我们把证书放在 Nginx 上,流量经过 Nginx 就会进行 SSL 证书校验,这样会让我们的 NAS 更加安全。

查看 WAF 面板,可以看到流量请求。

我们测试 WAF 的拦截效果,我们使用 https://xxxxxxx:5000/?id=1 and 1=1 #这个语句进行测试,看到下面这个页面说明 WAF 进行了拦截。

在 WAF 面板上可以看到攻击状态,因为我在内网进行测试,如果所以攻击 ip 显示的是我网关的地址。

这样我们的 WAF 部署就结束了,可以开心的玩耍了,再也不用担心应用被人干了还不知道了。
这个 WAF 也不是那么完美,因为是免费的所以很多功能受限,比如日志功能等,但是他完全可以给我们的应用提供第一道防护,这次的飞牛 NAS 的 0Day 漏洞是完全可以防护的。

在人工智能发展的早期阶段,AI 往往以“创新项目”“试点工程”或“专项研发”的形式存在于企业内部。它通常被视为一种附加能力,用于优化某个局部流程或解决特定问题。 进入 2026 年,这一形态正在系统性消失。 随着算力结构的持续优化、预训练模型泛化能力的显著提升,以及部署与治理体系的标准化成熟,AI 已完成从“技术插件”向“通用基础设施”的转变。它不再以独立项目的方式被单独管理,而是作为系统默认能力,嵌入到业务架构的底层逻辑之中。 这并不意味着 AI 的重要性下降,恰恰相反,这一变化标志着 AI 正式进入生产力稳定释放阶段。 项目制 AI 的典型特征,是围绕单一功能构建模型与数据闭环。每一个应用场景都需要单独立项、单独训练、单独评估,其生命周期往往与具体业务模块高度绑定,难以跨系统复用。 而底座化 AI 的核心特征,在于其先于业务存在。 在这一模式下,大模型或高度集成的智能组件被视为系统的逻辑基座。AI 不再是后期引入的“功能增强”,而是系统启动时即默认具备的认知能力层,向上通过统一接口为各类业务流程提供理解、推理与生成能力。 当智能逻辑成为系统的基础设施组成部分,单独为 AI 设立“创新项目”的必要性自然消失。 传统软件工程以确定性逻辑为核心,系统通过大量 If-Then-Else 规则覆盖业务场景。然而,随着业务复杂度呈指数级增长,这种模式的维护成本与系统脆弱性不断放大。 大模型的引入,改变了系统处理复杂问题的方式。 在新的工程范式中,开发者不再为每一个边缘场景编写规则,而是通过统一的智能中台,将语义理解、意图识别与任务规划交由概率模型处理。AI 成为系统中负责“非结构化判断”的通用引擎。 在这一背景下,行业中逐渐形成一种共识性实践现象,即智能体来了,它标志着智能能力开始以系统属性的方式存在,而非以单点功能的形式被调用。 过去,AI 项目的高成本主要来自重复建设:数据采集、标注、模型训练与部署在不同业务场景中不断被重新执行。 通用大模型的成熟,使这一模式发生根本变化。 通过零样本或少样本方式,企业可以在不重新训练模型的前提下,将智能能力快速适配到不同业务流程中。Prompt 设计、检索增强与工具调用,逐渐取代了定制化模型开发,成为主流交付方式。 当智能能力的调用成本趋近于基础算力消耗,AI 的经济属性开始接近电力或云资源。此时,是否“拥有 AI 项目”不再重要,真正的价值差异来自于如何组织与编排智能能力参与业务决策。 早期 AI 产品通常具有明显的技术边界,用户需要学习特定指令或操作方式,才能与系统协作。 在当前阶段,AI 正逐渐隐匿于交互界面之后。 自然语言成为默认入口,智能判断被嵌入搜索、审批、调度与自动化流程之中。用户完成任务的过程中,往往并不需要意识到 AI 的存在,但其行为已经被智能系统持续辅助与优化。 与此同时,底层基础设施不断集中和加重,而上层应用则变得愈发轻量。这种“厚平台、薄应用”的结构,使智能能力像数据库或云存储一样,被视为系统的默认资源。 从整体上看,AI 不再以“创新项目”出现,是技术成熟度提升的自然结果,其核心特征可以概括为: 对于企业与从业者而言,关键不在于是否继续“做 AI”,而在于是否完成认知与架构层面的转向: 当 AI 不再被单独命名、单独立项、单独宣传时,恰恰说明它已经成为系统的一部分。 2026 年并不是 AI 叙事的终点,而是其真正融入生产力结构的起点。一、从项目制到底座化:AI 角色的根本转移
二、软件工程逻辑的变化:从确定性规则到概率驱动系统
三、经济模型的转变:边际成本被彻底压平
四、交付形态的演进:从可见技术到无感能力
五、系统性特征总结
六、面向长期的实践方向
各位 V 友好!
开发了一个 Vue 3 的富文本编辑器组件库,分享给大家。
https://tiptap-ui-kit.vercel.app
5 种主题
AI 功能
支持 OpenAI 、Claude 、DeepSeek 、阿里云等 AI 服务商。
其他特性
Vue 3.5 + Tiptap 3 + TypeScript
购买链接: https://benngai.gumroad.com/l/tiptap-ui-kit-solo
欢迎试用 Demo ,有任何问题或建议都可以留言讨论!




在寻找供应商关系管理系统时,许多企业都渴望能有一份权威的排行榜,以便快速锁定最佳选择。然而,现实情况是,这个领域并不存在一份公认的、适用于所有企业的通用榜单。 市面上的各类热门榜单,无论是基于市场声量、用户口碑还是算法推荐,其评估维度、样本范围和价值导向都各不相同。这些榜单能很好地反映市场格局与品牌知名度,却难以精准匹配每家企业独特的业务流程、行业特性和发展阶段。 因此,解读任何排行榜的关键,不在于记住名次,而在于理解其背后的分类逻辑,并将其视为一张描绘市场格局的地图。本文将结合多方市场观察与实践反馈,梳理当前值得关注的几家供应商关系管理系统厂商。我们将深度解析不同厂商的产品理念、能力边界与服务模式,旨在帮助您建立一套自己的评估标准,从而在纷繁的市场信息中,找到最契合自身业务需求的那块“拼图”。 一、正远科技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 简直没法用了。