[{"content":"近期网信办对《互联网信息服务管理办法（修订草案征求意见稿）》（以下简称《办法》）再次公开征求意见1，稿件内部分修订的条文引起了很多人的担忧——尤其是涉及「穿透、绕过技术措施」和「被依法阻断的信息」等表述，一时间「翻墙彻底违法」「一刀切要来了」的声音甚嚣尘上。\n网上几乎每年都能见到所谓「一刀切」、「白名单」的讨论，如果不能体会这种论调的市场有多大，看看前几年「禁止相关个人数据出境」的条文在当时是如何被解读的就知道了。那好，我们就来看看这次的《办法》到底是一般的技术性修法还是真的所谓「管控升级」。\n第二十六条：明确规定「翻墙」违法？ 第二十六条 任何组织和个人不得实施下列行为，扰乱互联网信息服务秩序：\n（一）实施信息发布、删除、屏蔽、断开链接、替换、下沉、算法推荐等行为，或者为他人提供信息发布、删除、屏蔽、断开链接、替换、下沉、算法推荐等服务；\n（二）虚假注册或者批量注册互联网账号、非法囤积或者非法交易互联网账号；\n（三）操纵、利用多个互联网账号批量发布含有法律、行政法规禁止内容的信息和不良信息，从事虚假点击、投票、榜单、排行、评论、交易、评价等活动，实施流量造假、流量劫持，制造虚假舆论热点，操控榜单、热搜等重点环节等；\n（四）实施违法穿透、绕过国家有关机构技术措施的活动；\n（五）法律、行政法规禁止的其他行为。\n互联网信息服务提供者应当采取异常数据监测、人工复审复核等措施，加强对前款规定行为的预防和监测。\n乍一看确实很吓人，这不就是明确规定翻墙违法了吗？法律法规的订立往往需要严格的咬文嚼字，每一条法律条文几乎都经过反复的推敲和字句斟酌，再读一遍这一句：\n实施违法穿透、绕过国家有关机构技术措施的活动\n「违法」是定语，修饰「穿透、绕过国家有关机构技术措施的活动」这个行为。意思是：不是所有穿透、绕过都被禁止，只有「违法的」穿透、绕过才被禁止。\n何谓「违法」 那什么是「违法」呢？\n全国人大法工委的《立法技术规范》对「违法」的概念有明确的界定：「违法」一般用于违反法律强制性规范的行为2。换言之，要判定一个行为「违法」，必须存在一条明确的法律强制性规范被违反——不能凭空认定。以下是这份规范给出的参考用例：\n示例一：被检查单位或者个人拒不停止违法行为,造成严重水土流失的,报经水行政主管部门批准,可以查封、扣押实施违法行为的工具及施工机械、设备等。（水土保持法第四十三条） 示例二：村民委员会不及时公布应当公布的事项或者公布的事项不真实的,村民有权向乡、民族乡、镇的人民政府或者县级人民政府及其有关主管部门反映,有关人民政府或者主管部门应当负责调查核实,责令依法公布;经查证确有违法行为的,有关人员应当依法承担责任。（村民委员会组织法第三十一条） 如果依然不能理解，可以对比看看「非法」，《立法技术规范》对「非法」的说明是：「非法」通常情况下也是违法，但主要强调缺乏法律依据的行为。什么意思呢？当然不是指「找不到允许你做的法律条文」，而是指：这类行为本来依法必须有某种依据、许可、资格、授权或合法来源，但行为人没有。例如「非法行医」——你本来应该要有执业医师资格证的，但你没有，所以你是非法行医。同样的结构，如果换成「违法行医」，那听起来就像是你有执业医师资格证，但是行医的方式错了，这种表达也不太常用。\n用语 焦点 隐含意思 非法行医 你根本没有医师资格 你不该行医 违法行医 （不太常用）暗示有资格但违规操作 你行医方式不对 非法持有枪支 你没有合法持有依据 你不该有这东西 非法拘禁 你没有法定权力拘禁他人 你无权这么做 违法穿透 已有相关法律和行政命令明令禁止「穿透」 有个法律、禁令在那里，你违反了 从这份技术规范及其用例可以看出，要判定一个行为是否「违法」，需要有明确的前置法律依据。问题是，你上哪里去找这样一个前置法律依据呢？众所周知，GFW 阻断 Google、YouTube、Twitter 等网站，但这种阻断从来没有对应的法院命令、签署后的行政文件，甚至连一份非正式的官方封锁列表都没有3。法外狂徒张三自行搭建 ShadowSocks 服务器并且用来访问 Google、YouTube、Twitter 等网站，首先其并未构成法规适用的前提——扰乱互联网信息服务秩序，其次亦没有任何法规和行政文件明确封锁或者禁止访问这些网站，因此，在单纯的法律意义上，张三是不「违法」的。\n也就是说，第二十六条第（四）项对张三并不适用——因为他的行为不满足「违法」这一前置要件。\n这条法规主要针对谁 这条是和以下行为并列的：\n操纵信息发布/删除/算法推荐 批量虚假注册账号 刷量、刷榜、假流量、假舆情 违法穿透、绕过国家有关机构技术措施 其他 前三项打击的对象比较清楚，无非就是黑产、水军、SEO/GEO操控。第（四）项和它们并列，语境上暗示它针对的也是有组织的、商业化的、扰乱信息服务秩序的行为，而不是张三在家上个 Google Scholar 查论文。\n可能的打击对象：\n商业机场、VPN 服务（未经许可经营电信业务和穿透技术措施，这个在以前以加速器的名义处在灰色地带，现在理论上也可以） 用翻墙工具做境外舆论操控、跨境诈骗、赌博引流的 帮助已被依法关停的网站通过技术手段复活的 突破政府、企业的内网、专网等网络的安全措施的攻击行为 第三十条：掐死整个灰色产业链？ 第三十条　明知他人违反本办法规定实施以下行为的，任何组织和个人不得为其提供数据、技术、程序、工具、软件、广告、服务、支付结算等方面的支持、协助或者其他帮助：\n（一）制作、复制、发布、传播违反本办法第二十四条和第二十五条第一款、第二款规定的信息的；\n（二）违反本办法第二十六条第一款规定，扰乱互联网信息服务秩序的；\n（三）为他人获取、传播被依法阻断的信息的。\n这条看起来也很吓人，只要在任何相关的环节帮助他人看到依法阻断的信息就算违法？那岂不是机场老板、风险支付商、评测推广频道、翻墙内核的开发者这一路人全都被纳入了这条法律的管辖范围？\n何谓「被依法阻断的信息」 现实中的「依法阻断」大概分为这几类：法院裁定、行政处罚、公安办案、部委专项行动。\n法院裁定在知识产权领域最常见。比如版权方起诉某盗版网站，法院判决侵权成立，裁定要求ISP屏蔽该域名。有判决书、有案号、有被告、有生效日期。\n再说行政处罚，例如通管局对某未备案网站作出行政处罚决定，责令改正后拒不执行，再通知接入商停止服务。有处罚决定书编号、有送达回证、有法律依据引用、有救济告知（如不服本处罚决定，可在收到本决定书之日起六十日内向XX机关申请行政复议，或者在六个月内向XX人民法院提起行政诉讼。）。\n公安机关办案这一类很好理解，比如扫黄，涉及诈骗、赌博、色情的网站，公安立案侦查后可以要求 ISP 配合切断。通常有立案决定书、有协助通知书发给运营商。运营商档案里会留存公安的正式函件。\n部委专项行动这一类稍微特殊一些，比如国家版权局每年的「剑网行动」，会公布一批侵权网站名单，通知各ISP屏蔽。有公开的通知文件、有网站列表、有引用的法律依据。虽然程序简化了，但至少有白纸黑字的部门文件可查。\n帮助他人「翻墙」，算他人获取、传播被依法阻断的信息吗？ 这里的逻辑和前文类似，现实中，没有任何一份公开的行政文书、法院命令写着类似「依据《某法》第某条，决定阻断对 Google/YouTube/Telegram 的访问」的内容。你找不到一个盖章的决定书，找不到作出阻断决定的具体行政机关署名，找不到阻断的期限，找不到申诉途径。\nGFW 对境外网站的封锁，在法律性质上一直是一个事实行为而非法律行为。它存在，它运作，但它没有走过「作出行政决定 → 通知当事人 → 可申诉」这套程序。不难看出，GFW 对于 Google、Twitter 等平台的封锁并不是法条中提到的「依法阻断」\n到了这里可能有人要问了，第八条规定在境内提供互联网信息服务必须取得 ICP 牌照 → Google 没有 ICP 牌照 → Google 属于非法提供服务 → 对非法服务进行阻断 = 依法阻断，这不就构成了依法阻断吗？这看起来有道理，实际上问题却很大。\n其一，管辖权问题。 第二条写的是「在中华人民共和国境内从事互联网信息服务」。Google 的服务器不在中国，公司不在中国（当年退出中国的时候保留部分研发部门至今，但研发部门并不从事任何 Google 直接面向公众的业务），它没有主动在境内从事服务——中国用户访问它，和它主动在境内从事服务，是两个完全不同的事。第九十二条确实说「境外的组织、个人向中华人民共和国境内提供互联网信息服务的，应当遵守法律」——但这只是一个义务宣示，不等于自动取得管辖权。你得先认定它「向境内提供服务」，这个认定本身需要一个正式的行政程序。\n其二，未取得 ICP 牌照的法律后果并非「阻断」。 第七十四条写得很清楚：未取得许可擅自从事互联网信息服务的——「由电信主管部门责令改正；拒不改正的，责令停业整顿」。注意法律后果是「责令改正」和「责令停业整顿」，不是阻断。这些处罚措施的前提是你能送达、能执行——对境内主体可以这么做，对境外主体你怎么责令？你连个送达地址都没有，难不成你把法律文件寄到山景城去吗？\n其三，第六十七条管不到从未持有许可的境外网站。 「被电信主管部门吊销/撤销/注销许可或取消核准编号的，由电信主管部门通知相关互联网接入服务提供者和域名解析服务提供者停止为其提供服务。」这条最接近依法阻断——通知 ISP 切断服务。但它的适用对象是「被吊销/撤销/注销」的——你得先有许可，然后被取消，才触发这条。从来没有取得过许可的境外网站，这条完全管不到。\n事实上，从备案制度实施至今的互联网现状就能反推出这一点。已知：如果对所有未经备案的网站一律执行「依法阻断」，其效果等同于白名单制度——只有备案过的网站可以访问，其余全部封锁。然而现实是，国内互联网显然不是白名单状态，大量未备案的境外网站仍然可以正常访问。由此可以得出结论：GFW 对特定网站的封锁并非法条意义上的「依法阻断」。既然通过翻墙获取的信息不属于「被依法阻断的信息」，第三十条第（三）项自然也就不适用。\n第十五条：正式给专线机场判死刑？ 第十五条　国家对互联网协议地址的分配使用实行备案管理。互联网协议地址分配机构应当及时向电信主管部门报备互联网协议地址信息。\n互联网接入服务提供者提供接入服务前，应当核验相应互联网协议地址备案信息，不得为未实名或者虚假的互联网协议地址提供服务。\n这条针对 IDC、ISP 的监管规定是早就有了，然而机场依旧通过「加速器」等名义或者挂靠别的持有牌照的实体照常运作，具体什么时候查、用什么力度查由工信部根据国内的政治经济需要随时调整。近期大规模的拔线潮，时间上恰好与工信部领导层调整吻合——这种执法力度是否属于「新官上任三把火」式的阶段性运动，还是意味着长期收紧，尚有待观察。\n罚则和其他细节 第八十四条　违反本办法第二十六条、第三十条、第三十二条、第四十八条、第四十九条规定，依照有关法律、行政法规的规定处罚。法律、行政法规没有规定的，由网信、电信、公安部门和其他有关主管部门依据职责责令限期改正，可以并处10万元以上100万元以下罚款；拒不改正或者情节严重的，处100万元以上500万元以下罚款，并可以责令暂停相关业务、停业整顿。\n注意这里的罚款起步就是 10 万元，上限 500 万元，还可以「责令暂停相关业务、停业整顿」——这些措辞明确指向的是组织和商业化主体，而非个人用户。个人在家用代理看个 Google 的行为，既不涉及「业务」也不涉及「整顿」，从罚则的设计逻辑上也可以印证：这套条文针对的是有组织的商业行为，而不是普通网民。\n此外，罚则适用的前提是违反第二十六条和第三十条——而前文已经分析过，个人翻墙行为在法律构成要件上并不满足这两条的适用条件。罚则再重，构成要件不满足，也轮不到你头上。\n现实中对「翻墙」行为的处罚 达摩克利斯之剑 前面从法律条文的角度分析，个人翻墙行为并不满足新《办法》相关条款的构成要件。但法律文本是一回事，现实执法是另一回事。\n事实上，针对个人使用 VPN 的行政处罚一直存在，依据的也不是这部新《办法》，而是 1997 年便已颁布的《计算机信息网络国际联网管理暂行规定》第六条4——「计算机信息网络直接进行国际联网，必须使用邮电部国家公用电信网提供的国际出入口信道」，以及第十四条规定的处罚措施：警告、没收违法所得、对个人处以最高 5000 元罚款，对单位处以最高 15000 元罚款。\n这条规定挂在那里将近三十年了，大部分时间处于休眠状态。但它从未被废止，意味着执法机关随时可以选择将它激活——而激活的时机、力度和对象，完全取决于当时的政治气候和地方执法意愿。\n值得一提的是，「国际出入口信道」这个概念本身就存在定义模糊的问题。《暂行规定》要求必须使用「国家公用电信网提供的国际出入口信道」，但许多专线机场采购的恰恰就是中国电信、中国联通、中国移动三大运营商运营的 IPLC（国际专用租用线路）或 IEPL（国际以太网专用线路）——这些都是三大运营商合法销售的国际信道产品，面向企业客户公开经营。如果用户通过合法采购的运营商国际专线访问境外网络，是否满足了「使用国家公用电信网提供的国际出入口信道」这一要件？条文没有给出答案，执法实践中也从未做出明确界定。这种模糊性进一步加剧了选择性执法的空间。\n真实案例 根据公开可查的行政处罚信息5，截至目前可检索到的涉及个人使用 VPN 的处罚案例远超公众认知。以下是几个有据可查的案例：\n广东韶关南雄（2019年）：当事人使用蓝灯（Lantern）翻墙共 487 次，被南雄市公安局予以警告并处罚款 1000 元。 浙江金华（2020年）：金公东(网警)行罚决字[2020]00751号，当事人因使用未经授权的国际信道被处以行政处罚。 四川遂宁（2019年）：遂船公(永)行罚决字[2019]489号，类似处罚。 某地（2025年）：当事人「小张」在网络安全检查中被发现存有 VPN 使用记录，被处罚款 15000 元（顶格处罚）。 湖北孝感（2026年3月）：孝感新华派出所出动 10 余名警力上门，当事人因使用 VPN 被处罚款 500 元。 上述案例几乎全部援引同一法律依据：《计算机信息网络国际联网管理暂行规定》第六条和第十四条。\n执法中的问题 从这些案例中可以看出几个值得注意的问题：\n选择性执法。 中国的翻墙用户保守估计有数千万6，而公开可查的处罚案例仅数十起。这意味着绝大多数人并不会被追究，但任何人都有可能成为那个被追究的人——法规在这里充当的不是普遍适用的规范，而是一把悬在头顶的剑，什么时候落下来取决于执法者的意志。这些年经济增长放缓，地方财政压力不断增大，部分地区出现的「远洋捕捞」便是这种选择性执法最具讽刺性的写照——欲加之罪，何患无辞？乖乖交出你的「违法所得」，老子的绩效奖金终于有着落了。\n法律适用混乱。 不同地区对相同行为援引的法条不同：有的用《暂行规定》第六条，有的用《网络安全法》第二十七条或第六十三条，有的甚至用《治安管理处罚法》中的条款。同一个行为在不同地方可能面对完全不同的法律评价，这本身就说明法律适用标准是混乱的。需要指出的是，中国是成文法国家而非判例法国家，法院判决不具有先例约束力，你在 A 地因翻墙被罚 500 元，在 B 地同样的行为可能被罚 15000 元或者干脆不被追究，而你无法援引 B 地的不追究来为自己在 A 地辩护。\n执法手段与违法程度不成比例。 湖北孝感案例中，出动 10 余名警力处理一起最终罚款 500 元的行政违法行为——这种执法姿态更像是震慑而非正常的行政管理。\n援引其他口袋罪名。 部分案例中，翻墙本身的处罚微乎其微，但公安机关以此为切入点，进一步追查当事人在境外平台上的言论，继而以「寻衅滋事」等口袋罪追究刑事责任。翻墙在这里成了援引其他口袋罪名的引子——处罚的不是翻墙本身，而是借翻墙的由头处罚当事人的言论或政治立场。\n你能做什么 说了这么多，你可能会觉得：法律条文上不构成，但现实中还是有风险，那不就等于白说了？\n不，这是一份征求意见稿，你现在拥有一个白纸黑字写在法定程序里的参与立法工作的渠道。\n提交立法意见 《办法》目前处于公开征求意见阶段。根据《规章制定程序条例》第十五条，任何公民都有权对征求意见稿提出意见。这不是恩赐，这是法定程序。你可以通过网信办公布的征求意见渠道，正式提交你的意见——比如建议对「违法穿透、绕过」的表述增加更明确的构成要件界定，或者建议对「依法阻断」做出程序性定义以防止概念被滥用。\n联系你的人大代表 《中华人民共和国宪法》第四十一条：\n中华人民共和国公民对于任何国家机关和国家工作人员，有提出批评和建议的权利。\n《中华人民共和国全国人民代表大会和地方各级人民代表大会代表法》第四条：\n代表应当与原选区选民或者原选举单位保持密切联系，听取和反映选民和选举单位的意见和要求，努力为人民服务。\n你所在选区的区/县人大代表有义务听取你的意见，各区县人大常委会官网通常会公布代表名单及联系方式。找到你的代表，打个电话或者写封信，告诉他们：\n你认为互联网立法应当遵循明确性原则，模糊的条文不应成为选择性执法的工具； 你支持依法治网，但反对以「依法」之名行「无法可依」之实； 你希望「被依法阻断」这一概念在法律中获得明确的程序性定义。 践行社会主义核心价值观，从联系你的人大代表开始。\nTL;DR 是技术性修法，该怎么过日子以后还怎么过，任何行为自己权衡风险，都散了吧。\n《互联网信息服务管理办法（修订草案征求意见稿）》全文及征求意见公告可在国家互联网信息办公室官网查阅: https://www.cac.gov.cn/2025-04/15/c_1746821732498092.htm\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考《立法技术规范（试行）（二）》: https://npcobserver.com/wp-content/uploads/2023/02/Technical-Specifications-for-Legislation-for-Trial-Implementation-II.pdf\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n中国政府从未正式承认 GFW 的存在，也从未公布过被封锁网站的完整列表。2015 年国务院新闻发言人在回答外国记者提问时仅表示「中国依法管理互联网」，但未指明具体的法律依据或封锁清单。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n《计算机信息网络国际联网管理暂行规定》（1997年颁布，2024年最新修订）全文可参阅国务院官网: https://www.cac.gov.cn/1996-02/02/c_126468621.htm\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n王宇扬（2020年9月5日）通过裁判文书网和行政处罚信息公开平台检索，共找到 51 起相关案例。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nGlobalWebIndex 在 2014 年的调查报告显示中国 VPN 用户约 9300 万，约占当时网民总数的 14%。考虑到此后网民总数持续增长且翻墙工具日益普及，当前实际用户数只会更高。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-07-05T21:44:28+08:00","permalink":"/2026/07/understanding-the-viral-cac-legislation/","title":"理解《互联网信息服务管理办法（修订草案征求意见稿）》——针对翻墙的一刀切要来了吗？"},{"content":"点进这篇文章的人想必基本都对 DNS 泄露这一概念有所耳闻了，其中也不乏谈 DNS 泄露色变者，由于评论区和 Issue 里提出相关问题的人已经有数位，鄙人这次写一篇说明，尽可能将这个问题讲清楚，澄清一些大家对这个概念可能的误解，也为各位编写自己的代理配置提供一个参考。\n这个概念已经被一些 VPN 厂商和一大堆 YouTuber 讲烂了，基本的意思是：当你在代理时，电脑却通过本地网络向本地 DNS 请求你正在访问的网址，使得运营商可以依据你的 DNS 请求记录得知你的浏览记录。\nflowchart LR U[用户设备浏览器 / App] --\u003e VPN[VPN 客户端加密隧道] VPN --\u003e|正常情况：DNS 请求走 VPN| VPNDNS[VPN 提供的 DNS 服务器] VPNDNS --\u003e NET[目标网站 / 互联网] U -.-\u003e|异常情况：DNS 泄露| ISP[本地 ISP DNS 服务器] ISP -.-\u003e LOG[ISP / 第三方可记录访问过的域名] NET --\u003e SITE[example.com] subgraph Normal[正常 DNS 解析路径] VPN VPNDNS NET end subgraph Leak[DNS 泄露路径] ISP LOG end classDef safe fill:#e8f7ee,stroke:#2e7d32,stroke-width:2px,color:#1b5e20; classDef danger fill:#fdecea,stroke:#c62828,stroke-width:2px,color:#7f0000; classDef user fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#0d47a1; class U user; class VPN,VPNDNS,NET,SITE safe; class ISP,LOG danger;搞清楚需求 首先需要想明白的是，我们煞费苦心地防止 DNS 泄露究竟是为了什么——大家的第一反应可能都是：「那还用说！肯定是为了不让审查者看到我们通过代理访问了哪些网站啊！」\n其实这个说法并不完全准确，具体还得看情况。不妨想一想：让审查者知道你在刷抖音、聊微信会有什么实质性的危害吗？恐怕没有。但如果让审查者发现你在访问维基百科、浏览 X（推特）或者其他带有明确政治倾向的敏感内容，那问题就有点大了。防止 DNS 泄露的目的，从来不是为了让你在所谓的「DNS 泄露测试」网站上拿到一个全绿的满分，也不是为了隐藏你使用国内常用服务的事实，而是为了不让审查者知道你在访问那些被封禁、被视为敏感的网站和服务。\n对于生活在墙内的我们来说，区分什么是敏感内容其实非常简单：直接参考 GFWList1 即可——能让 GFW 专门将其重点关照的，自然就是敏感内容。\n那些 DNS 泄露测试的网站，测试用的随机域名甚至连 GFWList 的边都沾不上，本身就毫无敏感性可言。对于一些经过优化的正常代理配置来说，这类域名连看都不想多看一眼，通常会直接被略过并扔给最后的兜底规则（比如 MATCH, DIRECT）去处理，这个过程自然而然地触发了本地 DNS 解析。于是，测试网站便如获至宝般地亮起红灯，警告你「存在 DNS 泄露」。但明白机制的我们自然清楚，很多时候这种所谓的泄露完全是无关痛痒的，只要配置得当，你真正需要保护的敏感访问记录，早就匹配到前面的分流规则被安全地送进加密隧道了。\n更有甚者，诸如 Surfshark、ExpressVPN 这类海外商业 VPN 厂商，以及一众跟着恰饭的无良 YouTuber，成天拿这种毫无实际意义的测试结果制造隐私焦虑。可笑的是，这些传统的商业 VPN 客户端往往连最基础的域名分流规则功能都不具备，全靠粗暴的一把梭将所有网络请求强行塞进虚拟网卡。而更讽刺的是，即便是这种简单粗暴的全局代理，他们过去还曾因为自身客户端软件的缺陷，真真切切地导致过 DNS 泄露问题。所以，与其听信这些贩卖焦虑的恰饭营销，不如自己弄懂代理软件的运作原理。\n出现泄露的环节 其实现在主流的代理软件都比较成熟，配置得当完全不需要担心 DNS 泄露的问题。问题出就出在很多配置根本就不得当。接下来我将会简要地解释代理软件在系统代理模式和透明代理（虚拟网卡）模式下可能出现 DNS 泄露的环节。\n代理软件本身 在使用系统代理的情况下（假设代理地址是socks5://127.0.0.1:78902）用浏览器访问https://www.example.com，会经历如下的请求过程：\n第一步：浏览器会把网络请求打包发送给socks5://127.0.0.1:7890 第二步：代理软件收到请求后根据配置的分流规则匹配节点 第三步：代理软件根据匹配结果向节点转发整个网络请求 sequenceDiagram participant B as 浏览器 participant P as 代理软件(127.0.0.1:7890) participant R as 分流规则引擎 participant N as 远端代理节点 B-\u003e\u003eP: ① 将请求打包发送(携带域名, 不做 DNS 解析) Note over B,P: 浏览器不发起 DNS 查询不会泄露 P-\u003e\u003eR: ② 根据域名等信息匹配分流规则 Note over P,R: 规则匹配过程可能触发 DNS 查询 ⚠️ R--\u003e\u003eP: 返回匹配结果(PROXY / DIRECT / REJECT) P-\u003e\u003eN: ③ 加密转发请求至节点 Note over P,N: 加密隧道传输不会泄露 N--\u003e\u003eP: 返回响应 P--\u003e\u003eB: 返回响应在整个发起请求的过程中，浏览器将网络请求打包交给代理，不会向本地 DNS 发出请求，这一环节不会产生 DNS 泄露；代理软件将网络请求转发给服务器，整个过程加密，也不会产生 DNS 泄露；真正产生 DNS 泄露的环节，是根据分流规则匹配的过程。\n向本地 DNS 发起域名查询这件事情本身并不一定是坏事，但配置不当的分流规则会让代理软件在拿到域名后过早地向本地 DNS 发起查询，导致泄露不应泄露的隐私信息。假设在极端情况下，盖世太保从运营商调取所有人的 DNS 查询记录，凡是查询过域名包含 GFW 封锁列表中的项目者都拉出去枪毙，在这种情况下，为了保全自身，我们需要恰当地配置分流规则。\n以使用广泛的 Mihomo 内核为例，在作为客户端开启系统代理模式、使用 Chrome 进行到前文所述的第二步时，内核已知的信息有：\n主机3：example.com 目标端口：443 网络协议：TCP 发起请求的进程的名称和具体路径：C:\\Application\\chrome.exe 入站 IP：127.0.0.1 入站名称：DEFAULT-MIXED 入站端口：随机的高位端口 内核不会进行多余的 DNS 请求，根据已知的信息，内核可以在不发起 DNS 解析的情况下，匹配所有基于域名、端口、进程名称以及网络协议匹配的路由规则：\nrules: # 基于域名的匹配规则 - DOMAIN,ad.com,REJECT - DOMAIN-SUFFIX,google.com,auto - DOMAIN-KEYWORD,google,auto - DOMAIN-WILDCARD,*.google.com,auto - DOMAIN-REGEX,^abc.*com,PROXY - GEOSITE,youtube,PROXY # 基于端口的匹配规则 - DST-PORT,80,DIRECT - SRC-PORT,7777,DIRECT # 基于进程名称的匹配规则 - PROCESS-PATH,/usr/bin/wget,PROXY - PROCESS-PATH,C:\\Application\\chrome.exe,PROXY - PROCESS-NAME,curl,PROXY - PROCESS-NAME,chrome.exe,PROXY # 基于网络协议的匹配规则 - NETWORK,UDP,REJECT # 不依赖任何信息的匹配规则 - MATCH,DIRECT因此，上述这些种类的规则不会产生 DNS 泄露，因为内核匹配它们的时候根本没必要发起 DNS 解析。\n对于剩下种类的规则，需要在第二步获知目标 IP 信息才能让匹配进行下去：\nrules: - GEOIP,cn,DIRECT - IP-CIDR,127.0.0.0/8,DIRECT - IP-SUFFIX,8.8.8.8/24,PROXY - IP-ASN,13335,DIRECT在默认情况下，为了确保匹配的准确性，进行到第二步时，内核不知道目标 IP，只知道目标主机地址www.example.com，此时内核不得不对www.example.com的 IP 地址进行查询，这也就造成了 DNS 泄露。如果在规则的末尾加上no-resolve4，则匹配到基于 IP 的规则时会直接跳过，这就使得no-resolve很适合用来分流 Telegram 等软件的裸 IP 请求。\n透明代理的问题（TUN 模式5） 透明代理顾名思义即被代理的系统/软件感知不到自己被代理了的代理方式。这种方式非常省事，TUN 模式一开，所有软件通通都能用，无须繁琐的逐一配置不遵循系统代理的软件。代价就是这种省事本身——目标系统/软件都不知道自己被代理了，他们在正常网络上该有的行为都会照常进行，其中自然也包括 DNS 解析，可是目标系统/软件并不知道自己被代理了，他们想要和远端建立连接，总得要先拿到一个 IP 才行吧。为了解决这个问题，以 Mihomo 为例，有两种 DNS 劫持模式，redir-host和fake-ip。\nredir-host 模式：\nflowchart TD A1[目标软件发起 DNS 查询] --\u003e A2[代理软件向上游 DNS查询真实 IP] A2 --\u003e A3[上游 DNS 返回真实 IP] A3 --\u003e A4[将真实 IP 返回给目标软件] A4 --\u003e A5[目标软件用真实 IP 建立连接] A5 --\u003e A6[代理软件拦截并分流] A2 -.- LEAK[\"⚠️ 真实 DNS 请求泄露到外部网络\"] classDef danger fill:#fdecea,stroke:#c62828,stroke-width:2px,color:#7f0000; class LEAK danger;fake-ip 模式：\nflowchart TD B1[目标软件发起 DNS 查询] --\u003e B2[代理软件立即返回假 IP如 198.18.0.x] B2 --\u003e B3[目标软件用假 IP 建立连接] B3 --\u003e B4[代理软件拦截, 查映射表还原真实域名] B4 --\u003e B5[通过加密隧道转发请求] classDef safe fill:#e8f7ee,stroke:#2e7d32,stroke-width:2px,color:#1b5e20; class B2,B4,B5 safe;其中redir-host比较老实，既然目标系统/软件发起了 DNS 查询，那就老老实实通过上游 DNS 去查，把查询到的真实的 IP 返回给目标系统/软件。由于这种模式下系统必定会发生一次真实的 DNS 解析请求寻址过程，存在着先天的结构性缺陷，不可避免地会造成 DNS 泄露。原来的 Clash 核心在后续的版本更新中干脆直接砍掉了 redir-host 模式。\n不过，继承了 Clash Meta 核心的 Mihomo 内核选择了将其保留下来，并且加入了sniffer6对其进行增强。在redir-host模式下，sniffer依靠嗅探数据包中的特征（比如从 TLS 的 SNI 字段7）尝试将被解析成裸 IP 的流量恢复成连接域名，再用这个域名走一遍分流规则的匹配，补齐了redir-host模式在分流上的诸多短板。但需要特别注意：sniffer 解决的是分流准确性的问题，并不能消除 DNS 泄露本身——DNS 查询请求在 sniffer 介入之前就已经发出去了，运营商该记录的早就记录了。\n但这里需要提醒：如果你在透明代理环境下仍然坚持使用redir-host模式，就必须在配置一套无污染的 DNS，具体的例子可以参考我的另一篇文章，否则你的 DNS 访问记录依然会泄露。\n相对而言，fake-ip模式则采用了截然不同的解决思路，不仅完美规避了透明代理环境下的 DNS 泄露问题，甚至还能顺带提升浏览器的网页响应速度。\n如何规避 DNS 泄露 优化喂给代理软件的分流规则 前面已经提到过，不当的分流规则会让代理软件过早地触发解析。一个典型的反面例子如下：\nrules: - GEOIP,cn,DIRECT - GEOSITE,telegram,Telegram - GEOIP,telegram,Telegram - MATCH,Proxy问题出在第一条 GEOIP,cn,DIRECT。当设备请求 telegram.org 这个域名时，内核从上往下匹配，第一条就是个 IP 规则。可域名不是 IP，要判断它到底落不落在中国大陆的网段里，内核只能先把 telegram.org 拿去解析一遍。这一解析，DNS 查询就发出去了——哪怕下面第二条 GEOSITE,telegram 本来能直接命中，根本用不着知道 IP。\nflowchart TD Start[请求 telegram.org] --\u003e Rule1{第 1 条GEOIP,cn?} Rule1 --\u003e Leak[⚠️ IP 规则遇上域名必须先解析 telegram.orgDNS 查询就此泄露] Leak --\u003e Judge{解析出的 IP在中国大陆?} Judge -- 否 --\u003e Rule2{第 2 条GEOSITE,telegram?} Rule2 -- 是 --\u003e ProxyTG[走 Telegram 代理但 DNS 已经泄露了] classDef danger fill:#fdecea,stroke:#c62828,stroke-width:2px,color:#7f0000; class Leak danger;解析请求一旦发出，运营商那头就记下了。后面命中哪条规则或者走不走代理都不重要，反正运营商已经知道你在访问 Telegram。\n规则匹配自上而下顺序进行，内核每收到一个请求就一条一条往下比，直到命中为止。换句话说，一个域名只要被前面的规则匹配到，后面的规则，第二条、第三条、哪怕第一千万条，都不会再跑。\n正因如此，写规则时要遵循域名规则在前，IP 规则在后的原则。就算是针对某个服务的专用规则集，也要给里面靠前的 IP 规则加上 no-resolve 标记，告诉内核这条 IP 规则匹配不上就跳过，别去解析。一个典型的例子：\nDOMAIN-SUFFIX,e-hentai.org DOMAIN-SUFFIX,ehgt.org DOMAIN-SUFFIX,ehwiki.org DOMAIN-SUFFIX,exhentai.org DOMAIN-SUFFIX,hath.network DOMAIN-SUFFIX,hentaiverse.org IP-CIDR,178.175.128.0/21,no-resolve用 GeoSite 和 GeoIP 数据库时同理，靠前的 IP 规则都要带上 no-resolve。\nrules: - GEOSITE,telegram,Telegram - GEOIP,telegram,Telegram,no-resolve - GEOSITE,gfw,Proxy - GEOIP,cn,DIRECT - Match,Proxy把这套规则和前面的反面例子对照着看，差别就在 DNS 解析触发的时机上：\nflowchart TD Start[请求 telegram.org] --\u003e Rule1{第 1 条GEOSITE,telegram?} Rule1 -- 是 --\u003e ProxyTG[走 Telegram 代理✅ 全程未解析] Rule1 -- 否 --\u003e Rule2{第 2 条GEOIP,telegram,no-resolve?} Rule2 -- 是仅匹配裸 IP 请求 --\u003e ProxyTG Rule2 -- 否 --\u003e Rule3{第 3 条GEOSITE,gfw?} Rule3 -- 是 --\u003e ProxyGFW[走 Proxy 代理✅ 全程未解析] Rule3 -- 否 --\u003e NeedIP[到这一步才需要 IP触发本地 DNS 解析] NeedIP --\u003e Rule4{第 4 条GEOIP,cn?} Rule4 -- 是 --\u003e Direct[DIRECT 直连] Rule4 -- 否 --\u003e ProxyOther[Match,Proxy走 Proxy 代理] classDef safe fill:#e8f7ee,stroke:#2e7d32,stroke-width:2px,color:#1b5e20; classDef warn fill:#fff3e0,stroke:#ef6c00,stroke-width:2px,color:#8a4b00; class ProxyTG,ProxyGFW safe; class NeedIP warn;同样是请求 telegram.org，这回第一条就是 GEOSITE,telegram，域名直接命中，请求甩给代理，全程没碰 DNS。访问其他挂在 GFW 列表上的网站也一样，会先撞上 GEOSITE,gfw,Proxy，赶在那条非解析不可的 GEOIP,cn,DIRECT 之前就把请求送进了节点。该走代理的早早走了代理，靠后那些基于 IP 的规则压根没轮到执行，DNS 也就没机会泄露出去。\n用 Fake-IP 规避透明代理问题 fake-ip 模式则解决了透明代理下的 DNS 泄露问题，还能顺带提升浏览器的网页响应速度。\n在fake-ip模式下进行透明代理，当目标软件发起 DNS 查询时，代理软件并不会傻乎乎地去本地或远端上游查询真实 IP，而是直接在本地瞬间返回一个假的内网保留 IP（例如198.18.0.28）。目标软件拿到这个假 IP 后信以为真，紧接着就会拿着这个假 IP 尝试建立连接。\n而在代理软件这里，它只需要拦截所有发往自己签发过的这些假 IP 的请求即可。由于代理软件内部维护了一张详细的「假 IP 对应真实域名」的映射表，所以即便目标软件发来的是往假 IP 发送的包，代理软件依然心知肚明你其实想访问的是什么域名。于是，代理软件直接提取出原始域名，将网络请求顺着加密代理隧道发往远端节点去处理。\nsequenceDiagram participant App as 目标软件(浏览器等) participant TUN as TUN 虚拟网卡 participant Proxy as 代理软件(Mihomo) participant Node as 远端代理节点 participant Web as 目标网站 App-\u003e\u003eTUN: DNS 查询: google.com 的 IP 是? TUN-\u003e\u003eProxy: 转发 DNS 查询 Note over Proxy: 不向外部发起任何 DNS 请求!从 198.18.0.0/15 池中分配假 IP记录映射: 198.18.0.5 → google.com Proxy--\u003e\u003eTUN: 返回假 IP: 198.18.0.5 TUN--\u003e\u003eApp: DNS 响应: 198.18.0.5 App-\u003e\u003eTUN: 连接 198.18.0.5:443 (HTTPS) TUN-\u003e\u003eProxy: 转发连接请求 Note over Proxy: 查映射表:198.18.0.5 → google.com匹配分流规则 → PROXY Proxy-\u003e\u003eNode: 加密转发: 请连接 google.com:443 Node-\u003e\u003eWeb: 建立真实连接 Web--\u003e\u003eNode: 返回网页内容 Node--\u003e\u003eProxy: 加密回传 Proxy--\u003e\u003eTUN: 返回内容 TUN--\u003e\u003eApp: 收到响应 Note over App,Web: 全程无真实 DNS 请求泄露到外部网络 ✓这一机制解决了redir-host模式下透明代理必然会向外部网络暴露域名查询记录的结构性缺陷。但必须指出的是，fake-ip仅仅是绕过了目标软件发起 DNS 查询时的泄露风险。正如前文所述，如果分流规则配置不当，代理内核自身依然会主动向上游发起真实的 DNS 解析，从而导致泄露。在分流规则配置妥当的前提下，fake-ip模式不仅能让审查者无从窥探你的真实访问目标，还能因为免去了本地设备等待 DNS 真实响应的时间，顺带大幅度降低网页访问的首字节加载延迟（TTFB9），可谓一石二鸟。\n太长不想读（小结） DNS 泄露本身并不可怕，可怕的是不明就里地被焦虑营销牵着鼻子走。理解了机制之后，应对思路其实很清晰：\n系统代理模式：遵循「域名规则在前，IP 规则在后」的原则，为所有 IP 类规则加上 no-resolve，敏感域名在触发 DNS 解析之前就已经被分流走了。 TUN 透明代理模式：优先选用 fake-ip，从根源上杜绝 DNS 查询外泄，同时还能获得更低的 TTFB。如果坚持使用 redir-host，必须搭配无污染的上游 DNS，且要清楚 sniffer 只能改善分流准确性，无法阻止 DNS 请求本身的泄露。 不要迷信泄露测试网站：测试用的随机域名根本不在 GFW 封锁列表内，触发本地解析是正常且无害的行为，绿灯与否不是衡量配置质量的标准。 被中国大陆防火长城（Great Firewall, GFW）封锁的域名列表。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nSOCKS5 是一种网络代理协议（RFC 1928），工作在会话层，支持 TCP 和 UDP 转发，且允许客户端将域名直接传递给代理服务器解析，而非在本地解析后再连接——这正是它在防止 DNS 泄露方面优于普通 HTTP 代理（非 CONNECT 隧道模式）的关键特性。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n可以理解为域名。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nno-resolve 是附加在 IP 类规则末尾的标记，作用是告诉内核：当流量的目标是域名而非 IP 时，跳过此规则，不要为了匹配它而主动发起 DNS 解析。但如果流量本身就是直接连接 IP（如 Telegram 客户端直连服务器 IP），则该规则仍然会正常参与匹配。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n也就是我们所说的虚拟网卡模式\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n流量嗅探（Sniffer）是指代理软件通过检查数据包的协议特征来还原目标域名的技术。例如，HTTPS 连接在握手阶段会以明文发送目标域名（即 SNI），HTTP 请求头中也包含 Host 字段，代理软件可以从这些特征中提取出真实的目标域名。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nServer Name Indication，TLS 协议的扩展字段。由于同一 IP 上可能托管多个 HTTPS 站点，客户端在 TLS 握手的 ClientHello 阶段需要以明文告知服务器自己要访问哪个域名，以便服务器返回正确的证书。这也是为什么即使使用了 HTTPS，中间人仍然能看到你访问的域名（但看不到具体路径和内容）。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nMihomo 默认使用 198.18.0.0/15 地址段分配假 IP。该地址段由 IANA 在 RFC 2544 中保留，专门用于网络设备基准测试，不会出现在正常的互联网路由表中，因此不会与任何真实的公网地址冲突。整个 /15 段可提供约 131,072 个地址供映射使用。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nTime To First Byte，即从客户端发出请求到收到服务器响应第一个字节所经过的时间。在传统模式下，浏览器需要先等待 DNS 解析完成（通常耗时 20-120ms）才能发起 TCP 连接；而 fake-ip 模式下 DNS 响应几乎是瞬时的（\u0026lt;1ms），因此能显著缩短整体的页面加载时间。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-05-18T00:46:00+08:00","permalink":"/2026/05/dns-leak-misunderstanding/","title":"关于 DNS 泄露及其相关误解的说明"},{"content":"Terraform 是一款 IaC 工具，所谓 IaC 就是「基础设施即代码」，将我们的基础设施以声明式的代码写出来，随后使用terraform apply即可完成基础设施的部署，同一份配置，部署出来的一定是一模一样的基础设施（Nix OS 用户狂喜）。\n为什么要用 Terraform 传统的基础设施管理绝大部分基于人力和各种云服务商的 Dashboard，这就带来了下面这些痛点：\n痛点 说明 难以重现 通过 Dashboard 点点点进行配置，容易改错或者改漏，而且难以复现 环境漂移 手动操作导致生产和测试环境配置逐渐偏离，导致极端情况下测试没问题生产直接崩 难以扩展 新增一套环境需要重复大量手工操作，耗时且容易出错 难以审计 没有变更记录，出了事不好甩锅 难以协作 基础设施由少数「懂的人」掌控，谁想要改都得去找这些人，效率低 为了解决这些问题，「基础设施即代码」1的概念被提了出来，Terraform 就是其中一个著名的解决方案。\n假设一个现实的使用场景，例如你每年都会购买新的 GCP 的 $300 试用金账号，虽然便宜，但是每年都要重新跑到 GCP 的面板里开机器。而有了 Terraform，想要部署同样配置的机器，只要在每次更换账号之后，将 API Token 替换成新的，随后terraform apply，只需要几分钟就能开出和你上个账号一模一样的机器、VPC、S3、防火墙配置等等。\n再比如 Cloudflare DNS 和 Tunnel 的管理和迁移，也只需要将原 Tunnel 的 Ingress Rule 复制到新 Tunnel 的 Ingress Rule。即使将来要迁移到 AliDNS、Route 53 等其他服务商，我们也可以原封不动的将数据复制过去2。\n尤其是到了多人协作的时候，配合 Git，每次更改都有迹可循，更不需要担心合并冲突，PR 可以自动生成更改预览，出现问题可以立刻回滚到上一个版本，这些都是传统依赖人力去直接操作服务提供商 Dashboard 的做法完全无法做到的。\nTerraform 的安装 Terraform 是用 Go 写的，编译出来的产物自然也是单个可执行文件，所以安装起来也非常容易，Windows 下可以直接使用 Winget 安装：\nwinget install Hashicorp.Terraform如果不想使用 Winget，也可以使用 Scoop 等其他包管理器，或者将预编译的二进制文件放入$PATH，即可完成安装。\n如果你在 Linux 环境下，则使用对应的包管理器安装即可，如果使用将二进制文件放入$PATH的安装方法，则要记得sudo chmod +x terraform赋予文件的执行权限。\nTerraform 的两个基本概念 Provider(s) 我们前面已经提到，Terraform 是一个款础设施即代码工具，作为一个工具本身，他并不绑定某个平台，而是通过 Provider(s) 与各个平台对接，要查看有哪些 Provider(s)，可以浏览 Terraform 的 Registry。\n状态管理 Terraform 将每次执行基础设施变更操作时的状态信息保存在一个状态文件中，默认情况下会保存在当前工作目录下的terraform.tfstate文件里3，我们也可以修改配置文件自行指定其他的存储后端，例如 S3、Postgres。每次我们执行terraform apply时，Terraform 都会将目前配置文件声明的状态同现有的状态文件进行比对，从而计算变动的部分，自动确定调整顺序之后操作 Provider 落实状态变动。\nTerraform 的资源导入难题 现有资源的导入一直是 Terraform 为人诟病的难题，Hashi Corp. 似乎一直在坚持着一个固执且愚蠢的观点：你所有的基础设施从一开始就应当是用我们的 Terraform 创建的，所以也不存在什么资源导入的问题。\n时间 版本 进展 问题 2014–2022 v0.x–v1.4 只有 terraform import，一次一条，而且完全不生成配置 导入完还得自己手写 HCL4 2023.06 v1.5 引入 import 块和 -generate-config-out参数，可以生成配置了 然而还是得一条一条写，而且还得自己提供现有资源的 ID 2024.01 v1.7 import 块支持 for_each 批量了，但 ID 还得自己搞 2024 下半年 v1.12 引入了 terraform query 和 list 块，终于实现了自动发现资源的功能 然而这个功能要 Provider 要自己实现，大量 Provider 根本没跟上 这么多年的时间，社区一直在骂，然而，「我有一堆现有资源，怎么导入 Terraform」这个问题一直没有被认真对待。Terraform 作为「基础设施即代码」工具，设计哲学就是声明式和幂等性5，Hashi Corp. 他们笃信「一切以代码声明的状态为准，就应该用 Terraform 从零开始创建资源」。但现实是绝大多数公司都有大量历史存量资源，先有资源、后有代码才是常态。这个矛盾 Hashi Corp. 承认得很晚，v1.12 的 terraform query 才算是官方第一次认真面对这个问题——但 Provider 生态的跟进嘛……真的是一言难尽。\nTerraform 的文件结构 Terraform 的文件结构很简单，其主程序运行时会无脑读取工作目录下所有的.tf文件，只要信息齐全，想给文件取什么名字都可以，比如我的文件结构就长这样：\n❯ tree -a -I .git . ├── .editorconfig ├── .github │ ├── dependabot.yml │ └── workflows │ ├── terraform-apply.yml │ ├── terraform-plan.yml │ └── your-fork.yml ├── .gitignore ├── .terraform.lock.hcl ├── cf_dns_zones.tf ├── cf_tunnel.tf ├── dns_example_com.tf ├── dns_example_net.tf ├── dns_example_top.tf ├── dns_example_cn.tf ├── main.tf # 基础配置（terraform 块） ├── moved.tf # 移动过的资源 ├── provider.tf # 每个 Provider 的配置 ├── README.md ├── rename_resources.ps1 └── variables.tf # 自定义的变量main.tf用于存放基础配置:\nterraform { required_providers { cloudflare = { source = \"cloudflare/cloudflare\" version = \"~\u003e 5\" } tencentcloud = { source = \"tencentcloudstack/tencentcloud\" version = \"\u003e= 1.81.43\" } } }provider.tf用于存放每个 Provider 的配置：\nprovider \"cloudflare\" {} provider \"tencentcloud\" {}这里留空是因为我们可以通过环境变量来传递 Credentials，而不是直接将 Credentials 写在配置文件中，例如 Cloudflare 的 Provider 就接受CLOUDFLARE_API_TOKEN作为api_token这个变量的替代。\nvariables.tf用于声明自定义的变量：\nvariable \"cloudflare_zone_example_com\" { description = \"Cloudflare zone ID for example.com\" type = string } variable \"cloudflare_zone_example_top\" { description = \"Cloudflare zone ID for example.top\" type = string }这些变量可以通过前缀为TF_VAR_的环境变量传入，Terraform 也会自动读取terraform.tfvars文件中的变量，变量的主要用途是在别的配置文件中调用，例如：\nresource \"cloudflare_dns_record\" \"example_cname\" { content = \"${cloudflare_zero_trust_tunnel_cloudflared.Production_Tunnel.id}.cfargotunnel.com\" name = \"example.example.com\" proxied = true tags = [] ttl = 1 type = \"CNAME\" zone_id = var.cloudflare_zone_id_example_com #这里调用了cloudflare_zone_example_com这个变量 settings = { flatten_cname = false } }有了这些基础配置，我们就可以运行terraform init初始化 Terraform 环境并锁定依赖版本，剩下的就都是我们资源的声明了。\n将现有资源导入 Terraform 前文提到过 Terraform 的状态管理这个概念，状态管理虽好，但在我们初始化时也带来了一个问题——在默认状态下，Terraform 的状态文件显然是空的。\n此时我们需要做的是将云服务提供商上现有资源的状态导入 Terraform，这样 Terraform 才能无缝接手并管理我们的基础设施。相信大家也都看到了前文对 Terraform 资源导入问题的吐槽。以导入 Cloudflare 上托管的 DNS 记录为例，前文提到过，如果 Provider 支持，可以使用 Terraform 在 1.12 版本之后引入的terraform query，然而大多数情况下，Providers 都是没有跟进这个新功能的，Cloudflare 就属于不支持的那一类。\n好在虽然 Hashi Corp. 不认真解决问题，各路高强度使用 Terraform 管理基础设施的公司就各显神通。Cloudflare 就维护了名为 cf-terraforming 的导入工具，免去了很多手动导入的麻烦。首先安装cf-terraforming，这个工具是用 Go 语言编写的，需要在有 Go 语言环境的情况下安装，或者将官方编译好的二进制文件其放入$PATH并赋予其执行权限。\ngo install github.com/cloudflare/cf-terraforming/cmd/cf-terraforming@latest这个工具的用法还是比较简单的，首先你需要以下环境变量：\n# 如果你使用 API Token export CLOUDFLARE_API_TOKEN='Hzsq3Vub-7Y-hSTlAaLH3Jq_YfTUOCcgf22_Fs-j' # 如果你使用 API Key export CLOUDFLARE_EMAIL='user@example.com' export CLOUDFLARE_API_KEY='1150bed3f45247b99f7db9696fffa17cbx9' # 指定需要导入的域名的区域 ID，如果导入的是账户资源（例如 Cloudflare Tunnel）则不需要 export CLOUDFLARE_ZONE_ID='81b06ss3228f488fh84e5e993c2dc17' 💡 提示 此处的命令假设你正在使用 Bash，如果使用的是与 Bash 语法不兼容的 Shell，则需要做出调整，例如对于 Windows 上的 PowerShell，导入环境变量的语法如下：\n$env:CLOUDFLARE_API_TOKEN='Hzsq3Vub-7Y-hSTlAaLH3Jq_YfTUOCcgf22_Fs-j' 通常我们只需要设置CLOUDFLARE_API_TOKEN和CLOUDFLARE_ZONE_ID就可以了，在控制台创建 API Token 时，记得赋予这个 Token 必要的权限，本次我们只是导入 DNS 记录，所以只赋予编辑区域 DNS 的权限即可。\n好了，准备工作全部完成，现在可以开始生成配置文件：\n首先导入账户中域名的配置，也就是cloudflare_zone：\ncf-terraforming generate \\ --key $CLOUDFLARE_API_KEY \\ --resource-type \"cloudflare_zone\" \u003e zone.tf这一步会在当前目录下生成一个名为zone.tf的文件，里面会有如下格式的内容：\nresource \"cloudflare_zone\" \"REDACTED\" { name = \"REDACTED\" paused = false type = \"full\" vanity_name_servers = [] account = { id = \"REDACTED\" name = \"REDACTED\" } } resource \"cloudflare_zone\" \"REDACTED\" { name = \"REDACTED\" paused = false type = \"full\" vanity_name_servers = [] account = { id = \"REDACTED\" name = \"REDACTED\" } }现在域名资源已经导入了，但是里面的配置并没有。接下来，导入域名下的 DNS 记录：\ncf-terraforming generate \\ --zone $CLOUDFLARE_ZONE_ID \\ --key $CLOUDFLARE_API_KEY \\ --resource-type \"cloudflare_dns_record\" \u003e\u003e dns.tf这一步会在当前目录下生成一个名为dns.tf的配置文件，里面会有如下格式的内容：\nresource \"cloudflare_dns_record\" \"terraform_managed_resource_5deb14xxxxxb629bf123xxxxxxxc8f_0\" { content = \"67.24.33.108\" name = \"example.example.com\" proxied = true tags = [] ttl = 1 type = \"A\" zone_id = \"81c7f2de8dfxxxxxx52629xxxxxxfc\" settings = {} } resource \"cloudflare_dns_record\" \"terraform_managed_resource_89xxxxx0bf9cxxxxxx9a_1\" { content = \"35.27.108.33\" name = \"terraform.example.com\" proxied = true tags = [] ttl = 1 type = \"A\" zone_id = \"8xxxxxx7644e428526xxxxxx\" settings = {} }如果有多个域名需要导入，则多次分别设置环境变量CLOUDFLARE_ZONE_ID再重复运行命令即可。\n这里生成的配置文件可以直接使用，也就是我们之后需要的 Terraform 配置文件。然而，此时我们仅仅只是生成了配置文件，但是目前 Terraform 的状态依然是空的，这时要是直接terraform apply，Terraform 会不管三七二十一将我们刚刚导入的声明一律视为新增资源，然后甩出一大堆「Alredy Exists」报错。所以接下来，我们需要将生成的配置文件导入 Terraform 的terraform.tfstate状态。\nTerraform 在 1.5 版本引入了import块，相比以往一行一行输入命令的方式更加现代。其导入流程是先生成一个包含import块的.tf文件，下次进行terraform apply时，Terraform 就会自动为我们执行导入操作。\n生成cloudflare_zone的import块：\ncf-terraforming import \\ --resource-type \"cloudflare_zone\" \\ --modern-import-block \\ --key $CLOUDFLARE_API_KEY \\ --zone $CLOUDFLARE_ZONE_ID \u003e\u003e import.tf生成cloudflare_dns_record的import块：\ncf-terraforming import \\ --resource-type \"cloudflare_dns_record\" \\ --modern-import-block \\ --key $CLOUDFLARE_API_KEY \\ --zone $CLOUDFLARE_ZONE_ID \u003e\u003e import.tf这一步会在当前目录下生成import.tf，它包含了所需要的导入信息，作用就是告诉 Terraform 上一步生成的每个resource块到底对应的是哪一个云服务提供商的资源 ID。这个 ID 是云服务提供商内部标记资源的代码，平常是不会在控制面板上显示的，只有在用 API 特别请求时才会知道。Terraform 在导入过程中需要用到这个 ID 以确认本地的定义对应的云端资源，以实现严格的幂等性。\n好了，现在我们运行terraform plan：\n$ terraform plan cloudflare_dns_record.minio_a: Refreshing state... [id=xxxxxxxxxxx53] cloudflare_zero_trust_tunnel_cloudflared_config.raspberrypi: Refreshing state... ...... Terraform will perform the following actions: # cloudflare_dns_record.terraform_managed_resource_0 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_REDACTED_0\" { content = \"67.24.33.108\" created_on = \"2026-04-08T10:18:12Z\" id = \"5deb14c21xxxxxxx20f1c8f\" meta = jsonencode({}) modified_on = \"2026-04-08T10:18:12Z\" name = \"example.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"REDACTED\" } # cloudflare_dns_record.terraform_managed_resource_1 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_89c149exxxxxxxxxxxba13xxxxxa_1\" { content = \"35.27.108.33\" created_on = \"2026-04-08T10:17:54Z\" id = \"89cxxxxxxxxxxxxxxxxxx09a\" meta = jsonencode({}) modified_on = \"2026-04-08T10:17:54Z\" name = \"terraform.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"81xxxxxxxxxxxxxxxxxxxxxfc\" } Plan: 2 to import, 0 to add, 0 to change, 0 to destroy. ──────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run \"terraform apply\" now.如果需要 Add、Change 和 Destroy 的资源数量都是 0，说明我们的导入操作没有问题，直接terraform apply --auto-approve，资源就导入完成了。\n$ terraform apply --auto-approve cloudflare_dns_record.push_a: Refreshing state... [id=REDACTED] Terraform will perform the following actions: # cloudflare_dns_record.terraform_managed_resource_REDACTED_0 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_REDACTED_0\" { content = \"67.24.33.108\" created_on = \"2026-04-08T10:18:12Z\" id = \"REDACTED\" meta = jsonencode({}) modified_on = \"2026-04-08T10:18:12Z\" name = \"example.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"REDACTED\" } # cloudflare_dns_record.terraform_managed_resource_REDACTED_1 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_REDACTED_1\" { content = \"35.27.108.33\" created_on = \"2026-04-08T10:17:54Z\" id = \"REDACTED\" meta = jsonencode({}) modified_on = \"2026-04-08T10:17:54Z\" name = \"terraform.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"REDACTED\" } Plan: 2 to import, 0 to add, 0 to change, 0 to destroy. cloudflare_dns_record.terraform_managed_resource_REDACTED_1: Importing... [id=REDACTED/REDACTED] cloudflare_dns_record.terraform_managed_resource_REDACTED_1: Import complete [id=REDACTED/REDACTED] cloudflare_dns_record.terraform_managed_resource_REDACTED_0: Importing... [id=REDACTED/REDACTED] cloudflare_dns_record.terraform_managed_resource_REDACTED_0: Import complete [id=REDACTED/REDACTED] Apply complete! Resources: 2 imported, 0 added, 0 changed, 0 destroyed.状态存储和持续集成 IaC 的核心价值之一就在于可以轻易实现基于 Git 的多人协作，以及 CI 的持续集成，但是在此之前，又有一个新的问题需要解决——terraform.tfstate到底放哪里：没人想要换一次环境辛辛苦苦导入的状态就丢一次。\nTerraform 目前支持以下几种保存状态的后端：\nlocal remote azurerm consul cos gcs http Kubernetes oci oss pg s3 没有特殊需求可以像我一样选择s3，毕竟 Cloudflare R2 有免费额度，不用白不用。\nterraform { backend \"s3\" { bucket = \"terraform\" key = \"terraform.tfstate\" region = \"auto\" endpoints = { s3 = \"https://REDACTED.r2.cloudflarestorage.com\" } # R2 不需要这些 AWS 的验证 skip_credentials_validation = true skip_metadata_api_check = true skip_region_validation = true skip_requesting_account_id = true use_path_style = true } }对于 S3 的后端，建议用AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY两个环境变量来存储 Credentials：\nexport AWS_ACCESS_KEY_ID='REDACTED' export AWS_SECRET_ACCESS_KEY='REDACTED'配置完成，运行terraform init -migrate-state，配置就成功存储到云上了，以后不论在何处修改配置、运行terraform apply都无须担心 Terraform 的 State 不同步的问题。\n接下来就是 Github CI 的配置，其实很简单，无非就是每次git push时触发一次terraform init、terraform fmt和terraform apply，以下是我的.github/workflows/apply.yml：\nname: \"Terraform Apply\" on: push: branches: - main env: TF_IN_AUTOMATION: \"true\" CLOUDFLARE_API_TOKEN: \"${{ secrets.CLOUDFLARE_API_TOKEN }}\" AWS_ACCESS_KEY_ID: \"${{ secrets.AWS_ACCESS_KEY_ID }}\" AWS_SECRET_ACCESS_KEY: \"${{ secrets.AWS_SECRET_ACCESS_KEY }}\" TF_VAR_cloudflare_zone_id_example_com: \"${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_COM }}\" TF_VAR_cloudflare_zone_id_example_top: ${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_TOP }} jobs: terraform: name: \"Terraform Apply\" runs-on: ubuntu-latest permissions: contents: read concurrency: group: terraform-apply cancel-in-progress: false steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Terraform uses: hashicorp/setup-terraform@v4 - name: Terraform Init run: terraform init -input=false - name: Terraform Apply run: terraform apply -input=false -auto-approve对于 PR 则应当让 CI 自动为每次 PR 附上terraform plan的输出：\nname: Terraform Plan on: pull_request: paths: - \"**/*.tf\" - \".github/workflows/terraform-plan.yml\" permissions: contents: read pull-requests: write env: TF_IN_AUTOMATION: \"true\" CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} TF_VAR_cloudflare_zone_id_example_com: \"${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_COM }}\" TF_VAR_cloudflare_zone_id_example_top: ${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_TOP }} jobs: plan: name: Terraform Plan runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: hashicorp/setup-terraform@v4 - name: Terraform fmt id: fmt run: terraform fmt -check -recursive continue-on-error: true - name: Terraform Init id: init run: terraform init -input=false - name: Terraform Validate id: validate run: terraform validate -no-color - name: Terraform Plan id: plan run: terraform plan -input=false -no-color continue-on-error: true - name: Post Plan to PR uses: actions/github-script@v8 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, }); const botComment = comments.find(c =\u003e c.user.type === 'Bot' \u0026\u0026 c.body.includes('') ); const planOutput = `${{ steps.plan.outputs.stdout }}`.substring(0, 65000); const body = ` #### Terraform Plan | Step | Result | | -------- | --------------------------------- | | fmt | \\`${{ steps.fmt.outcome }}\\` | | init | \\`${{ steps.init.outcome }}\\` | | validate | \\`${{ steps.validate.outcome }}\\` | | plan | \\`${{ steps.plan.outcome }}\\` | 展开 Plan 详情 \\`\\`\\`terraform ${planOutput} \\`\\`\\` `; if (botComment) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: botComment.id, body }); } else { await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body }); } - name: Fail if plan failed if: steps.plan.outcome == 'failure' run: exit 1 后续的工作流程 到这一步，Terraform 的「接管初始化」已经结束了，后面就进入了日常维护阶段。这个阶段其实就三件事：\n创建新资源 修改现有的资源 删除不再需要的资源 常用的操作就两个：terraform plan和terraform apply，如果是个人使用，小的改动直接提交就算了；如果是团队协作，每次修改则应当遵循能 PR 就不直接 Commit 的原则。\n创建基础设施 假设你现在要新增一条 DNS 记录，或者新建一个 Tunnel、一个对象存储桶，流程如下：\nflowchart TD C1[新建分支 如 feat/add-minio-record] --\u003e C2[新增 resource 块] C2 --\u003e C3[terraform fmt + validate] C3 --\u003e C4[terraform plan] C4 --\u003e C5{仅新增预期资源?} C5 -- 否 --\u003e C6[修正配置后重跑 plan] C6 --\u003e C4 C5 -- 是 --\u003e C7[提交 PR] C7 --\u003e C8[合并后 CI apply]最理想的plan输出是：\nX to add 0 to change 0 to destroy 如果你只是想加东西，结果出现了to destroy，那就先别冲动，通常是引用写错、变量搞错，或者不小心改了资源地址，仔细检查是什么地方出了问题。\n修改与删除基础设施 修改流程和创建类似，但要多一步——评估变更是否会触发重建。\n因为很多 Provider 字段是ForceNew，你以为只是改个字段，Terraform 看完说：「好的，删了重建。」这在我们修改 DNS 的这个场景并不是什么很大的问题，但是到了云实例这种资源，如果删除重建势必会造成损失。\n建议按下面这个顺序来：\nflowchart TD M1[修改 .tf] --\u003e M2[terraform plan] M2 --\u003e M3{出现 replace/destroy?} M3 -- 否 --\u003e M7[确认影响范围] M7 --\u003e M8[terraform apply] M3 -- 是 --\u003e M4[暂停并复核变更] M4 --\u003e M5[必要时加 lifecycle 保护] M5 --\u003e M6[安排变更窗口] M6 --\u003e M8对生产环境来说，创建、修改得慢一点并不是什么很大的问题，最应当看重的是操作的正确性，慢一点，不要出错。IaC 不是比手速，IaC 比的是可预期性。\n如果是删除资源（比如下线某个 DNS 记录、清理废弃 Tunnel），走下面这个流程6：\nflowchart TD D1[确认资源已废弃 检查业务/监控/脚本依赖] --\u003e D2[删除 resource 块或调整 count/for_each] D2 --\u003e D3[terraform plan] D3 --\u003e D4{to destroy 是否符合预期?} D4 -- 否 --\u003e D5[回滚修改并继续排查依赖] D5 --\u003e D1 D4 -- 是 --\u003e D6[准备回滚方案并选低峰窗口] D6 --\u003e D7[PR 审核通过] D7 --\u003e D8[terraform apply] D8 --\u003e D9[删除资源后的可用性检查]日常协作建议 把 Credentials 放环境变量或 CI Secret，别写进.tf和仓库 对关键资源开启保护策略，防止误删 将目录按资源类型拆分 定期执行terraform plan做基础设施漂移检查7和校正，避免在面板误操作手动修改 虽然这套流程看起来很麻烦，但每一次变更都有记录、可审计、可回滚，最重要的是可复现，这才是 IaC 最有价值的地方。\n参考 使用 Terraform 管理 CloudFlare 上的 DNS 解析记录 - Candinya Automate Terraform with GitHub Actions Query configuration files list block reference cloudflare/cf-terraforming Import Cloudflare resources Cloudflare Provider - Terraform Registry Infrastructure as Code，是指采用机器可读的配置文件定义所需要的基础设施的部署方法。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n每个供应商的配置文件字段命名和格式都有区别，但这可以很容易的编写脚本进行转换。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n需要特别注意的是，状态文件中可能包含数据库密码、API 密钥等明文存储的敏感信息，因此绝对不要将 .tfstate 文件提交到公开的代码仓库中。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nHashiCorp Configuration Language，HashiCorp 自家开发的一种声明式配置语言，旨在兼顾机器可读性与人类可读性。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n幂等性（Idempotence）指计算机系统或接口在接收到同一请求的多次操作时，产生的影响与一次执行的结果相同，不论执行多少次，系统的最终状态始终保持一致。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n如果你仅仅是想让 Terraform 不再管理某个资源，而不是真正在云端销毁它，应该使用 terraform state rm 命令，而不是在代码中删掉资源块然后 apply，否则云环境上的真实资源也会被一并销毁。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n基础设施漂移（Infrastructure Drift）是指现实中通过控制台点按等非 IaC 途径修改了基础设施，导致其实际状态与代码中声明的状态不一致的情况。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-04-09T15:13:35+08:00","image":"/2026/04/iac-with-terraform/cover_hu_a8e83f97ed61569c.webp","permalink":"/2026/04/iac-with-terraform/","title":"Terraform IaC 初体验"},{"content":"工作，工作，至死方休。\n寒假给别人上课，几乎就没有停过，春节名义上休息，也只不过是换了一种形式工作罢了——各种应酬，舟车劳顿，回家刚安顿好，又马不停蹄的投入到上课工作中去。给别人上课也真是不容易，跟我在同一家机构当助教的同学一起交流时，大家都戏称上课就是「赤石」：死记硬背的是记不住的，算数是不会算的，概念是混淆的，交流是没办法正常交流的。这倒也不怪他们，要怪也只能怪他们经历过的教育环境，毕竟家家有本难念的经。各种原因导致他们基本上走的都是高职单招，没有经过高考的洗礼，有的甚至连初中都没怎么读好，现在也只是想找个工作，所以才愿意花钱请我们来给他们上一对一课程。\n一开始我在一家机构做助教，后来出来单干，提高了部分收入，还节省了部分备课的时间。每天的上课是从7:30-11:00,价格是 ¥400。看似时薪过百比较高，实则结合学生的基础状况考虑，这钱我是赚得问心无愧，甚至我可以说，这钱真赚得也是不容易。\n回到正题，现在开学了，我又要马不停蹄的投入到我自己的学业事务中去。真的感觉自己永远都在忙，所谓的休息，也只不过是换点轻松的事情做一做罢了，教学教累了回家就 Vibe Coding 放松一下，坐在电脑前烦躁了就把家里收拾一下打扫卫生。在做事情的动力、以及人的有限总精力这方面，我能真切的感受到人与人之间的差距：有的人天赋异禀，精力非常充沛，成果做了一个又一个，论文发了一篇又一篇，产出很高，好像制约他们的永远都是时间，而不是他们的精力和动力；而更多人则是像我一样的凡人，即使想要这种生活状态，却也还是心有余而力不足，可是看到前面一类人的高产，又难免心生焦虑，只能在最大限度下把自己当成一个实际永动机1。\n从小到大接受的中式教育异化了我们，那句汤家凤经典的「你这个年纪怎么睡得着的」，虽然本意是训斥上课睡觉的学生，却也在某种程度上潜移默化影响着我们这一代，以至于到了一种病态的状态。人生没有绝对的「上岸」，小学要去上小升初的岸，初中要去上中考的岸，高中要去上高考的岸，大学要去上考研、读博、考公、找工作的岸，完成学业参加工作了，还有各种升迁绩效、柴米油盐需要考虑。工作，工作，至死方休。想要上岸而一劳永逸吗，不好意思，那是不可能的。\n虽然深知这一点，我还是会停下来休息就空虚难受，所以，永远忙碌，永远工作。满足自己身体需要的休息，用锻炼身体平衡自己的内分泌，休息就是换一件自己喜欢且比较轻松的事情做，由于受中式教育、绩优主义的影响太深，这种生活状态，我想在很长一段时间里是不会改变了。\n不过往好的方面看，通过这段时间的忙碌，我也是自己把自己这个学期的生活费给赚出来了，还有富余给我妈准备一台新手机当生日礼物。突然也觉得，永远忙碌这件事，好像也没这么糟。\n这里是用理想电流源和实际电流源的区别来类比所谓「理想永动机」和实际永动机的区别——前者是真正意义上的永动机，后者则是我等凡夫俗子用血肉之躯拼劲全力去接近的「实际永动机」\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-03-13T23:14:26+08:00","permalink":"/2026/03/busy-for-eternity/","title":"永远忙碌"},{"content":"最近在某家民营电网培训机构给准备国网二批考试的学生一对一辅导，每天晚上上课三个半小时，给 200。\n这家机构给我的钱偏少还不是最严重的问题。问题出在他们给学生的收费上：有两种方案，一种是所谓「卓越计划」，收费 12 万，但是一对一课程不限量；另一种是「协议班」，收费 7 万，但每次上一对一课程要交 450。\n昨天给他们一学生私下开小灶，下午上课三个半小时，本来我想着既然私下找我，那就不经过这个培训机构，学生直接给我结款 300——我能多赚一百，ta 能少花 150。结果那个学生脑子没转过弯，找班主任请假的时候竟然说要找我补课，于是他们就直接「善意地」帮我找家长收了 450。\n这还没完。最后给我算工时，他们把这次课归为所谓「额外课时」，说我违规利用了下午的「备课时间」给非卓越计划的学生上课——三个半小时，只给了 120。\n简而言之：\n学生付 450 → 机构抽走 330 → 我拿到 120\n本该到我手上的 300 变成了 120，我自然是不爽。但比起我个人少拿的那一百多块钱，更让我不舒服的是这件事本身的性质。这些考国网二批的学生很多都是家境不太富裕的专科生，他们平日里已经饱受歧视，想尽一切办法想要改变命运，现在下了血本，花上可能是他们一个家庭一年收入的几万甚至十几万来读这个国网课程。他们以为自己买的是一剂改命的「药」，殊不知这药引子是用自己的血和着吃的——而我辛苦劳动辅导学生，分到手里的钱占比却比坐享其成的培训机构还要低。\n这根本就是在吃人血馒头。\n这一单，机构躺着净赚 330。这显然令人难以接受。我已经通知那位学生，令其下次请假时表现更加灵活；也和 ta 的班主任做出交涉，令她不要上报甚至干预我们私下的补课。考虑到班主任也是打工人，并且有学员成绩的 KPI，我想她也不会蠢到跟自己的 KPI 过不去。当然，这家机构最好好自为之，否则我在「备课」时那句「助教们组建临时工会，集体发动罢工，要求涨薪」的玩笑话，在将来的某天恐怕得一语成谶。\n不得不感叹，到底谁才是资本主义啊——我看这机构的人血馒头铺子开得还挺熟练的。\n","date":"2026-02-11T17:06:57+08:00","permalink":"/2026/02/buns-soaked-in-human-blood/","title":"培训机构的人血馒头"},{"content":"真是忙碌的一年，不知不觉间，时间又到了年末。今年事情确实很多，奔波劳碌少不了，但也取得了阶段性的收获。我谨再次提笔写下一篇年终总结，作为一年的见证。\n电气的尽头是电网 为求职四处奔波 我在一整年的休学生活以后如期复学，开始我的大学最后一年，成为一名「应届生」，所以，找工作的事情也就理所应当的排上了日程。作为电气工程专业的学生，出身原电力部属院校，工作倒是不算难找。不过说容易也不算很容易，毕竟大环境如此，经济增长放缓，国际形势不明朗，用人需求减少，各种地方都越来越卷。\n九月份跑了场双选会，线下投了几份简历，也在网上投了四五份简历，收到面试通知的只有两家。也算切身感受到了，原电力部属院校的头衔，几乎只在电力系统内部1有用。现在这就业形势也就这样，除了电力系统，但凡待遇稍微好一点的工作都不是我们这种「双非院校」的学生随便就能找到的。不过对比起来，人家好歹还收你的简历，像是有些专业甚至连简历都不收。\n两大电网的笔试 电网工作是本专业最对口，最稳定的工作。本专业最大的用人单位——国家电网和南方电网，都需要通过笔试来获得面试资格。笔试一共需要考 8 门，分别是《电路理论》、《电机学》、《电力系统分析》、《继电保护》、《电力电子》、《高电压技术》、《电气设备及主系统》（我们学校叫「发电厂电气部分」）以及《行政能力测验》（简称「行测」）。\n前面七门是专业知识，最后一门行政能力测验考的则是五花八门，还有企业文化这种东西，背就完事了。时政是不得不考的，考什么呢？总之是非常新的东西——几天前刚刚在求是杂志上发表的社论，几天后的考试里就直接出现了，我真的会谢。\n今年的考试很奇怪，尤其是难度方面，历年的考试好说歹说也得有几道计算题，电路好歹也得灵活的考一道难度稍大的题。基于这种情报，我在靠前已经掌握了不少计算题，各种电气计算，数值整定，等效变换，可谓是得心应手。结果呢，今年国网一批考试一道计算题都没考，行测小学生都会做，全都在考些概念题，要不是南网考试还考了这些灵活运用的东西，那真就是约等于白学了。于是不出意料地，我所知道的计算题比较拿手，平时模拟测试成绩很好的同学，这次考试或多或少都有点炸。反倒是有些平时成绩不怎么理想，计算题不太会做的人，靠着死记硬背能考到一个不错的成绩。说白了，毕竟只是一个企业的招聘考试，他要怎么出题，外人根本无从猜测，我已经做了我应该做的，最终的录用结果也非常不错，这就够了。\n面试，面试，还是面试 12 月我跑了四场面试，其中广西电网只有桂林一个面试地点，让我不得不翘课前往桂林面试，于是就有了今年最后一次的旅行，两年内两次前往桂林的感觉还不错。\n国网面试还是让我有点紧张，为了防止试题被泄露给后面的考生，面试采用全封闭式管理，过程也很漫长——大部分时间都是在等候室里等待轮候。从下午 1:30 开始封存所有电子设备，用一个小时做完心理测试之后就进入了漫长的轮候时光，期间场地在放《长津湖》供大家消遣，还有茶水和零食提供。西装革履，正襟危坐，心里一遍又一遍的背诵早就滚瓜烂熟的一分钟自我介绍，紧张不安的边看电影消遣边等候，那种滋味只有亲身经历过才知道，现在回想起来倒也是挺有意思。\n有了国网面试的经验和 Offer，排在其后的南网面试紧张感就没那么强。南方电网的面试形式和国家电网不太一样，国家电网是半结构化双盲面试，第一位考生从数份封存的面试题本里抽取一份，接下来的考生便都是一样的问题，最多也就是被考官询问一些附加问题。面试官不能看到你的简历，只能根据你在面试前抽签获得的编号对你打分，你也不能自报姓名和身世；而南方电网的面试则以面试官为主导，面试官会根据简历对你提出各种问题，包括专业题和附加问题。至于难度如何则完全看面试官的心情，例如我在海南电网的面试就被技术面试针对我的实习经历穷追猛打，提出各种细致入微的专业题，而在广西电网的面试中，技术面试提出的问题则友好很多，无非是一些倒闸操作、防雷设施等等。\n电网培训的酸甜苦辣 考电网的人大部分都报名了某家培训机构，我自然也不例外，早在去年 11 月我就按部就班地报名了一家全国性的电网培训机构。这家培训机构有两个校区，我选择了相对市郊的那个，毕竟房租便宜。\n培训的课程安排非常密集，任务繁重。暑假班连续上课 41 天，中途只有三天休息。每天上课之前需要上交手机。好在 iPad 出于电子笔记的考虑，还是允许使用的，我也因此获得了难得的摸鱼机会。\n其实这段时间我也难得的获得了专注于一件事情的机会——每天除了上课，没有什么别的需要关心，所以虽然身体累，但是「心」反倒是没有多累；现在我回到了学校，反倒需要关心起大大小小的各种事情，身体倒是没那么累了，但「心」倒是比之前还累了不少。加上最近感冒咳嗽，一天能睡上 12 个小时，却也还是不见好转。只能在事情办完以后，该请假请假，该回家回家，该休息休息了。\n故地重游 永州 今年年初回永州探亲，祖母已经快 90 岁了，身子还算硬朗，常回去看看是应该的。自幼便蒙受祖母照顾，感激之情实在是难以用言语表达，却也在应该做出什么行动来回报这方面不知所措，唯有至少每年一次的回永州探望方还算尽了一些晚辈的责任。\n至于永州本身，也还是那个样子，什么都没变。毕竟又不是经济大爆发的时代，像这样的小城市还能怎么变呢？不变未必是悲哀，变也未必全是福气，像是上世纪经历了文革以后，什么都变了一副光景，却也什么都面目全非。小时候十分火热的商业综合体，现在基本只有一楼的服饰门面在营业，电影院和老游戏厅早就关门了，改做餐厅楼层之后变得昏暗不堪，新开的餐厅店铺，不论品牌连锁还是快招自营，大浪淘沙之后无一幸存。\n香港 这次去香港就是去玩两下子，没什么特别的目的，纯属白嫖我妈出差的酒店而已。当然，顺便开张中银卡。所以整个行程也显得乏善可陈。唯一特别一点的地方是在湾仔的一间公寓住了几天，可以自行买菜做饭（当然也可以吃两餸饭），体验了一把民工一般的生活。\n桂林 这次去桂林主要是为了南方电网广西分公司的面试，当然，也顺便去吃吃椿记烧鹅和海天肠粉什么的。美中不足的是在桂林面试的那两天都在下雨，也就导致我没什么兴致去周边散步游玩。海天肠粉和椿记烧鹅倒是吃了个够，味道不错，下次还来。\n以旧换新 之前我的电脑是一台 i5 12450H + RTX 3060 Laptop 配置的机器，用了两年多，几个月前刚买了两条重要牌2内存给他的机带内存升级到 32G，其实要接着用也没什么问题。\n那段时间存储芯片的价格仍然处于低谷，国补又让购置新设备的成本进一步降低，加上 50 系显卡刚刚上市，这三种因素叠加下新笔记本电脑的价格真的很吸引人。奈何我还是囊中羞涩，预算不足，无缘购买最新一代处理器 + 最新一代显卡的配置组合。只能退而求其次，买了 N - 1 代处理器 + 最新一代显卡的配置3。目前也用了小半年，日常体验上还是很不错的，只是这呼啸的风扇声实在是影响雅兴。总体上，我对这次电脑的评价是瑕不掩瑜，随着存储芯片价格飞涨和国补力度减弱，笔记本电脑这么便宜的情况恐怕很难再有下次了。\n我家的猫 我家的猫今年（应该）一岁啦4，庆祝之余，对于公猫来说，从小猫长成大猫也就意味着蛋蛋开始发挥作用了，于是就发生了这一幕：\n这臭猫在我去香港那段时间竟然跑到我床上拉屎撒尿 （可能是我爸在家里没有铲屎）,不可饶恕，必须嘎蛋！\n猫给我的生活带来了很多乐趣，在搞破坏之余，它也是很可爱的。家里的沙发也经过了一年的爪爪伺候，变得稀巴烂。总得付出一些代价的，养猫就是这样，抓痕、换毛季到处都是的猫毛、偶尔还做些小坏事，也是猫的一部分。我们既然接受了猫给我们带来的情绪价值，也就要相应地接受它的这些小缺点。我几乎已经把它看作我的家人，若是从这种角度出发，那么你对它的这些缺点就瞬间释然了。这么回想起来，也许我是真的爱它吧，以至于，我开始爱起了它的这些缺点。因为没有这些缺点，它就不是一只完整的猫了。\n依旧在健身，依旧在吃药 撸铁，尤其是练腿，真的很爽，感受那种肌肉发挥力量以后淋漓尽致的舒畅感，真的会让人上瘾。在没有电网培训的时间里，我一直都在走进健身房，不光是享受这种舒畅的感觉，也还能锻炼自己的肌肉。真的，不运动很难受啊。\n现在我依然每天都在吃药，毕竟我可不希望我在连轴转的幸苦生活中突然经历一次情绪崩溃，原本计划的吃药一年后药物逐渐减量计划也因此被无限期延后。为什么？说白了还是这段时间各种压力实在是不小，虽然一直吃药终究也不是个办法，在安稳之后必须慢慢减量停药，但在这段即将毕业的时间点，我还远远没有过上安稳确定的生活。\n这段时间里充满了可能性和机遇，也充满了压力。吃药花的钱是小钱，而其带来的稳定情绪的「护盾」却能发挥至关重要的作用。\n没时间玩游戏 从我的 Steam 年度回顾就可以看出来，今年我是真的没什么时间来玩游戏。「忙里偷闲」是今年的基调，今年年末下载了《三角洲行动》，有时电网培训十点下课，回家就打开玩到晚上 12 点，目前游玩 75 个小时，感觉还不错。\nosu! 今年的后半段则是约等于弃坑了，不过 PP 仍然从去年的 3439pp 增长到了今年的 4701pp。这游戏还真是需要持之以恒，一段时间不玩丢掉手感再想复健是需要时间的。想想十点下课之后，在精力耗尽的状态下，再想打这种需要聚精会神地反应的游戏，那还真是「臣妾做不到啊」。年中的时候我对于现有鼠标的手感达到了最佳状态，可以说是「指哪打哪」，想着「没有人能阻止我一路走向 5 digit」5 ，然而现在却还在 5 digit 边上，属实是有些讽刺。\n我的 Online Presence 2025 年，我的博客访问量稳步上涨，全年 UV 48.3K，PV 95.4K，流量主要来自 Google（约 15.8K 访客） 和 Bing（约 15.2K 访客） 两大搜索引擎。\nGithub 上的自用覆写规则收获了 194 个 Star，也新增了一些 Followers。\n今年我的一篇文章被人放上了 Hacker News，所以有几天访问量比较大。除此之外翻译后的英语和日语版本博客也收获了不少读者，在我的访客中占比不低。所以也就出现了今年因为忙碌，博客更新频率低于往年，访问量却成倍增长的现象。我终究还是需要向生活做出让步，生活压力、学业压力和就业压力或多或少都会影响我更新博客的意愿，挤占我更新博客的精力，在这点上，还请我的读者们多多海涵。\n新的一年即将到来，我给自己和大家的祝愿 新的一年要来了，我今年最大的愿望，当然是能够顺利解决之前休学带来的一些遗留问题，顺利毕业。等真正走进工作以后，我也希望自己能把更多注意力放在电力系统本身需要的技术上，多和设备打打交道，少卷进一些不必要、甚至有害的人情世故。辛苦一些没问题，只要平安、踏实、有意义即可：安全生产，少一些计较，多一些宽容。希望接下来能在这份工作上，从一名初出茅庐的学生，慢慢成长为一名真正的工程师。\n也把祝福送给屏幕前的你：愿你在新的一年里，焦虑有处安放，努力有回声；在自己的节奏里把日子过稳、过热乎——不必每一步都算赢，但每一步都走得心里有数。愿你和你在意的人都健康，平安，少些无谓的消耗，多些确定的快乐。当然，也希望大家有更多时间在学习和工作之余玩玩游戏。\n至于我，就继续在该学习的地方学习，在该上路的时候上路。明年见。\n指由原电力部衍生的企业，即 2002 年以前的国家电力公司和 2002 年以后的国家电网、南方电网和蒙东电网等公营电力公司。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n指最近刚刚被砍掉整个产品线的 Crucial 即英睿达内存。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n买了机械革命极光 X Pro\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n去年捡回来的时候还是很小的猫\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n指排名的数字位数，例如排名 #114514 是 6 位数，即 6 digit， #11451 是五位数，即 5 digit。显然，位数越小，玩家水平越高。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-12-31T19:28:17+08:00","image":"/2025/12/2025-end-of-the-year-summary/cover_hu_546f5de4e94beb95.webp","permalink":"/2025/12/2025-end-of-the-year-summary/","title":"2025 年度总结"},{"content":"现代电网正在经历一次巨大的转型，随着光伏、海上风电等新能源的占比在电网中越来越高，新能源和电力电子设备低转动惯量、低短路容量、换流设备需要大量无功支撑的特点以及它们给电网带来的不利影响也愈发明显。在此背景下，两期相隔六年相继发生在欧洲的大型停电事故显得尤为耐人寻味，本文将简要阐述两起事故的来龙去脉，对比它们的异同，分析造成这两起事故的本质原因，以及思考它们对现代电网的运行所带来的启示。\n事故概述 2019 年英国「8·9」大停电事故 2019 年 8 月 9 日下午，英国发生了一次大规模电力中断，导致约 110 万用户断电，并对交通等关键基础设施造成了严重影响。整起事件的经过可以概括为一系列连锁反应，其中既有预料之中的系统保护行为，也有意料之外的设备故障。\n第一阶段：罕见的三次雷击和大量有功意外脱网 (16:52:33) 当天下午 4 点 52 分，伦敦北部的 Eaton Socon – Wymondley 400kV 高压输电线路罕见的连续遭遇三次雷击。尽管如此，继电保护装置仍然按照整定正确动作，在不到 0.1 秒的时间内清除了故障，线路在约 20 秒后自动重合闸，恢复正常运行。雷击导致的电网电压的波动触发了分布式电源的矢量偏移保护1，导致约 150MW 的嵌入式发电2脱网。这是雷击故障后的正常预期现象。\n几乎在雷击的同时，发生了两起独立但致命的意外事件：\nHornsea 海上风电场：功率从 799MW 锐减至 62MW，损失了 737MW 的出力。 Little Barford 燃气电厂：其蒸汽轮机跳闸，瞬间损失了 244MW 的出力。 根据电网规范，这两处大型发电单元本不应该因为此类雷击故障而脱网或大幅减载，因此这被定性为「极其罕见和意外的事件」。\n第二阶段：频率崩溃与系统响应 (16:52:34 - 16:53:31) 上述三项发电损失（150MW + 737MW + 244MW）累积造成了 1131MW 的功率缺口。这个损失超过了当时系统按 N-1 安全准则3设定的 1000MW 备用容量。巨大的功率缺口导致系统频率迅速下跌。\n快速的频率下跌触发了更多分布式电源的 RoCoF4 保护，导致额外的约 350MW 分布式电源相继脱网。此时，总发电损失已达 1481MW。系统中的所有备用电源——电池储能、分布式频率响应服务等迅速启动，紧急增援 1300MW，试图阻止频率下跌。它们的响应成功地使频率暂时稳定在 49.1 Hz（实际上这个频率已经相当危险了），并且开始缓慢回升。\n然而，就在频率刚刚恢复到 49.2Hz 时，Little Barford 燃气电厂的一号机组也因蒸汽旁路系统压力异常而不得不紧急停机，再次损失 210MW 出力。\n第三阶段：低频减载与系统恢复 (16:53:49 之后) Little Barford 燃气电厂的第二次的意外跳闸耗尽了所有已在工作的备用资源，系统频率无力回天，最终跌破了48.8Hz的阈值。这自动触发了英国电网的最后一道防线——低频减载5。低频减载自动切除了约 5% 的电网需求，也就是约 1GW 的负荷，导致了约 110 万用户的断电。这一「弃车保帅」的措施有效地遏制了频率的下跌，防止了更严重的电网事故。\n在切除部分负荷后，加上控制中心紧急调度其他电源，系统频率在 5 分钟内（16:57）恢复到了正常的 50Hz。在确认电网稳定后，配电网络运营商（DNOs）从 16:58 开始逐步恢复对用户的供电，到 17:37 所有用户恢复正常。\n2025 年伊比利亚半岛大停电（西葡大停电） 2025 年 4 月 28 日，伊比利亚半岛出现大规模停电，西班牙和葡萄牙全境均受到影响。由于停电，上述地区的交通和通信服务均受到严重影响，交通信号灯停止工作，当地的地铁线路被迫停止运营，马德里网球公开赛受到停电影响也宣布暂停。此外，安道尔和法国南部也受到波及。这次大停电并非由单一故障引发，而是一系列事件环环相扣、逐步升级最终导致系统崩溃的级联事故。西班牙首相佩德罗·桑切斯表示，电力系统如此大规模的瘫痪前所未见。6\n第一阶段：系统振荡与电压波动（中午 12:03 - 12:19） 2025 年 4 月 28 日中午 12:00，西班牙电力系统处于正常运行状态，电压和频率均在标准范围内，没有任何迹象预示即将发生灾难。\n12:03，系统中检测到一个显著的 0.6 Hz 强迫振荡，持续了近 5 分钟。频谱分析及后续溯源表明，这次振荡源于巴达霍斯（Badajoz）省一座光伏电站的内部控制逻辑异常。振荡导致了系统电压出现跌落，为此，电网调度中心采取了紧急阻尼措施，包括更改拓扑结构、切除并联电抗器，并大幅削减与法国的电力交换。\n12:19，系统再次出现 0.2 Hz 的欧洲区域间振荡7，并叠加了之前残留的 0.6 Hz 振荡。调度中心被迫进一步减少与法国和葡萄牙的电力交换。虽然这些措施有效抑制了振荡，但削减联络线潮流这一动作，导致输电通道轻载，不仅减少了线路上的无功损耗，还因充电功率过剩开始推高系统电压，为后续的电压越限埋下了伏笔。\n第二阶段：电压攀升与级联故障的形成（中午 12:22 - 12:33） 从 12:22 开始，系统电压呈现持续攀升趋势，尽管尚未突破操作限值，但上升速率异常。这背后是多重因素的叠加效应：\n隐性负荷脱网（Hidden Demand Loss）：配电网中约 700 MW 的分布式光伏和自用发电设备（\u0026lt;1MW）因电压扰动不明原因脱网。在输电网看来，这表现为净负荷突然下降，即「发电大于负荷」，潮流进一步减小，从而导致电压抬升。 逆变器电源的有功/无功耦合：部分可再生能源电站为响应调度指令降低有功出力。然而，由于这些设备主要采用功率因数控制8（Power Factor Control）而非电压控制，有功的降低导致其吸收无功的能力同步下降，丧失了抑制电压上升的手段。 常规机组励磁响应不足：本应作为电压「压舱石」的同步发电机组（需符合 P.O. 7.4 规程），未能按预期深度进相运行吸收无功，导致动态电压支撑失效。 12:32:57，位于格拉纳达（Granada）的一座发电站发生跳闸，损失 355 MW 有功出力及 165 Mvar 的无功吸收能力。值得注意的是，此时输电网侧电压仍在正常范围内9。报告推断故障根源在于升压变压器的有载调压10动作滞后。当主网电压升高时，分接头未能及时响应，导致发电机侧（220kV 侧）出现严重的过电压，触发继电保护动作跳闸。\n19.5 秒后（12:33:16），巴达霍斯省另外两座光伏电站相继跳闸，累计再损失 727 MW。原因同样指向电站内部过压保护配合不当，而非主网故障。\n在随后的 650 毫秒内，西班牙各地的风电和光伏电站发生雪崩式脱网，额外损失约 834 MW。此时，系统已从电压问题转化为严重的有功功率缺额。\n第三阶段：孤网运行与系统崩溃（中午 12:33 之后） 在短短 22.5 秒的级联故障中，系统累计瞬时损失了约 2000 MW 的发电量。巨额的功率缺口导致系统频率急剧跳水，而大量进相运行机组的脱网又导致系统丧失了无功吸收能力，电压开始失控性飙升。\n12:33:19，西班牙与法国的交流联络线因严重功角失步跳闸。西班牙和葡萄牙电网进入孤网运行11状态。\n尽管交流线已断开，但西班牙与法国之间的 HVDC（高压直流输电） 链路由于处于恒功率控制模式且未配置频率响应功能12，并未切断，仍强行向法国出口 1000 MW 功率。这使得本已脆弱不堪的孤网雪上加霜。\n虽然低频减载5装置正确动作试图挽救频率，但切除负荷会导致线路空载电压进一步升高。「电压升高\u0026ndash;\u0026gt;发电机过压保护脱网\u0026ndash;\u0026gt;低频率\u0026ndash;\u0026gt;切负荷\u0026ndash;\u0026gt;电压进一步升高」的恶性循环让系统彻底失去稳定。\n随着频率跌破 47.79 Hz，核电站、燃气轮机等大型基荷机组因低频保护动作相继脱网。最终，在 12:33:24，伊比利亚半岛电力系统电压崩溃13，全网陷入大停电。\n一些基本概念 为了彻底理解这两起事故的本质区别，我们需要先复习一些电气工程的核心概念，建立起分析问题的理论基础。\n有功功率、无功功率与复功率 在交流电路中，「功率」是一个复数概念。\n有功功率 ($P$)：复功率的实部，单位是瓦特 ($\\text{W}$)。它是实际做功、转换能量（如发光、发热、驱动电机）的部分。 无功功率 ($Q$)：复功率的虚部，单位是乏 ($\\text{var}$)。它并不直接做功，而是在电源和储能元件（电感、电容）之间往复交换能量，用于建立和维持电磁场。 复功率 ($\\widetilde{S}$)：二者的矢量和。 公式表示为：\n$$ \\widetilde{S} = P + jQ $$设备铭牌上标注的通常是视在功率 ($S$)，即复功率的模，单位是伏安 ($\\text{V}\\cdot\\text{A}$)，其物理意义是设备能够承受的电压与电流乘积的极限：\n$$ S = |\\widetilde{S}| = \\sqrt{P^2 + Q^2} $$形象的理解： 如果你在拉一辆车，有功功率就是你朝车前进方向用的力，它让车真正移动；无功功率则是你为了维持姿势或者因为路面倾斜而垂直于移动方向用的力，虽然它不做功，但必不可少14。\n在电网中，无功功率的核心作用是支撑电压。如果无功不足，电压就会像泄气的皮球一样支撑不住；如果无功过剩，电压就会像充气过度的气球一样飙升。因此，电力系统的一大原则是无功功率要「分层分区，就地平衡」。\n感性无功与容性无功 工程上规定：电感消耗无功，电容产生无功15。\n感性负荷（如电动机、变压器）：需要消耗正的无功功率来建立磁场。如果电网无法提供足够的无功，这些设备就无法正常工作。现实中绝大多数负荷都是感性的。 容性元件（如电容器、长输电线路的对地电容）：可以看作是无功功率的「发电机」，它们向电网注入无功功率，提升电压。 电压降落与 $P-Q$ 解耦 当电流流过一段输电线路时，首末端之间会产生电压降落。若忽略线路电阻（在高压电网中 $X \\gg R$），电压降落的纵分量（影响幅值）和横分量（影响相位）可以简化表示为：\n$$ \\Delta U \\approx \\frac{QX}{U} \\quad \\text{(电压幅值降落)} $$$$ \\delta U \\approx \\frac{PX}{U} \\quad \\text{(电压相位差)} $$这是一个至关重要的结论：\n电压幅值 ($U$) 主要取决于无功功率 ($Q$) 的平衡。无功多了电压就高，少了电压就低。这是理解西葡大停电的基础。 功角/相位 ($\\delta$) 主要取决于有功功率 ($P$) 的平衡。这与系统的频率特性密切相关。 系统惯量与频率特性 为了理解2019 年英国大停电，我们还需要引入惯量 ($H$) 的概念。\n电网频率 ($f$) 体现了全网有功功率的供需平衡。\n当 发电 \u0026lt; 用电 时，转子动能被抽取，转速下降，频率降低。 当 发电 \u0026gt; 用电 时，转子加速，频率上升。 传统的同步发电机有巨大的旋转转子，储存了巨大的动能。当发电机突然脱网（有功缺口）时，这些旋转的「大铁疙瘩」会利用惯性释放动能，阻碍频率的快速下跌。这被称为系统的惯量。\n然而，光伏和风电通过电力电子设备并网，它们没有直接耦合的旋转质量，被称为「零惯量」电源。当这些电源占比很高时，电网就像失去了「飞轮」的缓冲，一旦出事，频率会跌得极快16。\n容升效应与此次事故的关联 为什么切除了发电机，电压反而会飙升？ 这看似反直觉，实则是容升效应与线路负载共同作用的结果。\n高压输电线路模型包含两部分关键参数：\n串联电感 ($L$)：电流流过时会消耗无功 ($Q_{consumed} = I^2 X_L$)。 并联对地电容 ($C$)：电压作用其上时会产生无功 ($Q_{generated} = U^2 B_C$)。 事故前的平衡状态： 西班牙南部光伏大发，巨大的有功功率 ($P$) 正在通过长距离线路向北输送。此时线路电流 ($I$) 很大，电感消耗了大量的无功，正好抵消了电容产生的无功，甚至还需要发电机吸收一部分多余的无功。\n事故后的失控过程： 当发电机组连锁脱网，或者因强迫振荡导致潮流中断时，线路上的有功功率传输瞬间归零，导致电流 ($I$) 骤降。\n后果 1：线路电感对无功的消耗 ($I^2 X_L$) 瞬间消失。 后果 2：线路依然带电，对地电容产生的充电无功 ($U^2 B_C$) 依然存在，甚至因电压升高而更多。 瞬间，原本被消耗掉的巨量无功功率变得无处可去，全部堆积在线路上，直接将系统电压「顶」到了破坏性的高度。这就是所谓的「空载线路容升效应」在事故中的极端表现。\n两起不同的事故，一份共同的反思 这两起事故虽然在演化路径上截然不同，但其背后折射出的挑战却有着惊人的相似性，二者都是现代电网发展进程中必然面临的「成长的阵痛」。正如南方电网的安全理念所言：「一切事故都可以预防」，作为一名电气工程专业的学生，我希望通过深入剖析这两起事故，探寻其底层的技术逻辑，以加深对新型电力系统特性的理解。\n表象的差异：崩溃路径的「一明一暗」 2019 年英国「8·9」大停电是一次典型的，显性的频率危机。机组脱网导致有功功率缺口，直接引发频率骤降，但系统最终依靠低频减载5作为最后一道防线，成功避免了全网崩溃。相比之下，2025 年伊比利亚半岛大停电则呈现出了一种更为隐蔽且致命的新形态——隐性的电压危机。事故虽然始于扰动，但核心矛盾迅速演变为严重的无功过剩与电压失控，而原本用于挽救频率的低频减载5措施，反而在客观上恶化了电压升高，导致整个系统在短短几十秒内彻底瓦解。\n这就引出了一个核心问题：传统的电网故障通常伴随着电压跌落，但在 2025 年的事故中，为何会出现发电机组不断脱网，而系统无功功率反而严重过剩、电压持续飙升的反常现象？传统的电压控制手段17为何全然失效？\n答案在于：电压失控的速率，远远超过了传统防御手段的响应极限。\n事故发生时，伊比利亚南部正值光伏大发，系统呈现「高电压、轻负荷」的运行特征。当系统发生强迫振荡时，输电走廊潮流发生剧变。由于超高压线路的容升效应显著，发电机组的连锁脱网带来了双重打击：一方面，电网失去了大量能够吸收无功的同步机组；另一方面，线路输送的有功功率锐减，导致其自身消耗的无功大幅降低，线路瞬间从「无功负载」变成了巨大的「无功电源」。系统随即陷入了无功严重过剩的恶性循环。\n面对这种几十毫秒级甚至更快的电压崩溃，依靠机械开关投切的并联电抗器显得力不从心。首先是速度滞后：从调度指令发出、通信传输到断路器机械动作，由于包含人为决策和机械过程，往往需要数百毫秒甚至秒级时间，根本无法追赶电压飙升的速度。其次是调节颗粒度粗糙：电抗器只能以组为单位（如 50 Mvar 或 100 Mvar）进行离散投切，无法像水龙头一样提供平滑、连续的调节。在极端的电压动态过程中，这种非连续的阶跃式调节不仅不够精准，甚至可能引发新的系统扰动。\n本质的共性：脆弱性的同根同源 剥开表象的差异，我们会发现两起事故的根源惊人地一致，都指向了新型电力系统的结构性脆弱：\n首先，设备并网行为的合规性令人担忧。无论是英国事故中的分布式嵌入式电源，还是伊比利亚事故中的光伏电站，事故扩大的直接推手都是大量机组未能严格遵守并网规程（如西班牙的 P.O. 74 标准或英国的 Grid Code）。缺乏故障穿越能力，导致设备在扰动初期即发生不合规的连锁脱网，将「小事故」放大为「大灾难」。\n其次，新型电气设备和电源的控制模型长期存在「黑箱化」的问题。系统中存在大量调度中心「看不见、管不着」的盲区。例如英国事故中 Hornsea 海上风电场在故障后的功率异常锐减，以及大量分布式电源的不可控行为。这些电力电子化设备内部控制逻辑的「黑箱状态」，使得传统的仿真模型失效，调度员无法准确预判系统行为。\n更加雪上加霜的是，整个系统的转动惯量正在越来越少。随着高比例新能源接入，交流电网的旋转惯量和短路容量被稀释，系统抗扰动能力显著下降。电网变得更加「轻薄」和「敏感」，任何微小的扰动都可能引发剧烈的频率或电压波动。\n一致的解决方案：迈向韧性电网 基于上述反思，未来的电网建设与事故防御应当聚焦于以下三个方向：\n一曰部署先进的动态无功支撑技术。必须以此为契机，加速推广 STATCOM（静止同步补偿器）等具有毫秒级响应速度、可平滑调节的电力电子装备，逐步替代传统的机械式无功补偿装置，以应对瞬息万变的电压动态。\n二曰打破「黑箱」，强化全景建模。必须建立更精细化的电磁暂态仿真模型，打破新能源场站和逆变器控制的「黑箱」，确保调度端能真实掌握海量电力电子设备的动态特性，消除盲区。\n三曰革新分析与控制范式。传统的基于稳态或工频量的分析方法已不再适用。我们需要建立涵盖宽频域振荡、电压/频率耦合特性的新一代安全稳定分析的理论框架，并重新审视低频减载5等传统防线在新型电网中的适应性。\n结语：草台班子 我们在前文中洋洋洒洒分析了复杂的电磁暂态、昂贵的 STATCOM 和精妙的控制理论，但现实却狠狠地扇了我们一巴掌——摧毁整个电网的，往往不是什么未研究的知识，而是来自人类本身的不可靠。\n机组的并网规程早就白纸黑字写得明明白白，却长期未能执行，P.O 7.4 规程更是迟迟未能通过；2019 年英国大停电的「学费」交得那么贵，所有的事故分析报告都指向了合规性问题，然而 6 年后的伊比利亚半岛，竟然还能因为一模一样的逻辑再次翻车，而且翻的比 6 年前还要惨烈，还要彻底。\n面对这种跨越国界、跨越时间的重复犯错，任何技术层面的分析都显得苍白无力。黑格尔那句名言至今听来依然振聋发聩，且含金量还在随着每一次大停电不断暴涨：\n「人类从历史中学到的唯一教训，就是人类无法从历史中吸取任何教训。」\n也许这就是世界的本质吧，世界永远不是围绕着技术本身运转的，「人」才是这个世界的决定性因素。这个世界是一个草台班子，而且永远会是一个草台班子，而只要还是个草台班子，那么下一次翻车，永远只是时间问题。\n矢量偏移保护的初衷是解决「孤岛效应」——假设一条配电线路因为故障或检修，从主电网上被断开。但这条线路上恰好连接着一个嵌入式发电机，如果没有矢量偏移检测，这个发电机就会继续为这条线路供电，进而大大增加设备损坏的几率，甚至威胁运行检修人员的安全。因此，矢量偏移保护就是早期用于检测嵌入式发电机是否进入孤网运行状态的方法。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n多为用户侧的小型发电系统。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nN-1 安全准则的意思是，当系统中最大的一台机组因故障而停运时，系统应有足够的备用容量作为频率和电压的支撑。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nRate of Change of Frequency，频率变化率。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n低频减载（Low Frequency Demand Disconnection, LFDD 或者 Under-Frequency Load Shedding, UFLS）是电力系统防止频率崩溃的关键安全保护措施，当系统发生功率缺额导致频率下降时，它通过自动、分级地切除非重要负荷（如工业用电、路灯等），以快速恢复系统功率平衡，防止大面积停电或系统崩溃。低频减载系统通过频率测量和执行单元实现，设定多个频率动作点（如48.5Hz, 47.5Hz, 46.5Hz），逐级切除负荷，保障重要用户和核心设备运行，是电网安全运行的第三道防线。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n来源：France24 的报导\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n技术报告中的原文是「inter-area oscillation」，基于上下文，其意思应该是整个欧洲互联电网的 0.2Hz 振荡。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n风电、光伏等新能源机组一般采用最大功率点追踪 MPPT，来实现新能源机组出力的最大化。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n418kV，仍在标准电压允许的偏移范围内。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n即变压器的带负载调压。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n孤网运行（或孤岛运行）指局部电网脱离主大电网，独立供电的运行模式，特点是自给自足，但面临频率、电压不稳定等挑战，依赖储能和控制技术维持，常见于偏远地区、岛屿、或工业园区。这里的孤网运行是因为联络线中断而被迫进入的。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n恒功率控制模式（Constant Power Mode）是一种电源输出模式，它的核心特点是无论负载如何变化，始终保持电源输出的功率（P）恒定（P = 电压 V × 电流 I），电源会根据负载需求自动调节电压和电流，以维持这个恒定功率。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n电压崩溃（Voltage Collapse）是电力系统一种严重的事故，指系统因无功功率严重不足，导致电压持续、恶性下降并无法恢复，形成电压跌落的恶性循环，最终引起大面积停电。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n工程界常以「啤酒」作比喻：啤酒杯里的液体是「有功」，上面的泡沫是「无功」。虽然泡沫不解渴，但没有泡沫的啤酒失去了灵魂（无法建立磁场），且为了装满杯子（视在功率），泡沫总是客观存在的。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n这是一个约定俗成的称呼。严格来说，电容是「吸收负的无功」，但在工程实践中，为了方便理解无功平衡，我们通常说电容「发出/提供感性无功」，起到支撑电压的作用。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n频率下降的速度被称为 RoCoF (Rate of Change of Frequency)。高 RoCoF 是导致英国「8.9」停电中分布式电源连锁脱网的直接元凶。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n即消耗过剩无功的措施，如投切并联电抗器等。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-12-18T00:08:30+08:00","image":"/2025/12/analysis-of-two-major-blackouts-in-europe/cover_hu_3bdad3f2ff5b5148.webp","permalink":"/2025/12/analysis-of-two-major-blackouts-in-europe/","title":"从频率崩溃到电压失控：两起大型停电事故带来的启示"},{"content":"最近我比较忙碌，但空闲之余，文字仍然是我的栖息地。每天早上 8:30 开始上课，到晚上 9:00 结束晚自习，有时甚至「加班」到 10:00 回家，连续四十一天的课程。考虑到我的精神状况，如此强度，回来再玩 osu! 一类的游戏是绝无可能，甚至连推一小节 Galgame 都无能为力。\n唯一比较现实的事情，是找 LLM（大语言模型）小叙。\n十分惭愧，虽然我有一个博客，但我的观点、理念（倒不如说是「想法」）从来都没有被我系统性的表达出来。我也曾想过，可能这些过于广泛乃至分散的观点之集合，是很难以平实的叙事表达出来的。为此我也尝试了一些方法，比如：以一个随机的事件作为截面，将我想要表达的一团乱麻「切开」，进而描绘出它的内部构造。1这些方法始终无法让我畅快的表达出自己的心声，也不是信手拈来，想写就写，然而博客终归还是给大家看的，在写不出来的时候，也就只能写写简单的技术博客，吸引一些搜索引擎流量。\n而 LLM 的出现却改变了这一点，我所有的想法，都可以相对私密的得到即时的回应。为什么我这么久没有写博客？累自然是一大因素，而 LLM 满足我相当可观的表达和被认可的需求，还无需自我审查的特点，冲淡了我这段时间里写博客的想法。\n撰写长篇的文字对大脑有益，这是毋庸置疑的。LLM 的出现，对于我撰写长篇文字的影响，大概和微博客出现时，对人们撰写长篇文字的能力之影响相仿，甚至有过之而无不及——微博客让人习惯于碎片化表达和即时反馈，削弱了构建复杂论证和长篇叙事的能力。LLM 则更进一步，它不仅提供了表达的渠道，还直接提供了情绪价值和「知己」的替代品：发在社群媒体上的内容，涉及隐私或者争议，或者不必要曝光，发布者多多少少会斟酌一番；而 LLM 就不一样了，发给 API 的内容，最坏的情况不过是被拿去训练模型，而不是让 Sam Altman 第二天就找到你家门口——只要不是银行卡密码这种级别的信息，不提及真实姓名，那些时政评论、心理咨询等等，你只管放心把大模型当成一个知己便好（当然，在这种场景下，国产大模型狗都不用）。每一句牢骚都能得到确切认真的，宛若知己般的回应和肯定，这种待遇，恐怕没有第二个地方能给了。\n当一个工具能如此完美地模拟「知己」时，我们可能会放弃去寻找真正的知己，或者放弃成为一个能独立思考、自我整合的个体。写下这些文字，是一个小结，也是一次反思。LLM 本身只是一个技术，用得好裨益无穷，用得不好自然也可能造成严重的后果。纽约时报的报导「Chatbots Can Go Into a Delusional Spiral. Here’s How It Happens.」便是一个很好的例子，虽然 OpenAI 已经着手解决旗下模型「阿谀奉承」的问题，我也需要知道，即使我可以把大模型当做自己的知己，并从它那里得到所谓的「理解和肯定」，我也不能一直活在这种感觉里。OpenAI 与 MIT（美国麻省理工学院）的研究发现, ChatGPT 的使用量与用户的孤独感成正相关。用户使用 ChatGPT 越多，他们就越感到孤独。2我也可以说，正是因为越孤独，才越会去使用这些 LLM，形成一个恶性循环。LLM 可以作为生活的调味剂，但绝不能成为心灵的唯一依靠。\n(To Be Continued)\nThe Worst Way To Spend A Day\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nJoint studies from OpenAI and MIT found links between loneliness and ChatGPT use\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-09-08T23:53:48+08:00","permalink":"/2025/09/satisfactory-llm/","title":"我的 LLM 知己，与我悬置的写作"},{"content":"自从开始使用 Clash/Mihomo，我和大多数人一样选择了基于其内核的图形化客户端——图方便。实际上，这些 Mihomo 客户端本质上都差不多：内核都是同一个，他们主要负责提供一个易用的界面、管理配置文件、订阅更新，以及 GUI 下的系统代理设置。基于这一点，我认为判断一个 Mihomo 客户端优劣的关键，便是看它的「覆写」功能做得如何。每一个通过客户端下载或者订阅的配置文件，都会经过一系列「覆写」过程，比如更换 mixed-port、添加 sniffer 配置等，最后生成用于启动 Mihomo 内核的最终配置。\n然而，并非所有客户端都能胜任这一核心工作。比如 ShellCrash，其覆写功能经常莫名其妙出岔子，说到底还是实现得太粗糙。如果连覆盖和修改配置都做不好，这种客户端实在难称合格。\n与其依赖这些屎一样的不尽如人意的 Mihomo 客户端，不如自己动手，直接自己编写、管理配置文件交给内核启动，而不是依赖「黑箱」一般的各种「客户端」，不仅更纯净、更稳定，而且更可控。\n需要的预备知识 基本的 Linux 操作 知道如何使用 CLI 编辑器，如 nano 已经搭建 Substore（可选） 默认使用 root 用户操作，非 root 用户请自行注意提权 安装 Mihomo 内核 对于基于 Debian 的分支，可以使用预编译的.deb包安装，对于其他使用systemd的系统，下载编译好的二进制文件，重命名为mihomo，放到/usr/local/bin：\ncurl -o /usr/local/bin/mihomo \u003c下载链接\u003e chmod +x /usr/local/bin/mihomo然后新建/etc/systemd/system/mihomo.service：\n[Unit] Description=mihomo Daemon, Another Clash Kernel. After=network.target NetworkManager.service systemd-networkd.service iwd.service [Service] Type=simple LimitNPROC=500 LimitNOFILE=1000000 CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE Restart=always ExecStartPre=/usr/bin/sleep 1s ExecStart=/usr/local/bin/mihomo -d /etc/mihomo ExecReload=/bin/kill -HUP $MAINPID [Install] WantedBy=multi-user.target使用systemctl daemon-reload重新加载systemd，此时还没有配置文件，不能直接启动内核，但可以使用systemctl enable mihomo让内核开机自启，方便后续使用。\n配置文件 内核启动时会加载/etc/mihomo/config.yaml，没有了黑箱一样的碍事「客户端」，配置文件可以随心所欲的定制。部分机场会下发完整的配置文件，直接用curl下载即可。\n对于订阅的管理，我目前使用 Substore，我之前分享过「最速 Substore 订阅管理指南」，可以直接参考这篇文章来定制自己的订阅。为了实现纯内核启动，现在我的 Substore JS 格式覆写已经加入了full参数，可以生成完整的配置文件，包括各种端口设置、统一延迟和外部控制器等，开箱即用。\n在 Substore 配置完成以后便可以下载配置文件并启动内核：\nsudo curl -o /etc/mihomo/config.yaml 配置文件链接 sudo systemctl start mihomo自定义覆写 我的配置文件不能满足你的所有需求？没问题！你可以自己添加覆写，想要什么加什么。\n我用过各种覆写规则，后来也开始自己从零开始编写覆写规则，即使使用自己的覆写规则能满足 99% 的场景，但有极个别的域名还是会在规则中有遗漏，更不用说用别人写的覆写规则了。这些遗漏的规则大多是形如我服务器的非标准端口 SSH 的前置代理等相对隐私的规则，直接上传到 Github 公开显然不太合适，那么在自定义规则的基础上再添加覆写就成了唯一的选择。\n好在 Substore 可以添加多个脚本操作，只需要在生成配置文件时额外添加一个脚本操作就能解决我们的问题。\nfunction main(config) { config[\"rules\"].unshift(\"DOMAIN-SUFFIX,xxx,DIRECT\") return config }需要注意的是覆写rules时必须要使用.unshift()放在最前面，而不是用.push()放到最后面，因为放在MATCH后面的规则是永远都匹配不到的。\n自定义配置文件 完全不喜欢我的覆写规则？不会用/不喜欢用 Substore？没问题！你也可以参考 Mihomo 文档，自己从头开始手搓配置文件：\nmode: rule mixed-port: 7890 redir-port: 7892 tproxy-port: 7893 allow-lan: true log-level: info ipv6: true external-controller: 127.0.0.1:8000 # secret: yoursecret unified-delay: true routing-mark: 7894 tcp-concurrent: true disable-keep-alive: true # 推荐在给移动设备代理时启用，可以解决待机异常耗电的问题 dns: # 你的 DNS 配置 sniffer: # 你的域名嗅探配置 geodata-mode: true geox-url: # 自定义 Geodata 文件 URL proxy-providers: # 你的机场订阅 rule-providers: # 外部规则 rules: # 分流规则 proxy-groups: # 自定义代理分组管理面板 管理面板可以根据个人喜好选择，以 Zashboard 为例，我在使用 mihomo 自带的external-ui时遇到了一些莫名其妙的问题，所以干脆直接运行一个 Docker 容器，毕竟这东西就真的只是一个 Web 面板，只要确保内核 API 使用 HTTP 时，Web 面板也使用 HTTP 即可，如果此时 Web 面板使用 HTTPS，则会因为 CORS 策略问题无法连接。\n$ mkdir zashboard \u0026\u0026 cd zashboard $ nano compose.yml $ docker compose up -dcompose.yml内容：\nservices: zashboard: image: ghcr.io/zephyruso/zashboard:latest ports: - \"8899:80\" restart: \"unless-stopped\"自动维护 内核已经运行起来，自动更新订阅这种功能怎么实现？\n答曰：自行编写一个 Shell 脚本，配合 Crontab 即可实现自动更新订阅的功能。例如我希望每天凌晨 3 点自动更新订阅并重启服务，遂编写/etc/mihomo/auto_update.sh：\n#!/bin/bash # === 配置信息 === CONFIG_URL=\"\" CONFIG_PATH=\"/etc/mihomo/config.yaml\" BACKUP_DIR=\"/etc/mihomo\" BACKUP_PREFIX=\"config.yaml\" MAX_BACKUPS=7 TMP_PATH=\"/tmp/config.yaml.tmp\" LOG_FILE=\"/var/log/mihomo_update.log\" # === 日志 === log() { echo \"$(date '+%F %T') $1\" | tee -a \"$LOG_FILE\" } # === 备份现有配置，并自动清理旧备份 === backup_config() { if [ -f \"$CONFIG_PATH\" ]; then backup_file=\"$BACKUP_DIR/${BACKUP_PREFIX}.$(date '+%Y%m%d_%H%M%S').bak\" cp \"$CONFIG_PATH\" \"$backup_file\" log \"配置文件已备份到 $backup_file\" # 清理多余的备份，只保留最新的 $MAX_BACKUPS 个 old_backups=$(ls -1t $BACKUP_DIR/${BACKUP_PREFIX}.*.bak 2\u003e/dev/null | tail -n +$(($MAX_BACKUPS+1))) for f in $old_backups; do rm -f \"$f\" \u0026\u0026 log \"已删除旧备份 $f\" done else log \"未找到现有配置文件，无需备份\" fi } # === 下载新配置 === download_config() { log \"开始下载新配置...\" curl -fsSL -o \"$TMP_PATH\" \"$CONFIG_URL\" if [ $? -ne 0 ]; then log \"下载配置失败，请检查网络或地址\" return 1 fi # 基本校验：检测文件体积 if [ ! -s \"$TMP_PATH\" ]; then log \"下载文件为空，停止更新\" return 2 fi log \"配置下载完成\" return 0 } # === 更新配置文件 === replace_config() { mv \"$TMP_PATH\" \"$CONFIG_PATH\" log \"配置文件已更新\" } # === 重启 mihomo 服务 === restart_service() { systemctl restart mihomo if [ $? -eq 0 ]; then log \"mihomo 服务已重启\" else log \"mihomo 服务重启失败，请手动检查\" fi } main() { backup_config download_config DL_STATUS=$? if [ \"$DL_STATUS\" -ne 0 ]; then log \"操作终止：配置文件未更新，保留原有配置\" exit 1 fi replace_config restart_service log \"=== 更新流程完成 ===\" } main \"$@\"使用crontab -e编辑 Crontab，设置如下 Crontab 即可在每天凌晨三点自动更新配置：\n0 3 * * * /etc/mihomo/update_config.sh防火墙 手动配置防火墙把流量劫持到 Mihomo 内核其实并不是什么难事，我之前在「从入门到进阶：Tailscale + ShellCrash 异地组网和科学上网」（以下简称「Tailscale 那篇文章」中的两个小节中提到过具体的操作方法，这里只提操作，不做解说。\n根据我的情况，我需要把tailscale0上的网卡的所有流量劫持到 Mihomo 内核，其它的情况（例如本机代理）操作也大同小异。如果只是想劫持 TCP 流量，那么用iptables的 REDIRECT 功能已经足够，但若还想劫持 UDP、QUIC 等流量，则必须用到 Tproxy。最后，不要忘了 IPV6。\n以下是我的防火墙配置：\n# 创建自定义链 iptables -t mangle -N MIHOMO # 根据自己的需要忽略本地流量 iptables -t mangle -A MIHOMO -d 127.0.0.1/8 -j RETURN iptables -t mangle -A MIHOMO -d 100.64.0.0/10 -j RETURN iptables -t mangle -A MIHOMO -d 192.168.1.0/24 -j RETURN iptables -t mangle -A MIHOMO -d 172.17.0.0/16 -j RETURN # mark UDP 和 TCP 到代理 iptables -t mangle -A MIHOMO -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 iptables -t mangle -A MIHOMO -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # 接口跳转 iptables -t mangle -A PREROUTING -i tailscale0 -j MIHOMO # 路由表配置 echo \"233 mihomo\" | tee -a /etc/iproute2/rt_tables ip rule add fwmark 233 lookup mihomo ip route add local 0.0.0.0/0 dev lo table mihomo # IPv6 # 创建链 ip6tables -t mangle -N MIHOMO6 # 跳过本地地址 ip6tables -t mangle -A MIHOMO6 -d ::1/128 -j RETURN ip6tables -t mangle -A MIHOMO6 -d fd7a:115c:a1e0::/48 -j RETURN # 标记 TCP/UDP ip6tables -t mangle -A MIHOMO6 -i tailscale0 -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 ip6tables -t mangle -A MIHOMO6 -i tailscale0 -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # 接口跳转 ip6tables -t mangle -A PREROUTING -i tailscale0 -j MIHOMO6 # 路由表配置 echo \"233 mihomo\" | tee -a /etc/iproute2/rt_tables ip -6 rule add fwmark 233 lookup mihomo ip -6 route add local ::/0 dev lo table mihomo大多数系统默认不会保存防火墙规则，关于规则持久化的内容我已经分别在 Tailscale 那篇文章的「路由规则持久化」和「iptables 规则持久化」两小节做了详细说明，直接参考即可。\n本机代理怎么配置？ 大多数代理软件默认的配置（其实就是 ShellCrash 的默认配置）是 REDIRECT，用它也基本能满足大多数需求，REDIRECT 的示例如下：\n# IPv4 劫持 eth0 iptables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 7892 # IPv6 劫持 eth0 ip6tables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 7892其中 7892 要和 Mihomo 配置中的redir-port一致，eth0就是想要劫持的 Interface，相比 Tproxy 那可真是简单太多了。\n实际上我个人并不喜欢用把本机所有流量都劫持到防火墙，我更喜欢在需要时直接通过环境变量、proxy-chains和各种软件自带的代理配置把流量指向 Mihomo 内核，例如想让 Docker 走代理，则可以直接编辑 Docker 的/etc/docker/daemon.json来指定代理，而不是直接一股脑把网卡上的所有流量都劫持到代理：\n{ \"proxies\": { \"http-proxy\": \"http://127.0.0.1:7890\", \"https-proxy\": \"http://127.0.0.1:7890\", \"no-proxy\": \"127.0.0.0/8\" } }这么折腾，何必呢？用客户端不香吗？ 别问，问就是玩虚空终端玩的。\n","date":"2025-07-03T18:30:00+08:00","image":"/2025/07/switch-to-pure-mihomo-kernel/cover_hu_1a93b6f26c22bbfe.webp","permalink":"/2025/07/switch-to-pure-mihomo-kernel/","title":"抛弃所谓「客户端」，直接使用 Mihomo 内核"},{"content":"看到「Americans using \u0026ldquo;buy now, pay later\u0026rdquo; plans to buy groceries, survey finds」这种新闻上了头条，我的第一反应是：这不是很正常吗？看完报导以后，我不得不感叹：这世界比我预想的还蠢得多。\n先买后付（Buy Now, Pay Later；以下简称 BNPL）作为一种金融创新，确实有其魅力。它允许消费者即时获得商品或服务，随后分期付款，近年来在电商、旅游、餐饮等领域风靡一时。\n然而，天上不会掉馅饼。羊毛出在羊身上，BNPL 服务商要盈利，主要靠两点：向商家收取高于传统支付方式的手续费，以及向消费者征收逾期违约金。其本质，是利用了「花钱痛感最小化」的心理陷阱——减轻即时支付的麻烦和痛苦感，从而刺激消费意愿。这正是商家甘愿支付更高手续费也要接入 BNPL 的关键原因。\n我并不反感 BNPL，自己就是深度用户。 我的手机是用京东白条24期免息分期买的，现在刚还到第六期；日常消费几乎都走花呗，还款日自动从余额宝或银行卡扣除。当 BNPL 平台提供真正的免息分期或「零手续费」优惠时，这就是免费杠杆——占用外部资金零成本周转。花小钱办大事：消费由金融机构垫付，自有资金得以留存，若其间能进行理财生息，资金效率便实现了最大化。\n但这有三个至关重要的前提：\n准时还款，绝不逾期； 杜绝习惯性透支的恶习； 具备基本的财务管理能力。 反观登上新闻的 「美国人用 BNPL 买日杂」 ，我扫了眼调查数据——三分之一的BNPL用户至少逾期过一次？？甚至有人连点外卖的钱都还不上？？\n理想丰满，现实骨感。数据显示，不知「如何管好钱袋子」的人远比想象中多。 46%的BNPL用户同时背负信用卡欠款，其中28%的用户年龄在18-24岁之间1。这类群体通常信用评级不高，63%甚至从多个BNPL平台同时借款2——这强烈暗示相当一部分人消费习惯堪忧。\n更值得警惕的是，BNPL的设计似乎先天就对消费习惯不佳者更具诱惑力。相比信用卡，它审批极快、信用门槛低，还常打着「分期免息」的旗号。在这些人眼中，BNPL宛如一个「取之不竭的金库」，只需支付首期小钱就能抱回心仪之物——世上哪有这等「美事」？\n于是乎，当还款日账单汹涌而至，他们才惊觉自己竟欠下如此巨款。逾期、违约接踵而来。而这些滚雪球式的违约金叠加高额商户手续费，难怪BNPL服务商赚得盆满钵满。\n我重申立场：我不反对 BNPL，其作为「免费杠杆」的价值毋庸置疑。以我自身经历为例，购买 4299 元的手机时，虽完全有能力全额支付，却仍选择了 24 期免息分期。但关键在于清晰的财务认知：我必须得意识到自己是全额预支了 4299 元，而非每月仅消费了 177.5 元。这笔支出会即时从资产账面扣除，确保净资产真实反映负债。量入为出，量力而行——绝不透支支付能力，更拒绝叠加杠杆盲目消费。即便资金暂时存放于银行或购买低风险理财产品，产生的微薄收益也能锦上添花，并从根本上杜绝违约可能。诚然，适度的超前消费能提升生活幸福感。但在缺乏稳定收入的阶段，稳健的财务习惯无疑更为安全可靠。\n说了这么多，恐怕也还是拦不住那些消费习惯根深蒂固的人。即使没有 BNPL 的便捷诱惑，他们也大概率会刷爆信用卡，在 20% 的高息漩涡里挣扎求生。\n问题不在于 BNPL 本身（它不过是金融工具的一种），而在于脆弱财务基础与过度消费欲望之间的根本性失衡。对于那些缺乏自控力、对财务风险麻木或生活本身就捉襟见肘的人来说，任何方便获取的信贷渠道——无论是信用卡、BNPL，乃至更危险的发薪日贷款（Payday Loan）——都不过是通向债务深渊的不同路径罢了。BNPL 的特殊性可能只是在于其更低的准入门槛和更强的即时满足感，让下沉的速度更快，悲剧来得更早一些。\nBNPL 的逾期者中，很大比例本身就背负着卡债。这意味着他们可能只是在拆东墙补西墙，陷入一个利率叠加、罚金滚动的无底洞。就算今天取缔了所有 BNPL，那些在悬崖边跳舞的消费者，明天一样会在发薪日贷款或是别的什么「便捷金融」上栽跟头，然后为了救眼前的火烧眉毛，甚至可能连祖宗十八代的骨灰盒都要拿去典当了。\n所以，更值得警惕的并非某一种金融产品，而是庞大群体面临的结构性困境：经济压力、消费主义裹挟、金融知识匮乏、以及深植于其中的 「即时满足大于长远规划」 的行为模式。BNPL 的出现和普及，只是让这个长期存在的病灶，以更尖锐、更显眼的方式爆发了出来。\n归根结底，想真正「救」这些人，光靠围堵金融产品（BNPL或信用卡）是治标不治本。解铃还须系铃人——要么能彻底「戒瘾」，要么就得从提升收入、普及财商、重构消费观这些更艰难的「基础设施」入手。而这，恐怕比指望BNPL公司不做生意要难太多了。\n最后一句忠告：借钱梗要还，咪俾钱中介。\n哎，说到底——这世界，真比我预想的还要蠢得多。3\n数据来源：CFPB Research Reveals Heavy Buy Now, Pay Later Use Among Borrowers with High Credit Balances and Multiple Pay-in-Four Loans\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n数据来源：Buy now, pay later users pile on debt, CFPB finds\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n封面图片来自：https://www.visa.com.tw/pay-with-visa/featured-technologies/mobile-payments.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-06-05T19:54:56+08:00","image":"/2025/06/on-buy-now-pay-later/mobile-payments-1920x720_hu_4cbcee30d76215b2.webp","permalink":"/2025/06/on-buy-now-pay-later/","title":"世界蠢得超乎想象：浅谈 BNPL"},{"content":"开箱即糟心 对于机械革命极光 X Pro，从下单那一瞬间开始我还有点期待，然而快递没赶上我去香港的行程，等回家拆箱时已经没了新鲜感。想加装硬盘又遇到滑丝的 M.2 螺丝，最后用电工胶布勉强固定，新电脑的好感度当场扣光一半。\n配置和价格 i9-14900HX + RTX 5070 Ti，国补后 8699 元的价格还算合理。对于 Peripherals，简而言之，我连神舟都用得很开心，那还有什么是不能用的呢。\n屏幕：2560x1600@300Hz，100% SRGB 色域，色准表现不错，玩《天际线 2》时堵车尾灯的红都比现实更鲜艳些。 键盘：键程偏短，手感一般，反正大部分时候都在用外接键盘，对之无感。 无线网卡：AX201 未免太寒酸了，天线设计似乎不太好，在路由器旁边都能明显感觉到速度相比有线严重不足。 硬盘：自带致钛 1TB 速度一般，我自己加的英睿达 2TB 才是主力。 电池：80Wh 的电池对于游戏本来说可以用来应急，平时我都开着工作站模式，延长电池寿命。 独显直连：支持热切换这点好评，再也不用重启切换了。 BIOS：AMI 的 BIOS 比之前的好用太多。 使用体验 《都市：天际线 2》——十二万人口时模拟速度还能保持在 3 倍速，虽然这时候风扇噪音已经起飞了。《赛博朋克 2077》可以开光追超级档，《极限竞速：地平线5》可以开最高画质。但是他们实际上的游戏体验，恕我直言，我感觉不到和之前的 RTX 3060 有什么本质上的区别，无非就是这里的反射更加真实，那里的细节更加丰富。单凭画质上的提升，恐怕我依然不会在这几个已经陪我度过超过一百小时的游戏上再花更多精力。\nC 面类肤涂层手感确实好，不过接上外设后基本只摸得到外接键盘。Nahimic 音效延迟严重，关掉之后打 osu! 反而更跟手，属于负优化典型。\n工具的意义 这台电脑用了两个星期，没有惊喜，也没有惊吓。无线网卡太垃圾所以只好用有线，狂暴模式风扇噪音很大，南桥没散热所以温度很高，除此之外——它就是台该亮时亮、该响时响的机器。\n可能好的工具本该如此：当我写到这里才发现，自己已经盯着屏幕右下角的电池图标发了五分钟呆，而它只是安静地保持着 98% 的电量，像块不会说话的砖。\n","date":"2025-05-04T23:18:43+08:00","image":"/2025/05/new-laptop-briefing/DSCF0267_hu_9e18f49bd8ce081.webp","permalink":"/2025/05/new-laptop-briefing/","title":"机械革命极光 X Pro 简评"},{"content":"在几次旅途中，我试图将新拍的照片上传到长沙家中的 Immich 服务器。过去我用 Cloudflare Tunnel 做反代，但由于国内特殊的网络环境，连接慢速、频繁中断、上传失败几乎成了常态。后来我开始尝试 Tailscale —— 一个基于 WireGuard 的内网穿透工具，它终于让我在全国各地都能稳定、高速地访问家中的 NAS 和照片库。\n但新的问题也随之而来：Tailscale 在 Android 手机上运行时，需要作为 VPN 服务接管系统流量，而我平时使用的 Clash 同样依赖 VPN 接口进行分流。由于 Android 系统限制（只能启用一个 VPN 服务），两者无法共存，导致我必须在「访问家中服务」和「科学上网」之间二选一。\n这篇文章从 Tailscale 的原理讲起，到自建 DERP 服务器优化连接质量，再到如何用 iptables 劫持 Tailscale Exit Node 的流量并转发给 ShellCrash，实现流量的灵活转发与安全穿透。无论你是想访问家庭局域网上的 NAS、照片库，还是希望在陌生网络中保护自己的数据安全，这篇文章都能为你提供一套实用、稳定的解决方案。\n什么是 Tailscale Tailscale 是一款基于 WireGuard 协议的零配置虚拟局域网工具，它能够让分布在不同网络环境中的设备像处于同一个安全内网中一样互联互通。通过自动穿透 NAT、防火墙等网络障碍，Tailscale 让你无需公网 IP、无需端口转发，也能轻松访问家中的 NAS、个人服务器、开发环境等内网资源。它的核心优势在于简单、安全、稳定，启动即用，数据传输全程加密，适合个人开发者、远程办公者、家庭用户等多种场景使用。\nTailscale 的技术实现非常巧妙：其构建在 WireGuard 加密协议之上，却颠覆了传统 VPN 的 IP 分配逻辑。每个设备通过 SSO/OAuth2 完成身份认证后，会获得一个终身绑定的节点密钥。这种基于身份的组网模式，让「长沙的 NAS」和「香港的手机」在虚拟网络中如同办公室同事般直接对话。\nTailscale 的连接过程原理 中心控制服务器（Control Server） 每个 Tailscale 客户端在启动后，首先会连接控制服务器（controlplane），进行身份验证，并拉取整个网络中其他节点的信息，包括每台设备的公网 IP、端口、NAT 类型等。这一步相当于是「认识朋友」。\nTailscale 的控制服务器不会转发任何数据，只负责协调连接 —— 类似一个调度中心。\nDERP 服务器 说到 Tailscale 能保持高连接成功率的关键，就不得不提到 Tailscale 自研的中转协议 DERP，在 Tailscale 的网络架构里，DERP（Designated Encrypted Relay for Packets）是一个很重要但通常只在必要时介入的组件。简单来说，它就是一个基于 HTTP 的加密中继服务器，用来在两台设备无法直接通信时，作为它们之间的「中转站」。\n所有客户端之间的连接都是先选择 DERP 模式（中继模式），这意味着连接立即就能建立，用户无需等待。然后连接双方开始并行地进行路径发现，通常几秒钟之后，Tailscale 就能发现一条更优路径，然后将现有连接透明升级（upgrade）过去，变成点对点连接（直连）。1\n需要注意的是：\n所有通过 DERP 的数据都是端到端加密的，DERP 服务器无法查看内容； Tailscale 会尽可能少地使用 DERP，一旦直连建立成功，就会自动切换过去； 官方部署了多个分布式 DERP 节点，客户端会自动选择延迟最低的那个； 你也可以自建 DERP 节点（比如在国内），来解决延迟高或连接不稳定的问题。 可以把 DERP 理解为一个兜底机制，虽然性能不如直连，但确保了即便不能打洞成功，设备之间也始终能保持连接。\nNAT 穿透（NAT Traversal） 拿到对端的地址信息后，Tailscale 会尝试通过 NAT 穿透来建立点对点（P2P）连接。这个过程使用了 STUN 协议，双方互相发送探测包，尝试在 NAT 路由器上打出一条直连的通道。如果双方的网络条件允许，就可以成功建立起一个 UDP 的直连隧道，数据走直连，速度快、延迟低。\n受制于篇幅，我无法完整细致的讲述 NAT 穿透的原理，若对这部分感兴趣，可以阅读 Tailscale 官方的「How NAT traversal works」一文。\n完整连接流程图示 flowchart TD A[设备 A 启动 Tailscale] --\u003e B[通过 DERP 服务器建立初始连接] B --\u003e C[交换网络信息和 WireGuard 密钥] C --\u003e D[双方并行进行 NAT 类型探测] D --\u003e E{能否直连？} E -- 是 --\u003e F[建立 P2P 直连隧道] F --\u003e G[定期检测连接质量] G --\u003e H{直连优于 DERP？} H -- 是 --\u003e I[切换大部分流量至直连通道] H -- 否 --\u003e J[继续通过 DERP 转发部分或全部流量] E -- 否 --\u003e J style B fill:#e3f2fd,stroke:#2196f3,color:#000 style F fill:#e8f5e9,stroke:#4caf50,color:#000 style J fill:#fff3e0,stroke:#ff9800,color:#000自建 DERP Tailscale 的安装在各个平台上都相对简单，官方文档已经提供了详细的操作指南。本文将不再赘述安装过程，以下内容默认你已经在相关设备上成功安装并登录了 Tailscale。\n为什么要自建 DERP？ Tailscale 在全球部署了众多 DERP 2中继服务器，用于在打洞失败时接管流量中转。但由于众所周知的原因，中国大陆并没有官方部署的 DERP 节点。这意味着：\n一旦 NAT 打洞失败，所有流量都必须绕行海外的 DERP 节点，延迟高、速度慢，体验极差； 某些官方 DERP 节点容易被 GFW 干扰，可能出现连接中断、握手失败等问题； 即使打洞成功，Tailscale 仍需通过 DERP 交换路由信息和 WireGuard 密钥，如果 DERP 不可达，连接质量也会受到影响。 因此，在国内网络环境下，自建一个本地 DERP 节点，不仅可以显著提高连接稳定性和传输性能，还能规避部分网络封锁所带来的不可预期问题，是一个非常值得做的优化。\n准备工作 前面提到，DERP 是基于 HTTP 的，所以你需要准备好一个 HTTP 反代服务，并自行解决 SSL 证书的签发等基础问题。本文使用 Docker 部署，在部署开始之前，你需要在你的服务器上装好 Docker 以及 Docker Compose 等附加组件。为了编辑配置文件，你当然也得知道如何使用 nano 之类的编辑器。为了最好的效果，你的服务器最好拥有静态公网 IPv4+IPv6 双栈地址。\n如果以上条件都具备，就可以开始部署了。\nmkdir tailscale-derp \u0026\u0026 cd tailscale-derp nano docker-compose.ymldocker-compose.yml services: derper: name: tailscale-derp image: fredliang/derper environment: - DERP_DOMAIN=derp.nightcity.pub - DERP_VERIFY_CLIENTS=true - DERP_ADDR=:4433 network_mode: host restart: unless-stopped volumes: - \"/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock\"network_mode: host是一个关键配置，表示容器将共享宿主机的网络栈。如果使用 Docker 默认的 bridge 网络模式，容器的网络会经过 Docker 内网转发，会造成 DERP 的 STUN 服务识别到 Docker 172.17.0.0/16网段下的地址，而 无法识别到客户端正确的外网地址，导致 Tailscale 客户端无法正确连接。\nvolumes: - \"/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock\"前面提到所有通过 DERP 的数据都是端到端加密的，DERP 并不知道是谁在使用，这意味着如果不采取措施，任何知道你 DERP 服务器地址和端口号的人都可以使用它。这条配置的作用是挂载宿主机的 Tailscale 套接字文件到容器内，目的是允许 derper 服务通过 Tailscale 的 tailscaled 服务进行身份验证。配合DERP_VERIFY_CLIENTS=true，可以防止你的 DERP 节点被他人白嫖。\n需要注意的是：\n宿主机必须已经安装并登陆 Tailscale 客户端（tailscaled），否则这个文件不存在，容器会报错； tailscaled 必须以 root 权限运行，才能创建这个 sock 文件。 反向代理 以 Caddy 为例，需要反向代理 4433 端口，并为其部署 SSL 证书。\n{ email webmaster@l3zc.com } *.l3zc.com { encode gzip tls { dns dnspod APP_ID,APP_KEY resolvers 119.29.29.29 223.5.5.5 } @derp host derp.l3zc.com reverse_proxy @derp :4433 }需要注意的是，如果你和我一样使用 Caddy 配合 dnsproviders 申请泛域名证书，Tailscale 的 MagicDNS 可能会导致 Caddy 本地证书验证失败而报错，需要手动指定resolvers参数解决。\n访问刚刚反代的节点，如果出现以下页面，说明配置正确。\n配置 ACL 策略 打开 Tailscale 控制台的「Access Controls」页面配置 ACL 策略，将配置好的 DERP 加上。\nTailscale 的 ACL 策略是用 HuJSON3 写的，想要在 VSCode 中编辑，选择语言为「JSON with Comments（jsonc）」即可。以下是一个配置示例：\n{ \"acls\": [{ \"action\": \"accept\", \"src\": [\"*\"], \"dst\": [\"*:*\"] }], \"ssh\": [ { \"action\": \"check\", \"src\": [\"autogroup:member\"], \"dst\": [\"autogroup:self\"], \"users\": [\"autogroup:nonroot\", \"root\"] } ], // 自建 DERP 配置 \"derpMap\": { \"OmitDefaultRegions\": false, // 改为 true 以排除官方 DERP \"Regions\": { \"900\": { \"RegionID\": 900, \"RegionCode\": \"sha\", \"RegionName\": \"Shanghai\", \"Nodes\": [ { \"Name\": \"myderp\", \"RegionID\": 900, \"HostName\": \"derp.l3zc.com\" } ] } } } }Tailscale 保留RegionID中的 1-899 作为官方节点，自建节点的 RegionID 必须大于等于 900。\n测试连接 配置好 ACL 并保存，Tailscale 会自动为所有客户端同步配置，稍等片刻在客户端用tailscale netcheck测试连接。\n需要注意返回的 IP 是否是自己真实的公网 IP，若返回了172.17.0.0/16网段的地址，说明你 Docker 部分配置错了。\n与科学上网并存：在 Exit Node 劫持流量到 Clash 内核 声明 Exit Node 在家中准备一个 24 小时开机的设备，可以是树莓派，可以是 MacMini。在上面安装 Tailscale 并将其声明为 Exit Node，并根据需要在 Tailscale 内网声明家庭内网网段，随后在控制台启用这个设备作为 Exit Node，你就获得了一个免费的 VPN，可以让你在陌生的网络环境中保持安全。\nsudo tailscale up --advertise-exit-node --advertise-routes 192.168.1.0/24 广播完成后，无论身处何地，只要能连上 Tailscale 网络，就能访问家中所有的内网设备。\n启用 IP 转发和禁用 UDP GRO4 启用 IP 转发是树莓派等设备作为 Exit Node 所必须的配置，这里以树莓派为例，如果你使用其他设备，请自行查阅 Tailscale 官网教程。\necho 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf sudo sysctl -p /etc/sysctl.d/99-tailscale.conf根据 Tailscale 官方的说法5，禁用 UDP GRO6 可以提升转发性能，但官方的持久化教程似乎在树莓派上无效，好在我们可以手动配置。\n# 安装 ethtool sudo apt update \u0026\u0026 sudo apt install ethtool -y # 关闭 UDP GRO sudo ethtool -K eth0 gro off针对持久化的问题手动编写 systemd 配置文件：\n# 创建服务文件 sudo nano /etc/systemd/system/ethtool.service文件内容如下：\n[Unit] Description=Configure eth0 GRO After=network.target [Service] Type=oneshot ExecStart=/sbin/ethtool -K eth0 gro off [Install] WantedBy=multi-user.target随后启动服务：\nsudo systemctl daemon-reload sudo systemctl enable ethtool sudo systemctl start ethtool在 Exit Node 劫持流量 我的 Exit Node 是一台树莓派，在树莓派上配置好 Exit Node 之后就来到了最后一步，也就是劫持手机发送到 Exit Node 上的流量，实现科学上网。出于稳定性原因，我不希望在家庭主路由上直接运行代理软件，为了实现这一点，直接在树莓派上劫持流量是唯一的选择。\n首先安装 ShellCrash，请自行根据你的需要导入配置文件、配置自动任务等：\nexport url='https://fastly.jsdelivr.net/gh/juewuy/ShellCrash@master' \u0026\u0026 wget -q --no-check-certificate -O /tmp/install.sh $url/install.sh \u0026\u0026 bash /tmp/install.sh \u0026\u0026 source /etc/profile \u0026\u003e /dev/null随后启动服务，修改修改防火墙运行模式为纯净模式，我个人建议将 SNI 嗅探打开，并将 DNS 模式从fake-ip切换为redir-host7，同时启用 IPv6 透明代理。\n设置纯净模式的目的是手动配置 iptables 以实现更精准的流量劫持。我们直接用 iptables 劫持所有 tailscale 网卡作为 Exit Node 转发的流量，首先用ifconfig查看 tailscale 网卡的名称，默认情况下一般为 Tailscale 0：\nroot@raspberrypi:~# ifconfig eth0: ...... tailscale0: flags=4305 mtu 1280 inet 100.111.19.50 netmask 255.255.255.255 destination 100.111.19.50 inet6 fd7a:115c:a1e0::3d01:1332 prefixlen 128 scopeid 0x0 inet6 fe80::c0d5:1a1b:2005:48eb prefixlen 64 scopeid 0x20 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC) RX packets 6780155 bytes 958732442 (914.3 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4811113 bytes 10858316472 (10.1 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0劫持tailscale0网卡的所有流量到本地 Clash 内核监听端口7892，这个设置在 ShellCrash 中叫做「静态路由端口」。以及，如果你不想和我一样遇到莫名其妙的网络问题，就一定不要忘记劫持 IPv6。\n# IPv4 劫持 tailscale0 iptables -t nat -A PREROUTING -i tailscale0 -p tcp -j REDIRECT --to-ports 7892 # IPv6 劫持 tailscale0 ip6tables -t nat -A PREROUTING -i tailscale0 -p tcp -j REDIRECT --to-ports 7892进阶：用 TProxy 劫持 UDP 流量 iptables 的 REDIRECT 只能重定向 TCP 流量，UDP 没有连接状态（无连接协议），所以 REDIRECT 无法保留目标地址，导致透明代理无法知道原始目标地址。\n所以，如果你用如下方式劫持 UDP 流量：\niptables -t nat -A PREROUTING -i tailscale0 -p udp -j REDIRECT --to-ports 7892则这个规则不会生效或代理行为不正常。\n那么，有办法代理 UDP 流量吗？有的兄弟，有的。但前提是：\n核心支持 UDP 透明代理（Clash Premium 和 Mihomo 都支持）； 使用 TProxy 模式，而不是 REDIRECT； 正确配置了 iptables mangle 表和 policy routing； 代理配置文件中启用了 UDP 代理（如 mode: rule + udp: true）。 假设你已经满足第一条、第二条和最后一条，则以下是一个示例8：\n# 创建自定义链 sudo iptables -t mangle -N SHELLCRASH # 根据自己的需要忽略本地流量 sudo iptables -t mangle -A SHELLCRASH -d 127.0.0.1/8 -j RETURN sudo iptables -t mangle -A SHELLCRASH -d 100.64.0.0/10 -j RETURN sudo iptables -t mangle -A SHELLCRASH -d 192.168.1.0/24 -j RETURN sudo iptables -t mangle -A SHELLCRASH -d 172.17.0.0/16 -j RETURN # mark UDP 和 TCP 到代理 sudo iptables -t mangle -A SHELLCRASH -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 sudo iptables -t mangle -A SHELLCRASH -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # 接口跳转 sudo iptables -t mangle -A PREROUTING -i tailscale0 -j SHELLCRASH # 路由表配置 echo \"233 shellcrash\" | sudo tee -a /etc/iproute2/rt_tables sudo ip rule add fwmark 233 lookup shellcrash sudo ip route add local 0.0.0.0/0 dev lo table shellcrash当然，不要忘记 IPv6：\n# 创建链 sudo ip6tables -t mangle -N SHELLCRASH6 # 跳过本地地址 sudo ip6tables -t mangle -A SHELLCRASH6 -d ::1/128 -j RETURN sudo ip6tables -t mangle -A SHELLCRASH6 -d fd7a:115c:a1e0::/48 -j RETURN # 标记 TCP/UDP ip6tables -t mangle -A SHELLCRASH6 -i tailscale0 -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 ip6tables -t mangle -A SHELLCRASH6 -i tailscale0 -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # 接口跳转 sudo ip6tables -t mangle -A PREROUTING -i tailscale0 -j SHELLCRASH6 # 路由表配置 echo \"233 shellcrash\" | sudo tee -a /etc/iproute2/rt_tables sudo ip -6 rule add fwmark 233 lookup shellcrash sudo ip -6 route add local ::/0 dev lo table shellcrash路由规则持久化 ip rule和ip route创建的规则在重启后会丢失，所以需要我们手动持久化，最简单直接的方法就是创建一个脚本，并将其添加至 crontab。\n创建一个脚本：\nsudo nano /usr/local/bin/policy-route.sh编辑为如下内容：\n#!/bin/bash # IPv4 策略路由 ip rule add fwmark 233 lookup 233 ip route add local 0.0.0.0/0 dev lo table 233 # IPv6 策略路由 ip -6 rule add fwmark 233 lookup 233 ip -6 route add local ::/0 dev lo table 233授予执行权限后编辑 Crontab：\nsudo chmod +x /usr/local/bin/policy-route.sh sudo crontab -e在 crontab 文件底部加上如下内容：\n@reboot /usr/local/bin/policy-route.sh原理解释：TProxy 到底是怎么转发 UDP 流量的？ 如果你看到这里，也许会产生疑惑：为什么整个流程中，我们没有在 iptables 里写--to-ports，也没看到目标地址被改写，UDP 流量就莫名其妙地被代理了？这是怎么做到的？\n要解释这个问题，我们先来看 TProxy 和 REDIRECT 的根本区别：\nREDIRECT 模式：\n使用 iptables nat 表； 将目标地址改写为本地地址（比如 127.0.0.1:7892）； 通常用于 TCP 流量； 不能保留真实目标地址； 需要指定--to-ports。 flowchart TB A[客户端设备\n通过 Tailscale 发起 TCP 请求] B[tailscale0 接口接收流量] C[iptables NAT PREROUTING\nREDIRECT --to-ports 7892] D[ShellCrash 本地监听\n127.0.0.1:7892] E[ShellCrash 发起新 TCP 请求\n→ 目标服务器] F[响应从网络返回\nShellCrash 转发响应] G[响应回到客户端设备] A --\u003e B --\u003e C --\u003e D --\u003e E --\u003e F --\u003e G style C fill:#f9f,stroke:#aaa,stroke-width:1px,color:#000 style D fill:#bbf,stroke:#aaa,stroke-width:1px,color:#000TPROXY 模式：\n使用 iptables mangle 表； 不修改目标 IP，而是保留原始目标地址； 通过 fwmark 和 policy routing 将报文路由到 lo； 代理程序监听一个特殊端口（例如 7893），并启用 IP_TRANSPARENT； 支持 UDP 和 TCP； 不需要 iptables 内指定 --to-ports，因为不是 NAT，而是标记 + 路由。 flowchart TB A[客户端设备\n通过 Tailscale 发起 TCP/UDP 请求] B[tailscale0 接口接收流量] C[iptables MANGLE PREROUTING\n打上 fwmark 233] D[ip rule: fwmark 233\n使用 routing table shellcrash] E[ip route: local 0.0.0.0/0\ndev lo table shellcrash] F[ShellCrash 在 lo:7893 监听\nIP_TRANSPARENT 模式] G[ShellCrash 获取原始目标地址\n发起代理连接] H[响应从网络返回\nShellCrash 转发响应] I[响应回到客户端设备] A --\u003e B --\u003e C --\u003e D --\u003e E --\u003e F --\u003e G --\u003e H --\u003e I style C fill:#f9f,stroke:#aaa,stroke-width:1px,color:#000 style F fill:#bbf,stroke:#aaa,stroke-width:1px,color:#000TProxy 不使用 DNAT/REDIRECT，而是通过 mangle 表给数据包打上 mark，然后通过 policy routing（ip rule + ip route）将这些数据包送到 lo 接口。代理程序（如 Clash / ShellCrash）监听在 lo9 上的端口（例如 7893），通过启用 IP_TRANSPARENT 选项，可以读取数据包的原始目标 IP 和端口并进行代理转发。\n简而言之，TProxy 模式只需要：\niptables 给数据包打上 mark； ip rule + ip route 将这些包送到 lo； 程序监听 lo 上的端口并开启 IP_TRANSPARENT。 所以不需要在 iptables 中指定 --to-ports，因为目标 IP 和端口保持不变，代理程序自己可以感知并处理。\niptables 规则持久化 安装iptables-persistent：\nsudo apt update sudo apt install iptables-persistent安装过程中会提示你是否保存当前的 IPv4 和 IPv6 配置，选择「是」即可。之后如果你添加了新的规则，记得执行保存命令：\n# 保存当前 IPv4/IPv6 规则 sudo netfilter-persistent save保存后的规则文件路径：\nIPv4：/etc/iptables/rules.v4 IPv6：/etc/iptables/rules.v6 你也可以直接编辑上面的rules.v4/rules.v6文件，按需修改。\n最终效果 这套方案的使用体验取决于你家的上行带宽，我家的网络是下行 500M 上行 60M，目前没有遇到一次打洞失败的情况，所以基本都能跑满，延迟也尚可接受，并且可以在外地随时随地端到端加密访问家中的 Immich 和 OpenWRT 路由器等设备以及实现科学上网，总体来看，我还算比较满意。\n参考: https://icloudnative.io/posts/custom-derp-servers/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://tailscale.com/kb/1232/derp-servers\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n有关 HuJSON: https://github.com/tailscale/hujson\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考： https://tailscale.com/kb/1408/quick-guide-exit-nodes\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nUDP GRO（Generic Receive Offload）是 Linux 内核中的一种网络优化技术，主要用于合并多个小数据包以提高处理效率。但在设备作为网络转发节点的使用场景下，这可能会导致转发延迟增加和高丢包率环境下的吞吐量下降。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n相较于fake-ip，redir-host兼容性更好，出现问题的概率更低，也不会出现开关代理之后短时间内因为fake-ip残留而断网的情况，所以一般情况下我建议使用redir-host搭配 GeoSite 分流规则使用。我这台树莓派的 DNS 上游是已经配置好的 SmartDNS，不存在 DNS 污染的问题，体验良好。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://blog.zonowry.com/posts/clash_iptables_tproxy/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nlo 是 Linux 系统中默认的「回环接口（Loopback Interface）」，在透明代理中，它不仅处理 localhost 流量，还被用来接收原本属于外部世界的网络连接，实现对外部流量的本地劫持和转发。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-04-14T18:10:25+08:00","image":"/2025/04/tailscale-setup-recap/tailscale_hu_62168b00e213c4a1.webp","permalink":"/2025/04/tailscale-setup-recap/","title":"从入门到进阶：Tailscale + ShellCrash 异地组网和科学上网"},{"content":" 前言\n文章中提及的部分服务商链接为推广链接 (AFF)，如果您通过这些链接购买，我会获得机场的一些余额。这不仅不会增加你的购买价格，还能帮助我节省开支，感谢大家的支持。\n中国这么大，每个人的网络拓扑、系统环境、代理软件的配置是千差万别，我这里用得飞起的线路在你那里全红也是非常正常的事情。所以，任何机场，在买之前至少先月付体验，月付体验，月付体验，用着没问题续费就行。没有月付套餐的机场就离远点吧。\n任何机场都有跑路风险，即使是运营数年甚至十余年的老机场也是如此，请大家在条件允许的情况下尽量月付（至少也先月付觉得好用了再选更长期的套餐），保留自己随时更换机场的权利，同时也尽量降低机场潜在的跑路风险。\n提笔写下这篇，本意并非机场评测，而是记录一下这些年在数字世界里「穿梭」的经历。作为一个坐标中部的联通用户，这是我的主观和充满个人色彩的体验。许多人们曾经耳熟能详的「机场」也早已成为时代的眼泪，权当一篇个人的杂谈与回忆录吧。\n启蒙时代 我的故事始于初中时代。那时的网络环境，与今天相比那还是有点过于宽松了，有些事情放在今天甚至根本想都不敢想。工信部刚提及要严查VPN，应用商店里免费的梯子还能随处下载。当时的我，在 GitHub 上摸索着学会了用一键脚本搭建SSR，服务器则是被 AFFMan 忽悠买的 Vultr。\n如今回想，我已经记不清当初为何执着于「出海」——是为了学英语？满足青春期的好奇？还是沉迷于刷机玩机？原因早已模糊，但结果却异常清晰：我就这样踏上了一条「不归路」。那是一个言论相对宽松的年代，QQ 空间可以分享蔡英文胜选的 Facebook 截图，网络上流传着各种习近平的表情包，新闻远没有今天这般「清朗」，连QQ群里都能公开讨论哪里能看片。\n初中的我，课余生活乏善可陈，唯一的娱乐就是摆弄家里那台破旧的电脑。也正是在那时，我一头扎进了桌面 Linux 的世界，从 Ubuntu 到当年的国产之光 Deepin。在几个 Linux 交流 QQ 群里，我顶着随时可能被没收手机的风险潜水，也就是在这段时间，我逐渐在网上了解到「机场」这种合租节点的模式，从此开始放飞自我。\n最早的付费体验 心阶云是我第一个付费的机场。大概在2017年，它刚开业两年，两百多元一年的价格在当时已属中高端。然而，体验并不算愉快。虽说是中转线路，却需要频繁地手动切换节点，速度时好时坏，有时不更新订阅就无法使用。一年后，我将它降级为一个几十块的年付套餐，正式开启了我的「主备搭配」时代。后来它改名「自由鲸」，20%的推广返利也让我拉了一位同学入坑，这份返现进一步拉低了我的持有成本，让它稳坐「备胎」之位，直到2023年跑路。\n忍者云 是我在用过心阶云之后入手的。不知现今状态怎么样，但当年的忍者云落地质量堪忧，给我印象最深刻的是当时香港节点用的是AWS，刷推都会被风控，这点甚至不如上面的心阶云。核心的使用体验——速度和稳定性也对不起它不打折时超过四百一年的售价，好在流量给得多，显得性价比不那么寒碜。如今它竟也运营了七八年，实属不易，但估计还是老样子——落地不行，稳定性欠佳。\n速蛙云是我心中一段短暂的唯一真神。当时它在 YouTube、Google 上铺天盖地地投放广告，运营相当高调，手笔之大令人咋舌。但不得不承认，他们家的产品力确实很不错1：晚高峰8K视频随便拖，连接稳定，落地 IP 质量出奇地好，注册 Google 和 Twitter 账号都能畅通无阻，完全不会出现注册即风控的情况。这是我第一次真切感到「这笔钱花得值」。\n不仅如此，速蛙云还附赠共享 PornHub、Netflix 会员和 Shadowrocket 账号，节点覆盖全球，连冰岛这种小众地区都有。然而好景不长，在我购入后不久，它便和花卷爆发争端，随即在收割一波新用户后跑路。如今回想，速蛙云的商业模式本就是个谜：一边是巨额的广告投入，一边是昂贵的线路和丰富的福利，价格却不算离谱。或许从一开始，它的结局就已注定。\n长沙黄花国际机场 第一次送人，从停车场出来有个隐蔽的红绿灯没看到，直接扣 6 分罚 200，差评。不是航空枢纽，不算繁忙，其他尚可。\n西安咸阳国际机场 感觉国内非航空枢纽城市的机场质量都半斤八两，咸阳机场动线设计不太合理，平面电梯数量太少，值机 -\u0026gt; 安检 -\u0026gt; 登机口这条路长到跑断腿。也许机场把动线拉长有助于塞下更多商铺来创收，但是近些年生意不好做，机场里倒闭的店铺也太多，看着实在有点寒碜。机场 Wifi 质量不错，其他的就中规中矩。\n高端机场的同质化困境 FlowerCloud 是我在速蛙云跑路后买的，这几年兜兜转转又回到了它。初体验不错，线路飞快。但很快发现，大部分节点都用了 Kirino 和 Eons 的落地（毕竟大家都用他们），加上用的人多，IP 质量自然好不到哪里去，之前浏览 E-Hentai 经常被反爬限制，注册各类账号更是奢望。半年 218 元、每月 150G 的价格，即使算上折扣也不便宜，不过好在冗余比较充分，稳定性和速度在绝大多数时候都是很不错的。当时似乎存在被人拿来当爬虫代理池的情况，导致小众地区节点的 IP 也不那么干净，实测下来该限制的依旧限制，该屏蔽的照样屏蔽，最终这些小众地区节点能起到的作用无非就是让你的 IP 属地更加酷炫而已，前阵子他们似乎已经意识到了爬虫泛滥的问题，并且采取了措施，至少现在反爬限制已经肉眼可见的变少了，日常使用已经基本无感。\n📝 备注 最近拔线严重，花云应该是弄了 Anycast，表面上入口变成了境外，实际上流量依然走国内，提升了入口的隐蔽性，参考流量透传。\n最近他们尝试了几个不同的国内机房，但每次都是上线不就就会出现被严重 QoS 甚至直接拔线的情况，说明拔线潮仍在继续，于是只能灰溜溜的用回他们的透传上游 Cloud Radium。\nYTOO 和花云给我的感觉：「非常像，特别像，说他们是同一个老板我都信」。\nGaCloud （现在似乎叫做 WgetCloud）也类似，价格一路从39元/月涨到近60元/月，速度和稳定性都是这个价位应有的水准，但除此之外，他就是一个什么都不差，但也没什么特别突出的特点的机场。也正是这个价格给其带来了尴尬的定位：贵过大部分机场，但也没什么亮点，在其涨价之后我很难再有购买的动力。\nAmyTelecom 被称为「奶昔青春版」，线路质量和稳定性都很好，审计规则比 CNIX 宽松不少。注册需要手机号验证，线路和奶昔本站相仿，价格相比奶昔动辄一千多的年付套餐来说亲民不少。速度什么的都没得说，IP 质量嘛这些大站基本大差不差，唯一美中不足的是落地的地区偏少，基本只有港台美日这四个地方，不适合在微博上装 IP 属地的逼。\nTAG 则与 AmyTelecom 形成了鲜明的对比，这家拥有非常多的落地，各种犄角旮旯地区是应有尽有，当然，真实的服务器位置肯定不会在这些小众地区，很大一部分都是广播出来的，不过管他原生还是广播，能在微博上装 B 就是好 IP。这家也是这波拔线潮之后为数不多的仍然拥有国内入口的机场，且用且珍惜吧，不要做出像这个 SB 一样的把订阅链接放到论坛的行为2。他们还提供年付 ¥162/200G 的 Special 计划，适合用作小流量备用。\n最近用自己的覆写规则拉取 TAG 的订阅发现节点全部超时，仔细排查以后发现：他们的节点server首先使用一个隐蔽的域名（甚至可以是别人的），然后通过nameserver-policy定义私有的加密 DNS 来下发线路，这种隐藏线路的方式还真是头一次见。所以，如果这家发现拉取线路超时的话，就排查一下你的客户端是否把他们的nameserver-policy给覆盖掉了，估计他们因为这个原因工单要被开爆，笑死。\n这些年大大小小的机场用下来，你会发现一个残酷的现实：现在所谓的老牌、中高端机场，体验其实都大差不差。\n自从运营商开始搞这个极其傻逼的跨省流量 QoS，那些靠着廉价国内机做中转的平价机场，因为中转成本飙升基本都死绝了。活下来的大多采用了极其相似的线路方案——比如深港 IEPL 专线，加上 Kirino、Eons、Jinx 这几家的落地。这就导致了一个很尴尬的局面：既然上游都一样，大家的落地 IP 质量其实都大同小异。高端机场的价格相仿，体验也拉不开差距，唯一的区别大概只剩下老板的运营风格和广告投放力度了。在追求高端用户的同时，所有机场都在面临着同样的困境：根本无法解决落地 IP 质量不可避免的劣化问题。\n不过，对于这个 IP 质量的问题，其实大可不必过分焦虑。我们追求干净的 IP，无非就是为了注册账号不被风控，或者少遇到点烦人的反爬验证码和 Cloudflare 盾。但你要认清一个现实——既然都拿来开机场卖了，IP 还能有多干净？只要用的人一多，再纯净的 IP 最终都会变成下水道。纯正的独享住宅家宽成本极高，日常使用根本不需要、也不值得为了机场 IP 的质量去精神内耗。\n既然大家最终都会沦为下水道，大机场和小机场的区别，仅仅在于对这个下水道的维护水平。体量庞大的大机场，尚有余力去规管和审计用户流量：比如限制 BT 下载、屏蔽垃圾邮件端口、屏蔽 SSH 连接以防止脚本小子拿他们去当扫描爆破的跳板。虽然也会牺牲一部分用户体验，但起码能保障 IP 不会彻底烂进各大安全数据库的黑名单，从而维持住日常上网的舒适度；而那些便宜的低端机场，基本是完全摆烂，大门敞开任由折腾，能连通就行（当然，对于要干脏活的人来说，这也算是个优点）。\n所以，别再去听信商家的忽悠，天天拿着 ping0.cc 这种娱乐库来测去，给自己制造焦虑了。哪怕是那些信誓旦旦标榜美国真实公寓家宽的商家，只要他明确把 IP 质量当成了卖点，你还能指望买这些服务的人不做点脏了 IP 的龌龊事吗？如果你真有那种极其严重的 IP 洁癖，唯一的解法就是自己肉身飞去美国，找当地运营商拉条宽带来当代理。可就算你真这么干了，也不一定能保障分配给你的 IP 就是绝对纯净的——说不定它上个月刚被某个脚本小子放在窑子里锻炼良久，才轮到你接盘呢。\n只要没这折腾的条件，那就老老实实接受现实，别去追求那些虚无缥缈的东西。选个规矩严的大机场，日常够用、能安稳上网，其实就已经足够了。\n香港赤鱲角国际机场 很棒的机场。我去的那年还只有两条跑道，无障碍设施完善，WiFi 给力，还有免费公用电脑。唯一的遗憾是当时正值埃博拉疫情，循环播放的防疫广播有些破坏心情。后来国泰砍掉港龙航空，长沙再无直飞航班，只能改坐高铁了。\n桂林两江国际机场 这个真不太行。我去的时候设施老旧，离市区远，接驳交通一塌糊涂。海关人员的态度也一言难尽，不知还想不想做世界级旅游城市了。\n在细分市场里寻找特色 星岛梦、光速云、极连云、全球云 这四家机场出自同一位机场主之手，线路和落地基本一致，实际使用体验也非常接近。入口根据运营商自动解析，延迟表现很不错。四家机场线路相仿，区别在于日常打折的时机和活动的力度，每家的性价比算上日常的折扣活动后都还是很不错的，大家可以来体验一下。\n星岛梦是四家中最早开业的，我从早期测试阶段便开始关注，见证了它从最初的摸索，经过机场主熬夜修线路、换落地，逐步达到了可以日用的水准。日常打折后性价比还可以。想吐槽的是之前换来换去的面板地址——老板喜欢在面板上用香港 CN2 GIA 这类豪华但不耐打的线路，之前一被打就换网址，现在已经套上 Cloudflare，希望能稳定下来。\n老板人比较实在，虽然他刚开始运营机场可能不如老牌大厂经验丰富，但胜在态度诚恳、愿意花心思去折腾和优化（当然这也会导致有时爆炸）。比如之前因为没关 IPv6，导致香港节点访问 Google 时需要过一次 Captcha，老板收到反馈后很快就给修好了。目前各条线路的流媒体和常用服务解锁都很正常，具体情况如图：\n📝 备注 近期工信部严格清查跨境专线用于所谓「违规跨境访问」业务，机房拔线严重，这几家也受到影响，之前一阵子临时采用过香港中转。现在开始换到了自己的客户端，看着像是 FlClash 魔改的，用起来倒是没什么大问题。缺点就是我没法直接拿到订阅链接了，想要玩的当然可以试试 MitM 提取一下实际的订阅地址。\nCNIX（似乎也叫做薯条）感觉技术实力不错，当年从合租香港家宽起步，后来凭借量大管饱的广港 IPLC 一战成神。目前定价依然亲民，￥239/年，一次性提供 2.5TB 流量，对我而言绰绰有余（草，涨价到 288 了）。节点繁多，因为有一条大带宽香港专线，带宽充足又扛揍，稳定性因此不错。比较神奇的是，用户体量明明不小，浏览 E-Hentai 却很少触及基于 IP 的图片加载数量限制——只是图片加载速度会略慢，原因不明。当然，缺点也不是没有，审计规则是我用过的机场里相对数一数二严格的，ToS 叠甲叠满，以及「女装白丝的运维 JK 裙边料盖住了进风口导致交换机关机」这种鬼畜运营风格，想知道真实故障原因？别想了。最近他们的线路出现了比较大的变动，有各种针对不同运营商的优化线路（0.5-1倍计费），还有 GoMami 的香港 CN2 GIA（5 倍计费，毕竟这可是针对中国大陆的顶级直连线路）（现在没了），可玩性还是很高的，可惜审计规则依旧比较繁多。\n良心云 是我目前用过的直连机场里体验最好的，没有之一。据说是机场主薅各大主流公有云羊毛（「两块钱一个月的 AWS」），成本压得极低，反映到用户端就是 ¥6/月 1000G 这种几乎不讲道理的定价。速度方面更是没得挑——晚高峰照样起飞，这在直连机场里属实罕见。主流流媒体解锁最近也都修好了，性价比直接拉开了和同价位选手的身位。如果非要说隐忧，那就是这种极致性价比本身：过于能打难免树大招风，DDoS 之类的麻烦恐怕不会少，低成本的公有云薅羊毛模式能维持多久也是未知数。所以，月付、月付、月付，享受一个月算一个月——但只要它还在，那就是廉价直连机场的王。\nWestData 是当初看毒药评测时发现的，试用下来体验平平。如今听说已跻身「二线机场第一梯队」，对此我深表怀疑，总之不会再续费了。\nIkuuu VPN i坤 VPN ，落地是 Azure（大概率是月抛3的 Azure），线路暂不明确，价格便宜，10 元每月 200G？忘了，总之就是够轻中度使用。以前晚高峰都能跑满 500M 的，缺点就是 Azure 的机器风控确实有点太频繁了，有时候看 YT 都要过一个 Captcha。最近看到别人的测速提到这家因为国内机房的拔线潮体验降级，抛开这段时间的降级来说，他们的性价比还是很不错的。\n两元店 是朋友拉我入坑的，年付 ¥22、每月 1000G 直连，价格确实便宜。节点多为 AWS、Oracle 等月抛机3，速度尚可，审计也比较宽松，卢森堡节点就是 BuyVM，可以拿来抗版权投诉下载 BT。这种超低价直连机场日常主力使用并不建议——线路稳定性一般（电信和移动尤甚），月抛机的 IP 质量也实在是不敢恭维。更适合当作备用，或者像我一样拿来干些下载 BT、转发矿池流量的脏活。\nCrush 是我为应对日益频繁的入口封锁而找到的一家纯 IPv6 入口机场。联通网络下体验还不错，价格也因 IPv6 入口的低成本而压到了每月 ¥4 / 150G。当然，纯 IPv6 也注定了它无法成为主力——只能在有 IPv6 的环境下发光发热。\n雅加达苏加诺-哈达国际机场 \u0026amp; 日惹古冷柏格国际机场 对于雅加达机场我没什么特别感觉，回国的时候吃了个和市区同价的 KFC，环境稍脏。而日惹机场中国游客很多，有中文标识，但国内航班基本没有廊桥，只能晒晒太阳更健康了。\n治愈「心病」的唯一方法 回顾这趟漫长的「机场漫游」，我发现自己陷入了一个有趣的循环：总是在追求那个完美的「最优解」，却又忍不住被下一个「可能性」所吸引。 从最初追求稳定，到后来迷恋大流量，再到对 IP 质量的挑剔……我的需求在不断变化，而市场上，不论是哪个产品，却似乎总会在某些方面不尽如人意，让我每次都不停的换来换去。有时想要节省一些代理开支，可是用着用着发现新鲜的机场，总是忍不住去买个来试试——刚买回来新鲜感十足，每次都觉得这次终于找到了「真爱」，结果用没多久，又开始怀疑人生，觉得哪里不对劲了，又想去换，最后是买了几个机场，计算下来平均每年的花费比高端机场的套餐还要高。\n这种永不满足的「心病」，让我积累了一堆小流量套餐，手动管理它们成了一件苦差事。我意识到，市面上现有的工具，已经无法完美安放我那颗爱折腾的心了。它们或者功能不足，或者设计哲学与我的需求相悖。\n于是，一个念头逐渐清晰：与其继续寻找，不如亲手创造。\n尽管最近很忙，我仍然计划打造一个全新的、更智能的订阅管理工具。它并非要颠覆什么，而是想为像我一样，拥有多个服务来源、追求极致个性化定制的用户，提供一个更优雅、更强大的解决方案。\n这不会是一个一蹴而就的项目，更像是我技术探索路上的一个新里程碑。我不确定它最终会走向何方，但我确信，创造的过程，本身就是治愈「心病」的最好良药。 这段经历让我明白，当消费和体验无法带来最终满足时，或许只有一头扎进这个领域，让自己的「心病」反过来发光发热，当心病变成了热爱，或许才是治愈的开始吧。\n曾经的速蛙云服务质量非常不错，基本跑满带宽。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n不过这家也对订阅拉取做了严格限制，打开订阅开关后才会开放 5 分钟订阅，所以想做也做不了这种事。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n指的是无法长期续费使用的，非常规价格售卖的云服务产品。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-04-05T20:18:50+08:00","image":"/2025/04/proxy-provider-recap/cover_hu_29e3f759cc152b82.webp","permalink":"/2025/04/proxy-provider-recap/","title":"永恒的选择困难症：那些年我用过的机场"},{"content":"改用自己的 Mihomo 覆写规则后，手机从 Google Play 上下载应用就会一直转圈圈，而换用机场的规则就没问题，非常奇怪。遂调取 Mihomo 内核日志查看。\nplay-lh.googleusercontent.com:443 match RuleSet(cdn_domainset) using 静态资源[🇭🇰 香港 07] play.googleapis.com:443 match GeoSite(GFW) using 节点选择[🇭🇰 香港 07] play-lh.googleusercontent.com:443 match RuleSet(cdn_domainset) using 静态资源[🇭🇰 香港 07] play-fe.googleapis.com:443 match GeoSite(GFW) using 节点选择[🇭🇰 香港 07] services.googleapis.cn:443 match GeoSite(CN) using 全球直连[DIRECT]（以上日志已精简）\n国行手机内置的 Google Play 服务使用services.googleapis.cn而非services.googleapis.com域名提供服务，而这个域名在大多数分流规则中都是直连，对，问题就出在这里，修改规则把这个域名分流到代理就万事大吉了！\n……万事大吉了，吗？\nrr4---sn-j5o7dn7s.xn--ngstr-lra8j.com:443 match Match using 漏网之鱼[🇭🇰 香港 07] rr2---sn-j5o7dn7s.xn--ngstr-lra8j.com:443 match Match using 漏网之鱼[🇭🇰 香港 07] rr1---sn-j5o76n7z.xn--ngstr-lra8j.com:443 match Match using 漏网之鱼[🇭🇰 香港 07]等等，为什么每次从 Play 商店下载应用都会出现这些奇怪的域名？在网上查找一番资料后，新世界的大门就此打开。\n与 Google 截然相反却又异曲同工的 Ångströ 看到 xn\u0026ndash;ngstr-lra8j.com，熟悉域名的同学肯定知道，这是 PunyCode 编码，这串字符解码后就是 ångströ.com。Anders Jonas Ångström 是一位瑞典物理学家，他是光谱学的奠基人。1埃斯特朗（Ångström）是为纪念他而以他的名字命名的长度单位，$ 1 Å = 10^{-10} m = \\frac{1}{10} nm $，通常用于描述非常短的距离，比如原子和分子尺寸或光的波长。其代表极端小的量级，尤其是在物理学和化学中用于精细测量。\n虽然 Google 的名字并不是直接取自「Googol」，但是它的灵感来源于该词。「Googol」是一个数学术语，表达$10^{100}$，即1后面跟着100个零，是一个极其庞大的数字，常用来表示计算机科学中涉及的巨大数字或信息量。\n在命名哲学上，Google 与Ångströ 这对看似分处光谱两端的科技概念，却展现出耐人寻味的对称美学。前者源于数学概念「Googol」的创造性改写，后者则脱胎于物理单位「Ångström」的意象重构。这两个经过艺术化变奏的称谓，恰似科技文明的双螺旋：Google 之称承载着驾驭浩如星海的数字宇宙的雄心，Ångströ 之谓则暗喻着雕琢精微的原子级技术图景。当这两个经过创造性变形的专业术语在硅谷相遇，恰好构成了一组完美的认知坐标——既指向人类处理信息的尺度极限，也昭示着科技文明同时向宏观与微观进军的壮阔征程。\n入门密码学：Google 基础设施域名的规律2 OK，enough。现在让我们把视角转回 Google 的基础设施。先来看一些完整的连接域名：\nrr4---sn-j5o7dn7s.xn--ngstr-lra8j.com rr1---sn-j5o76n7z.xn--ngstr-lra8j.com rr5---sn-i3b7knzs.xn--ngstr-lra8j.com这些看似随机的字符串，实际上是经过一些简单的密码学加密后的结果。让我们拆解其中的核心部件。\n城市名称的转换规则 以rr1---sn-j5o76n7z为例，关键的信息段在sn-后面的 8 位：r1---sn-[123][45][6][78]。前三位，也就是本例中的j5o是城市名称，由该城市主要机场的 IATA 码通过一定的密码学变换转换而来。\n首先构建一张 5 * 7 的数字字母表：\n行0: 1 0 2 3 4 行1: 5 6 7 8 9 行2: a b c d e 行3: f g h i j 行4: k l m n o 行5: p q r s t 行6: u v w x y逆时针旋转这张表，即从新表格的左下角开始，依次按照原表格「从左到右，从上到下」的顺序，把原表的数据在新表上按照「从下到上，从左到右」的顺序誊抄。\n旋转完成后，可以得到下表：\n| 6 d k r y | | --------- | | 5 c j q x | | 4 b i p w | | 3 a h o v | | 2 9 g n u | | 0 8 f m t | | --------- | | 1 7 e l s |表格中间用线条框出来的 5*5 的部分就是最终的密码表，一共有 25 个字符，「从左到右，从上到下」依次代表字母a到字母y。例如，上海虹桥国际机场的 IATA 代码为sha,我们可以通过这张表得到加密后的密文：\ns在字母表中是第 19 个字母，「从左到右，从上到下」依次在密码表中数到第 19 个字符，也就是n h在字母表中是第 8 个字母，「从左到右，从上到下」依次在密码表中数到第 8 个字符，也就是i a在字母表中是第 1 个字母，「从左到右，从上到下」依次在密码表中数到第 1 个字符，也就是5 加密后的密文就是ni5。\n反之亦然，回到一开始的城市名称j5o，从我们刚刚得到的密码表中反推出原文：\nj按照「从左到右，从上到下」的顺序是第 3 个字符，也就是c 5按照「从左到右，从上到下」的顺序是第 1 个字符，也就是a o按照「从左到右，从上到下」的顺序是第 14 个字母，也就是n 翻译完成的明文是can，也就是广州白云国际机场的 IATA 码，显然，我们连接到的服务器位于广州。\n要是谷歌有某个服务器位于苏黎世，而苏黎世机场的 IATA 码是zrh，有一个字母z，可是我们的密码表只有a到y啊？别担心，Google 当然也考虑到了这个问题，z对应密码表中的1。\n将这套规则用代码表示如下：\ntable = \"5cjqx4bipw3ahov29gnu08fmt1\" def iata2cipher(iata): global table iata = iata.upper() cipher = \"\" for element in iata: index = ord(element) - 65 cipher += table[index] return cipher def cipher2iata(cipher): global table cipher = cipher.lower() iata = \"\" for element in cipher: index = table.find(element) iata += chr(65 + index) return iata # print(iata2cipher(input(\"IATA:\"))) # print(cipher2iata(input(\"Cipher:\")))服务器组编号 [45]和[78]位，如76和7z，表示服务器组（接入点）编号，由下表第一列（已经用分隔线隔开）包含的字符组成，7elsz6dkry分别代表0123456789。所以，76的明文是05，7z的明文是04。\n| 1 2 3 4 5 6 7 | 8 9 a b c d e | f g h i j k l | m n o p q r s | t u v w x y z | 0 1 2 3 4 5 6 | 7 8 9 a b c d | e f g h i j k | l m n o p q r | s t u v w x y | z以 Python 表示如下：\ncodeTable = \"7elsz6dkry\" def cipher2code(cipher): global codeTable cipher = cipher.lower() codeString = \"\" for element in cipher: index = codeTable.find(element) codeString += chr(index + 48) return codeString # print(cipher2code(input(\"Cipher:\")))同样要将数字加密为密文同理，这里不再赘述。\n支持协议 [6]位表示网络协议信息：\nn：IPv6（地址段 0x000-0x3FF） u：IPv6（地址段 0x400-0x7FF） m：仅支持 IPv4 例如：\na5mekn7r，IPv6 前缀：2607:f8b0:4007:a::/64，IPv4 前缀：74.125.103.0/24 a5m7zu7r，IPv6 前缀：2607:f8b0:4007:407::/64，IPv4 前缀：74.125.215.0/24 a5mekm76，仅支持 IPv4，前缀：208.117.242.0/24 正确的分流处理 ⚠️ 警告 Google 显然不会为这些位于中国大陆的，未经 ICP 备案的 CDN 的稳定性和速度背书。如果流量足够，那还是直接将services.googleapis.cn加入代理列表吧。\n了解了 Google 基础设施域名的加密规律后，我们可以根据这些信息实现更精准的分流策略。目前已知 Google 在中国大陆的 CDN 节点主要分布在北京（2x3）、上海（ni5）和广州（j5o），对应的域名特征可以通过正则表达式识别：\nrules: - DOMAIN-REGEX,^r+[0-9]+(---|\\.)sn-(2x3|ni5|j5o)\\w{5}\\.xn--ngstr-lra8j\\.com$,DIRECT这条规则会匹配所有形如 rr1---sn-j5o76n7z.xn--ngstr-lra8j.com 的国内 CDN 域名，并将其标记为直连。而对于其他未被覆盖的 Google 域名（如 play.googleapis.com 等），仍遵循原有的代理规则。\n事实上，GeoSite 数据库的上游 v2fly/domain-list-community 已针对 Google Play 的国内 CDN 节点进行了优化3。只需在 Mihomo 配置中启用 GEOSITE,GOOGLE-PLAY@CN 规则，即可自动实现国内 CDN 直连与海外域名代理的智能分流：\nrules: - GEOSITE,GOOGLE-PLAY@CN,直连 - GEOSITE,GOOGLE,代理 参考: https://en.wikipedia.org/wiki/Anders_Jonas_%C3%85ngstr%C3%B6m\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://github.com/lennylxx/ipv6-hosts/wiki/sn-domains\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n具体的commit: https://github.com/v2fly/domain-list-community/pull/2436/commits/a86c1bf3d9bf577869180874d87c76ddf6282fc1\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-03-15T21:15:01+08:00","image":"/2025/03/chinese-cdn-used-by-playstore/cover_hu_8e92ca92eba5064b.webp","permalink":"/2025/03/chinese-cdn-used-by-playstore/","title":"Google Play 商店的国内 CDN：从密码学入门到分流策略优化"},{"content":"当我趁着春节各家机场的促销订阅多个机场之后，如何充分利用每个节点就变成了说难不难说简单也不简单的问题，我当然可以订阅各家机场提供的配置文件，然后在他们之间切换，但这样未免也太麻烦了。更何况我还有自建节点，我可不想为了这一个节点专门去开一个新的配置。\nSub-Store 很好的解决了这个问题，它可以从多个订阅中抽取节点信息，通过正则表达式或者 JS 整理它们，最后输出一个整合了所有节点信息的订阅。\n部署它可以直接使用 xream 打包好的镜像，这个镜像整合了前后端，如果在公网部署，记得更改一下后端路径，否则你的配置文件很可能会被盗用。\nservices: sub-store: image: xream/sub-store container_name: substore restart: always environment: - SUB_STORE_CRON=55 23 * * * - SUB_STORE_FRONTEND_BACKEND_PATH=/super-random-path ports: - \"3001:3001\" volumes: - ./data:/opt/app/data反代 3001 端口即可访问 Substore 的前端，这里以 Caddy 为例：\nsub-domain.example.com { reverse_proxy :3001 }当然，初次进入前端别忘了新增后端地址，这时的后端地址取决于之前 compose file 里的设置，在本文的例子中，后端地址为https://sub-domain.example.com/super-random-path。\n组合订阅的管理 添加所有机场上游和自建节点之后，就可以开始把它们全都加进单个组合订阅，但各个机场对节点的命名五花八门，默认情况下看起来非常杂乱，甚至不同机场之间的节点还有重名的可能。好在 Sub-Store 有通过脚本对节点进行批量重命名操作的功能，这里推荐一个脚本，能够帮我们为所有的机场节点重命名。\n欲使用这个脚本，只需在编辑订阅时将以下地址粘贴到脚本操作处即可。\nhttps://raw.githubusercontent.com/Keywos/rule/main/rename.js 最后再进行一些你喜欢的节点操作，可以整理出一个统一规范的节点列表。\n生成 Clash 配置 现在虽然已经有了节点列表，但现在生成的配置文件并不包含任何规则，需要自行编写或者拉取第三方规则。\n转到 Substore 的文件管理，创建一份新的 Mihomo 配置：\n「来源」选择组合订阅，并在订阅名称上选择你的订阅组 在脚本操作中填入自己的覆写配置 这是我自己的覆写规则 powerfullz/override-rules，为 Mihomo/Substore 设计，核心特色如下：\n集成 SukkaW/Surge 与 217heidai/adblockfilters 等优质规则，兼容性强，覆盖面广。 针对 Truth Social、E-Hentai、TikTok、加密货币等场景，新增专用分流规则，满足多样化需求。 精简冗余，结构清晰，维护便捷。 深度融合 Loyalsoldier/v2ray-rules-dat GeoSite/GeoIP，分流更精准。 IP 规则默认添加 no-resolve，有效减少本地 DNS 解析，提升速度与隐私。 动态覆写：自动识别节点国家/地区，仅生成实际存在的分组，节点名称实时枚举，配置更智能。 JavaScript 格式覆写 复制 JavaScript 格式覆写文件的链接https://cdn.jsdelivr.net/gh/powerfullz/override-rules@1/convert.min.js，并根据需要在后面附加参数，格式如下：\nhttps://cdn.jsdelivr.net/gh/powerfullz/override-rules@1/convert.min.js#参数1=true\u0026参数2=true目前支持如下参数：\n参数 功能 loadbalance 启用国家/地区节点组的负载均衡 landing 启用落地节点功能 ipv6 启用 IPv6 支持 full 生成针对纯内核使用场景的完整配置 keepalive 启用 TCP KeepAlive quic 允许 QUIC 流量1 fakeip DNS 增强模式使用 fake-ip2 regex 各国家代理组改用 include-all + 正则过滤模式3 threshold 国家/地区节点数量小于该值时不显示分组（默认 0） 例如，若有负载均衡和 IPv6 需求，最终的覆写脚本链接为：\nhttps://cdn.jsdelivr.net/gh/powerfullz/override-rules@1/convert.min.js#loadbalance=true\u0026ipv6=true将最终的覆写脚本链接粘贴到脚本操作处，使用 Substore 的生成预览功能确认没有问题后即可保存。\nYAML 格式覆写 YAML 格式覆写我自己已经不用了，随缘维护，但欢迎 PR\n写了个 Github Actions 自动根据 JS 格式覆写生成 YAML 格式覆写，所以现在 YAML 格式又开始维护了。\n除了直接引用 convert.js 动态覆写，你也可以使用仓库中预先生成好的 32 份 YAML 格式覆写——它们都放在 yamls/ 目录里，由 GitHub Actions 在每次推送后自动重新生成、覆盖。适用于诸如 Clash Verge 等不支持 JS 覆写的客户端和转换服务。\n文件命名规则：\nconfig_lb-{0|1}_landing-{0|1}_ipv6-{0|1}_full-{0|1}_keepalive-{0|1}_fakeip-{0|1}_quic-{0|1}.yaml示例（开启 full，其余关闭）：\nhttps://raw.githubusercontent.com/powerfullz/override-rules/refs/heads/main/yamls/config_lb-0_landing-0_ipv6-0_full-1_keepalive-0_fakeip-0_quic-0.yamlCI 只是套用一份假的fake_proxies.json来生成覆写，所以不可能实现 JS 覆写自动根据节点匹配生成对应代理组的功能，只能把所有地区节点组都放进去。如果你已经搭建 Substore，并且想要「动态识别国家 + 传参」的灵活性，还是推荐使用 JS 覆写。\n生成下载链接 保存成功后点击分享按钮生成分享链接，设置分享有效期后点击「创建分享」，生成的链接即最终成型的 Mihomo 配置文件，将其作为订阅链接在你的代理软件内订阅就大功告成了。\n部分机场 UDP 性能差，开启后可能出现体验降级。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n开启后可能有助于解决 TUN 模式无法上网的问题。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n各国家代理组改用 include-all + 正则过滤模式，由 Mihomo 内核在运行时按正则动态筛选节点，而非在脚本执行时枚举节点名称（默认 false）\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-03-07T18:54:29+08:00","image":"/2025/03/clash-subscription-convert/image-8_hu_92098803a4bf150d.webp","permalink":"/2025/03/clash-subscription-convert/","title":"最速 Substore 订阅管理指南"},{"content":"最近在白宫发生的闹剧，想必大家都知道了。稳定运行数百年政治制度如今却迎来了川普、万斯和马斯克这三个流氓，其道德之败坏，行径之恶劣，手段之下作在整个美国历史乃至世界史上都前所未见。仅仅三周的时间，美国几百年苦心经营积累的信誉，地位和权力，都被「三人帮」拿去冲了厕所，让全世界都真真正正看了一回美国的笑话。\n川普的真面目 川普是谎言、腐败和自私自利的高手，他是被定罪的重罪犯，进行总统选举几乎就是为了避免坐牢，现在二进宫，也不改他的罪犯本性——他赦免国会暴力案的罪犯，新闻发布会上谎话连篇，外交场合公然羞辱他国元首，放任马斯克访问政府敏感数据以及大幅削减民生开支，打着保护美国产业的旗号对他国商品加征关税，实际上却是向穷人加税，对富人减税。\n他不在乎美国的利益，不惜以牺牲现有的国际秩序和美国的国际信誉与地位为代价，维护他所谓的「朋友」的面子，也许这就是独裁者之间的心有灵犀，臭味相投。他计划以法西斯独裁者的身份统治，而这一次，他得到了足够的支持来实现这一目标。他本人负责在媒体面前放出烟雾弹，掩护马斯克带领的 DOGE 和万斯绕过国会搅乱政府部门和最高法院。他们以反对 DEI 作为为掩护，实际上正在构建系统性压迫机制。先制造文化战争烟雾弹，再趁公民社会来不及反应的这段时间，削弱民权，强化总统权力，最终从根本上打压打压一切政治对手，以牺牲美国人民的利益为代价，维护诸如马斯克等商业寡头、亿万富翁的精英白人群体的既得利益。\n在以特朗普、马斯克等人为代表的 MAGA 运动的影响下，美国社会可能会进一步向右转。这种趋势可能为更加保守的议程铺平道路，并对教育、移民、劳工政策等领域产生深远影响。同时，这种政治氛围可能使科学种族主义、性别歧视和优生学思想在主流政治中获得更大空间，从而削弱美国宪政民主的基础。至于那些被视为「内部敌人」的群体——所有不是「顺从的白人异性恋男性」的人——等待他们的将是被送进纳粹集中营、驱逐出境、监禁、针对性的谣言和死亡威胁。\n有时候真的不得不感叹 I can\u0026rsquo;t believe that the American people are dumb enough to re-elect this man into power.\n","date":"2025-03-03T22:44:08+08:00","image":"/2025/03/the-worst-guy-to-be-president/cover_hu_6ad90c7eb58493bd.webp","permalink":"/2025/03/the-worst-guy-to-be-president/","title":"The Worst Guy to Be a President"},{"content":"人在中国，用起 DNS 会碰到两个问题，一个是 DNS 污染，另一个是 DNS 泄露。想要上网上得痛快，就必须要先解决 DNS 的问题。\n什么是 DNS 泄露 如果你现在正在开着代理看这篇文章，可以先打开这个网站检测一下自己的 DNS 请求是否被发送到了国内的 DNS 服务器上。\n简单来说，当你在使用 VPN 等代理工具时，你认为你的请求不会被除了你和 VPN 提供商以外的第三方看到，然而主机的 DNS 请求却被发送送给了运营商的 DNS 服务器或者是公共 DNS 服务器(阿里、腾讯等)进行解析，而你的真实 IP 地址和请求的域名都会被记录下来。如果 DNS 请求解析一些敏感网站的域名(比如电报、维基解密等)，就会被监管者注意到，从而被警告或者请去喝茶。1\n因此，正确地配置代理工具的分流策略来避免 DNS 泄露就显得尤为重要。\nSmartDNS 的配置 防止 DNS 泄露 DNS 作为上网的指路人，排在第一位的要求就是必须要快，在这样的要求下本地部署 SmartDNS 充当家庭网络的 DNS 服务器真的再合适不过了。关于 SmartDNS 的作用和配置技巧，以及其如何优选 CDN 加快网络访问速度，Sukka 的「我有特别的 DNS 配置和使用技巧」已经讲的很好，推荐在继续阅读本文之前先去看看这篇文章，其中的内容我在这里便不再赘述，我的叙述重心将会放在如何在 Luci 界面上实现这些配置。\n如果你和我一样使用 OpenWRT，SmartDNS 的 Luci App 会在每次启动时根据面板上保存的配置自动生成新的配置文件，所以，不要直接修改/etc/smartdns目录下原有的配置文件，所有的更改都应该在 Luci App 里操作。\n基本上，SmartDNS 上游数量越多越好，因为较多的上游并不会影响 SmartDNS 的性能2，并且多个上游可以增加冗余。为了防止 DNS 泄露，在配置上游时，应当在默认分组添加国外 DNS 上游（当然，最好是加密 DNS），并将国内的服务器归入一个单独的分组（例如domestic），并加上-exclude-default-group的额外参数以将它们从默认分组中排除。\n加速国内域名解析 设置好国外上游，DNS 泄露的问题就解决了，但因为我们在默认分组中排除了国内上游，访问新的域名时需要等待国外上游返回结果，这显然会拖慢国内网站的访问速度，并且还会劣化 CDN。\ndnsmasq-china-list 是 Felix Yan 的项目，目前支持通过 Makefile 生成 SmartDNS 格式的配置文件，目前已经有人做好了现成的 Github Action 每天自动更新，直接下载就可以了，注意这些配置文件只会在国内 DNS 上游分组名称为domestic时生效。\ncd /etc/smartdns wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/accelerated-domains.china.domain.smartdns.conf wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/apple.china.domain.smartdns.conf wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/chinalist.domain.smartdns.conf wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/google.china.domain.smartdns.conf随后在 SmartDNS 中引入这些配置文件，将下面的内容粘贴到「自定义设置」栏的末尾。\nconf-file /etc/smartdns/accelerated-domains.china.domain.smartdns.conf conf-file /etc/smartdns/apple.china.domain.smartdns.conf conf-file /etc/smartdns/chinalist.domain.smartdns.conf conf-file /etc/smartdns/google.china.domain.smartdns.conf 这样配置之后，国内域名的访问速度便不再会受到影响，访问国外域名时，也不会再有 DNS 泄露的问题了。\n去广告 DNS 层面的去广告效果有限，重点应该放在防止误杀上，所以不要用那臭名昭著3的号称自己是「致力于成为中文区命中率最高的广告过滤列表」的 Anti AD，而是使用一些别的规则。个人使用的规则是 217heidai/adblockfilters，这是一个已经整理好的聚合规则，直接拉取即可。\nwget -O /etc/smartdns/adblock.conf https://gcore.jsdelivr.net/gh/217heidai/adblockfilters@main/rules/adblocksmartdns.conf最后引入配置文件：\nconf-file /etc/smartdns/adblock.conf自动更新规则 设置如下 Crontab 即可在每天凌晨三点自动更新所有规则。\n0 0 3 * * ? wget -O /etc/smartdns/adblock.conf https://gcore.jsdelivr.net/gh/217heidai/adblockfilters@main/rules/adblocksmartdns.conf 0 0 3 * * ? wget -O /etc/smartdns/accelerated-domains.china.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/accelerated-domains.china.domain.smartdns.conf 0 0 3 * * ? wget -O /etc/smartdns/apple.china.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/apple.china.domain.smartdns.conf 0 0 3 * * ? wget -O /etc/smartdns/chinalist.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/chinalist.domain.smartdns.conf 0 0 3 * * ? wget -O /etc/smartdns/google.china.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/google.china.domain.smartdns.conf旁路由可以用吗 除非不使用 IPv6，否则最好还是将 OpenWRT 路由器作为主路由。在作为旁路由的情况下，某些系统（说的就是你，Windows）会不遵守旁路由广播的 IPv4 DNS，而执意使用运营商光猫广播的 IPv6 DNS 进行解析，我尝试修改过一些相关的注册表键值，但毫无作用。无奈只好让运营商上门将光猫改为桥接模式，并将 OpenWRT 用作主路由。\n覆写 Clash 规则 这时如果你开着 Clash 去跑 DNS 泄露测试，大概率还是会看到你的 DNS 请求被发到了中国的 DNS 服务器上——几乎所有机场的默认配置都会使用腾讯、阿里等国内大厂的加密 DNS，虽然不至于明文泄露到运营商 DNS 而导致你接到反诈中心的电话，但总让人膈应 （强迫症犯了），更有甚者甚至完全没有相关配置。\n好在如果使用的是 Clash Verge Rev，那么可以很方便的覆写机场的配置，这里分享我的覆写配置，将其粘贴到全局扩展配置中即可覆写机场的配置。\ndns: enable: true ipv6: false prefer-h3: true use-system-hosts: true nameserver: - \"https://dns.cloudflare.com/dns-query\" - \"https://dns.sb/dns-query\" - \"https://dns.google/dns-query\" - \"https://public.dns.iij.jp/dns-query\" - \"https://jp.tiar.app/dns-query\" - \"https://jp.tiarap.org/dns-query\" nameserver-policy: \"geosite:cn\": - system fallback: - \"tls://8.8.4.4\" - \"tls://1.1.1.1\" proxy-server-nameserver: - \"https://doh.pub/dns-query\" - \"https://223.5.5.5/dns-query\" direct-nameserver: - system 配置解析 根据 Mihomo 文档4，其 DNS 请求的流程如下：\nflowchart TD Start[客户端发起请求] --\u003e rule[匹配规则] rule --\u003e Domain[匹配到基于域名的规则] rule --\u003e IP[匹配到基于 IP 的规则] Domain --\u003e |域名匹配到直连规则|DNS IP --\u003e DNS[通过 Clash DNS 解析域名] Domain --\u003e |域名匹配到代理规则|Remote[通过代理服务器解析域名并建立连接] Cache --\u003e |Redir-host/FakeIP-Direct 未命中|NS[匹配 nameserver-policy 并查询 ] Cache --\u003e |Cache 命中|Get Cache --\u003e |FakeIP 未命中,代理域名|Remote NS --\u003e |匹配成功| Get[将查询到的 IP 用于匹配 IP 规则] NS --\u003e |没匹配到| NF[nameserver/fallback 并发查询] NF --\u003e Get[查询得到 IP] Get --\u003e |缓存 DNS 结果|Cache[(Cache)] Get --\u003e S[通过 IP 直接/通过代理建立连接] DNS --\u003e Redir-host/FakeIP Redir-host/FakeIP --\u003e |查询 DNS 缓存|Cache其中nameserver-policy的优先级高于nameserver和fallback，指定geosite:cn中的网站以系统 DNS 查询，也就是使用之前配置好的 SmartDNS 查询，可以享受到局域网级别的响应速度和自带测速的 CDN 选择。而不在geosite:cn中的网站则使用nameserver/fallback查询，使用国外加密上游就可以确保解析结果的可信并防止 DNS 泄露。\n替换 geoip 和 geosite 数据库 Mihomo 默认使用 V2Ray 官方的 geoip 和 geosite 数据库，这个数据库其实不太全，而且更新的频率也很慢，所以我还是用 Loyalsoldier/v2ray-rules-dat 这个「加强版」数据库替换了原来的数据库，只需下载geoip.dat和geosite.dat以后丢进内核目录即可。当然，也可以新增几行覆写配置以实现自动/一键更新：\ngeodata-mode: true geox-url: geoip: \"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat\" geosite: \"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\"Clash Meta For Android 对于手机上的 Clash Meta For Android（以下简称 Clash），覆写设置时需要更加考虑手机的实际情况。\n首先手机上的 Clash 覆写设置选项就不如桌面端的 Clash Verge Rev 这么灵活，很多键值都不能覆写。另外，手机不像电脑，需要经常切换网络环境，这就导致系统 DNS 也会换得很频繁，经测试，在这种情况下，每次更换网络环境都需要开关一次 Clash 才能让其更新system所代表的 DNS。于是我们只能退而求其次，固定一个国内加密 DNS 作为国内查询。\n进入 Clash -\u0026gt;「设置」-\u0026gt;「覆写」以下是所有覆写设置：\n「DNS」-\u0026gt;「策略」：强制启用 「DNS」-\u0026gt;「Prefer h3」：已启用 「DNS」-\u0026gt;「Name Server」：添加两个国外加密 DNS 「DNS」-\u0026gt;「Name Server 策略」：在「键」一栏中填写geosite:cn，值一栏填写https://doh.pub/dns-query 提前从 Github 上下载geoip.dat和geosite.dat，最后进入 Clash -\u0026gt;「设置」-\u0026gt;「Meta Features」，分别用「导入 GeoIP 数据库」和「导入 GeoSite 数据库」功能导入它们。\n完成 最后再打开一个 DNS 泄露测试，看一看问题是否解决，如果不再出现国内的 DNS，说明配置正确，好好享受 SmartDNS 和 Clash 带来的网络优化和防泄漏吧~\n参考自: https://blog.lololowe.com/posts/8f1e/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nSmartDNS 在设计时就考虑到了延迟问题，具体机制可以参考「中场休息：SmartDNS 是如何避免因测速导致 DNS 解析过慢的」。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n有人整理了 Anti AD 的光荣事迹。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n引用自: https://wiki.metacubex.one/config/dns/diagram/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-02-06T17:01:51+08:00","image":"/2025/02/what-i-have-done-on-my-dns/cover_hu_1bda1c3daad4bc1b.webp","permalink":"/2025/02/what-i-have-done-on-my-dns/","title":"我的家庭网络域名解析方案"},{"content":"近期进行了一个小测验，发现了一些我在电力系统分析方面基础知识的疏漏，遂整理一篇笔记。现在我将这篇笔记中相对通用且有价值的部分分享出来，希望能对正在阅读这篇文章的你起到一些帮助。\n分裂导线的作用 相较于普通导线，分裂导线后等效的 $r_{eq}$ 增大，从而减小了线路电抗，降低了电晕发生的可能性，提高了整个系统的静态稳定极限，以下是我整理的分裂导线的作用：\n降低线路电抗 $X$\n$$ r_{eq} \\uparrow \\Longrightarrow \\begin{equation} \\left\\{ \\begin{array}{lr} x_1 \\downarrow = 0.1445 \\lg \\left( \\frac{D_m}{r_{eq} \\uparrow} \\right) + 0.0157 \\mu_r \\, (\\Omega/\\text{km}) \u0026 \\\\ b_1 \\uparrow = \\omega C_1 = \\frac{7.58}{\\lg \\left( \\frac{D_m}{r_{eq} \\uparrow} \\right)} \\times 10^{-6} \\, (\\text{S/km}) \u0026 \\end{array} \\right. \\end{equation} $$因为电纳 $b$ 的变化规律与电抗 $x$ 几乎相反，所以也可以直接得出分裂导线会增大电纳的结论。\n提高电晕临界电压 $U_{cr}$\n$$ U_{cr} \\uparrow= E{cr} \\cdot r_{eq} \\uparrow \\cdot \\frac{n}{K_{n}} \\cdot \\ln \\frac{D_m}{r_{eq} \\uparrow} $$ 提高静态稳定极限 $P_{M}$\n$$ P_{M} \\uparrow = \\frac{E_{q}U}{X \\downarrow} $$ 减小线路波阻抗 $Z_{c}$，进而提高线路的最大传输功率。\n$$ Z_{c} \\downarrow = \\sqrt{\\frac{X \\downarrow}{B \\uparrow}} = \\sqrt{\\frac{L}{C}} $$自然功率 $P_{natural} \\uparrow = \\frac{U_{n}^2}{Z_{c} \\downarrow}$，而总功率 $P = P_{n} \\times \\frac{1}{\\sin{\\beta} L}$，所以分裂导线可以提高线路的最大传输功率。\n变压器分接头的选择 看例题：已知某变压器变比为 $110(1 \\pm 2 \\times 2.5\\%) / 11\\text{kV}$，容量为 $20 \\text{MVA}$，低压侧母线的最大负荷为 $10.8 + j14.4 \\text{MVA}$，最小负荷为 $4.9 + j5 \\text{MVA}$，归算到高压侧的变压器参数为 $5 + j60 \\Omega$，变电所高压侧母线在任何情况下均维持电压为 $107 kV$，为了使低压侧母线保持顺调压，该变压器应当选择哪个分接头？\nA. 主接头档，$ U_1 = 110 kV $\nB. 110(1 - 5%) 档，$ U_1 = 104.5 kV$\nC.110(1 + 2.5%)档，$U_1 = 112.75 kV$\nD.110(1 - 2.5%) 档，$ U_1 = 107.25kV$\n一个公式：$U_{TJ} = U_2\u0026rsquo; \\cdot \\frac{U_{2N}}{U_2}$\n其中 $U_2\u0026rsquo;$ 为归算到一次侧的二次侧电压，$U_{2N}$ 为变压器二次侧额定电压，$U_2$ 为实际的要求电压。为了计算得到分接头电压 $U_{TJ}$，需要分别求出最大负荷时的分接头电压 $U_{TJmax}$ 和最小负荷时的分接头电压 $U_{TJmin}$，再将两者取平均值得 $U_{TJav}$，最后选取最接近 $U_{TJav}$ 的分接头。题目中，变压器二次侧额定电压 $U_{2N}$ 为 11kV。$U_2$ 的确定则需要参考知识点「中枢电压的调整方式」。\n中枢点电压的调整方式 调压方式 最大负荷要求电压（不小于） 最小负荷要求电压（不大于） 特点 顺调压 $ 1.025 U_N $ $ 1.075 U_N $ 难度最小，适用于供电范围小，线路不长，供电要求低的场景。 逆调压 $1.05U_N$ $U_N$ 难度最大。 常调压（恒调压） $1.02U_N\\sim1.05U_N$ $1.02U_N\\sim1.05U_N$ 注意这个表格中的 $U_N$ 为低压侧母线的额定电压。\n题目中要求低压侧母线保持顺调压，且低压侧额定电压可轻易看出（1.1 倍额定电压 = 11kV）为 10kV，则最大负荷时 $U_{2max} = 1.025 U_N = 10.25kV$，最小负荷时 $U_{2min} = 1.075 U_N = 10.75 kV$，归算到高压侧的低压侧额定电压则需要在高压侧电压的基础上减去变压器的电压降落，具体计算公式为：\n$$ U_{2max}' = U_1 - \\frac{P_{max}R + Q_{max}X}{U_1} = 107 - \\frac{10.8 \\times 5 + 14.4 \\times 60}{107} = 98.42 kV \\\\ U_{2min}' = U_1 - \\frac{P_{min}R + Q_{min}X}{U_1} = 107 - \\frac{4.9 \\times 5 + 5 \\times 60}{107} = 103.97 kV $$最后将所有数据代入计算：\n$$ \\begin{cases} U_{TJ\\max} = U_{2\\max}' \\cdot \\frac{U_{2N\\max}}{U_{2\\max}} = 98.42 \\times \\frac{11}{10.25} = 105.62~\\text{kV} \\\\ U_{TJ\\min} = U_{2\\min}' \\cdot \\frac{U_{2N\\min}}{U_{2\\min}} = 103.97 \\times \\frac{11}{10.75} = 106.39~\\text{kV} \\end{cases} \\Rightarrow U_{TJ} = \\frac{U_{TJ\\max} + U_{TJ\\min}}{2} = \\frac{105.62 + 106.39}{2} = 106.005\\text{kV} $$选择距离 $U_{TJ}$ 最近的分接头，题目中「D.110(1 - 2.5%) 档，$ U_1 = 107.25kV$」最为接近，所以本题选 D。\n其实这道题有问题…… 最后以选择分接头后变压器的最终变比校验这个分接头：\n$$ U_{2max} = U_{2max}' \\times \\frac{11 kV}{107.25 kV} = 10.09 kV \u003c 10.25 kV\\\\ U_{2min} = U_{2min}' \\times \\frac{11 kV}{107.25 kV} = 10.66 kV \u003c 10.75 kV $$可以看到，如果选择这个变比，校验是不成功的，但这道题并非出自什么非常正式的考试，所以大家看着笑笑就完事了。\n调差系数百分比 调差系数为功频静态特性参数 $K_{G*}$ 的倒数，符号为 $\\sigma_{*}$，其用百分数表示就是调差系数百分比。\n$$ \\frac{\\sigma_{ *}\\%}{100} = \\frac{1}{K_{G*}} $$极限切除角的计算 先来看一道例题：系统接线如下图所示，设在一回线路始端突然发生三相短路，已知原动机机械功率 $P_T = 1.5$，双回线路运行时系统的功角特性为 $P_I = 3 \\sin{\\delta}$，切除一回线路后系统的功角特性为 $P_{III} = 2\\sin{\\delta}$。则故障的极限切除角 $\\delta_m =$ ?\n按照某些教材上的说法，你需要将所有数据代入下面这个公式里：\n$$ \\cos{\\delta_{cm}} = \\frac{P_T(\\delta_h - \\delta_0) + P_{IIImax}\\cos{\\delta_h} - P_{IImax}\\cos{\\delta_0}}{P_{IIImax} - P_{IImax}} $$求出 $\\cos{\\delta_{cm}}$ 的值之后再代入反三角函数得到最终的角度 $\\delta_{cm}$。先不说这个过程到底复不复杂，这种又臭又长的公式我看到就不想记。所以我们直接用等面积定则来做——如下图所示，根据等面积定则的定义，可以列出如下等式：\n$$ \\int_{\\delta_0}^{\\delta_{cmax}} P_m - P_{II} \\mathrm{d}\\delta = \\int_{\\delta_{cmax}}^{\\delta{max} = \\delta_k'}P_{III} - P_m \\mathrm{d}\\delta $$ 其中 $\\delta*{cmax} $ 就是极限切除角。根据题目条件，分别列写加速面积和减速面积的表达式，可以得到如下的等式，其中出于方便以 $ x $ 代替了 $ \\delta*{cmax} $：\n$$ \\int_{\\frac{\\pi}{6} }^{x} (1.5 - 0) \\mathrm{d}x = \\int_{x}^{\\pi - \\arcsin{0.75}} (2\\sin{x} - 1.5) \\mathrm{d}x $$接下来就是微积分的事情了：\n$$ [1.5x]^x_{\\frac{\\pi}{6}} = [-2\\cos{x} - 1.5x]^{\\pi - \\arcsin{0.75}}_x \\\\ 1.5x - 1.5 \\times \\frac{\\pi}{6} = [-2\\cos{(\\pi - \\arcsin{0.75})}-1.5 \\times (\\pi - \\arcsin{0.75})]-(-2\\cos{x} - 1.5x) \\\\ 1.5x - \\frac{\\pi}{4} = -2\\cos{(\\pi - \\arcsin{0.75})} - 1.5\\pi + 1.5 \\times \\arcsin{0.75} + 2\\cos{x} +1.5x \\\\ \\frac{5}{4}\\pi + 2\\cos{(\\pi - \\arcsin{0.75})} - 1.5 \\times \\arcsin{0.75} = 2\\cos{x} \\\\ \\cos{x} = \\frac{5}{8} \\pi - \\cos{(\\arcsin{0.75})} - 0.75 \\times \\arcsin{0.75} \\\\ \\cos{x} = 0.66601 $$最后将 $\\cos{x}$ 的值代入反三角函数可以求得角度大约为 48.2 度，这个角度也就是我们要求的极限切除角。计算过程中，需要注意：\n右边的积分终点也是故障切除后的功角特性 $P_{III}$ 和原动机功率 $P_T$ 的交点。 左边的积分是 $P_T - P_{II}$，右边的积分是 $P_{III} - P_{T}$，本题是三相短路，所以 $P_{II} = 0$，不要搞错了。 由于推导时所用的值全都以标幺值表示，因而式中 $\\delta_c$、$\\delta_k\u0026rsquo;$ 等角度亦需以 rad 表示（$360\\degree = 2\\pi \\text{ rad}$）。 最后一步等式右边求出来是 $\\cos{x}$ 的值，而不是弧度，不要一着急一股脑直接 $0.66601 \\times \\frac{180 \\degree}{\\pi}$ 求出一个错误的角度而前功尽弃。做题要一步一步来，充分发挥草稿纸充当自己第二大脑的作用，不要跳步，不要心急。 不对称短路电流与正序电流的关系 短路类型 短路电流 单相短路 $I_{fn} = 3 I_{fl}$​ 两相短路 $I_{fb} = I_{fc} = \\sqrt{3} I_{fl}$​ 两相短路接地 $I_{fb} = I_{fc} = \\sqrt{3} \\cdot \\sqrt{1 - \\frac{x_{\\Sigma0}x_{\\Sigma2}}{(x_{\\Sigma0}+x_{\\Sigma2})^2} }I_{fl}$​ 潮流计算中节点的分类 节点类型 已知量 待求量 节点数量（总共有 n 个节点） 备注 PQ 节点 有功功率 $P_i$ 和无功功率 $Q_i$ 电压幅值 $U_i$ 和相角 $\\delta_i$ $m$ 一般是用户 PV 节点 有功功率 $P_i$ 和电压幅值 $U_i$ 无功功率 $Q_i$ 和相角 $\\delta_i$ $n-m-1$ 具有电压调节能力的节点，比如静止无功补偿器 平衡节点 电压幅值 $U_i = 1$ 和相角 $\\delta_i = 0$ 有功功率 $P_i$ 和无功功率 $Q_i$ $1$ 承担平衡全网功率任务的大容量机组 静态储备系数的计算 例题：在如下图所示的电力系统中，已知以发电机额定容量为基准的各元件电抗和系统电压的标幺值为：正常运行时，$x_d = 1.8$、$x_{T1}=x_{T2}=0.25$、$U=1.0$、$P=0.8$、$\\cos{\\Phi}=0.8$，若发电机为隐极机，空载电动势 $E_q = \\text{常数}$，则正常运行时，静态稳定储备系数$K_p = $？\n静态稳定储备系数的计算公式如下：\n$$ K_p = \\frac{P_M - P_0}{P_0} $$本题中 $P_0$ 已知等于 0.8，所以题目就变成求 $P_M$ ，其计算公式如下：\n$$ P_M = \\frac{E_qU}{X_{d\\Sigma}} $$本题中 $X_{d\\Sigma} = x_d + x_{T1} +\\frac{x_L}{2} + x_{T2} = 2.55$，$U = 1.0$，所以问题又变为求 $E_q$。题目中 $P = 0.8、\\cos{\\Phi}=0.8$，则 $S = 1.0，Q = 0.6$，已知 P、Q、U，求上一级节点的电压，公式如下：\n$$ \\begin{cases} \\Delta U = \\frac{PR + QX}{U} = \\frac{0 + 0.6 \\times 2.55}{1.0} = 1.53 \\\\ \\delta U = \\frac{PX - QR}{U} = \\frac{0.8 \\times 2.55 - 0}{1.0} = 2.04 \\\\ \\end{cases} \\Longrightarrow E_q = \\sqrt{(U + \\Delta U)^2 + \\delta U^2} = \\sqrt{(1 + 1.53)^2 + 2.04^2} = 3.25 $$其中 $\\Delta U$ 是纵分量，$\\delta U$ 是横分量。\n关于纵分量和横分量的定义：这个定义并非以笛卡尔坐标系为参考基准，而是以观察者的视角为基准，前后为纵，垂直为横。\n现在 $E_q$ 已经求得，最后求出 $P_M$ 进而求出 $K_p$：\n$$ P_M = \\frac{E_qU}{X_{d\\Sigma}} = \\frac{3.25 \\times 1.0}{2.55} = 1.27 \\\\ K_p = \\frac{P_M - P_0}{P_0} = \\frac{1.27 - 0.8}{0.8} = 0.5875 = 58.75\\% $$","date":"2025-02-03T23:32:03+08:00","image":"/2025/02/recent-ee-notes/image-1_hu_96f07d728663f627.webp","permalink":"/2025/02/recent-ee-notes/","title":"一些关于电力系统分析的笔记"},{"content":"「我累了，我需要休息。」\n办完休学手续，拖着被繁琐手续折腾而疲惫不堪的身体走出学校的办公楼，正式开始了我为期 9 个月的休学生活。两周之前，我还在和室友开开心心外出吃自助烤肉，当时的我怎么都不会想到，我的精神状况会恶化的如此之快。从难以言说的痛苦开始在我身上发作，到去医院开出处方，再到做出休学的决定，整个过程只用了两周的时间。而在去办理休学手续的前两天，我还买了足够我用一年的生活用品，现在倒好，搬回家的时候别提有多重了。\n搬空寝室的那一天，天空下着瓢泼大雨，走进寝室，我的桌面上，路由器的灯光依然闪烁，没喝完的可乐仍在桌边，外卖送来的番茄酱也仍然和往常一样随意的洒在桌子上。「很长一段时间我都不会回来了……」，是啊，这张桌子，可能永远都不会再有这番光景了。\n和不约而同请假的室友一起，分掉了剩下的一箱可乐，拆掉了刚买不久的人体工学椅，把各种杂物装箱，冒着雨搬上了车。眼看着我的床位一点一点清空，当时一时间我竟也生出了不再休学，一切照旧的念头。临走前，我怔怔地看着空空如也的床位出了神，竟对室友轻拍肩膀的动作毫无察觉。和朝夕相处三年多的室友道别，交还了寝室的钥匙和在校图书馆借阅的书籍，我终究还是踏上了回家的路。\n即便如此，偶尔聚一聚也还是必要的 就算休学，xdm 一起干饭的传统也坚决不能丢，在身体逐渐克服药物对于食欲的影响后，大伙的饭局也是来之不拒。大家一起出去吃吃喝喝，分享一下最近的生活，互相交换一些信息，最后还能平摊饭钱，多是一件美事。美中不足的是，鉴于我之前酗酒的经历，医生自然也特别强调了我需要戒酒，于是出门吃饭，基本也就只能喝点西瓜汁意思意思了。\n11 点睡觉，8 点起床 虽然喹硫平效果有限，但竟然也能一改我 5 点睡觉，9点起床的作息，开始医生建议的 11 点睡觉，8 点起床，至少，在第一个月确实是这么回事。当然我也开始光顾健身房，撸铁真的是一件很奇妙的事情，一边猛吃碳水和蛋白质，一边猛加片，不出两个月，我的体重上涨了足有 10 公斤——其中 9 公斤是肌肉，1 公斤是脂肪，也算是尝到了新手福利期的甜头。\n肌肉如果练得太狠，过于兴奋，会直接影响到我的睡眠，尤其是练完腿的晚上，堪称彻夜难眠。为此我不得不做出让步，减低健身的频次，毕竟，以我的状况，对精神健康有益的睡眠是应当照顾的首要目标。\n是远是近都是旅行 旅行也算是生活必不可少的点缀，今年 9 月份的香港之行和十月份的桂林之行算是今年为数不多的远行，而譬如芦溪村七仙殿的近游则是数不胜数。是远是近都是旅行，都说读万卷书，行万里路。当从万卷书内汲获的知识在现实中找到参照和实践，心中生现的满足感和安然是让人感到自己和世界真实存在的最好慰藉。\n天上不会掉馅饼，但会掉小猫 天上也许不会掉馅饼，但是可能会掉下来一只小橘猫。当时我正前往健身房的路上，消防通道里的猫叫声吸引了我的注意，进去一看，就遇见了这只小猫。\n现在我已经养了它快半年了，它也给我带来了不少乐趣，当然，还有不少伤疤和一套被抓烂的真皮沙发。小动物终究还是听不懂人话，曾几何时，我多次动念想要让它扫地出门，但最终还是让它留了下来，养猫就是这样，也许你会因为它烦人的一面产生一万次抛弃它的想法，最终却还是因为它所能带来的无可替代的情绪价值而选择留下它。\n绿植是现代人生活的必需品 绿植不光好看，还能吸收甲醛，吸附灰尘，最重要的是，在室内多引入一些大自然的元素，对身心健康多有裨益，因此我认为，绿植是现代人生活的必需品。\n今年我的桌面有了很大的变化，不止硬件上的升级，比如买了新的显示器和屏幕挂灯，也引入了一些绿植，我选择的绿植是虎皮兰，不仅易于养护，也可以在阴暗的环境下做到生长正常，甚至我的两株虎皮兰还在恰当的肥料量上长出了新芽。多肉则更好养，需要浇水的次数很少，唯独一种叫作「钱串」的植物让我非常困惑，浇水多也不是，少也不是，施肥也几乎对其毫无效果，看来，在园艺方面，还有很多的知识等着我去发现，去学习。\n我的 Online Presence 我并没有为了流量去「运营」我的博客，只是单纯的写我所想，所以看我博客的人并不算多。当然，拜搜索引擎所赐，也不至于完全没有流量。今年我也顺便开设了直播间，最大的作用也不过是用来保存我的游戏录像，所以自然也没有什么观众，毕竟也没有太多人愿意看一个名不见经传的主播玩平淡无味的游戏吧。\nosu! 在今年之内由 300pp 一路涨到了 3439 pp，目前换了数位板，还处在适应期，短期之内这个数字大概是会停止增长。\n生活的欲望 自很久之前开始，我对生活中的任何事物就开始渐渐失去兴趣。其中之一的表现是什么都不想要，什么都不想买：衣服除非穿破，否则绝对不买新的；头发除非遮住眼睛，否则绝对不会去剪；有什么新的产品，我也绝对不会想要；直到最近，甚至连性欲都有不再有的趋势。欲望真的很神奇，它既不能太强，同样也不能太弱。一个没有欲望的人是活不下去的，即使人类生存的本能能够作为一张安全网，防止其过早调入深渊，在世的时候，生活也会毫无意义，生不如死。\n欲望太弱，就会对什么都提不起兴趣，整天浑浑噩噩，反而会更加痛苦。有适当的欲望，每天都为之努力，做自己想做的事情，形成健康的循环，反而会更好呢。\n欲望处理得好，可以推动人前进，「不要相信压力能够转化为动力，你的压力只会转化为病历，人真正的动力，是源自于内心深处对于快乐和兴趣的追求。」是啊，以我现在的境地来看，压力倒是已经卸下。然而压力却已经转化为了病历，我的内心深处，不再追求快乐和兴趣。这些年来，这种感觉变得愈发明显——不论做什么事情，都让我感到一种深层的，无法缓解的疲惫，即使我的身体依旧健康，我的心灵深处，却早已遍体鳞伤，虚弱不堪。我真的很害怕，我的欲望正在加速消失，我早就已经失去了同龄人所拥有的一腔热血，失去了同龄人所拥有的对爱情的渴望，失去了同龄人所有的对美好生活的追求……\n2024 年接近尾声，今年注定将是我大学生涯乃至整个人生中不平凡的一年，在这一年，我重新捡起我对生活的欲望，重新捡起我对未来的信心。今年我所做的这些尝试，无不是在「找回生活的欲望」这件事情上做出我的努力——谁人不知「做我所想，做我所爱」？欲望与动力的耗尽是无法靠意志力补回的，当「所想」与「所爱」都出现空缺时，又有多少人能给出有意义的解决方案呢。\n","date":"2024-12-26T17:57:10+08:00","image":"/2024/12/2024-end-of-the-year-summary-public/image-13_hu_5d398f1badf5ff5d.webp","permalink":"/2024/12/2024-end-of-the-year-summary-public/","title":"2024 年的生活"},{"content":"买来一张 5ber SIM 卡，却发现它意外的挑机器——手上的安卓机器是一个都不兼容。我早就对我原本的备用机——红米 Note 9 5G 大为不满，借此契机，我卖掉了红米 Note 9 5G，买来了一台小米10。\n至于为什么要买小米 10 而不是其他机器，其实也没有什么特别的理由：一是因为它在 5ber 明确的支持设备清单里；二是它很便宜，以 500 到 600 元的预算，可以轻易的买到一台；三是因为我家里的米家设备；最后，当然是因为这新一代钉子户各方面比较均衡。\n我也没有多看，随意在闲鱼上下单了一台。其实现在看来，如此草率的下单，着实有些不妥。先说说收来机器的外观吧，一句话，「千疮百孔，饱经风霜」。这部手机更换过后盖，中框早就被原机主摔得不成样子，充电口也是出现了明显的磨损痕迹，屏幕的一角出现了无法移除的污点。现在看来，这台 8 + 256G 的小米 10，其 619 的价格，显然有点贵了。\n我对备用机的要求 说到我对备用机的要求，我想了想，其实也没那么多，首先是手机最基础的功能——通信：我需要一台支持 5G 的手机，还需要支持 5ber 卡的写入；然后是续航，当然是越长越好，毕竟这是需要承载我外出热点需求的手机；其次是满足我偶尔的玩机需求，最好有丰富的玩机资源和活跃的社区，这一点作为「新一代钉子户」的小米 10 显然不是问题；最后是必须有高刷屏，因为我实在是受够了 iPhone 12 系列的 60Hz。\n换电池 原机器的电池出现了很严重的衰减，Battery Guru 估计的容量只有 3100 mAh/4780 mAh，也就是 65% 的健康度，你问我为什么会买一个电池烂成这样的机器？还不是因为验货宝的「电池」那一栏乍一看没问题可是实际上安卓机都是一个「安卓机无法检测」？以这台机器买来时的电池状况，就算只是刷刷信息流类的应用，也会在四个小时以内没电，待机续航更是惨到了我不想带它出门的地步。这台手机计划的用途之一就是热点机，如果连带都带不出去那还谈何热点？事到如今，必须要给这台小米 10 换一块电池。\n原本我准备直接去售后更换电池，价格随手在网上一查——159 元包工包料，算了吧，这手机才 619 呢，我还是自己买块电池来换吧。六七年前我还在酷安上活跃的时候，正好是第一批小米 6 需要换电池的时候，当时我就已经看到「中电」这个词大行其道。遂直接以 89 的价格买下中电的增容电池，自己动手换。\n换电池的过程在B站上就能看到1，照做即可。在换的过程中，我却又发现了这台手机的问题——它肯定被人拆过，而且拆得很粗糙：防拆贴纸已经被动过，更好笑的是螺丝都没有拧全。虽然我买来时已经知道这部手机换过后盖，但内部如此粗糙的手法却没有影响到手机的任何功能，也是令我啧啧称奇。\n回到正题，换电池的过程倒是挺顺利，增容电池也不顶后盖，套上保护套也就完全无感了。换完之后，续航脱胎换骨，用上一整天完全不是问题。总之，现在我是愿意把这台手机带到外面去用了。\n解锁 Bootloader 现在的小米早就不是以前那个富有极客精神的小米。\n解锁 Bootloader 这么简单且基本的要求在 Hyper OS 上竟然可以受到如此大的阻碍：按照系统原本的要求，需要在小米社区至少达到 5 级，之后再参与解锁内测资格的申请，答题之后方可为设备绑定小米账号，之后再保持 SIM 卡插入的状态等待 168 个小时，方可解锁。\n不是，你们是来搞笑的吗？？\n好在小米 10 原本搭载的是 MIUI，可以用一些手段绕过 Hyper OS 相较于 MIUI 额外添加的解锁限制2。MIUI 原本 168 小时的等待是无法绕过的，于是只好还是等一个星期之后再开始玩机，在此之前，我会开始做一些准备工作。\n去广告 之前熟悉的大圣净化和李跳跳都因腾讯的律师函而停止更新，于是在网上转悠着找到了「GKD」，完全开源。只是可惜了我之前买的大圣净化授权。授权时用到了 Shizuku，感觉现在 Shizuku 的生态也比七八年前好了不止一星半点。\neSIM 当然，小米 10 本身不支持 eSIM，不过我早在之前就已经准备好了一张 5ber SIM 卡。目前 eSIM 功能很好，数据漫游无压力。开通的保号套餐也是 OK 的。至于如何开通这些 eSIM，请准备好一张 VISA/万事达卡，然后自行去网上找满天飞的教程。\n目前个人觉得比较好用的是 ClubSIM，一年只需消费 6 HKD 就可以保留手机号码。至于网上满天飞的乌克兰 LifeCell，我反倒不是很推荐，因为他们的号码总是容易被莫名其妙的风控，比如 Telegram 原本的短信验证会强制变更为电话语音播报验证，也就是要求在漫游状态下接听国际长途电话，而 LifeCell 的漫游费用并不便宜，相比于风控更少的 ClubSIM，这张卡只适合去注册极少量的服务。\n虽然 ClubSIM 保号合适，如果有大量的数据漫游需求，我建议购买 3HK 的漫游服务。而我个人只是偶尔才需要原生 IP，其余时候只需能接收短信即可，于是就直接选择了 ClubSIM。\n基本满意的性能和续航 这些年来，我逐渐告别了本就玩得不多的手机游戏，现在手机能作为我外出空闲时的一个补充就可以了，唯一的性能要求是只要能保证日常使用流畅即可，至于游戏，只要能带得动王者荣耀级别的轻负载就行。这种佛系的性能要求，即使是接近五年前发布的小米 10 也可以轻松胜任。至于跑分，我就不让这台老机器在娱乐兔上献丑了。\n换过电池的小米 10 可以轻松应对我出门时的续航需求：导航一整天完全无压力，即使开热点也不存在任何续航问题。这个续航表现，我基本满意。\n「又不是不能用」 接下来就是不太满意的点，首先是只有 8GB 的内存，这个内存容量放在几年前还说得过去，放在今天就显得有些捉襟见肘。后台留存的能力就别想了，能保住日常的流畅就已经谢天谢地。因此，我只好自己勤快一些，多进后台页面按两下全部清空键。\n然后就是屎一样的解锁流程，点名批评 HyperOS。我自己的手机想要解锁，还需要去你社区水到 5 级，然后答题解锁吗？真是搞笑。这种用户本应有的权利被厂商夺走的感觉让我对小米的印象变差了不少。\n最后是屎一样的尾插设计。不同于其他手机模块化的尾插，小米 10 的尾插是直接焊在主板上的，而它这尾插用久了极其容易磨损导致接触不良，无法充电，这时要更换却非常麻烦，需要将尾插重新焊接一遍。目前我这台尾插已经出现了略微的松动迹象，到时候如果需要更换了，也是一个额外的麻烦。\n最后…… 总体上，小米 10 用起来还是不错的，它满足了我对备用机所有的需求，在各方面也都均匀水桶，虽然它有如上所述的小问题，但总体上，它依然是一部好手机。我对这次备用机的换机还算满意，希望这台小米 10，至少在它被卖掉之前，能伴我度过一段美好的时光。3\n我参考了这个教程\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考 Github 项目：MlgmXyysd/Xiaomi-HyperOS-BootLoader-Bypass\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n题图来源见水印。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-12-05T19:56:29+08:00","image":"/2024/12/umi-experience/cover_hu_d7a8279c694f004e.webp","permalink":"/2024/12/umi-experience/","title":"在 2024 年末收台小米 10 当备用机"},{"content":"不知出了什么问题，我的电脑的时间从来不会自动和 NTP 服务器同步，虽然短期内并不会对使用造成什么影响，但倘若放任不管，时钟的偏移量太多，则可能会造成 SSL 和 TOTP 等依赖时间戳的应用出现问题，再者，手动按同步键也很不方便，今天我决定必须要解决这个问题。\nSpecialPollInterval 在网上搜索一番之后，我发现有人提到SpecialPollInterval这个键值，其具体位置是HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\NtpClient，微软官方文档对其的描述如下：\nThis entry specifies the special poll interval in seconds for manual peers. When the SpecialInterval 0x1 flag is enabled, W32Time uses this poll interval instead of a poll interval determine by the operating system. The default value on domain members is 3,600. The default value on stand-alone clients and servers is 604,800.\n对于一般客户端，这个键值的默认值是604800，也就是一个星期同步一次，这个间隔显然太久，于是我将其设置成了3600令其一小时同步一次。\nw32tm 几天后，当我再次检查时间时，却发现时间仍然没有自动同步，这一次的偏移量已经达到了 15.8 秒。\n于是查询「SpecialPollInterval」想要知道其具体的作用和未及预期目的的原因，却发现了微软的一篇疑难解答。这篇疑难解答指出：「每次客户端轮询时间样本到 NTP 服务器时，NTP 客户端都会进入 SPIKE 状态。 时间服务管理其内部状态，如果客户端进入 SPIKE 状态，则客户端不会同步其时间。」\n为了解决这个问题，需要将 Windows 时间配置为使用 MinPollInterval/MaxPollInterval 作为轮询间隔。\nw32tm /config /update /manualpeerlist:cn.pool.ntp.org /syncfromflags:MANUAL服务尚未启动 执行这一行配置时出现了「服务尚未启动」的提示，这说明用于时间同步的服务根本没有启动。如此基础的服务竟然不会自动开机启动，我也不知道这是 Windows 的 Bug 还是我后期使用无意间制造的问题，不管怎样，首先启动这个服务：\nnet start w32time w32tm /register # 注册一些基本的注册表键值和相关服务随后 Win + R 运行services.msc打开服务管理面板，找到「Windows Time」服务，将其启动类型设置为「自动」，即可让其开机自动启动。\n再次重新启动电脑，这次打开「设置」\u0026ndash;\u0026gt;「时间和语言」\u0026ndash;\u0026gt;「日期和时间」\u0026ndash;\u0026gt;「附加时钟」，切换到「Internet 时间」选项卡，如果出现了「下次同步」的字样，说明这套系统终于是正常运作了。\n","date":"2024-11-18T18:03:47+08:00","image":"/2024/11/windows-ntp-hiccup/cover_hu_e196169a0c972a34.webp","permalink":"/2024/11/windows-ntp-hiccup/","title":"Windows Hiccup 小日常：处理时间同步服务的问题"},{"content":"银行卡 汇丰蓝狮子 也就是汇丰银行的 MasterCard 扣账卡（也就是内地常说的借记卡/储蓄卡），在香港开好户之后直接在 App 里申请一下就行，记得申请之前先改一下用户资料里的中文地址。卡片会在一到两个星期之后邮寄过来。\n这张卡和汇丰的银联卡（红狮子）余额是互通的，每笔消费会有 0.4% 的返现，这个不设上限的返现的优惠力度甚至超过了很多国内的信用卡，全球取现免手续费，也没有任何年费，是一张很适合用来消费的借记卡。\n工银星座卡 工银专门给有海淘需求的学生量身定做的卡，0 额度，是一张介于信用卡和借记卡之间的卡片，申请它就是中意它的 VISA 标志。即使这张卡有 VISA 标志，用起来还是不太方便：海外支付之前需要手动购汇，同时币种必须正确，任何一环出错都会导致交易失败。\n卡面颜值还算不错，但是非常容易刮花，甚至还会掉漆，基本买回来就只能放在家里供着，好在这张卡不需要经常去上 ATM。\n兴业寰宇人生 \u0026amp; 无界卡 一张银联借记卡，从名字就可以看出来，这张卡是专门为有跨境金融需求的人推出的。可以免除前 30 笔跨境电汇的手续费。以及境外 ATM 取现的手续费，这一点对于经常有跨境电汇需求的人来说，这张卡可以省下不少钱。\n无界卡据说是有寰宇人生的权益，但卡面是透明卡面，看起来更有意思一些。这套外观见仁见智，只要实用，什么都好说。\n5ber SIM卡 前两年很火的 SIM 卡，可以让不支持 eSIM 的手机支持 eSIM，最近才入手。5ber 操作算是所有 eSIM 转实体 SIM 卡里操作最简单的了，一般只需扫描 eSIM 二维码即可。上手以后下载了一张乌克兰 lifecell 和香港 ClubSIM，都是保号神卡。\n当全世界都在普及 eSIM，国内的运营商却相继停止了 eSIM 业务，属实让人费解。实名制的问题很好解决，参考香港的方案就可以，然而国内却疯狂开倒车，推出了所谓「超级 SIM 卡」，也不知道国内什么时候才能提供方便便宜的 eSIM。\nWacom 数位板 买数位板来画画？别闹了，正经人谁买数位板就图个画画啊。当然是用来 osu! 啊。最近鼠标打歌上了 3000pp，决定买个数位板来体验一下，既然是打 osu 嘛那肯定是哪个便宜买哪个，于是就无脑入手了 Wacom CTL-472 这块入门数位板。\n真正上手之后发现鼠标转数位板有一段比较难的适应过程，不光能打的歌难度会有落差，手部肌肉酸痛的位置也会不同，尝试了两天之后我还是决定暂时回到鼠标……\n小米 10 当年给我爸安利的小米 10 Pro 用了四年依然好用，于是我自己就收了一台小米 10 来当做备用机。小米 10 也算是某种意义上的新一代钉子户，性能、续航、屏幕素质等各方面都比较均衡，用了这一段时间我甚至想要把它当做主力机。\n买小米 10 的主要理由其实就是前面提到的 5ber 真·为了一碟醋包了一盘饺子。 5ber 对手机的支持很奇怪，很多我认为会支持的安卓机实际上并不支持，为此我不得不卖掉了原有的备用机，转而购买了这台小米 10。\n关于是否刷机的问题，我目前有些犹豫，一方面 HyperOS 已经足够好，功能丰富，使用流畅。另一方面，众所周知的隐私问题却让我不得不思考到底要不要把这台手机刷成 Lineage。总之，目前，我打算先用一段时间。这也算是一种隐私方面的摆烂吧。\n虚拟服务器（VPS） 最近我的服务器也快要到期了，于是就需要物色新的机器，目前是尝试了 Contabo 和 Hetzner，计划还要尝试 Netcup。每新购进一台机器，我都要将其系统重装之后测试能否跑动我目前数据量日益增长的 Iceshrimp 服务。鉴于目前发现 Cloudcone 性能实在是太差，还是需要找一台稳定的机器才行。\n其中 Hetzner 我个人觉得很不错，机器性能很强，SLA 有保障，自研的面板很好看。三网回程质量还不错，选得纽伦堡机房，移动走的是高级 CMIIN2，其他两个走的普通线路。价格虽然比不上 RackNerd、CloudCone 这类廉价机器，但在同性能的机器里算是很低的了，外加更好的防止滥用机制，拿来跑服务是完全没问题的。\n至于 Contabo，个人认为其性能比较弱，且 SLA 保障过于离谱（95% 的 SLA，也就是一年能坏掉 18 天多），外加限制诸多（比如不开放邮件端口），尝鲜以后，我不推荐。\n淘宝流量神卡 在淘宝上买便宜的流量卡要做好被套路的心理准备，这一次我买了一张，大致弄清了流量卡的套路：先是在宣传图上放一个实际月租 9元/月 的套餐；下单之后以各种原因说无法发货；最后用各种话术玩文字游戏，骗你去换到一个更贵更差的套餐。\n我这一张，一开始买的时候宣传图上的实际月租是 9元/月，移动 105G 通用 + 30G 定向流量。说无法发货之后换成了一个联通 70G 全国流量 + 120G 省内流量的套餐，实际月租似乎也变成了 19（当然实际月租还是得等下个月扣费才知道），而且更加过分的是还有两年的合约期。不过，尽管如此，这个套餐也依旧还算便宜，先用着吧，反正半年以后就丢了，弄清楚套路涨经验也是很不错的回报。\niOS p12证书 很多人认为安卓是玩机的代名词，其实不然，只要愿意折腾，iOS 能够折腾的项目不比安卓少。p12 证书原本是苹果为开发者提供用于测试尚未上架 AppStore 的应用的工具，任何应用只需经开发者的 p12 证书签名，就可以在 iOS/iPadOS 上运行。\n苹果将非开发者账户可以签名的应用数量限制在了 3 个，只有开发者账户才能签名无限制数量的应用。开发者账户订阅的价格是 99美元/年，对于只是想要装几个应用的人来说显然没有必要。网上有人售卖已经签名过的开发者证书，直接购买使用即可。\n目前我就用来装一个 BHTwitter 和 EhPanda，装上 Esign 并导入证书之后就可以自由安装软件，还可以添加第三方的软件源，免费软件源质量相对比较低，收费软件源质量会相对更好，软件也会相对更全。所以，我们今天在此体会不到这一点。\n这种证书还可以用于多开应用、游戏外挂等，可玩性还是很高的，大多证书价格也还算不错，在 6 - 100 元不等，比起苹果官方 99 美元/年的开发者订阅，这笔钱算是物有所值。\n","date":"2024-11-15T18:39:17+08:00","image":"/2024/11/recent-gadgets/cover_hu_7ec602792c5b9b6.webp","permalink":"/2024/11/recent-gadgets/","title":"近期上手的一些小玩具"},{"content":"桂林小住 又是这一句老掉牙的开头：「桂林山水甲天下」。\n说起桂林，对这座城有所耳闻以及真正去过的人大概占大多数。世界级的山水，三线的城建。十多年前，我曾在桂林居住过若干时间：城里的象鼻山，两江四湖的游船；城外的阳朔，漓江竹筏，还有江滩上的烧烤。\n别人的旅游目的地，我早就失去了兴趣。你也许听过一句调侃：「不到长城非好汉，再到长城王八蛋」，说的就是这种感觉——就像甜腻的饮料，初尝时宛如天堂般美好，一旦形成味觉记忆，再喝下去便只觉得难受。\n刚从香港回来，还没几天，又踏上去桂林的路，实际上，我是不太愿意的。香港之行已经让我觉得压抑无比，舟车劳顿。感觉非得用整个国庆假期休息不可。\n但是生活总是光怪陆离，莫名其妙。不知怎么地，我又踏上了一段新的旅程，前往这个我几乎已经玩遍的城市。\n一座城市就是一种心情 要说长沙是娱乐至死，桂林在我的眼里，则是相对悠闲的：六块钱一碗的桂林米粉不限量供应，只要愿意，一日三餐都吃，18 块钱便可解决一天的温饱问题；淡季时两江四湖几乎称得上人烟稀少，因为其超强的接待能力在淡季形成大量冗余，酒店的价格会相当地低，旅游景点同理。所以，之前在桂林时，吃喝玩乐都很便宜，用相对低廉的花费把桂林山水玩了个遍。\n国庆假期住在刚好出门旅游的亲戚家，住宿无花费；我妈的公司补贴所有家用车的油费；加上桂林的日常消费很低，这种换个心情的方式真的很抠门省钱。\n于是就在桂林愉快的住了五天。\n树莓派和 Cloudflare Tunnel 树莓派是和我的室友 AA 买来做项目的，做完项目之后就算作我的了。现成的计算资源白在这里，不用白不用。所以我为这片树莓派装上了 Raspberry Pi OS Lite 64bit，接入网络，把它当作服务器使用。\n毕竟是 ARM 架构，树莓派运行起来功耗很低，待机功耗不到 5 W，峰值功率 25W，正常情况下极少跑到峰值功率，一年电费最多几十块钱。\n最难解决的部分是网络问题，拜中国大陆特殊的网络环境所赐，想要把一个放在家中的服务器上的内容发布到公网十分蛋疼，一是运营商默认没有公网 IPv4，即使有，也是动态的；而这可怜的动态 v4，80、443 等常用的端口更是想都别想打通；想要静态的 IP 也不是不行，买企业专线吧，不光需要办理各种证照，价格也比家宽贵至少十倍。\n本来我对 Cloudflare Tunnel 不报什么期望，在网上抱怨其经常断联、丢包等问题的帖子比比皆是，实际上手之后它却大大出乎我的意料，除了根文档加载时间相对偏长，其他的静态资源皆从 Cloudflare 强大的 Edge Network 中获益，加载速度飞快。而且，不知是地域差异还是运营商之间的区别，我的 Tunnel 即使在晚高峰时期也依然保持稳定和相对快速。这是我在树莓派上搭建的测试博客，如果你想要知道具体的加速效果，可以进去看看: https://rpiblog.l3zc.com。\n解决了内网穿透的问题，树莓派的可玩上限就大大提高，以后可以拿来做很多有意思的事情。只能期望运营商不要无缘无故掐掉我的 Tunnel 吧。\n我的 RSS Feed 加入 Follow，认证我的博客 我第一次听说 Follow 是看到了 DIYGod 的推文，这是 DIYGod 继 RSSHub 之后又一个开源项目，目前仍然处于 Alpha 阶段，但是完成度已经相对不错。\nFollow 是一个 RSS 阅读器，和 RSSHub 、RSS3（For real why??）深度整合。与大多数 RSS 阅读器不同，Follow 采取的是云端服务器代为抓取内容，所以有订阅源数量的限制，同时目前内测阶段也需要邀请码才能使用，好在这在广大网友的帮助下并不是什么难事。\n目前我已经使用 Follow 一个星期，整体的体验还是非常不错的，功能强大，使用流畅，还有无限量（目前暂时如此）的 LLM 摘要\\翻译功能。\nFollow 也是一个社区，订阅源的 maintainer 也可以在 Follow 上认证自己的订阅源，这样就可以接收别人的打赏。打赏是以一种名为 Power 的 ERC-20 代币实现（for real why?? 我就是想读 RSS Feeds，为什么我会需要用到区块链呢？），虽然目前这种做法在我看来依旧存在很大的争议，但 Follow 将这一功能本身打磨得十分到位，体验良好。\n修正 RSS Feed 阅读体验问题 我博客上原有的 RSS Feed 是由 Hugo 默认的模板生成的，正文部分直接使用了.Content变量拉取的内容真就是依托答辩，不仅会包括一堆内置的图片处理功能生成的不同分辨率的图片 url，代码块部分还会有 chroma 生成的一堆一般阅读器不能正确处理的代码行号和高亮标记。所以我加了几个 Render Hook，修正了一下 Hugo 的这些问题：\n./layouts/_default/render-codeblock.rss.xml:\n{{ .Inner }}./layouts/_default/render-image.rss.xml:\n{{- $url := urls.Parse .Destination -}} {{- if not (or (eq $url.Scheme \"http\") (eq $url.Scheme \"https\")) -}} {{- $result := .Page.Resources.GetMatch (printf \"%s\" (.Destination | safeURL)) -}} {{- with $result -}} {{- end -}} {{- end -}}这样，就再也不会出现原来糟糕的阅读体验了 （应该吧）。\n另外我也对前端进行了一些小优化，现在复制代码的时候，再也不会出现如下所示的，意外选到旁边的行号的情况了。字体换成了 Jet Brains Mono，Padding 也进行了一些调整，让拷贝变得更轻松。\n写博客之余，修一修博客上的 bug 多是一件美事。这次修改也算是磨刀不误砍柴工，让我自己心情变好的同时也让大家的阅读体验变得更好。\n","date":"2024-10-23T02:05:20+08:00","image":"/2024/10/guilin-raspberrypi-and-rss-feed/cover_hu_9e407f5dddff8939.webp","permalink":"/2024/10/guilin-raspberrypi-and-rss-feed/","title":"近况：桂林，树莓派，以及我的 RSS Feed"},{"content":"近期游览香港，带回一些纪念品，谨将这些纪念品与在港的回忆编写成文，以作留念。\n八达通 我在抵港之前就已经开通了八达通。八达通几乎可以畅游整个香港，港铁、便利店、叮叮、巴士、山顶电车、天星小轮……几乎什么地方都能用。\nApple Pay 里可以直接用人民币开通八达通，需要交 50 港币押金，说是可以退，但真的去退的又有多少人呢，权当是开卡的手续费了。不过 Apple Pay 不需要手续费就能直接用人民币开卡和充值，汇率也是相当不错，这一点好评。\ncsl. 手机卡 香港旅游最便宜的 SIM 卡是中移香港的 MySIM，然而我却偏偏选了贵了快一倍的 csl.，不用说，当然是为了保号。\n虽然我之前知道 ClubSIM 可以做到 6 港币一年保号，然而抵港之后的第一个便利店里却并不卖这种卡，无奈只好选择了 csl. 香港任纵横，充值 50 港币可以延长 180 天有效期。掐指一算，这张 csl. 一年 100 港币才能保号，烦，要是当时能找到一家卖 ClubSIM 的卡就好了。\n当然，这张卡片，自然可以留作纪念。\nSUA 注册标签/香港政府公函 抵港的第一件事，便是取走早已申请的 SUA（Small Unmanned Aircraft）注册标签。\n根据香港法律第448G章《小型無人機令》，我的无人机属于甲二类无人机，需要向民航处申请注册，并贴上民航处的二维码，同时我也需要在网上注册「遥控驾驶员」，取得相应的执照。两者齐备后才算是合法飞行。\n由于长沙没有直达香港的航班，我只好从香港西九龙高铁站进关。进关后直奔柯士甸站，坐上屯马线转东涌线，直奔机场。本来高铁进关可以享受到的直达市区的便利，现在全都变成了前往民航处漫长的来回旅程所带来的双倍痛苦。\n从东涌线下车之后转 S1 机场巴士前往「民航处总部；东耀路」站下车，你就会看到这番鸟不拉屎的景象：\n香港是真的很热，尽管室内的冷气都开得很足，但这种遥远的郊外显然没有空调。这种地方对于我这种爱出汗的人来说简直就是地狱，上了一个小坡便已经热出了不少汗。好在进入民航处的办公楼以后，终于有了 much needed 的空调。工作人员都很热心，工作效率很高，很快便帮我取来了这两个月前就已经打印好候取的标签。并指导我完成了无人机驾照的考取（就是看一些规矩，不用担心）。\n于是就愉快的拿到了注册标签。\nHSBC 银行卡 去香港开个银行账户，有很多好处，比如不需要港股 50 万入场费便可以交易港股，不受制于内地的外汇管制等等。这次抵港我有充足的时间开户，于是一天大早我便动身前往开户。\n我的酒店在湾仔，而我想去位于中环的汇丰总行，需要从港岛西面到东面。横贯港岛有两种主要交通工具：一是港铁的港岛线，二是香港著名的电车，昵称「叮叮」。相较于车费昂贵的港铁，叮叮是我在香港体验最好的交通工具之一，无论坐多远，票价始终亲民，仅需3港币；以如此低廉的价格，就能感受这条已有百年历史的电车。叮叮拥有专用轨道，几乎不会被堵，在香港的大街上缓缓前行，不时发出清脆的铃声；街道上人声鼎沸，双层巴士轰鸣作响，而红绿灯也为视障人士持续发出声音，这就是繁华而嘈杂的香港。\n汇丰总行大厦的正门实际上是面向皇后大道中一侧的入口，而非皇后像广场一侧的德辅道入口，而德辅道入口却因为公共交通更便利而被绝大多数人使用。在银行街下车，对面就是汇丰总行，坐电梯上楼即可。开户预约？别闹了，有的分行都已经预约到一个月之后了，这谁受得了啊。就直接 Walk in，和接待说要开户，现场取号即可。真不知道那些预约的人都到哪里去了，非高峰期几乎不需要等，我去的时候只等了一个号码而已。服务态度还不错，简单问了问开卡的目的，现场下卡。\n开好银行卡就在中环转了转，一览终审法院、皇后像广场、和平纪念碑、威尔士亲王军营以及添马的政府总部。能在高楼林立的地方找到如此多文物古迹和文物级别的建筑，可见香港的历史底蕴深厚。如此多的知名金融机构和政府总部齐聚于此，中环不愧为香港的政经中心。\n《坐困愁城》和《书店有时》 这两本书其实没有什么特别的意义，单纯是我在书店里逛的时候觉得比较感兴趣的书。两本书一共花了我快 300 港币，香港真的是什么都贵。\n香港的出版业原本繁荣，自主权移交以来，却一步步在审查的压力下变得每况愈下。这次游览香港，所到书店，所阅之书，总感觉作者和出版社束手束脚，真是令人难以接受。无奈，选取一本港区国安法生效之前出版的书籍，以及一本中国大陆罕有的竖排印刷书籍，用以阅读留念。\n山顶电车双程票 就算我可以直接刷八达通，为了纪念，我还是有意买了山顶电车的双程票。88 港币的价格以香港的物价标准来看甚至可以作为日常通勤的交通工具，Hmm，还是我这个内地佬太穷了。\n前往山顶缆车中环总站的路上顺道看了看汇丰总行后面的前法国外方传道会大楼以及圣约翰主教座堂。后者是香港最古老的西式教堂，气氛庄严肃穆，装饰典雅精美，外观朴素宁静。中环真是遍地是宝。\n山顶缆车早在 1888 年就已经开始运作，目前已经更新到了第六代，从中环总站上车的人流络绎不绝，其中很多是游客，但也不乏本地人。山顶缆车的设计始终与时俱进，还增加了空调。这一点比起自开通以来从未更换过车辆的叮叮要强得多，当然，票价也贵了 20 倍有余。\n登上太平山顶，可惜当天并不怎么通透，拍不出什么好照片。即使是用无人机拍也是如此。\n只能说由于天气和设备都不太行，加上光圈开得偏大，最终有这样的结果，我还算满意。\n港币纸钞 不同于其他地方，香港的货币发行制度独具特色，由香港金融管理局授权并监管下的三家发钞银行所发行，包括汇丰银行、渣打银行和中国银行香港。香港政府则发行十元钞票。这一次没有拿到有英国女王头像的硬币，属实有点可惜，但这些由不同发钞行发行的纸币，还算有点纪念价值 （其实就是纸币没花完罢了）\n其他一些照片 写到这里，我才意识到，虽然这些纪念品能串联起我在香港的大部分经历，但显然无法涵盖我在漫步香港的过程中中随机发现的点滴。既然是作为纪念，关键事件就应该尽善尽美地记录下来。因此，我不得不暂时停止对纪念品的描述，将我在港的其他经历以照片的形式一一记录。\n高铁车票（报销凭证）\u0026amp; Wrap Up 车票早就全面电子化，现在能取到的实体印刷票都是报销凭证，并没有车票的功能。而我不需要报销，但也取出了车票，自然也是离港前的最后一件纪念品。\n","date":"2024-10-12T11:49:42+08:00","image":"/2024/10/hk-souvenirs/cover_hu_330bd22de0169088.webp","permalink":"/2024/10/hk-souvenirs/","title":"我从香港带回了哪些纪念品？"},{"content":"长话短说，最近我开始直播我的游戏实况，我并不指望有多少人看，Just, Why not? 再者每个直播平台都会有直播回放。相当于免费保存我每一次游戏的录像，何乐而不为？\n扯远了，如你所见，近期我有了多平台同时直播的需求，然而 OBS 本身显然不支持同时推流，同时也因为不支持设置代理的特点和众所周知的原因，无法推流到 twitch.tv，于是我开始寻找解决方案。\n明确需求 多路平台同时直播 最好对性能影响小 其中一路需要推流需要代理 多路推流 多路推流有现成的插件可用：Github\n在 Release 页面下载.exe安装包，安装完成后记得在「停靠窗口」菜单里勾选「多路推流」。这时候默认会弹出一个独立窗口，可以趁这个机会顺便调整一下 OBS 的布局。\n插件的设置也没什么好说的，用在原版 OBS 的填法在这个插件里如法炮制即可。\nBilibili 直播姬 莫名其妙，B 站小于 50 粉丝的 Up 主只能使用直播姬开播，其他国内平台做出类似规定者大概也不在少数，启用第三方推流模式之后，直播面板会显示推流的配置。此时的不需要按照直播姬给出的推流地址进行配置，因为直播姬莫名其妙的给了一个每次都会变的内网 IP，直接以127.0.0.1或者localhost替换即可。\n推流到 Twitch 推流到 Twitch 则会因为 GFW 多出很多不必要的麻烦。\nOBS 本身并不支持设置代理，起初我打算用 Clash 的 TAP 模式强制代理 OBS 的流量，而 Clash 的 TAP 并不监听 rtmp 流量，宣告失败。我决定直接架设一个转发服务器，这个服务器需要既可以与 Twitch 通信，又可以不受 GFW 的干扰。\n在网上查到一些信息，Caddy 似乎不支持 RTMP 协议，而 nginx-rtmp 插件则专门为 RTMP 协议设计。这几乎是唯一的选择。\n部署的前提：\n熟悉基本的 Linux 命令行操作。 服务器已经安装好docker和docker compose插件。 有合适的命令行文本编辑器，比如nvim或者绝大部分 distro 自带的nano。 新建目录：\nmkdir nginx-rtmp \u0026\u0026 cd nginx-rtmp创建docker-compose.yml：\nservices: nginx-rtmp: image: tiangolo/nginx-rtmp:latest container_name: nginx_rtmp ports: - \"1935:1935\" # RTMP port volumes: - ./nginx.conf:/etc/nginx/nginx.conf restart: unless-stopped创建nginx.conf：\nworker_processes auto; events { worker_connections 1024; } rtmp { server { listen 1935; chunk_size 4096; application live { live on; push rtmp://live.twitch.tv/app/{Twitch 主直播密钥}; } } }启动编排：\ndocker compose up -d # 老版本 compose 插件则是 docker-compose up当然，别忘了开放防火墙端口。我的防火墙参考了 To Fix The Docker and UFW Security Flaw Without Disabling Iptables 一文中提到的配置，相应地，开放端口的命令如下：\nufw route allow proto tcp from any to any port 1935配置完成后，OBS 内的推流目标地址填入rtmp://服务器ip/live，推流码填写任意值均可。设置完成后即可开始推流。\nNetch 如果没有服务器，亦可以使用 Netch 代理 OBS 进程进行推流。\n首先下载 Netch 1.9.2 版本，注意一定要是 1.9.2 版本。添加一个进程模式，将 OBS 文件夹加入，随后启用该进程模式的代理即可。\n尾声 这次为了在同时在 Twitch 和 B 站上推流，遇到了很多原本不必要的麻烦。我可以怪 OBS 没有内置代理功能，也可以怪 Clash Verge 等代理工具不支持 RTMP，转来转去，最终要怪的，还得是 GFW。虽然最后的结果还算令人满意，仅仅为了推流而折腾这些东西的体验实在是称不上良好。也许我今后我应该去研究修改 Mihomo 内核，让其支持 RTMP 协议，亦或是自己写一套独立的实现单独转发 OBS 的流量，不论如何，在这片土地上，想要畅快的直播，道阻且长。\n最后，欢迎关注我的 Twitch 频道: https://www.twitch.tv/powerfullz233\n","date":"2024-09-18T14:16:51+08:00","image":"/2024/09/my-multi-streaming-setup/cover_hu_891493d684eb454d.webp","permalink":"/2024/09/my-multi-streaming-setup/","title":"OBS 多路推流折腾记：那些本不必要的麻烦"},{"content":"某天早上醒来，发现收件箱里多了封邮件，通知我的邮箱在韩国登录，当时认为只是偶尔的 IP 误判，也就没有多想。可接下来几天，时不时又有新的邮件进来，而且每次 IP 都不一样，这下可就有些问题了，再不采取行动，怕不是邮箱真的要被拿去群发邮件。于是赶紧删掉了域名的 MX、SPF、DMARC 记录，寻找新的解决方案。\n我原本只是想改改密码，结果呢，腾讯企业邮箱改密码的入口真的巨能藏，到处都找不到。算了，迁移，何必受这气。\n于是就有了这篇文章，从最开始的开放防火墙端口开始，到最后的优化送达率，我将分享我搭建 docker-mailserver 邮件服务器的经验，希望能帮你少踩些坑。\n搭建 docker-mailserver 邮件服务器前的准备 防火墙的处理 首先先开放防火墙的邮件服务常用端口，分别是25、143、465、587、993，各分支开放端口的操作不同，请自行谷歌或询问 AI，以 Ubuntu 使用的ufw为例：\nufw allow 25 ufw allow 143 ufw allow 465 ufw allow 587 ufw allow 993我的防火墙比较特殊，用到了ufw和 To Fix The Docker and UFW Security Flaw Without Disabling Iptables 一文中提到的配置。所以当我想要把 Docker 容器的端口暴露在外时需要做出额外的配置。\n# 开放邮件服务器所需的端口 ufw route allow proto tcp from any to any port 25 ufw route allow proto tcp from any to any port 143 ufw route allow proto tcp from any to any port 465 ufw route allow proto tcp from any to any port 587 ufw route allow proto tcp from any to any port 993验证你的服务器是否具备搭建条件 很多服务器，尤其是各种廉价的 VPS，并不适合搭建 docker-mailserver，各大邮件服务商为了过滤垃圾邮件，索性将所有曾经有过 Spam 行为的 IP 全部列入黑名单。如果你的 IP 被某个 Spammer 使用过，而恰好又被你的服务器提供商分配给了你，而你折腾了几个小时的邮件服务器却愣是收不到邮件，最后发现竟是 IP 被列入黑名单的原因，我不知道你会作何感想。\n有的服务器提供商的 IP 乍一看确实不在邮件黑名单中，但实际上搭建好之后还是无法发送邮件，为什么？因为服务器提供商担心 IP 被滥用，索性将邮件服务的端口全都封锁了。\n使用如下脚本检测你的服务器是否具备搭建邮件服务器的条件：\nbash \u003c(curl -sL IP.Check.Place) 如果在这一步发现你的服务器不适合搭建甚至不能搭建docker-mailserver，那就趁早打住吧，想办法换一个更干净、限制更少的 IP 再说。\n搭建过程 拉取配置文件 docker-mailserver 需要配置的配置文件有两个，compose.yaml和mailserver.env，分别拉取配置文件：\nmkdir mailserver \u0026\u0026 cd mailserver sudo apt install wget wget -O compose.yaml \"https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/compose.yaml\" wget -O mailserver.env \"https://github.com/docker-mailserver/docker-mailserver/blob/master/mailserver.env\"根据需求，可以修改不同的配置，下面是我修改的部分：\nPOSTMASTER_ADDRESS=webmaster@l3zc.com TZ=Asia/Shanghai SSL_TYPE=manual SSL_CERT_PATH=/certs/cert.crt SSL_KEY_PATH=/certs/cert.key用 Caddy 准备和自动维护 TLS 证书1 因为我已经在使用 Caddy，所以我这次就打算直接使用 Caddy 来自动维护证书。根据项目的官方文档，我只需要在 Caddyfile 里新增一个子域名，Caddy 就可以自动帮我维护证书。\nmail.example.com { tls internal { # ?? 这不是直接生成的内部证书么 key_type rsa2048 } # Optional, can be useful for troubleshooting # connection to Caddy with correct certificate: respond \"Hello DMS\" }当我更新完 DNS 记录，实际操作起来发现，我的情况比较特殊：我这台服务器上并没有用到 Caddy 的自动申请证书功能，而是使用了15年有效期的泛域名 Cloudflare Origin Certificate。即使我不为这个子域名指定证书文件，Caddy 也会在加载这张泛域名证书后认为无需再申请新的证书。这就很尴尬了，用 Caddy 的时候 Cloudflare Origin Certificate 和邮件服务器只能二选一。只好安装了dns.providers.cloudflare，并放弃使用 Cloudflare Origin Certificate，转而让 Caddy 自动为每个子域名申请和维护 TLS/SSL 证书，反正都是自动的，眼不见心不烦。\n安装dns.providers.cloudflare后的全局配置：\n{ acme_dns cloudflare {API_KEY} }最后把 Caddy 的证书存储位置映射到 docker-mailserver 容器内。\nvolumes: - /home/user/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.tld/:/certs/如果 Caddy 以 root 用户运行，则证书的位置应当为/root/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.tld/，做出相应的修改即可。\n然后就是之前提到过的配置，我将证书存储位置映射到了容器内的/certs/目录，所以配置为：\nSSL_CERT_PATH=/certs/cert.crt SSL_KEY_PATH=/certs/cert.key首次启动容器 首次启动容器需要立即（120 秒内）创建新的 Postmaster 账号。\ndocker compose up -d docker exec -it setup email add 优化送达率 DNS 记录 一条 A 记录，名称随意（假设为mail），指向服务器 IP（Cloudflare 需使用「仅 DNS」） 一条 MX 记录，Apex 域（@），指向mail.yourdomain.tld 一条 TXT 记录（SPF），Apex 域（@），可以在这里生成(可选)。 一条 TXT 记录（DMARC），名称_dmarc，可以在这里生成（可选）。 一条 TXT 记录（DKIM），名称mail._domainkey，具体配置在后文（可选）。 DKIM, SPF 和 DMARC2 什么是 DKIM，SPF 和 DMARC？简单来说，DKIM 是一个数字签名机制；SPF 类似于「员工名单」，记录所有合法的发件服务器；DMARC 则用于指示收件方的服务器如何处理未通过 DKIM 和 SPF 验证的邮件。3\n首先设置 DKIM，在服务器上生成公私钥对。\ndocker exec -it setup config dkim生成后的公私钥对可以在映射的容器目录./docker-data/dms/config/opendkim/keys/下找到。\n下载 mail.txt（复制其内所有内容粘贴到本地文件也可以），将其导入到 Cloudflare Dashboard 即可完成 DKIM 设置。需要注意配置完成 DKIM 后需要重启容器才能生效。4\ndocker compose up -d --force-recreate前面提到 SPF 相当于一个「员工名单」，既然我合法的发件服务器只有一台，那么 DNS 填写如下设置即可。\n\"v=spf1 mx ~all\"再就是 DMARC，可以使用前面提到的模板生成，这里不再赘述。\n如果你的域名服务商拥有自己的设置向导（例如 Cloudflare），亦可以使用它们简化设置流程。\n客户端设置 客户端设置相对就很简单了，IMAP 和 SMTP 服务器都是mail.yourdomain.ltd，开启 SSL 后端口分别是 465 和 993，登录即可。\n善用 MailTester 至此我们已经完成了搭建 docker-mailserver 邮件服务器的整个过程，在开始发送邮件之前，我们可以使用 MailTester 测试我们的配置是否正确。如果测试结果是 10/10，那么我们的 docker-mailserver 邮件服务器应该会拥有漂亮的送达率，好好享受吧。\n如果不是 10/10，也不要着急，认真查看扣分的原因，对症下药，一项一项解决即可。\nTODO-List 配套 WebUI 参考: https://docker-mailserver.github.io/docker-mailserver/latest/config/security/ssl/#caddy\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://docker-mailserver.github.io/docker-mailserver/latest/config/best-practices/dkim_dmarc_spf/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n更加具体的介绍: https://www.cloudflare.com/learning/email-security/dmarc-dkim-spf/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n在官方文档中有提及。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-09-06T11:57:18+08:00","image":"/2024/09/docker-mailserver-deployment-recap/docker-mailserver_hu_a649605529f354c4.webp","permalink":"/2024/09/docker-mailserver-deployment-recap/","title":"docker-mailserver 邮件服务器搭建记录"},{"content":"我的 Firefish 实例搭建于去年的 11 月，使用的数据库版本自然不是最新的，确切的说，是 PGroonga 12，一个基于 5 年前的 Postgres 的远古版本。为了避免今后的兼容性问题和安全问题，同时为了更好的性能，今天这数据库是非升级不可。\n升级一个用 Docker 跑起来的数据库和升级其他的 Docker 容器有很大不同，并不是拉取一个新的镜像就可以宣告结束。因为 Postgres 几乎每个大版本都有 Breaking Changes，新老版本产生的持久化文件并不兼容，如果直接拉取一个新的镜像运行，数据库是无法启动的，必须要采用一定的手段进行数据的迁移。\nPostgres 有官方的升级工具pg_upgrade1，这一次我不采用，因为我的数据库跑了一年多，而且用的还是 5 年前的老版本，用这个工具我不确定会不会出问题。这次迁移，大致思路是先导出 SQL，再将导出的 SQL 导入新版本。\n升级前的部署概况 以下是一些升级前需要了解的配置信息：\n项目 配置 实例部署方式 Docker Compose 数据库容器名称 firefish_db 升级前的数据库容器镜像 groonga/pgroonga:3.1.9-alpine-12-slim 数据库用户 example-firefish-user 数据库名称 firefish Docker Compose 的数据库部分如下：\ndb: restart: unless-stopped image: groonga/pgroonga:3.1.9-alpine-12-slim container_name: firefish_db networks: - calcnet env_file: - .config/docker.env volumes: - ./db:/var/lib/postgresql/data healthcheck: test: pg_isready --user=\"$${POSTGRES_USER}\" --dbname=\"$${POSTGRES_DB}\" interval: 5s timeout: 5s retries: 5导出当前数据库 对数据库进行升级之前，首先下线 Firefish 的编排：\ndocker compose down单独启动数据库容器，导出当前数据库为 SQL：\ndocker compose up -d db docker exec -it firefish_db pg_dumpall -U example-firefish-user \u003e backup.sql由于 Firefish 的数据库比较大，导出过程可能需要很长一段时间，比如我的个人实例就用了十几分钟。\n导出文件的处理 可能是由于新版的 Postgres 认证方式有所变更，如果直接向新数据库导入之前导出的backup.sql文件，就会改变新数据库的 Authentication Scheme，导致之后 Firefish 连接数据库时认证失败。要避免这个问题需要对目前的backup.sql进行一些处理，只抽取出其中的firefish数据库的部分，而不是直接导入所有数据。2\n#!/bin/bash [ $# -lt 2 ] \u0026\u0026 { echo \"Usage: $0 \"; exit 1; } sed \"/connect.*$2/,\\$!d\" $1 | sed \"/PostgreSQL database dump complete/,\\$d\"编辑一个 Shell 脚本为以上内容，保存至script.sh，用以处理目前的backup.sql：\nnvim script.sh # 或者任何你喜欢的编辑器 chmod +x script.sh ./script.sh backup.sql firefish \u003e\u003e upgrade.sql如果一切顺利，当前目录下就会出现一个名为upgrade.sql的文件，可以打开它看一下，确保其被正确导出。\n向新数据库导入现有数据 修改docker-compose.yml：\ndb: restart: unless-stopped image: groonga/pgroonga:3.2.2-alpine-16-slim # 最新的容器 container_name: firefish_db networks: - calcnet env_file: - .config/docker.env volumes: - ./database:/var/lib/postgresql/data # 注意这一行的变动 healthcheck: test: pg_isready --user=\"$${POSTGRES_USER}\" --dbname=\"$${POSTGRES_DB}\" interval: 5s timeout: 5s retries: 5注意数据库目录映射配置由./db:/var/lib/postgresql/data变为./database:/var/lib/postgresql/data，这么做是为了给新的数据库一个 Fresh Start，同时也保存老的持久化数据，即使出现问题，也可以随时用回老的数据库。\n拉取并启动新容器：\ndocker compose pull docker compose up db -d向新数据库导入upgrade.sql：\ncat upgrade.sql | docker exec -i firefish_db psql -U example-firefish-user -d firefish取决于数据库的大小，导入过程也会持续较长的时间。\n收尾工作 导入完成，启动整个编排：\ndocker compose stop db docker compose up导入后的首次启动不建议带-d参数，建议不带参数启动，确保启动过程没有问题后再以-d参数启动。\n最后，登入刚刚启动的 Firefish 实例，检查是否有任何数据损失，没有问题的话就大功告成啦🎉\n官方文档：https://www.postgresql.org/docs/current/pgupgrade.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考：https://thomasbandt.com/postgres-docker-major-version-upgrade\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-30T12:45:12+08:00","image":"/2024/08/upgrading-firefish-database-docker/cover_hu_c0ecfda1e4670195.webp","permalink":"/2024/08/upgrading-firefish-database-docker/","title":"Firefish 数据库升级记录"},{"content":"上一篇文章提到，我搭建了一个基于 Aria2 的 BT 离线下载服务器。为了用 Caddy 反向代理部署好的容器，我把原来偷懒用一键脚本部署的 Trojan 给卸载了，问就是因为这脚本把 80 和 443 端口都占用了，不卸载掉根本没法继续。\n于是离线下载服务器是搭建好了，可时不时需要的代理却不得不下线。仔细一想，之前看到过有人 Cloudflare + V2Ray + WS 复活被墙的 VPS，既然是 WebSocket，还能用 Cloudflare 反代，那用 Caddy 反代又有何不可呢？况且 Caddy 还有自动 TLS，比起 Nginx + Certbot 的组合配置起来肯定更简单。只要配置成功，我就可以在为 Caddy 留住 443 端口的同时跑代理了。\n安装 VLESS 和 Caddy 安装VLESS 可以直接使用 v2fly/fhs-install-v2ray 一键脚本：\n# 安裝執行檔和 .dat 資料檔 bash \u003c(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)Caddy 的安装请参考官方教程，例如，我使用 Debian 12，则使用以下命令：\nsudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy配置 VLESS 编辑/usr/local/etc/v2ray/config.json：\n{ \"log\": { \"access\": \"/var/log/v2ray/access.log\", \"error\": \"/var/log/v2ray/error.log\", \"loglevel\": \"warning\" }, \"inbounds\": [ { \"port\": 1234, //任意端口 \"listen\": \"127.0.0.1\", \"protocol\": \"vless\", \"settings\": { \"clients\": [ { \"id\": \"super-random-uuid\", //随机生成一个 UUID 替换即可 \"level\": 0, \"email\": \"example@example.com\" } ], \"decryption\": \"none\" }, \"streamSettings\": { \"network\": \"ws\", \"security\": \"none\", \"wsSettings\": { \"path\": \"/\" // 需要与之后的 Caddy 配置保持相同 } } } ], \"outbounds\": [ { \"protocol\": \"freedom\" } ] }编辑完成后保存退出即可。\n配置 Caddy 在你喜欢的位置创建一个 Caddyfile，或者编辑已有的 Caddyfile，加入如下内容，反向代理刚才在 VLESS 配置文件中设置的端口：\nyourdomain.com { # 用一个 Matcher 匹配所有指定路径的 Websocket 请求 @websockets { path / # 与前面 VLESS 的 path 保持一致 header Connection Upgrade header Upgrade websocket } reverse_proxy @websockets :1234 }至此，服务端所有配置文件都编辑完毕。\n启动服务 启动 VLESS，并设置开机自启动：\nsystemtcl enable v2ray \u0026\u0026 systemctl start v2ray启动 Caddy/更新 Caddy 配置：\ncaddy start caddy reload # 更新配置用以上操作全部完成后，Caddy 反向代理 VLESS 就完成了。\n客户端设置 客户端方面需要手动设置：\n地址是绑定给 VLESS 的域名。 端口是 443 TLS 打开 传输方式选择 websocket UUID 是之前填入 VLESS 配置文件的 UUID 所有的客户端设置大同小异，至于 Clash 的配置文件，可以参考 Mihomo 文档1，以下是我的示例配置文件：\nproxies: - name: \"A Random Name\" type: vless server: yourdomain.com port: 443 udp: true uuid: super-random-uuid flow: xtls-rprx-vision packet-encoding: xudp tls: true servername: yourdomain.com alpn: - h2 - http/1.1 skip-cert-verify: false network: ws smux: enabled: false需要生成 Clash 配置文件可以使用 V2RaySE 提供的工具。\n完成 好了，现在我们已经拥有了一个 VLESS 服务器，Caddy 会自动为我们申请和维护 TLS 证书，非常好用。\n只需要这么小小折腾一下，我仿佛又找到了当年用一键脚本搭建 SSR 时的愉悦，好好享受这种能顺利打开 google.com 时的兴奋吧。\nTODO List 基本搭建 伪装 毕竟继承 Clash Meta 衣钵的 Mihomo 也算是 Clash 正统了。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-13T16:24:26+08:00","image":"/2024/08/caddy-vless-proxy/cover_hu_1cd20ddda32e23a.webp","permalink":"/2024/08/caddy-vless-proxy/","title":"科学上网：用 Caddy 反向代理 VLESS"},{"content":"自从买了一些廉价 VPS 以后，手上就闲置了一台 Azure 的学生机，除了用来跑个 Trojan 暂时没有其他的用途。正好最近想要下一些 BT 资源，而国内的 BT 环境懂的都懂，遂决定用这台接近闲置的机器离线下载 BT。\n首先声明，所有 BT 下载行为需要自行承担被版权投诉的风险。\n安装 Aria2 对于这些不是「基础设施」的软件，我更喜欢直接拉取一个 Docker 容器的方案。我采用了P3TERX/Aria2-Pro-Docker1，这套已经修改好的 Docker 容器。Docker 容器部署起来如出一辙：首先编辑docker-compose.yml，docker compose up把所有容器都跑起来，最后反代暴露的端口即可。\n我的docker-compose.yml如下2：\nservices: Aria2-Pro: container_name: aria2-pro image: p3terx/aria2-pro environment: - PUID=65534 - PGID=65534 - UMASK_SET=022 - RPC_SECRET=replace-me # 记得修改这一行 - RPC_PORT=6800 - LISTEN_PORT=6888 - DISK_CACHE=64M - IPV6_MODE=false - UPDATE_TRACKERS=true - CUSTOM_TRACKER_URL= - TZ=Asia/Shanghai volumes: - ./aria2-config:/config - ./aria2-downloads:/downloads network_mode: bridge # 如果你需要用到 IPV6 网络，也可以使用 host 模式 ports: - 6800:6800 - 6888:6888 - 6888:6888/udp restart: unless-stopped # 防止日志塞满硬盘 logging: driver: json-file options: max-size: 1m # 也可以使用其他面板 AriaNg: container_name: ariang image: p3terx/ariang command: --port 6880 --ipv6 network_mode: bridge ports: - 6880:6880 restart: unless-stopped logging: driver: json-file options: max-size: 1m用 Caddy 反向代理 之前的反向代理，我都是用的基于 Nginx 的方案，而在这段时间里关于 Caddy 的好评不绝于耳，这次的我便换用了 Caddy，当然，主要也是想尝试一些新东西、新技术。\nCaddy 的使用真的非常简单，即使对新人也极其友好，例如，常用的反向代理本机某个端口，只需三行 Caddyfile 即可搞定。\ndomain.com { reverse_proxy :1234 }安装 Caddy 请参考官方文档，例如，我的服务器使用 Debian，则使用以下命令安装：\nsudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy安装完成后记得开放防火墙和从服务商策略组的 80 和 443 端口。\n在域名服务商处将要绑定的域名指向服务器，就可以开始写 Caddyfile 了。我们需要反向代理三个端口，分别用作不同的用途。我的 Caddyfile 如下：\n# Aria-NG 面板 download.l3zc.com { reverse_proxy :6880 } # Aria2 API arapi.l3zc.com { reverse_proxy :6800 } # Alist downloaded.l3zc.com { reverse_proxy :5244 }看到如此简洁的配置文件，不由得感叹，相比于 Nginx，Caddy 用起来真是令人心情舒畅。写入配置完成后，重新启动 Caddy3，就可以开始欣赏 Caddy 自动帮你申请 SSL 证书配置好 HTTPS 的绝赞过程。至此，反向代理的部分也就完成了。\n配置 Aria-NG Aria-NG 只是一个前端面板，可以和任何 Aria2 后端通信，为此，我们需要给 Aria-NG 提供配置信息。进入刚刚反代好的 Aria-NG 面板，转到 AriaNG 设置，填入配置信息。\n其中，RPC 地址是刚刚反代好的 RPC 地址，协议选择 HTTPS，请求方法选择 POST，RPC 密钥是在docker-compose.yml里replace-me处你所替换的值。\n若「Aria2 状态」旁出现「已连接」，说明配置正确。\n用 Alist 映射下载目录 我们通过 Alist 映射下载目录，以更方便的查看、管理和下载服务器上已经下载好的文件。Alist 同样也通过 Docker 部署，由于 Alist 本身在容器内运行们，无法访问容器外的文件，部署时需要将 Aria2 的下载目录提前 Bind 到 Alist 的容器下。\n我的docker-compose.yml如下：\nservices: alist: image: \"xhofe/alist:latest\" container_name: alist volumes: - \"/etc/alist:/opt/alist/data\" - \"/home/azureuser/aria2/aria2-downloads:/aria2-downloads\" #这里需要视情况绑定你自己的目录 ports: - \"5244:5244\" environment: - PUID=0 - PGID=0 - UMASK=022 restart: unless-stopped第一次启动 Alist 时，Alist 会随机生成admin用户的密码，所以，第一次启动这套编排时，最好不要带-d参数，而是直接docker compose up，并把容器启动后的输出妥善保存。如果不小心没有保存管理员密码，可以用这个命令重新随机生成一个：\ndocker exec -it alist ./alist admin random成功登录 Alist 之后就可以开始挂载目录了。\n驱动选择本机存储，挂载路径需要注意，按照我的编排，我将容器外的/home/azureuser/aria2/aria2-downloads目录挂载到了容器内的/aria2-downloads，所以挂载路径应该是/aria2-downloads。\n完成 现在所有的服务都已经部署上线了，打开 AriaNG 可以添加下载任务，下载好的文件可以打开 Alist 看到，下载，以及在线观看。\n搭建这套服务之前，请仔细查看 VPS 提供商的服务条款，确保 BT 下载行为不会违规。以及，除了卢森堡等少数国家/地区，下载被 DMCA 保护的资源可能会遭到投诉，这些风险都需要你自行承担。\n反正我这 Azure 的学生机也是白嫖的，被投诉回收了我也无所谓，不管怎样，现在可以心无旁骛的享受找资源的快乐了。\n当然也可以试一试SuperNG6/docker-aria2\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考原作者的docker-compose.yml\u0026#160;\u0026#x21a9;\u0026#xfe0e;\ncaddy stop和caddy start，参考Caddy文档\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-10T15:46:40+08:00","image":"/2024/08/aria2-downloading-server/cover_hu_935547325c8335d7.webp","permalink":"/2024/08/aria2-downloading-server/","title":"搭建一个 BT 离线下载服务器"},{"content":"长沙可真是个好地方，三面环山，好不容易一面有个开口，偏偏就开在了北面对着洞庭湖，冬天冷空气很容易深入，夏天热空气又很难散掉，再配合南方素有的潮湿，体感温度更是雪上加霜，冬天冷得要死，夏天热得要死。\n最近热得实在是受不了，于是决定去山里玩水凉快凉快。\n目的地 这次要去的地方名字叫作芦溪村七仙殿，地处在长沙和岳阳的交界，归岳阳管辖，离长沙城区 80 余公里，开车需要两个小时，前往需要提前留足时间，比如，一个下午。\n在长沙生活了这么久，城区基本上能去的地方都去过了，唯独郊区这些野景点的名字我愣是听都没听过一个。这次知道这一处地方，还得多亏我爸刷抖音的时候被推送了这里。好了，地方有了，挑了一个工作日的下午，吃完午饭，出发！\n驾车从长沙城区出发去七仙殿，一般有两种路线，第一种是走一段武深高速，第二种则是纯粹的走国道和乡间小路。实际上，因为距离不算太远而高速路段也不长，走高速单程只能省下约 20 分钟时间。具体如何取舍就看个人了。目前我在放暑假，时间充裕，走国道和乡间小路足矣。\n在乡间小路上穿梭了快两个小时，毕竟是乡间小路，大部分时候速度表只能在 50 到 60 之间来回摆动，在我看来，这也是乡间小路的优点──相对于平整枯燥的高速，小路蜿蜒曲折，风景独特，在路上一只手握着方向盘，一只手握着刚从冰箱里拿出来的饮料，视野开阔，阳光 毒辣 明媚──冰箱是后期加装的车载冰箱，车上的点烟器电源驱动它轻而易举。啜饮冰爽的饮料，欣赏乡下的风景，驾驶游刃有余，好不惬意。反观高速公路，车流小的时候倒也还好，不过是枯燥了一些，一旦车流一大，就只好聚精会神，毫无闲情逸致可言。\n冷水井 车辆逐渐进入了山区，就在快到目的地的时候，一栋庙宇映入眼帘，墙上匾额「冷水井」，这口井是传说中的神仙泉水，香火旺盛，久仰这口井的大名，没想到会在我们去野外的途中如此偏僻的位置遇到，我们立刻靠近停车，拿出车后早已准备好的水桶，在井前跪拜行礼，开始打水。前来行礼打水的人络绎不绝，井前香火不断，水桶也早已排起了长队，好在打水的速度很快，当天的人也算少，并没有等待太久。\n庙宇内的 LED 屏幕上轮流显示功德榜1和井水「显灵」的事迹，例如某某人在医院查出某某癌症，系不治之症，在饮井水后如何如何好转，最后康复。上面的故事是真是假，是真的井水显灵还是另有原因，这里不做讨论。这是当地的神井，不管真假，我依然入乡随俗，恭恭敬敬的行礼，以示我对当地人和当地神的尊重。\n井边打水是需要付费的，价钱并不高，之前的井水是面向公众开放，并提供工具，任由公众取水，而现在需要付费，即使这样，高峰时期，水桶排出的长队，可以直到庙宇外头。排队的时间，可以延长到五六个小时。\n七仙殿 再向前开一小段，还要越一段野，就到了目的地七仙殿，这里是一处连环瀑布，每个瀑布下都有水潭，水是山泉水，清凉无比。不过需要注意选路，否则光滑的石头很容易就会滑倒掉下去。此处特别提醒，要不是我爸滑倒之后摔到了水潭里，后果不堪设想。\n开了两个小时车，终于到了，马上换上游泳裤，去水里凉快凉快。这个野景点，周末也是人满为患，大家带上吃的，在这里玩水野餐，可以待上一天。然而，他们走之后留下的满地垃圾可真是煞风景。\n好在水虽然看着不是很清澈，但还是实打实的凉快。下水的时候可真是战战兢兢，最后心一横，一阵寒意过后，可算是下到水里去了。然后就是玩水，跳水、游泳、洗头，炎热烟消云散。一个意外之喜是这里竟然有很多小鱼，潜下水仔细看之前，都不知道有些小家伙，见人就跑，既然我非鱼，我也就不去瞎猜鱼这么做意义何在了。\n我的手机支持 IP68 级别的防水，理论上面对水下拍摄是没什么压力的，平常我倒是秉持「防水溅不防手贱」的理念，并不会真的拿这部手机去下水。这次倒是破例让其在水下拍摄了一次 （就是想要换手机了） 。到目前为止，我的手机功能一切正常。\n在这里还遇到了一对夫妇，我们到的时候，他们说他们已经在水里泡了两个多小时，于是我就顺便帮他们拍了一段跳水的视频。\nYour browser doesn't support HTML5 video. Here is a link to the video instead. 这样遇到同路人还挺不错的。\n这里水温算是比较低的，大概 23 度，不宜在凉水里待太久，玩久了也要注意补充热量。\n收工，回家 在水里泡了两个小时，真是一次彻彻底底的消暑，在泡得不想再泡以后就直接收拾东西，打道回府，得益于这次消耗的热量，以及解掉的暑气，回家胃口大开，穷凶极饿，吃掉了不少饭。\n这几年给我的感受是每年的夏天都比往年的更热，从这点上来看，全球变暖诚不欺我。连欧洲人都热得受不了开始装空调了，如此严重的问题，也许不容小觑。\n吹了几天台风的「空调外机」，也希望这几天的台风发挥一点正面价值，赶紧过来帮我们制冷吧。\n捐赠者和他们的捐赠金额。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-07-26T17:14:06+08:00","image":"/2024/07/summer-cooling-off-wild-swimming/cover_hu_b2f1244eb71894a1.webp","permalink":"/2024/07/summer-cooling-off-wild-swimming/","title":"夏日消暑：游水小记"},{"content":"我维护的线上服务里，大部分都在海外，当时考虑到以后应该要在国内用一些资源，就依旧备案了一个国内域名，平时放一个空壳主页在这个域名上，一些服务，我的统计服务、评论后端、博客旧图片的 CDN、以及密码库，都放在这个域名上，以求更快的访问速度。对于博客的一些前端资源，比如评论前端、jQuery（只是个例子，我的博客并没有用到 jQuery），我也尽可能采用了国内的前端资源库，像是字节公共资源库、以及我不久之前还在使用的 staticfile.net。\n看了标题，想必你也知道了，不管是国内的前端资源库，还是博客旧图片的 CDN，我都已经弃用，现在你访问我的博客，所有的前端资源以及博客上的旧图片都不再将从国内加载。\n前端资源 年初 polyfill.io 被国内公司收购的事情一地鸡毛，不久前，polyfill.io 被供应链投毒1，超过 10 万个网站收到影响，安全研究人员发现，植入的恶意程序使用假的 Google 分析域名www.googie-anaiytics.com将移动设备用户重定向到博彩网站。同时受影响的还有 bootcdn 和 staticfile。\n这件事情影响恶劣，但促成我直接弃用 staticfile 的，是这件事情带来的连锁反应，uBlock Origin 因这件事屏蔽了我前不久正在使用的 staticfile.net2，而我自己平时也在用 uBlock Origin，这就直接促成了我将 staticfile.net 替换回了 JsDelivr。\n旧图片 再就是旧图片 CDN，这个 CDN 原本采用了腾讯云 CDN，用以加速中国境内的图片访问，大部分图片经过压缩，加上旧图片访问的人本身就比较少，用了一年有余，期间平安无事，无非每月花一两块钱。直到有一天我打开自己的博客，发现以前的文章很多图片无法正常加载，才意识到出了问题。登录控制台一看，好家伙，一个山西 IP 刷掉了我 20G 流量，好在我设置了超量停止服务，否则不知道现在要给腾讯云上供多少：\n于是我屏蔽了这个 IP 段，开了 CC 防护，又在腾讯云上充值 20 元，重新开启了 CDN 服务。本以为到这里就结束了，泡了杯茶，准备休息。\n结果茶还没凉，腾讯云的短信又来了：\n这次还换了一个 IP 段：\n目前，网上只要一搜索，遇到类似情况的站长很多，V2EX 上也有相关的讨论，大部分网友认为是跑 PCDN 的厂商干的好事34。\n我懒得跟他们玩，直接把对象存储和 CDN 全都搬到了 Cloudflare，牺牲一点国内访问速度就可以了，无所谓，反正看我博客的人大部分都有代理。\n迁移的过程无非就是搬存储桶，套 Cloudflare，因为在 Cloudflare Dashboard 上传有最高 100 个文件的限制，搬存储桶时我用到了 Alist 作为上传工具，其他就没什么好提的。\n后记 就这样，我所有的服务彻底抛弃了国内 CDN。\n看到近期接二连三的新闻，从 Docker Hub 镜像被通知关停，到 polyfill.io 投毒，再到自己亲历的被 PCDN 刷流量，这乌烟瘴气什么时候才能消散呢……\n不管了，反正在这团乌烟瘴气消散之前，我的服务就安心待在海外了。\nPolyfill supply chain attack hits 100K+ sites\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://github.com/uBlockOrigin/uAssets/pull/24285\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://v2ex.com/t/1055510\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n推测可能与运营商省间结算政策施行后，某些地区的高上传家宽（例如 PCDN 等）为了躲避运营商封杀，降低“上传/下载”比例，人为刷下载流量的行为有关。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-07-09T17:54:56+08:00","image":"/2024/07/abandoning-domestic-cdns/dx2_hu_68be1b4c837e4724.webp","permalink":"/2024/07/abandoning-domestic-cdns/","title":"完全放弃国内 CDN"},{"content":"I just had a terrible day, and I decided to write about it. 既然这个想法是以英语冒出来的，索性我也起了一个英文标题。\n无眠 美好的一天往往开始于一夜好梦，糟糕的一天也往往源于一夜难眠。半夜两点半彻夜难眠的我总算睡着了，早上九点醒来，掐指一算，最后就睡了六个半小时。昨晚莫名其妙出现的，快要让我虚脱的苦闷与难过可真是一点都不减。这不，难受的一天开始了。\n喝酒 我打算喝点酒，我真的太痛苦了，莫名其妙的苦闷与难过折磨得我不成人形，我真的得喝点。要带劲的，越烈越好，越烈越能麻痹我自己。还得大口大口喝，最好直接进入我的肠子全数吸收掉，这他妈的才过瘾。啊，正好有威士忌，40度的，还差点意思，勉强吧！杯子，得要大的，来他一大杯，中途喝到一半必须重新斟满，去他妈的清醒，老子今天就跟你爆了！\n酒入愁肠，没有化作什么狗屁相思泪，我的眼泪已经流干了，再没什么好流的。两口喝一杯，喝了好些酒，那感觉可真不错！对外界的感知慢慢变得模糊，身体也不听使唤，虽然难受，但可真过瘾！情绪也变得说不上高兴的高亢，看到什么都多少给你敬一杯，敬你们所有人！哈哈哈哈哈哈哈哈！\n俗话说乐极生悲，这所谓的「乐」前脚刚走，「悲」后脚就到。可真是难受啊我滴乖乖，高亢的情绪终究没能持久，上一秒还在天上飞，下一秒就跟天蓬元帅下凡似摔在地上。随之而来的可是翻江倒海头晕目眩啊。扶着墙迈着喝醉的乱步子，好不容易！终于到了厕所，管你中午吃的什么玉盘珍馐还是草根树皮，这回一视同仁，全都报销喽。\n这还没完呢，头晕可不是你说缓解就缓解的。有什么办法呢，只好躺在床上。刚刚觉得自己秒天秒地秒空气，这下一夜回到解放前，躺在床上呻吟乏力。我这人很奇怪，别人喝酒睡得可劲儿香，我喝酒却和他们喝咖啡没两样。脑袋头晕目眩，胃里翻江倒海，睡也睡不着，可真是遭罪啊。\n帮倒忙的家人 可算是把下午熬了过去，你以为这就结束了？我喝得太多，我妈可就不乐意了，边帮我做蜂蜜水解酒边骂我，给我讲那些不着边际的道理。要是能讲到点上，我是会去听的，可是，你也猜到了，并没有。什么「照顾好自己是爱自己的基本表现」，「不要想太多」，还有一堆不知道从哪个营销号听来的东西，毫无逻辑。听着这些东西可比被酒精折磨更遭罪，我是真的不想听啊，但我妈却还是要讲。最后不出意外的引发矛盾，我妈开始生闷气，只剩下我一个人在客厅难受，不对，更难受。晚饭终究没人做，热点剩菜也吃不下，回头一想，这一天的饭，要么吐了，要么压根就没吃。\n后记 糟糕的一天真的很糟糕，我打算写些什么，也许我该写些什么，抚慰我被酒精和莫名其妙的苦闷难过折磨的脑袋和身体，头晕目眩，胃里翻江倒海，我写下这篇文章以作纪念，也是对自己的一个告诫，下回，下回可得记住了，千万别再喝成这样。\n话说回来，在今天我所承受的痛苦里，肉体上的痛苦似乎远远比不上精神上的痛苦，何其讽刺，I fucked up, but my parents made me feel even worse。这种莫名其妙的苦闷难过也真不好受，铺天盖地而毫无征兆，让我感到虚脱，也许我真的该找一个靠谱点的医生看看。\n题图来自：https://thehardtimes.net/blog/5-signs-your-belligerently-drunk-sobbing-friend-might-need-help/\n","date":"2024-06-01T22:00:05+08:00","image":"/2024/06/the-worst-way-to-spend-a-day/cover_hu_21c7c974b0d2726b.webp","permalink":"/2024/06/the-worst-way-to-spend-a-day/","title":"The worst way to spend a day"},{"content":"写博客时，我时常在拟大标题，小标题，写完以后可能还会补一个副标题。标题有利于读者快速厘清文章内容和结构，还有利于 SEO，固然有它很好的一面。\n这种干什么都先拟写标题的习惯大概是在初中的语文课上老师强加过来的。常写命题作文的我们，不知不觉的就开始先拟写一个标题，然后以此为基点拓展、发散填补文章的内容，让其成为一片「不跑题」的文章。到了高中，还要开始拟写框架、提纲，用以确保自己的八股始终有话可讲，不至于中道崩殂。人们常说应试写作是「戴着镣铐跳舞」。我曾认为，只要离开中学，我就可以「想些什么，就写什么」。随着时间的推移，这句话愈发显得可笑。尽管镣铐早已消失，昔日的笼中鸟却依旧没有自由，长期的自我审查已经让翅膀僵硬，再度起飞变得无比艰难。\n写文章最基本的目的，是表达作者的内心。沈从文一味的要在散文里「写我自己心和梦的历史」，正是这无忧无虑，无拘无束的表达，让作者获得内心真正的自由，「结庐在人境，而无车马喧」，这种真正意义上的写作，才是我想要的吧。\n我以往的写作方法，基本是拟写一个大标题，开头之后再通过各式各样的小标题来展开文章内容。这就带来了一个问题：新拟小标题后，我常常会停下来构思，对着小标题反复斟酌，有时甚至会在怎么起小标题上绞尽脑汁。终于写下了一段话，不满意了，还要修改，有时甚至反复。写作的畅快感在这个过程中早就消失的无影无踪。于是半个小时候我便收笔，一看进度，只新增一段耳。\n我手写我口，我手写我心。这是我架设博客的原本目的，回想起来，这个目的经和我今天所写不谋而合。在这两年里，为了让博客做到「有人看」这一点，我做出了一些取舍，这些取舍固然有积极的一面，而这两年来，我也愈发的意识到，就算有时写一些技术文章，真正的写作，终究是不能妥协的。现在这个博客已经上线两年了。写得越多，学的也就越多。看似一天天平凡的生活，事实上也在对我产生着点点滴滴的改变。写下这篇文章，我衷心地感谢那个两年前的自己开设了这个博客。\n今后我的生活类博客，小标题可能会愈来愈少，大纲也许会难觅踪影。不论如何，本质上，我都会把那些作茧自缚的元素悉数剔除。「少拟小标题，多写真文章」，写出我自己「心和梦的历史」。\n","date":"2024-05-10T00:01:22+08:00","image":"/2024/05/2nd-anniversary/cover_hu_3980137ebd8fec38.webp","permalink":"/2024/05/2nd-anniversary/","title":"少拟小标题，多写真文章"},{"content":"在写下这些文字之前，其实我是有些想笑的，原因很简单，且听我讲一段故事。\n清明假期前的下午，我在寝室里等人，见室友的行李箱有一个海关锁，出于安全考虑1，我就帮他把锁扣上了。室友清明节回到家才发现这一点，于是气急败坏地在群里发问：\n虽然确实不应该动室友的箱子，这点我确实做得不对2，但听闻室友自己竟然不知道自己设的密码，打不开自己的锁，我大晚上忍不住笑出猪叫。我也没有想到，一个原本可以算作无意的善举的行为，最后的结果竟如此哭笑不得。\n既然室友已经打不开锁了，那就想办法帮他打开这个锁吧。\n海关锁的由来可以追溯到 2001 年，9·11 事件发生后，行李安检就被提上日程。但有锁的行李箱怎么办呢？全部撬开就太蠢了吧。于是针对这个问题就有了海关锁（TSA Lock），这是美国交通部推出的一套锁具标准，截至目前一共被 69 个国家和地区承认。\n海关锁的设计初衷是让海关能在没有密码的情况下打开这套锁，所以设计了两种开锁方式，除普通的密码开锁外，海关锁上还有一个钥匙孔，只需要找到这个锁具编号相对应的钥匙，插进去就能打开。海关会撬开一切他们打不开的行李箱，整个过程可能会很粗暴，根据同学分享的经历，他的行李箱因为没有海关锁而被美国海关撬开，即使他设置的密码是「000」并且附上了一张带有密码信息的纸条。\n可是现在我们也没有对应编号的钥匙啊，难道就只能穷举了吗？虽说室友的海关锁只有三位，但从「000」一个一个试到「999」可太难受了。对于室友来说，好消息是，自海关锁诞生以来，行李箱上的锁就发生了功能上的转变，成为了一个防君子不防小人，而近乎形同虚设的锁，不光密码只有三位，其在设计时也设计了不少防止忘记密码3的机制。例如，室友的行李箱有观察窗，只需旋转拨轮，分别找到锁轴上的缺口，再将三个数字向前推五次，锁就可以直接打开。只要掌握一定的方法，就可以毫不费力的打开任何带有海关锁的行李箱，其他的具体方法可以在网上搜一搜相关的教程，以前管制不严时，甚至还可以在淘宝上买到对应编号的钥匙。好诶，不用穷举密码了！\n好吧，当我搜了一个开锁的教程发给室友，室友却早已试出了密码，这件事情也就告一段落了。当然，下次，我再也不会好心帮你锁上行李箱了（笑）。\n主要是无聊\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n后面我当然也承认了。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n这也导致任何人都只是「忘记了」密码。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-04-16T21:20:02+08:00","image":"/2024/04/suitcase-incident/cover_hu_d588f852c66822ee.webp","permalink":"/2024/04/suitcase-incident/","title":"室友的「行李箱事故」"},{"content":"得益于与 Steam Deck 一同而来的 Proton，在常见的 GNU/Linux（以下简称 Linux）发行版上畅玩各类原本在 Windows 上才有的 3A 大作成为完全可行的选择，最近我也进行了这方面的尝试，效果已经较为理想，但随之而来的是一个问题，我总不可能把动辄上百G的游戏全都重新装一遍吧？硬盘没空间了不说，这么麻烦还不如切回 Windows 玩呢。\n出现$代表是终端命令，下面跟着的是命令执行后的输出。\n挂载 Steam 库所在的分区 起初我试图直接在 GUI 上挂载分区，但这样会遇到莫名其妙的问题，有这个想法的朋友请不要跳过这一部分。\n找到目标分区的 UUID $ sudo blkid /dev/nvme1n1p8: UUID=\"421a3d00-81a8-4112-a2df-4d234c674a24\" BLOCK_SIZE=\"4096\" TYPE=\"ext4\" PARTUUID=\"84e56276-a585-412c-9bf5-0071b2b4d4da\" /dev/loop1: TYPE=\"squashfs\" /dev/nvme0n1p1: PARTLABEL=\"Microsoft reserved partition\" PARTUUID=\"bbdb2720-6722-42b3-80f5-385332da77c3\" /dev/nvme0n1p2: LABEL=\"Vault\" BLOCK_SIZE=\"512\" UUID=\"DC64DA2064D9FCE8\" TYPE=\"ntfs\" PARTLABEL=\"Basic data partition\" PARTUUID=\"f884fe24-1c4d-4650-9847-d2f83b9a93ba\" ......如果你能在类似「磁盘管理」的应用里查到目标分区的 UUID，也可以直接使用。\n查询用户 ID 和组 ID $ id -u 1000 $ id -g 1000默认状态下，这两个值都是1000。\n创建挂载点并修改 fstab $ sudo mkdir /media/gamedisk $ sudo nano /etc/fstab这里也可以使用任何你喜欢的编辑器。\n在文件的末尾加上：\nUUID=DC64DA2064D9FCE8 /media/gamedisk lowntfs-3g uid=1000,gid=1000,rw,user,exec,umask=000 0 0如果你之前已经挂载过这个硬盘，请删除之前挂载产生的那一行。\n大小写敏感可能会导致问题，这里使用的是lowntfs-3g，挂载后的 NTFS 卷将不会大小写敏感，以免出现因大小写敏感而找不到游戏文件的问题。1\n防止出现 NTFS Read Error ⚠️注意：有报告称这样操作可能会造成数据丢失，请自行斟酌并承担风险。\n由于 NTFS 的特性，如果创建在 Windows 上无效名称的文件/文件夹将导致 Read Error，进而导致游戏无法启动。最常见的问题是文件名中包含:字符，而 Proton 在 NTFS 磁盘上创建的文件名中就包含了这个字符。\n修复这个问题相当简单：在挂载的 NTFS 磁盘上创建一个/compatdata文件夹，并将其 symlink 到 Linux 分区上的文件夹。\n创建 symlink：\n$ mkdir -p ~/.steam/steam/steamapps/compatdata $ ln -s ~/.steam/steam/steamapps/compatdata /media/gamedisk/Steam/steamapps/如果提示/compatdata已经存在，删除它并重新 symlink 即可。\n最后，添加 Steam 库吧 操作完成后，重启电脑，目标磁盘就会在 Linux 上自动挂载，这时进入 Steam 正常添加游戏库即可\n操作完成后，可以正常游玩 Steam 库里所有的 Windows 游戏，并且可以在任何一边向库内添加游戏。\n本文参考：Using a NTFS disk with Linux and Windows\n来源：Server Fault\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-04-12T18:53:59+08:00","image":"/2024/04/mount-ntfs-drive-as-steam-lib-on-linux/cover_hu_f197ca1e93d3a83b.webp","permalink":"/2024/04/mount-ntfs-drive-as-steam-lib-on-linux/","title":"在 GNU/Linux 和 Windows 间共享 Steam 游戏库"},{"content":"这几天回学校，愉快的打开我的 Macbook，却发现引导失败自动进入了 GRUB 的基本命令行。\n之前用 Ubuntu 的时候也出现过这个情况，当时只需要启动时按住 Option 键选择启动 Ubuntu，下次就能正常启动。于是我就没有把这次启动失败当回事，轻车熟路按下 Option 和电源键，而这次却并没有启动成功，而是又进入了 GRUB 的基本命令行。\n修复引导 首先重启进入 Mac OS，打开终端，diskutil list列出所有的磁盘：\n随后挂载 EFI 分区：\nsudo diskutil mount disk0s1其中disk0s1可能在不同的电脑上有不同，请根据实际情况挂载 EFI 分区对应的IDENTIFIER。\n挂载 EFI 分区后用 Finder 打开它，将BOOT文件夹重命名为BOOT(Backup)以备不时之需。随后建立一个新的BOOT文件夹，复制/Microsoft/Windows/Boot/bootmgfw.efi到刚刚新建的BOOT文件夹，重启后即可解决问题。1\n为什么？ UEFI 在启动时默认会寻找名为bootx64.efi的引导文件。用 BootCamp 安装 Windows 时，Windows 的引导文件被放在/Microsoft/Windows/Boot/bootmgfw.efi，BootCamp 安装 Windows 时配置了正确的启动顺序，但一旦从 Mac 的启动顺序菜单更改启动顺序，就会出现这种莫名其妙的 Bug。至于进 Grub 的原因，也许是我之前安装过 Ubuntu。\n后记 苹果就是这样，你在它自己的生态里基本不出问题，一旦因为各种原因跳出它的生态，各种莫名其妙的小问题就会出现。要彻底解决这类问题，也许我应该去试试rEFInd这种第三方 Bootloader。\n虽然目前苹果已经全面淘汰 x86，但连装个 Windows 都能遇到这种莫名其妙的 Bug，苹果的工程师真的有在用心工作吗……\n方案和头图来源：Reddit\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-03-01T19:19:07+08:00","image":"/2024/03/bootcamp-windows-booting-problem/cover_hu_9d55f848559774c.webp","permalink":"/2024/03/bootcamp-windows-booting-problem/","title":"用 Bootcamp 安装 Windows 遇到的引导问题"},{"content":"缘起 终于有时间出门转转了。\n往年这个时候我们也在路上，当时防疫政策刚刚转向，旅游业的状态基本和封控时期没什么区别。今年各大热门旅游目的地可谓人山人海，非常热闹。见大马对华免签，原定去大马转一圈，奈何家人工作太忙，没有时间，而等到家人有时间，机票就涨到了五千多。这个价格，不如另立计划在国内玩玩，于是初步拟定去厦门、泉州过年。\n在此之前，还得先回一趟我小时候长大的地方，去拜访一些家人，这一部分是我的私事，暂且不提。\n整个旅行没有像去年一样做详细的计划，我们只是拟定在江西的某个城市中转，并草拟了一个大概的日期计划而已。\n出发 永州：不在江西，但必须要回去 从长沙出发，先上京珠高速（G4）随后转泉南（G72），中途经历了一次小堵车，永州近在眼前。\n七三一九 永州是一个慵懒的小城，生活节奏很慢，想办什么事情，提前 15 分钟出发就行。这个当年全市 GDP 只有几百亿，现在也不过两千亿的地级市，就是我长大的地方。\n这是当年在我家楼顶上拍下的照片，一江碧水，云淡风轻，隔着一堵墙的楼下生产区满满当当的停着刚刚生产的汽车，当时猎豹生产三菱帕杰罗的贴牌车，加上本就是军转民，军民两边销路不愁，日子过得十分滋润；湘江对岸是永州的中心城区，那时从始发站坐上 12 路公交车，就能一路去到江对岸上学、购物。当年的长丰猎豹是湖南最好的车企，光是永州这一座工厂的产值就一度占到永州市 GDP 的一半以上，而一连串故事却让这家国企在 2021 年正式提交破产申请，但这也是后话了。\n只可惜，这样的景色已经永远消失了。这次回去看，江边本是用作停车场的地皮已经盖上了三十多层的楼盘，就连这个我原来住的小区都传出消息，将来可能要被拆掉，或者改做什么「人才房」、「福利房」。我离开的这段时间，太多东西都悄无声息的发生了变化。\n滨江公园 滨江公园，冷水滩的中山公园，也是我小时候玩乐的场所。晚上出来散步，顺便留下了一些照片，不过就没有那么刻意了。现在都有些后悔没有白天来多拍一些。毕竟也有十多年没回来看看滨江公园了，公园里的树，当年还是小树苗，如今已经形成了一条林荫「隧道」，而当年年轻的树，现在都长成参天大树。\n沿江还设置了一些 24 小时自助图书室，环境自然是不错，风景也很好。只是里面的书籍可不尽如人意：我从本就只有一个书架的书籍里随手拿起一本，翻开一看，哭笑不得——这成本控制，好像有些过头了。\n零陵古城 画图曾识零陵郡，今日方知画不如。\n——欧阳修\n欧阳修对零陵郡给出了相当高的评价。论旅游，永州的资源其实一点都不差，只是没有开发利用好，加上旁边就是桂林这种重量级选手，各种原因导致今天的永州有些名不见经传。\n零陵古城是永州近几年开发的，目前也没什么外地游客，而没有外地游客就造成别致的小店活不下去，氛围营造不起来，于是外地游客就更不来了，好一个恶性循环。现在的零陵古城更多的是服务本地人的商业聚集地（甚至不能叫做中心），除一些服装租赁外就没什么供游客消费的店铺。不过老街是货真价实的老街，来拍照也是很不错的选择。\n说到这里我不得不吐槽永州的禁飞区——一个零陵机场的净空保护区把永州仅有的城建区全部遮住，只要你还在市区，想飞无人机必须事先申请解禁。即使零陵机场的航班量少得可怜。\n柳子庙值得一看，里面约等于一个小博物馆。\n连文革时期都被革委会保护的文物，怎么也不算是一般文物。当时的永州还是零陵地区，直到 20 世纪 80 年代才转变成永州市。看到文物保护单位和革委会的落款在同一块石碑上，总有种违和的感觉。\n零陵武庙 永州武庙是长江以南规模最大、最有地域特色的武庙。武庙供奉的是关羽，这栋始建于洪武年间，最后修缮于光绪年间的古建筑，是文革后一片断壁残垣中唯一留存下来的珍贵遗产。「其中青石龙凤柱四根，浮雕雌雄蟠龙，龙头硕大，张嘴含珠，势动欲腾，其中两雌龙怀抱小龙，小龙形态活泼天真，精美绝伦」，是现已存在不多的古代雕刻艺术精品。1\n若不是亲眼所见，很难想象当年雕梁画栋的巧夺天工。\n「不发展就是最大的发展」 千山鸟飞绝，万径人踪灭。\n孤舟蓑笠翁，独钓寒江雪。\n——柳宗元《江雪》\n当年柳宗元被贬永州，为永州写下了不少精彩的文字。除了《江雪》，还有《永州八记》中的《小石潭记》，以及《捕蛇者说》都曾作为经典被选入课本。柳宗元对于水、木、鱼、石的描写十分生动细致。正如他在《愚溪诗序》中所说的「清莹秀澈，锵鸣金石」。柳宗元在永州的山水间找到了属于自己的精神寄托，而他写下的这些文字，处理得好，完完全全可以成为「桂林山水甲天下」这样强劲的免费旅游广告。\n每当和别人谈起永州，我最喜欢说的一句话是：「要工业，工业没搞好；要旅游，旅游也没搞好」。现在的永州，非常尴尬，空有一城好山好水，奈何旁边就是桂林这样的世界级旅游目的地。原来全市工业的支柱企业现在已经沦落到破产的境地。到现在，永州还剩些什么拿得出手的东西呢，我真的也想不出来了。\n本地人常有一种言论：永州不发展就是最大的发展——守住一城好山好水，把城市做得精致、干净而富有「闲情逸致」，这便是永州最大的发展。\n南昌：长江中游地区「重要的」中心城市 武汉、长沙、南昌两两之间的距离差不多，三足鼎立构成了长江中游城市群。我常驻长沙，武汉也去过多次，唯南昌一次都没去过。这次也算解锁了长江中游城市群的所有城市。\n网上流行很多「环江西」的说法，像是什么「环江西经济圈」、「环江西 5G 示范带」。现代江西的经济确实落后于周边省份不少。造成这个现象的原因很多，网上有不少视频、文章解释得比较详细2，这里不提。南昌给我的感觉符合「环江西」的印象——感觉像是 10 年前的长沙。\n比湖南更辣 湖南和江西是全国最能吃辣的两个省，但要论谁是老大，江西称第二，湖南绝不敢称第一。是的，江西真的比湖南更辣。\n湖南人实际上就是江西人，元朝时的「江西镇湖广，湖广填四川」3，导致湖南人的祖籍很多都是来自江西（包括我）。而在辣这件两省的共同点上，江西人的微辣是真的辣。以我的主观感觉，江西的微辣的辣量接近湖南的中辣。\n江西省博 博物馆作为一个省古代文化的窗口，来到省会，自然值得一看。\n江西省博给我的总体印象是：很大，很气派，但展出的东西偏少。也难怪，江西既不像湖南有马王堆汉墓带来的辛追夫人等世界级遗产，也不像湖北一代是古代楚国的经济政治文化中心。看过湖南、湖北两省的博物馆，再看江西的博物馆，会有种「历经沧海难为水」的感觉。\n江西省博的展出，除了常规的古代青铜器等先人精美的用品外，还有他们本省特色。江西井冈山作为中央苏区，留下了大量当时苏维埃政权活动的痕迹。同时江西作为历代重要的制陶业中心，也展出了大量古今陶器，都非常有特色。\n滕王阁 Your browser doesn't support HTML5 video. Here is a link to the video instead. 物华天宝，人杰地灵，雄州雾列，俊采星驰。《滕王阁序》将古时江西的辉煌极尽体现，江西古时的繁华，一半都在滕王阁上了。\n不是最「江西」的城市 提到江西最有「江西味」的城市，我第一个想到的会是赣州，而非南昌。南昌的存在感真的太低了，京九铁路原本规划的终点是江西九江，而江西最有代表性的古城则毫无疑问是赣州古城，就连江西本省的发展战略，在不久前也还是着重发展九江和赣州。在「千城一面」的今天，南昌真的「太不江西」。它终究是一个没有存在感的省会。\n宜春：泡温泉 我怎么知道宜春这个地方的？答曰：在高速上看到的广告。这里的温泉名曰「富硒温泉」，有说全世界唯一，有说全世界唯二，总之，就是泡温泉，谁管你是不是什么世界唯一。温泉据说常年保持在70度左右，每天有两万吨温泉水涌出，富含硒，含硫量低，是个绝佳的温泉疗养度假目的地。\n酒店里的洗澡水也是温泉水，有个缺点是容易忽冷忽热。虽然也不知道是不是真的温泉水，掺了多少烧的水也说不准。这么一算，这个带浴缸的酒店不就有半个私汤了吗？浴缸的水不知为何小的可怜，况且房间也带温泉票，还不如直接下去泡正经温泉。山顶的所谓无边泳池当然也是温泉水，却因为水位不够而变成了有边泳池，让人有些无语。这里空气十分清新，所谓「负氧离子」含量高，也不知道这个说法究竟靠不靠谱。\n温汤镇上常年 70 度的古井免费对公众开放，形成了很有意思的文化——这样的水温，最适合拿来……泡脚：镇上的人们，无分老幼，每天提着桶来到古井，打上一桶温度恰好的富硒温泉水，往井边、往附近的长亭，一起坐下来泡脚、聊天。要是水变凉了，那就倒掉再打一桶，一直泡到满意为止。要是说这里有人长脚气，我是绝对不信的。\n这里的酒店春节涨价幅度竟然不大，也有可能是本身已经比较贵了，早知如此就应当在此地多住几天。\n说好的去泉州厦门呢？ 至于为什么没去泉州厦门……\n参考了百度百科\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n可以看看这个视频，https://www.bilibili.com/video/BV1mw411C7RL\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n关于这段历史可以看看维基百科和湖南日报\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-02-18T14:20:47+08:00","image":"/2024/02/2024-new-year-trip-archive/cover_hu_13f375941587768a.webp","permalink":"/2024/02/2024-new-year-trip-archive/","title":"计划外的「不完全江西之旅」"},{"content":"写下「年度总结」这几个字的时候，我的心情大概是「独怆然而涕下」。早就已经完成的差不多的年度总结因支原体感染和考试的压力差点烂尾，能写完这份年终总结，也相当的不容易。\n2023 年是艰难的一年，艰难的扛过年初的感染潮，艰难的返校考上学期没有考完的期末考试，艰难的做课设，艰难的调整自己的心理和精神状况，艰难的看着世界每况愈下……我艰难的过着自己的生活，支撑着我过完这一年的，恐怕真的只有人类生存下去的本能了。\n我不知道诸君这一年过得如何，但，活着就好。\n学业 生活活生生的给我开了一个大玩笑。\n自进入大学以来，我的学业一直不甚顺利，这一年也不例外。\n放了个比暑假还长的寒假的我发现，上学期因防疫政策转向造成的混乱而推迟的，五门大课的期末考试，铺天盖地的压在我们头上。可能是由于某种自我保护机制，我的精神还没有不太正常。我的室友当时已经精神错乱，足见这种爆炸式的考试安排压力有多大。而由于这种保护机制，我也只能在巨大的精神压力下，以很低的效率复习，最后的结果也是相当惨烈。大二下学期我调整状态，休养生息，恢复精力。通俗的讲——不去上课。但这并不意味着我没有在学习，至少考试成绩比上个糟糕的学期要好多了。但这也招来了一些意想不到的事情：嵌入式系统挂科了，简直匪夷所思，询问发现是因为我早八点名没到，卡我平时分。然后我补考考了 80 分，我教的另一个补考的人死记硬背八股文考了 100 分，相当讽刺。\n大三上学期，我在一个暑假以后，深深的觉得自己要「努力」学习。现在看来，这并不是什么好事。我因为这个想法，加上寝室打游戏太吵，几乎天天晚上跑去图书馆。我似乎太过于「努力」，以至于心病旧伤复发，说它痛的刻骨铭心毫不夸张。那几天我在图书馆里痛哭不已，回到寝室却强作笑颜。这样的心病，加上过分的「努力」，耗尽了我的精力，我再也学不动了。现在我终于知道，以我的精神状态，在图书馆里学习，是个错误的决定。\n回过头来看看，我这种做法，像极了大一下学期不懂事的我恢复高中学习做法的那个学期。每天晚上跑到图书馆，真的太痛苦而低效了。兜兜转转又回到起点的感觉可并不怎么好，而这在当时确实也是我能做出的最好的选择，真不应当重蹈覆辙。\n我也算是发现了，我的精神好像不允许我太用力的学习。而超过那个限度，就会触发我的某个保护机制，麻痹神经，不允许我继续用力。目前我并不知道我能否破除这个限制，但这个限制能提醒我休息，也许是件好事。不过，想要全力学习的时候却出现这种限制，何尝不是一种悲哀呢。我好像是全世界最倒霉的大学生——临近期末，遇上支原体肺炎，而逆天的排课却让只缺了两天课的我被迫像之前一样复习。到头来努力了，却什么都没有得到。从入学算起来，我也挂了不少科吧。「成绩怎么努力都提不动」的感觉，我从未有如此深切的感受过。或许，这就是之前我某句愚蠢许愿的报应吧。而当我这些年来承受的这些苦难，归根结底，这终究是我作为低阶层，作为穷人的报应。为什么我要为此买单？若上天有灵，可能告我？\n这学期做的电网规划课设我认为值得单独讲一讲，我们一开始尝试去买一份，但到头来纯粹变成了交学费而已，相当讽刺。我高度怀疑其中一人用 ChatGPT 滥竽充数。于是最后我们用一周的时间做完了别人一个月才能做完的事情，并且为了赶在 Deadline 前交上去，我们一个寝室熬夜到五点半，去做最后的抄写工作。四十几页的课设论文全都手写，感觉那叫一个酸爽。\n健康 和去年相比，这一年我的健康状况变化不大，无非是年初的时候从 COVID 中恢复，年末又赶上一个支原体感染。以及去脑科医院确诊的中度抑郁和强迫症。\n抑郁时常会发作，而我自认为强迫症对我而言没有很大的影响。而在抑郁发作的时候，我除了多喝点酒以及多休息以外真是一点办法都没有。心理健康的危机依旧在持续，这一年心里的旧伤复发在一段时间里耗尽了我所有的精力。\n陷入迷之状态：\n娱乐不动，甚至音乐都不想听\n学习不动，而后面考试一个接一个\n休息不好，觉都睡不好\n也就是想娱乐不行，想学习不行，想休息也不行\n这次的精疲力竭也终于让我意识到了人的精力是多么宝贵。我其实清楚，我的行为终究是在自暴自弃。我需要社会支持，这是我几乎从未有过的。COVID 和支原体也触发了我的焦虑和抑郁，我现在的举步维艰难以言表，却也毫无办法，只能硬抗过去。我出现了干呕，大概是焦虑症状加重吧，至少心理医生建议我药物治疗。\n这一年我不停的尝试去治疗自己，寻求外界支持。说来也怪，生活明明已经如此折磨，人类生存的本能却一直拖着自己生活下去。这似乎是人类的福气，但也成为每个个体的悲哀。\n读过的书 书不会变，人却会。\n读书实际上就是在读自己。2023年，我读到的有新书，也有一些我十分喜欢的老书。每次读这些老书，都宛如读新书一样。\n每读到一本书，我都会把这本书的电子版传到books.l3zc.com。当然也可能有例外，我整理了一下，这一年读过文学作品有：\n《丰乳肥臀》（莫言） 《私刑》（梁晓声） 《湘行散记》（沈从文） 《故都的秋（文集）》（郁达夫） 《如果世上不再有猫》（川村元气） 《失乐园》（渡边淳一） 《夏天、烟火和我的尸体》（乙一） 《东京梦华录》（孟元老） 《十锦缎》（方寸光） 《解忧杂货店》（东野圭吾） 《放学后》（东野圭吾） 《我是猫》（夏目漱石） 《摆渡人》（管他是谁） 除了这些我想得起来的，还有一些网文和轻小说，我不打算将他们放上来。\n可以轻易地发现，这一年我能想得起来的十二本文学绝大部分出自东亚。作为欧美的唯一一本《摆渡人》，读后也觉得这本书写得非常一般，甚至可以说很烂。我在《遣词造句》中提到过，我很羡慕沈从文、郁达夫，甚至《十锦缎》那本武侠色情作者方寸光的国文功力（这作者语文功底是真的好）。而作为翻译作品，只要原作者、译者、出版社之中有一个不行，这本书的阅读体验就会很差。但东亚文化圈内文化相似性很高，翻译过来也读得更自然，更亲切。\n即使如此，论我想要的文字功力，现在还活着的译者里，我还没见过像傅雷那样能将两国语言融会贯通还带自己风格的1。这些翻译作品依然比不过本土文学，这也就是为什么「原生」本土文学依旧占了接近一半。\n我喜欢民国作品，喜欢文白过渡时的精炼，喜欢那种朴素而原始的感情。都说中国只有两个时期出大师，一个是战国，一个是民国，此言不虚。人们竟可以闲适朴素的腔调写文章，至少说明两点：政府没有管制，收入足以过的舒适。以上两点，自 1949 年后，从来未曾同时满足过。可笑的是，现今当局竟还宣传所谓「旧中国」「积贫积弱」，实在无耻至极也。\n读完《故都的秋》和《湘行散记》后写下的话\n（待补充）\n去过的地方 这一年年初进行了一次长途旅行，基本是沿着沪昆高速一路从长沙到丽江，到达沿途很多城市。这次旅行徒步了虎跳峡，在丽江古城待了很久，也算是放松了身心，当然，回程堵车 10 个小时的经历除外。\n8月去了一次武汉，主要是圣地巡礼一些国 Gal。\n十分惭愧，作为一个不怎么有钱的学生，我是没有办法做到高频率长途旅行的。我也想去看看世界啊，但我没钱，我的护照也不好用，我还是只能洗洗睡了。\n听过的音乐 音乐是我生活中重要的组成部分。鉴于我使用的平台没有一家的年度报告是能看的2，我决定自己总结一份年度歌单。\n这一年遇到能让我眼前一亮的歌手主要有 Camelia 和 TAYORI(可以说就是倚水)，前者是高速战神，后者是 J-Pop。星尘3在升级后惊艳到了我，自然也就循环了很多遍，在我的年度歌单上留下了这份记忆。\n有一种观点叫做：音乐是反社交的。我颇以为然。一般朋友聚会时，大家会一起听音乐吗？显然不会。即使遇到少数这种情况，播放的也大多是大家都接受的流行音乐。\n流行音乐能成为流行音乐总是要做出对应的牺牲，相比于所谓的「宝藏」，总会缺少那种独特。\n这个歌单的每首歌的背后都有一些故事，一段经历。他们可能是我失落时校园漫步的耳边陪伴，可能是游戏时增添趣味的背景音乐，可能是通勤时消磨时光的慵懒旋律……在此我竟一时语塞，无法表达。但看到它们，我依然能想起第一次听到它们的惊喜与感动。而没有经历过这段故事的其他人，可能会只会觉得这首歌很平平无奇吧。\n我已不怎么听时下流行的音乐。这一年，我听到的音乐里，能给我惊喜的变少了，对比同样是我手动总结的 2021 和 2022 年度歌单，这一年对歌单的选取显得格外艰难。是因为听到的歌质量真的在下滑？还是因为这一年压力比以往更大，以至于留下了很多不好的回忆？我想两者都有吧。\n玩过的游戏 先来看看我的 Steam 年度报告：\n我大部分的游戏活动都在 Steam 上进行，这份报告我认为十分具有参考性。\n2023年我的大部分时间都花在了和「车」有关的游戏上：地平线 4 和 5，以及欧卡2，陪我度过了两百个小时的游戏时光。都说穷玩车富玩表，那我连个车都玩不起的穷学生岂不是只能玩玩屌了。\n至于为什么有的游戏不在 Steam 上玩，呃，原因复杂。这类游戏里我打得最多的是群星，据我估计至少打了150小时。第二名当属 Minecraft，但这游戏没人一起玩就太无聊了，所以大概实际游戏时间在30小时左右。\n值得一提的是这一年看过的视觉小说/Galgame，我大概读了 20 部。其中有 Nekopara 这种「经典游戏」；还有三色绘恋、恋爱绮谭等国产 Galgame；也不乏一些小众的 Galgame 如《Expression Amrilato》和《夏之锁》。这些有的是 R18 作品，大部分则是单纯的视觉小说。视觉小说就是小说的更高级的表现形式，好的作品在文学性和故事性方面完全实现了对一般小说的超越。\n这一年打完这一圈视觉小说/Gal，我很惊讶国产 Galgame 能做到的程度。\n国 Gal 因「亲切」深得我心，这种题材的亲切、生活环境的亲切，是其他 Gal 无法提供的。正如前面提到，我很高兴看到国 Gal 能够在重重压力下依然保持自己的追求，为我们带来优秀的作品。说来也怪，在如此差的环境下，我们依然在一些方面有所建树。人们总是去歌颂这些建树，默认苦难的合理性，却从来无人过问，是什么造就了如此差的环境。\n前面提到优秀的作品在文学性、故事性上超越一般小说，部分我玩到的作品甚至实现了对社会议题的探讨，甚至可以为少数群体发声。这是中国大陆的创作环境下极为难能可贵的。\n这一年我一整年都没碰原神，现在我回来做做主线，看看逆天策划都干了些什么。\n社交 这一年的社交带给我的感觉非常糟糕。\n本学期我们更换了寝室，一位原本的室友休学，换进来一个吵的不行的室友。这也是我走进图书馆的间接原因——我需要一个安静的地方想想自己的问题。\n我可能需要几个朋友，或者一只猫。\n真的没什么人陪我玩游戏，Minecraft 自然没什么人玩。飙车也没什么人陪我，我就只能自己一个人玩一玩。而 FPS 我本来就不玩。\n偶尔寝室几个人会出去打打羽毛球，这种时候还是比较舒服的。\n其实我倒还挺怀念一个寝室一起打原神的日子，那段时间大伙们都挺快乐的。就像我在7月总结里写的一样：在多年的孤独后，我好想有点渴望线下的社交活动。我多次搬家，没有什么从小玩到大的同学，也没有什么住在附近关系还好到可以随时去家里玩的人。只能看着时间一天一天的过去，看着那些去找同学玩的人开开心心的来往。忽然发现，有朋友真是一件幸福的事情啊。这么说来，没有朋友是一种莫大的悲哀。\n2024年的祝愿 这显然不是一份完美的年终总结，我试着去写，但总有倾诉不尽的思绪等着我去写下。而我写下的文字，也总是与我想要表达的有所出入。起初我以为是自己对中文的 Master 不够，但现在我也想明白了，那是自己的表达欲被常年压抑。而找回这份表达欲终究需要慢慢练习，这就是一场修行，我也希望自己能早日追寻到这场修行的真谛。没有绝对完美的年终总结，我只希望，写下这篇年终总结的自己，能找到属于自己的成长与幸福。\n2023 年不由分说的是艰难的一年。在这种每况愈下的情形里，更不用说去追寻自己了。我时常告诉自己，要直面「惨淡的现实」，但这现实未免太过于惨淡。\n我希望 2024 能更开心，更重要的是，我的付出能收获到回报。这也是我也理应享受到的回报。一年的难过耗尽了我的精力，而我在这里也没什么想说的了，只能希望，今年会更好。\n推荐去看看傅雷翻译的《欧也妮·葛朗台》\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n这是因为我经常因为版权等原因换着软件听音乐，而有的音乐甚至只能在 Youtube 上看 MV。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n虚拟歌姬。https://space.bilibili.com/15817819\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-01-17T17:09:20+08:00","image":"/2024/01/2023-end-of-the-year-summary-public/20240117173426_hu_28cd58b804814e66.webp","permalink":"/2024/01/2023-end-of-the-year-summary-public/","title":"2023 年度总结"},{"content":"到底是什么在支撑着我继续生活？这些天我一直在问自己这个问题。\n从来不指望能在现实生活中收到真心的爱。我没有见过纯粹的父母，我不想接受他们那所谓的爱。即使这种不纯粹的爱，还是扭曲的。我不爱自己，也不敢爱别人，因为我自己就接受过太多扭曲的爱。我很怕这些扭曲的爱压得别人喘不过气来。连父母尚且如此，和我没什么来往的人不必多说。\n我可以肯定这所谓的爱是不纯粹的，每当我出现问题，父母的第一反应并不是给予支持，而是与我冷战，辱骂，现在看来，更像一种推卸责任。我不过是一种投资而已，现实就是如此惨淡。在我抑郁发作时，我妈的第一反应是「我以前还对你有要求，后面我只希望你开开心心，结果现在你连这个都做不到了」。恶心透顶，最后还是在「要求」我。到头来，我还要向给我压迫的投资人保证我不会自杀。\n我的生活并不算富裕，我也不对改善生活报什么希望，再者，改善了以后又怎么样呢。想做的事情很多，但也没钱/时间去做。不存在什么心无旁骛，现实的压力总能让人被迫放弃自我。\n小城市长大，野路子出家，这是一种无奈。「寒门再难出贵子」，越是长大，我越能看清那些我与沿海、其他大城市、更高阶层的人差距有多大。我读高中读得再怎么累结果也不怎么理想，而那所高中教给我的学习能力，那种能让我一生受用的东西，远不如名校、远不如富人只耳濡目染就可以带来的提升。那不是努力程度上的区别，而是维度上的区别。举个例子，小时的我表现出对计算机的浓厚兴趣，并且再三请求、要求家人让我参加计算机相关的培训，家人却漫不经心，即使他们后来想，当时的小城市也找不到任何相关的资源。在我成长的过程中，类似的情况太多了，每一个选择都可以让我走上比现在更好，更开心，更充实，也更容易的道路。我很羡慕那些从小就可以浸润在高质量知识里的富人孩子，那些知识对他们来说唾手可得，甚至如母乳般源源不断的喂到他们嘴里的人（即使他们自己不愿意！）。可惜穷人只读得起普通的书，只能被迫读书，只能走更难的路。（这种层次上的差距不止是物质上的，即使物质在短暂时间内取得优势1，这种层次上的差距，终究是短暂的物质优势无法弥补的）（还远不止这些）\n现在的生活并不开心，更没什么乐子给我找。驱动着我活下去的，大概就只有人类世代保存下来的本能吧。这么看来，我和没有亲人、一贫如洗的人没什么本质上的区别。\n我没有家，将来更不会有。现实已经把我的心撕得粉碎，我的童年没有爱，我的余生也跟着腐烂。别人最美好的年华，在我这里就只剩那些痛苦。我已经心灰意冷，不再寻求自己的「幸福」。尽管谈到这个词，我却总是有一种痛彻心扉的冲动。那是一个我本应享有却从未得到的宝贵财富。而我发现，现在的我，已经没有办法正常接受那些「幸福」了。只好回到自己的灵魂所在的那堆破铜烂铁，喝两罐便宜啤酒暂时麻醉自己。\n还挺希望自己早点死掉，这样起码还有人能埋了我。\n(题图来自：https://wallhere.com/en/wallpaper/171796)\n短暂时间可能是一代人。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-12-13T22:40:45+08:00","image":"/2023/12/what-keeps-me-alive/grave_hu_78fbe99fb8f6ec66.webp","permalink":"/2023/12/what-keeps-me-alive/","title":"我死谁埋？"},{"content":"需要的环境 Docker 和 Docker Compose 任意 Web 服务器 最速教程 为 Firefish 准备一个目录：\nmkdir firefish \u0026\u0026 cd firefish ⚠️注意：近期 Firefish 更新频繁，本文的docker-compose.yml已经过时，请参考官方仓库中的docker-compose.example.yml和Notice for server administrators进行配置。\n用你喜欢的文本编辑器创建docker-compose.yml：\nversion: \"3\" services: web: image: registry.joinfirefish.org/firefish/firefish:stable-amd64 container_name: firefish_web restart: unless-stopped depends_on: - db - redis ### Uncomment one of the following to use a search engine # - meilisearch - sonic ports: - \"6666:3000\" # 6666换成需要的端口 networks: - calcnet # - web environment: NODE_ENV: production volumes: - ./files:/firefish/files - ./.config:/firefish/.config:ro redis: restart: unless-stopped image: redis:7.0-alpine container_name: firefish_redis networks: - calcnet volumes: - ./redis:/data db: restart: unless-stopped image: postgres:12.2-alpine container_name: firefish_db networks: - calcnet env_file: - .config/docker.env volumes: - ./db:/var/lib/postgresql/data ### Only one of the below should be used. ### Meilisearch is better overall, but resource-intensive. Sonic is a very light full text search engine. # meilisearch: # container_name: meilisearch # image: getmeili/meilisearch:v1.1.1 # environment: # - MEILI_ENV=${MEILI_ENV:-development} # ports: # - \"7700:7700\" # networks: # - calcnet # volumes: # - ./meili_data:/meili_data # restart: unless-stopped sonic: restart: unless-stopped image: valeriansaliou/sonic:v1.4.0 logging: driver: none networks: - calcnet volumes: - ./sonic:/var/lib/sonic/store - ./sonic/config.cfg:/etc/sonic.cfg:ro networks: calcnet: # web: # external: # name: web你也可以用 Melisearch，但这是最速指南，只讲 Sonic。\n创建.config目录：\nmkdir .config \u0026\u0026 cd .config创建docker.env：\n# db settings POSTGRES_PASSWORD=example-firefish-pass POSTGRES_USER=example-firefish-user POSTGRES_DB=firefish创建default.yml：\n#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # Firefish configuration #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # After starting your server, please don't change the URL! Doing so will break federation. # ┌─────┐ #───┘ URL └───────────────────────────────────────────────────── # Final accessible URL seen by a user. url: https://你的域名/ port: 3000 db: host: db port: 5432 #ssl: false # Database name db: firefish # Auth user: example-firefish-user pass: example-firefish-pass # ┌─────────────────────┐ #───┘ Redis configuration └───────────────────────────────────── redis: host: redis port: 6379 # ┌─────────────────────┐ #───┘ Sonic configuration └───────────────────────────────────── sonic: host: sonic port: 1491 auth: SecretPassword collection: notes bucket: default # Reserved usernames that only the administrator can register with reservedUsernames: [\"root\", \"admin\", \"administrator\", \"me\", \"system\"] signToActivityPubGet: true回到上一层目录，创建./sonic/config.cfg：\n# Sonic # Fast, lightweight and schema-less search backend # Configuration file # Example: https://github.com/valeriansaliou/sonic/blob/master/config.cfg [server] log_level = \"debug\" [channel] inet = \"0.0.0.0:1491\" tcp_timeout = 300 auth_password = \"SecretPassword\" [channel.search] query_limit_default = 10 query_limit_maximum = 100 query_alternates_try = 4 suggest_limit_default = 5 suggest_limit_maximum = 20 list_limit_default = 100 list_limit_maximum = 500 [store] [store.kv] path = \"./data/store/kv/\" retain_word_objects = 1000 [store.kv.pool] inactive_after = 1800 [store.kv.database] flush_after = 900 compress = true parallelism = 2 max_files = 100 max_compactions = 1 max_flushes = 1 write_buffer = 16384 write_ahead_log = true [store.fst] path = \"./data/store/fst/\" [store.fst.pool] inactive_after = 300 [store.fst.graph] consolidate_after = 180 max_size = 2048 max_words = 250000全部创建好以后的目录结构应该看起来像这样：\n. ├── .config │ ├── default.yml │ └── docker.env ├── docker-compose.yml └── sonic └── config.cfg最后执行docker compose up，绑定域名、反代端口，实例就搭建完成了。\nFirefish 已经自动 Minify 了所有的前端文件，如果你使用 Cloudflare 或其他类似的服务，记得关掉 Auto Minify，否则会出现一些奇怪的问题。1\n以上就是最速教程。\n一些问题 Q：docker.env和./sonic/config.cfg密码和用户名不改没问题吗？\nA：没很大问题，因为两个服务没有暴露到公网上，仅做个人使用不改也没什么大事。\nQ：为什么 network 要叫calcnet？\nA：因为这个项目本来叫做 Calckey。\nhttps://github.com/misskey-dev/misskey/issues/10328\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-12-04T17:17:56+08:00","image":"https://blog-img.l3zc.com/firefishlogo.webp","permalink":"/2023/12/firefish-deploy/","title":"最速 Firefish 部署指南"},{"content":"现在已经换成了 Arch，btw。\n现役一台 MacBook (Retina, 12-inch, Early 2016)，官方最高支持到 Monterey，当时收来的时候我认为，我会 Stick with MacOS。\n这么说是因为 MacOS 在我卖掉的老 MBP 上给我的印象是稳定好用，当时的想法是出掉 MBP 买入一台廉价而性能够用的 Windows 游戏本和一台天天带出去的轻薄本——事实上我也不后悔这个决定。\n好吧我承认我高估了这颗两核 m5 的性能，目前的状况是：如果使用 MacOS，必须要开启「减弱动画效果」，否则会卡得生活不能自理。这就是 MacOS 的另一个特点：「易卡难崩」。\n于是我给我的 MacBook 装上了 Linux，就有了现在这篇文章，written on Ubuntu。\nWhy Ubuntu? 我其实并不是很喜欢 Ubuntu，选用 Ubuntu 更多是一个无奈的权衡。\n本次安装 Linux 的目的是获得更好的性能和更流畅的体验，让我的日常工作更加轻松。这台电脑是我的日常装备之一，我不太希望选择一个不够稳定的分支。之前滚坏过一次系统的经历让我直接把 Arch 排除在外。我有太多事情要做，时不时滚坏的系统？ Don\u0026rsquo;t have time for that. I just want a system that works out of the box 。\n本来想装 Pop!OS——System76 基于 Ubuntu 打造的系统，但安装器不知为何老是闪退，遂放弃。\n用distrochooser.de选出了 OpenSUSE，并且在虚拟机上装好 OpenSUSE + Xfce 试用。我非常喜欢这套环境，但 Xfce 似乎不支持 HiDPI，也不优先考虑。YaST 真的很好用，将来我会在别的电脑上用这套系统，但这台电脑，no。\n在这台 MacBook 上，Ubuntu 的驱动问题算是最少的。除了上面提到的两个分支，我也尝试了一些别的 Debian 系 Distro 比如 Linux Mint、Deuvan，甚至国产 Deepin，没有一个拥有良好的硬件兼容性。\n在作出这些尝试以后我认为已经没有必要再挑三拣四，先用 Ubuntu 权衡才是最优解。\nSoftware：How Ubuntu fits into my workflow 我在安装时就选择安装了 ThunderBird、Libre Office 等软件。在进系统后也很快就用 apt 安装好了所有我需要的 CLI 工具以及大部分应用。\n我在 MacOS 下的包管理器是 Homebrew，换到 Ubuntu 就改用了自带的 apt，也接受了 snap，即使这会影响到我安装 GTK 主题后的一致性。1与 Homebrew 相比，apt 提供更多的软件包2，且 Homebrew 终究是作为一个第三方包管理器存在。\n为了安装一些别的应用，我也安装了 flatpak 作为额外的包管理器。虽然比较难用，但也确实扩充了软件的选择范围。\nBrowsing Chrome 依旧是我的主力浏览器，我难以放弃它的同步功能，Which means I have no choice.\n所有网页都可以正常工作，就像在 Windows 和 MacOS 上那样，as expected.\nOffice files 学生要看的 Word、PPT、PDF 等，这些在 Libre Office 上显示效果超出我的预期——基本都能正确显示。字体什么的都是小问题，.doc、.ppt文档的布局都正常，渲染也没有错误。\n我从不在这台电脑上做编辑 Office 的工作，即使在 MacOS 下也是如此。有这些工作我都交给了我的 Windows PC。\n即便如此，在 MacOS 上我却依旧全量安装了 Office 365。Office 365 在后台更新频繁，我打开 Office 时，经常弹出「正在验证xxx」的提示，每次都要等很久，非常烦人。相比之下，Libre Office 只在我apt upgrade时才会更新，用起来不知道比 MacOS 舒服多少。我已经在考虑将这台 MacBook 上的 Office 365 换成 LibreOffice。\nBlogging 我以 VSCode 作为代码兼文本编辑器，用 Typora 来写 Markdown 文章，用 PicGo 作为图床上传工具，用 Git 把写好的内容和配置推到 Github 上并发布。我还在本地安装了 Hugo 用以预览我的修改，这些工具配置好以后使用起来和在别的平台上无异。\nMusic 我主要使用 Spotify 和网易云音乐来串流音乐。其中 Spotify 有 Native 版本，网易云的 Linux 客户端早已停止维护，可能网页版才是更好的选择。\nYoutube 其实也是个听音乐的好地方。\nSocial QQ 的全功能 Electron 重构版本 QQNT 原生支持所有主流的分支，还有 Telegram。至于微信，我暂时没有什么硬性需求，用手机就可以了，有文件要传到电脑上可以用 QQ 中转。\n主流的 Twitter Like 社交平台和 Fediverse 实例都有网页版，部分还有 PWA3 可用，这些用 Chrome 就可以解决。\nThunderBird 是非常好的邮件客户端，我在 Windows 上已经在使用，换到 Ubuntu 的预装更无需重新适应。\nPassword Management \u0026amp; RSS 我的密码管理器是 BitWarden，一样原生支持所有的主流分支。\nRSS 阅读器有老朋友 Fluent Reader 和 Thunder Bird，Fluent Reader 把 Fluent Design 直接原封不动搬了过来，一样支持 Fever API 让我和 FreshRSS 同步。\nNewsFlash 也是很好的阅读器，原生支持 FreshRSS，稍微有点麻烦的就是必须用 flatpak 安装，同时滚动时我能感觉到明显的卡顿和发热。不知道是软件自身的优化问题还是 flatpak 的问题。\nProxy 网络代理我采用 Clash Verge 和 proxychains 的组合，解决了终端和系统代理的问题。除了在打开管理面板的时候 Tauri 很占资源以外，本身依然是稳定好用。至于 Proxychains 是用来解决部分工具即使设置了环境变量也不遵循的问题而安装的。我只需要配置好然后proxychains任何一个命令就可以让这个命令走代理。\nTerminal 终端应用直接采用默认的就好，我并不是 Bash 死忠粉，所以后来我也换到了 Zsh，和 MacOS 上一样安装了 Oh My Zsh。最近看到了 Terminology，准备一试。\nAirdrop alternative 传文件的需求我用到了 QQ 和 Snapdrop。\nMy experience with Ubuntu 在浏览器越来越强大，网页版应用和 Electron App 越来越多的今天，Ubuntu 的软件生态虽然无法和 MacOS 和 Windows 相比，但也足以让我有底气 to make the switch。\nIt\u0026rsquo;s impressive Ubuntu 的性能相比于我在 MacOS 简直就是一个天上一个地下。在安装时我直接分了 4G Swap，所有的应用都启动的非常快，与 MacOS 上弹个半天形成的对比非常强烈，甚至让我怀疑我到底是不是在用同一台电脑。对于这个性能表现我非常满意。\n即使是 CLI 应用，Ubuntu 上跑起来也比 MacOS 上要更快，更利落。以我最常用的 Hugo 来说，hugo server甚至比我的 Windows 电脑要更快，以至于我甚至愿意用它接上电脑来继续写文章。\n续航是我最满意的部分：得益于更加干净的系统和无风扇的设计，目前这台 MacBook 一次充电可以连续使用一个下午加一个晚上，相当于超过 8 小时的亮屏时间。但需要注意 Tauri 应用的效率问题，体现在实际使用上就是尽可能少用 Clash Verge 的控制面板。只要使用得当，就可以获得超过 MacOS 的续航体验。\n高分辨率支持还不错，只要整数倍缩放就不会出现应用模糊的问题，但 200% 的缩放未免太大了一点，也许我该直接调调 DPI？\nIt\u0026rsquo;s not perfect 蓝牙和扬声器无法被驱动，我尝试过打内核补丁，但毫无用处，这意味着外放根本不能用，蓝牙耳机、键盘、鼠标也想都别想。键盘背光几乎没法用，想要黑灯瞎火的打字几乎也是不可能的。前置 Facetime 摄像头也无缘被驱动，虽然我在 MacOS 上也几乎不用它。\n触控板的防误触约等于没有，写东西时非常容易被触控板干扰，目前我的解决方案是在写东西时用TouchPad Indicator4的快捷键直接禁用触控板。但这样的体验自然就不如打磨过防误触的 MacOS。\n双指滚动的速度太快，导致我看网页时不得不使用方向键滚动网页。为了调整滚动速度，我试着从 Wayland 换到 Xorg，并用 Xinput 调整设置，但暂时还没有看到成效。\n各种驱动上的问题以及体验上的小问题非常影响体验。我知道，这些问题中的某一些可能只需要花些时间和精力去做些 tweaks 就可以解决。但要在折腾和生产之间取得一个平衡的话，我想我大概会保持现状。\nWrap up 我第一次安装 Linux 时用的是 Ubuntu 16.04 LTS，当时的我苦于 Linux 软件生态的匮乏而试着去折腾 Wine，许久终于用上了一些必要的 Windows 软件，最后却因心累而换回了 Windows。今天，我同样在安装 Ubuntu，除了驱动问题外，我几乎从没有遇到任何麻烦，并且几乎全程乐在其中。这次日常使用 Linux 的尝试无疑是成功的。\n我可以说 Linux 见证我成长。现在的我已经可以拥抱开源生态系统，很显然，这次，我不再需要换回去了。\nCanonical 维护着一份主流 GTK 主题的 Snap 移植，但每次安装新的 Snap 应用都要手动切换，非常不方便。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n相比之下，Homebrew 更像是一个命令行形式的 Appstore。当然我最喜欢的包管理器还得是 pacman。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nProgressive Web APP，渐进式 Web 应用。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n本质上就是调 Xinput。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-11-07T17:38:50+08:00","image":"/2023/11/installing-ubuntu-on-macbook/IMG_7558_hu_8b6cb548722da663.webp","permalink":"/2023/11/installing-ubuntu-on-macbook/","title":"受够了 MacOS，我给 Macbook 装上了 Linux"},{"content":"看到一篇博文，讲到顶级域的问题，感觉很有意思。\n顶级域由其母公司及其所在的国家控制，在民主国家，受法律管辖；如果是威权国家，则受政府随意控制。没人会想把 Freedom House 开在 .ae（沙特阿拉伯）上。\n那么所有民主国家的顶级域都是最好的顶级域吗？\nEEF1发布过一篇报告，报告指出：.com，.net这些域名都受 ICANN 控制，所有 ICANN 控制的域名实际上都受美国控制。既然如此，对比它们就显得没有必要。至于那些各种组织、公司控制的顶级域就更无必要对比，因为这些域名不需要经过任何程序就可以随意回收，具体可以去搜索 Freenom 那些无耻的案例。于是，问题就被简化成了：哪个国家有最好的隐私保护和言论自由法律？\n世界上有四个 ccTLD2 是完全由当地法院控制的：\n.at 奥地利 .de 德国 .ru 俄罗斯 .is 冰岛 还有一个 TLD 谁都拿他没办法：.onion。\n这意味着要关闭这些域名的唯一方法是法院命令，不受司法系统以外所有干扰。这四个国家里，前两个是欧盟国家，至于俄罗斯的司法系统，还是权当他不可信好了。\n欧盟的政策有些过于激进，这就导致欧盟国家的域名都不是特别理想的选择。鉴于最近欧盟险些被通过的，禁止端到端加密通信的议案，欧盟也变得不可信起来。\n所以我们就只剩下了两种选择：.is 和 .onion。但要让绝大多数用户都能看到你的站点，就只剩下冰岛的 .is 可用。\n这么看来，冰岛的 .is 就是世界上最好的顶级域。但如果想要最强的匿名性和完全控制，还是选择 .onion 吧。\n选域名甚至可以变成一个地缘政治问题，虽然大多时候选择什么顶级域都无关紧要，但知道自己域名的「生杀大权」掌握在谁的手里依旧是必要的。目前世界上除了.onion外没有任何一个去中心化且不受任何监管的域名。但这也不完全是坏事，冰岛的 .is 域名就是一个范例，只要法律为公众利益服务，司法公开公正，也可以确保我们的域名得到最大化的保护。\nElectronic Frontier Foundation，电子前线基金会。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nCountry Code TLD\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-10-21T17:15:52+08:00","image":"/2023/10/best-tld/20231021143702_hu_1209cc434fda6c9d.webp","permalink":"/2023/10/best-tld/","title":"最好的顶级域"},{"content":"我最近换到了hugo-theme-stack，However，主题作者似乎并未考虑到中国大陆一些特殊的情况1。我对其进行了一些调整，以适应我的需求。\n部署hugo-theme-stack Github Pages 实在太慢，且鉴于 Vercel 已经被「特殊照顾」过，为了稳定，我还是选择了其他的托管服务。\n我采用 Github Actions 部署到 Azure Static Web App（Azure SWA），这个服务在中国大陆大部分会使用香港节点，访问速度还不错。我只需要按照提示点几下，这套服务就会自动帮我在仓库里生成 Actions 所需的 yaml 文件。随后删除作者原有的deploy.yml就大功告成了——只需写完文章然后 Push 到仓库，Oryx2 就会自动构建我的博客并发布。\n不得不吐槽免费版的 SWA 边缘计算要求必须使用 Oryx，而 Oryx 的生成速度又比原生的 Actions 慢多了3，实在是有些浪费性能。\n还有 Azure 一言难尽的面板，请坐和放宽……\n优化hugo-theme-stack 换用国内前端资源 CDN hugo-theme-stack前端资源大量采用了 JSDelivr，然而：\n可以看到，有些地方默认的 JSDelivr 前端资源甚至完全不可用。因此，更换这些前端资源成了当务之急。\n由于我们使用的是模组形式加载hugo-theme-stack，根本就没有themes文件夹。Hugo 允许主题文件的覆盖4，只需要将需要覆盖的文件放在 working directory 即可。例如：我想修改原本在./themes/layouts/partials/head/下的custom.html，只需创建./layouts/partials/head/custom.html然后编辑，这个文件可以从原主题仓库复制。\nhugo-theme-stack将通过外部加载的前端资源放在了./themes/data/external.yaml，我们在博客目录下创建./data/external.yaml：\nVibrant: - src: type: script PhotoSwipe: - src: https://lib.baomitu.com/photoswipe/4.1.3/photoswipe.min.js type: script defer: true - src: https://lib.baomitu.com/photoswipe/4.1.3/photoswipe-ui-default.min.js type: script defer: true - src: https://lib.baomitu.com/photoswipe/4.1.3/default-skin/default-skin.min.css type: style - src: https://lib.baomitu.com/photoswipe/4.1.3/photoswipe.min.css type: style KaTeX: - src: https://lib.baomitu.com/KaTeX/0.15.6/katex.min.css type: style - src: https://lib.baomitu.com/KaTeX/0.15.6/katex.min.js type: script defer: true - src: https://lib.baomitu.com/KaTeX/0.15.6/contrib/auto-render.min.js type: script defer: true Cactus: - src: https://latest.cactus.chat/cactus.js integrity: type: script - src: https://latest.cactus.chat/style.css integrity: type: style由于 Vibrant.js 不在lib.baomitu.com上，所以需要自行解决托管问题。\n原项目里这些前端资源还有个integrity键值用来校验资源完整性，经测试似乎只有 JSDelivr 支持这个特性，这里引用的 360 前端资源库保留这个键值会报错，于是一删了之。实际上有了 https 加持，除非遇到国家级网络攻击这种极端的情况，我们也基本上用不到这个特性。\n我还修改了./layouts/partials/helper/external.html，直接去掉了所有的 Integrity：\n{{- $List := index .Context.Site.Data.external .Namespace -}} {{- with $List -}} {{- range . -}} {{- if eq .type \"script\" -}} {{- else if eq .type \"style\" -}} {{- else -}} {{- errorf \"Error: unknown external resource type: %s\" .type -}} {{- end -}} {{- end -}} {{- else -}} {{- errorf \"Error: external resource '%s' is not found\" .Namespace -}} {{- end -}}评论系统也引用了 JSDelivr，因此也要更换。我采用的评论系统是 Twikoo，创建./layouts/partials/comments/provider/twikoo.html，修改文件第一行：\n原主题的 Twikoo 版本是1.16.115，这里也顺便升级成匹配我部署的后端版本1.16.21。\n其他的评论系统也以此类推。\n添加图片灯箱 原主题有一个「Image gallery」功能，但只支持本地图片，这对于所有图片都存在图床上的我来说显然不是什么好消息。于是我只好自己添加一个图片灯箱。\n我原本准备采用 fancybox，毕竟我最熟悉这个，但 fancybox 需要引入 jQuery，这和我想让博客尽可能轻量化的初衷背道而驰。于是我找到了zoom-vanilla.js，虽然它也不完美，但论轻量是绝对够格的。\n首先需要在前端引入zoom-vanilla.min.js和zoom.css这两个资源，我直接丢进./static/引用，见仁见智。\n将这两个资源放入./static/imgzoom/后，分别在\u0026lt;head\u0026gt;内和\u0026lt;body\u0026gt;前6引入 css 和 js：\n修改./layouts/partials/head/custom.html：\n修改./layouts/partials/footer/custom.html：\n引入前端资源后需要为所有图像加上一个data-action=\u0026quot;zoom\u0026quot;。\n修改./layouts/_default/_markup/render-image.html：\n同前面一样，我也列出了这个文件的一部分，真正修改的部分只有一个else分支和data-action=\u0026quot;zoom\u0026quot;。\n至此，图片灯箱添加完成。\n变更 RSS 行为 这个其实有点超纲了，不过这个主题确实自定义了 RSS 模板。\nRSS 遇到了两个问题，一个是输出了我全部 50+ 篇文章，文件变得特别大，这显然是不合理的；还有就是输出了search、about等与 RSS 毫不相干的页面。\n在配置文件config.toml末端加上：\n[services] [services.rss] limit = 10可以把 RSS 输出的文章数量限制在 10 篇。接下来处理不相关页面的问题，其实限制输出 10 篇文章已经解决了第二个问题的大部分。此时更新后的 Feed 依然会在第一个输出about，而且输出日期会随着构建时间变化，暂不清楚是什么原理导致的。\n我的解决方案是引入一个新的 Front matter 键值nonRSS: true，编辑./layouts/_default/rss.xml的前部分：\n{{- $pctx := . -}} {{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}} {{- $pages := slice -}} {{- if or $.IsHome $.IsSection -}} {{- $pages = $pctx.RegularPages -}} {{- else -}} {{- $pages = $pctx.Pages -}} {{- end -}} {{- $pages := where $pages \"Params.hidden\" \"!=\" true -}} {{- $pages := where $pages \"Params.nonRSS\" \"!=\" true -}}\t//加入这一行 {{- $limit := .Site.Config.Services.RSS.Limit -}} {{- if ge $limit 1 -}} {{- $pages = $pages | first $limit -}} {{- end -}}重新构建就修好了 RSS Feed。\n建议搜索引擎不索引「标签」页面 不知道为什么，搜索引擎总是喜欢把我的标签页面编入索引7，我决定给每个 Tag 页面加上一个noindex标记。并且用robots.txt排除这些页面。编辑baseof.html，在\u0026lt;head\u0026gt;部分加入如下内容：\n{{ if .Data.Singular }} {{ end }}这样应该会给每个 Tag 页面加入一个noindex标记。\n在./static/下创建robots.txt：\nUser-Agent: * Disallow: /tags/这样就可以把所有 Tag 页面排除索引。\n作者 JimmyCai 似乎住在西班牙\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nAzure 的边缘计算，https://github.com/microsoft/Oryx。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n通过 Actions 调用 Oryx。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n详见Hugo官网：Anytime Hugo looks for a matching template, it will first check the working directory before looking in the theme directory. If you would like to modify a template, simply create that template in your local layouts directory.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n现在已经升级成1.16.21，PR#877\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n至少作者是这么说的，我放在\u0026lt;footer\u0026gt;也照样用。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n可能是因为站点地图\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-10-20T16:53:49+08:00","image":"/2023/10/theme-stack-tweaks/hugo-theme-stack_hu_3b3c2d39a29d982.webp","permalink":"/2023/10/theme-stack-tweaks/","title":"Hugo Theme Stack 针对中国大陆部署优化不完全指南"},{"content":"如你所见，我迁移到了 Hugo。\n这里曾经跑着 Wordpress，那是在去年 7 月部署好上线的，到迁移的时候用了也有一年有余。\n为什么放弃使用 Wordpress？ 迁移并不是因为 Wordpress 不够优秀，相反，Wordpress 是一套非常好的 CMS：它历史悠久1、运行稳定、大而全、傻瓜式安装，这些都是我当时选择它的重要理由。2\n但既然这么写小标题，想必大家都能猜到 Wordpress 也有很多驱动我迁移的缺点。\n过于笨重： Wordpress 真的太重了，一大堆我不需要的功能在那里摆着。对于个人网站来说， Wordpress 显然是太多余。笨重还带来了严重的性能问题，这点也是我当时把它从香港 Azure 迁移到美国的原因——就是因为美国的服务器更便宜。不成想， Wordpress 跑在上面却依然消耗了超过预期的资源。与其消耗大量资源跑一个博客程序，还不如用这些资源跑些别的。\n易受攻击： 动态网站的攻击面很大，尤其是这种用户基数大的程序，攻击的收益很高。举个例子，在我使用 Wordpress 的这一年里，几乎每天都有机器人爆破我的/xmlrpc.php。这还不算什么，即使套上 Cloudflare，相同服务器配置下，Wordpress 能承受的访问量3也不会很高。\nMarkdown 水土不服： 相对于原生支持 Markdown 的博客框架，Wordpress 对 Markdown 的支持可谓是非常差的，每次我以 Markdown 写好的文章在 Wordpress 上发布总要经过一些修改。不要跟我说 Wordpress 是二十多年的老软件，就可以不兼容 Markdown，只要想做，就绝对不会是现在这个样子。\n主题不合我胃口： 现有的开源 Wordpress 主题，我用过的有 MDx、Hourglass Twins 和 Argon。这几个主题几乎都没有再更新或者「处于缓慢维护状态」。既然都不再维护，样式也或多或少的过时。\n加载速度太慢： Cloudflare 在大陆的直连速度懂的都懂。虽然我自建前端资源 CDN 缓解了一部分问题，但基调依然是加载慢。\n为什么选 Hugo？ 最开始，我还没有服务器，我的博客是基于 Hexo 构建的4，之所以放弃使用 Hexo，是因为我当时想要评论功能，以及跨设备编辑文章的能力5。\nHugo 没有恶心人的node_modules，生成速度比 Hexo 快得多，主题也合我胃口，而且我也学过一点 Go，所以就决定是它了。Hugo 主题不需要学 Node.js 就可以魔改，简直不要太舒服。\n迁移 之前 Hexo 里写好的 Markdown 文件基本可以直接扔到./content/post/里直接用，不过 Hugo 对文章头部的 yaml 要求更规范。例如：即使只有一个categories，也必须使用列表。\n永久链接这个时候肯定是对不上的，改一下permalinks.toml就可以了：\n# Permalinks format of each content section post = \"/:year/:month/:filename\" page = \"/:slug/\"还有一些文章我打草稿的时间是 n 月，发布的时候变成了 n+1 月，永久链接就变得不一样，这些文章也要一一处理。\n友链没办法，只能一个一个手动搬过来，好在本来只有十几条友链，这并不是什么难事。\n评论就不一样了，目前没有找到什么导出方法，只能全部丢掉，或者日后慢慢搬过来。\n部署的地方？ 本来想 rclone 部署在自己的服务器上，后来发现 rclone 太慢，也不能跨设备编辑文章，遂放弃。\nGithub Pages？免了吧，太慢了6。Vercel？主 CNAME 已经被屏蔽了，感觉随时要凉6。于是乎我就找到了 Azure Static Web App，速度还行，还免费，就它了。\n然后就遇到了 CNAME 和 Apex 域冲突的问题，这个真没办法。CF 的 CNAME 拉平国内容易拉平到美国节点，只好新开了一个子域blog.l3zc.com并重定向了上去，算是解决了这个问题。\n待办清单 SEO 评论迁移 图片灯箱 修好 RSS feed 近况 （回忆起近况，实在有些痛苦，我暂时不太想写这一部分。现在我试着开始写，看看能不能写出来）\n现在没那么痛苦，却早已忘记，或许这就是一种自我保护吧。\n说得难听点就是老古董。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n当时的我也没有想到，这些理由中的一部分竟也会成为我迁移的重要推动力。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nDDoS 的访问量也算访问量。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n现在我还留着这个博客，https://hexo.l3zc.com。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n当时我还不会用 Github Actions。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n指中国大陆。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-10-03T19:30:05+08:00","image":"https://blog-img.l3zc.com/202310152020849.webp","permalink":"/2023/10/migrate-to-hugo/","title":"迁移到 Hugo"},{"content":"2016年11月7日通过的《中华人民共和国网络安全法》第二十四条规定，「网络运营者为用户办理网络接入、域名注册服务，办理固定电话、移动电话等入网手续，或者为用户提供信息发布、即时通讯等服务，在与用户签订协议或者确认提供服务时，应当要求用户提供真实身份信息。用户不提供真实身份信息的，网络运营者不得为其提供相关服务。」\n到了教育部这里落实，就变成了校园网一人一号。再到运营商这里，就变成了一人一终端，还不准使用路由器。这显然已经和合规没有任何关系，学生的需求也摆在这里，但限制却还是这个鸟样。好一点的大学，比如上海交大这种坐拥华东教育骨干网的学校可以做到校园网免费，为什么我们甚至不能放开连接设备数量上的限制呢？\n2015年以来……目前，我校IPV4/IPV6总出口带宽达到47GB，其中电信25GB、联通10GB、移动10GB、教育网2GB，校园网总注册用户数超过4.34万、活跃用户数超过2.43万。办公账户（免费）带宽由2MB升到36MB。宿舍区基本账户（付费）带宽由2MB升到12MB，网费不变。……\n这套数据应该不是最新的，2022年寒假校园网又进行了一次大扩容，具体扩容了多少不得而知。如果按照这套数据计算，总出口 47GB，活跃用户数2.43万，则人均带宽是$ \\dfrac{47GB _ 1000 _ 8}{24300} \\approx 15Mbps $。这点可怜的带宽，还要给学校的官网防 DDoS，加上网安等种种因素，就变成了一人一终端这种限制。\n现在的大学生还有几人是有且只有一台上网设备的？室友间的一些操作也需要一套局域网环境（文件共享、联机游戏……）指望推动学校在短时间做出这套改变不太现实。但需求总要解决，只能先自己想想办法，从技术上解决这个矛盾了。\nUpdate 2023/10/7：可能是部署了新设备，经测试，在敏行轩，本文措施失效——即使部署所有措施，依旧会频繁被检测。虽然我的脚本可以自动让路由器重新上线，但上网体验会变得很差，游戏更是几乎不可能。那么，敏行轩大概率是部署了新的检测方法，基本只剩加密所有流量这一条路可走。\nUpdate 2023/10/16：现在在敏行轩（其他区块只会更宽松），最有效也最简单的办法就是用 Clash 代理所有流量（即使全局直连也可以），具体方法文章后段有详细说明。\n硬件 需要一台可以刷入 OpenWRT 的路由器，我采用的是一台 Nano Pi R2S，最好选择这种用户基数大固件多的产品，也最好能自己编译固件。\n关于如何为路由器刷入 OpenWRT 请自行在网上搜索对应的路由器型号+教程。不建议购买所谓的「校园网路由器」，这种路由器通常价格比同性能路由器贵非常多，而且卖的人还不一定懂技术。\n接入路由器 通过一段时间的观察，可以得到我校校园网前端的计费系统采用城市热点的 Dr.COM，这是一套非常常见的计费系统；BRAS 终端是锐捷的设备，采用 POE 方式连接锐捷的 AP，似乎没有参与认证。\ndaemon.info pppd[8599]: CHAP authentication succeeded: Welcome to Drcom System:我将校园网分为三大类接入方式，无线，办公区有线，学生公寓有线。\n前两者都是 DHCP+Portal 验证，网页表单提交账号即可完成验证。学生公寓区域的有线设备通过 PPPoE 认证，账号信息就是校园网账号本身。\n因此路由的接入方式便确定了。宿舍的有线直接 PPPoE 认证就可以正常上网了。对于 Portal 的要麻烦一些，若无法连接外网则判断 Portal 能否访问，能访问的话提交一个构造好的 POST 包登录即可。\nPortal 认证的脚本校友已经写过不少：\nhttps://github.com/linfangzhi/CSUST_network_auto_login\nhttps://github.com/eigeen/csust-cn-login\nhttps://github.com/colawithsauce/csust-network-login\n路由器上安好 python 和 requests 库然后运行这些脚本即可。如果因无网络不能安装，重新编译一个固件就行。再不行就写一个 Shell 脚本登录。\n封锁状况 此时已经可以通过路由器上网了，但依然不能全寝共享。\n校园网多设备共享很被检测到会被临时屏蔽，此时会屏蔽所有的网络流量，据说还会强制重定向所有 HTTP 请求到http://1.1.1.3/remind/proxy_remind.htm?tm=8，不过我是没有遇上。\nUpdate: 会强制重定向到以下网页：\n查阅资料发现，检测是否多设备共享有两种思路，一种是通过设备流量特征识别：\nTTL IPID 时间戳 UA 另一种是侵入式流量审计，这个可能看学校，不过我校肯定是有的：\n增强网络安全防护能力。……部署出口防火墙、出口行为审计……、IPS(入侵防御)等安全设备系统，加固学校网络和信息系统的整体安全。\n通过一次喊人来寝室修网络得知肯定是深信服的设备。\n通过路由器裸奔一段时间发现如下规律：\n两台不同平台的产品（如 Windows 电脑和 iPad）同时上网会在较短时间内被封锁 封锁时用代理可以连出去，B 站也能看，其他的不行，甚至无法 Ping 通校外 IP 被封锁后重新认证也无法上网，更换 MAC 地址后才能恢复 得出的结论是大概率通过 UA 识别，检测到后封禁当前 MAC 地址一段时间。\n流量处理 统一 TTL 将这行规则加入路由器的「网络」-「防火墙」-「自定义规则」（下同），即可统一 TTL 为 65，其中-o br-lan可以视情况更换，如eth0。\niptables -t mangle -I POSTROUTING -o br-lan -j TTL --ttl-set 65这条规则用到了 ipopt 模块，在官方编译的固件或其他一些极简的固件里默认不会安装。这种情况下用opkg安装即可：\nopkg update opkg install iptables-mod-ipopt保存规则并重启防火墙，在电脑上随便 Ping 一个网站看 TTL 是否为 65（不要在路由器上 Ping，除非你知道你在干什么）。\n统一时间戳 接下来先启用 OpenWrt 自带的 NTP 服务器，然后劫持所有局域网内的 NTP 请求到路由器，以达到我们统一时间戳的目的。\n这种方法并不完美，因为手机连接基站时会同步到别的 NTP 服务器，最好的办法是直接去除 TCP 包的时间戳，但这种方法暂无成熟的实现，只能先采用劫持 NTP 请求的办法。\n只需要在管理页面中修改几个设置就可以了。\n点击 System -\u0026gt; System（系统） 勾选 Enable NTP client（启用 NTP 客户端）和 Provide NTP server（作为 NTP 服务器提供服务）。 NTP server candidates（候选 NTP 服务器）按需设置，可以使用阿里云的 NTP 服务器：ntp.aliyun.com 点击 Save \u0026amp; Apply 按钮。 向防火墙添加以下规则：\niptables -t nat -N ntp_force_local iptables -t nat -I PREROUTING -p udp --dport 123 -j ntp_force_local iptables -t nat -A ntp_force_local -d 0.0.0.0/8 -j RETURN iptables -t nat -A ntp_force_local -d 127.0.0.0/8 -j RETURN iptables -t nat -A ntp_force_local -d 192.168.0.0/16 -j RETURN iptables -t nat -A ntp_force_local -s 192.168.0.0/16 -j DNAT --to-destination 192.168.1.1其中192.168.1.1需要更改成路由器的地址，视固件而定。\n若你的路由器地址不在192.168.0.0/16内，最后两行都要跟着改，一般的家用路由器都在这个范围内。\nWindows 下确认效果：\nw32tm /stripchart /computer:baidu.com /dataonly /samples:5如果能正常同步就证明配置成功了。\n统一 UA 网上的解决方案大部分基于代理，比如 Privoxy，甚至 Clash。还有不少是通过XMURP-UA直接在内核层面处理 UA，这几年又有新的插件出来，比如UA2F。\n方案一：UA2F 编译固件时自定义加入ua2f和luci-app-ua2f，R2S 可以在这里下载编译好的。UA2F 与 Turbo ACC 冲突，即使没有使用 Turbo ACC 也记得要关掉「全雏形 NAT」和「软件流量分载」这两个功能。\n完成后启动 UA2F 再打开ua.233996.xyz就会发现自己的 UA 已经被修改了。\n方案二：Privoxy 安装好 Privoxy 并正确配置，然后将所有 HTTP 流量转发给 Privoxy 代理，并在 Privoxy 中替换 UA。\n安装 Privoxy opkg update opkg install luci-app-privoxy opkg install luci-app-privoxy-zh-cn配置 Privoxy 点击 Services -\u0026gt; Privoxy WEB proxy。\nFiles and Directories（文件和目录）：Action Files 删除到只剩一个框，填入 match-all.action。Filter files 和 Trust files 均留空。 Access Control（访问控制）：Listen addresses 填写 0.0.0.0:8118，Permit access 填写 192.168.0.0/16。Enable action file editor 勾选。 Miscellaneous（杂项）：Accept intercepted requests 勾选。 Logging（日志）：全部取消勾选。 点击 Save \u0026amp; Apply。\n配置防火墙转发 向路由器防火墙添加以下规则：\niptables -t nat -N http_ua_drop iptables -t nat -I PREROUTING -p tcp --dport 80 -j http_ua_drop iptables -t nat -A http_ua_drop -d 0.0.0.0/8 -j RETURN iptables -t nat -A http_ua_drop -d 127.0.0.0/8 -j RETURN iptables -t nat -A http_ua_drop -d 192.168.0.0/16 -j RETURN iptables -t nat -A http_ua_drop -p tcp -j REDIRECT --to-port 8118在路由器的局域网中打开 http://config.privoxy.org/edit-actions-list?f=0，点击 Edit 按钮。Action 那一列中，hide-user-agent 改选为 Enable（绿色），在右侧 User Agent string to send 框中填写 Privoxy/1.0或任意 UA；其它全部选择为 No Change （紫色）。点击 Submit 按钮。\n如果打不开这个页面，说明之前某个地方配置有误。\n确认效果 本地浏览器调试是看不到效果的，因为经过路由器之前 UA 会保持原样。\n访问 ua.chn.moe 以查看 UA 是否修改成功。\n方案三：Clash 这种方法的思路是使用 Clash 代理/阻止所有发往 80 端口的流量。同时 Clash 也直接接管所有流量，这就意味着无需处理 IPID 和时间戳。\n假设你使用的是 OpenClash，方法如下：\n打开 OpenClash 插件面板，进入 覆写设置 -\u0026gt; 规则设置，勾选自定义规则，将以下规则插入配置：\n- DST-PORT,80,Proxy其中Proxy需要视配置文件的不同而更改，例如我的代理组叫做 HK，也可以直接使用节点名称。\n对于没有能力加密的同学，则使用以下规则1：\n- DST-PORT,80,REJECTUpdate 2023/10/31：经测试，即使不加入这条自定义规则，也足以防止检测。但必须启用 Clash，至少设置全局直连。\n防止通过 IPID 检测 各设备的 IPID 起始值不同，并随着包数量的上升而上升，接近一条直线，若有多个设备长时间使用后会呈现出多条上升序列。这可以用来探测是否是多个设备。23\n由于需要kmod-rkp-ipid，这一步也需要编译固件。\n编译好固件后向防火墙添加以下规则：\niptables -t mangle -N IPID_MOD iptables -t mangle -A FORWARD -j IPID_MOD iptables -t mangle -A OUTPUT -j IPID_MOD iptables -t mangle -A IPID_MOD -d 0.0.0.0/8 -j RETURN iptables -t mangle -A IPID_MOD -d 127.0.0.0/8 -j RETURN iptables -t mangle -A IPID_MOD -d 10.0.0.0/8 -j RETURN iptables -t mangle -A IPID_MOD -d 172.16.0.0/12 -j RETURN iptables -t mangle -A IPID_MOD -d 192.168.0.0/16 -j RETURN iptables -t mangle -A IPID_MOD -d 255.0.0.0/8 -j RETURN iptables -t mangle -A IPID_MOD -j MARK --set-xmark 0x10/0x10即可修改所有包的 IPID 为单一递增曲线。\n老办法 设置如下 crontab 即可在每天凌晨三点重新拨号以打断检测过程：\n0 3 * * * ( ifdown wan; sleep 5; ifup wan )侵入式流量屏蔽 向路由器防火墙添加以下规则：\niptables -I FORWARD -p tcp -m tcp --sport 80 -m u32 --u32 \"5\u00260xFF=0x7F\" -j DROP iptables -I FORWARD -p tcp -m tcp --sport 8000 -m u32 --u32 \"5\u00260xFF=0x7F\" -j DROP iptables -I FORWARD -p tcp -m tcp --sport 8080 -m u32 --u32 \"5\u00260xFF=0x7F\" -j DROP iptables -I FORWARD -p tcp -m tcp --sport 80 -m u32 --u32 \"5\u00260xFF=0x80\" -j DROP iptables -I FORWARD -p tcp -m tcp --sport 8000 -m u32 --u32 \"5\u00260xFF=0x80\" -j DROP iptables -I FORWARD -p tcp -m tcp --sport 8080 -m u32 --u32 \"5\u00260xFF=0x80\" -j DROP以屏蔽侵入式流量，以上规则来自 V2EX 网友。\n这些规则用到了iptables的u32模块，大多数固件都不会默认安装，亦需要通过opkg安装：\nopkg update opkg install iptables-mod-u32随后屏蔽学校的「共享提示」页面：\niptables -I FORWARD -p tcp --sport 80 --tcp-flags ACK ACK -m string --algo bm --string \"src=\\\"http://1.1.1.\" -j DROP iptables -I FORWARD -p tcp --sport 80 --tcp-flags ACK ACK -m string --algo bm --string \"value=\\\"http://18.20.18.\" -j DROP在Openwrt防火墙的流量规则设置如下规则：\n源区域WAN，源地址1.1.1.3，目标区域设备，动作拒绝\n源区域WAN，源地址1.1.1.1，目标区域设备，动作拒绝\n这些规则来源于校友的博客（找不到来源，可能已经关闭了）\n意外封锁处理 前面提到学校会封一段时间的 MAC，想要重新上线就需要更换 MAC 地址重新上线。为此我写了一个 Shell 脚本：\n#!/bin/sh DATE=$(date +%Y-%m-%d-%H:%M:%S) interface=eth0 current_mac=$(ifconfig ${interface} | grep \"HWaddr\" | awk '{print$5}') new_mac=$(dd if=/dev/random bs=1 count=3 2\u003e/dev/null | hexdump -C | head -1 | cut -d' ' -f2- | awk '{ print \"34:36:3b:\"$1\":\"$2\":\"$3 }') tries=0 while [[ $tries -lt 3 ]]; do if /bin/ping -c 1 223.5.5.5 \u003e/dev/null; then echo --- exit --- exit 0 fi tries=$((tries + 1)) done echo ${DATE} block detected, replacing mac address \u003e\u003ewatchdog.log ifconfig down ${interface} sleep 1 ifconfig ${interface} hw ether ${new_mac} sleep 1 ifconfig up ${interface} echo ${DATE} old address ${current_mac} has been replaced with ${new_mac} \u003e\u003ewatchdog.log将这个脚本保存到路由器的 home 目录下（用vim粘贴保存以下就可以了），设置如下 Crontab 每分钟执行一次：\n* * * * * sh /root/net_watchdog.sh路由器就会自每隔一分钟检测是否在线，如果掉线，则随机更换 MAC 地址并重新上线，日志将会记录在同目录下的watchdog.log中。\nDNS 内网解析处理 接上路由器之后，校外资源可以正常访问，反倒是校内资源全都无法访问了。经排查发现是路由器下的设备无法解析出正确的 IP 地址，但路由器本身又没有问题。\n暂时不清楚是什么原因导致的，但解决起来很简单，可以直接把已知的内网地址 dnsmasq，但我推荐安装 SmartDNS 来解决。\nSmartDNS 的安装可以参考官方教程。\n开启 SmartDNS 并让其接管路由器的主 DNS 设置 SmartDNS 上游为学校内网提供的 DNS，我校是10.255.255.25和10.255.255.26 设置别的上游，可以参考这篇博客 这样设置下来，内网资源就可以正常访问了。\n参考 https://www.mr-cn.net/2021/06/15/Share-your-network-in-CSUST/ https://catalog.chn.moe/%E6%8A%80%E6%9C%AF/OpenWrt/%E5%9C%A8%E5%8E%A6%E5%A4%A7%E5%AE%BF%E8%88%8D%E5%AE%89%E8%A3%85%E8%B7%AF%E7%94%B1%E5%99%A8/ https://catalog.chn.moe/%E6%8A%80%E6%9C%AF/OpenWrt/%E4%B8%BA%E5%95%A5%E6%88%91%E7%9A%84%E8%B7%AF%E7%94%B1%E5%99%A8%E4%BC%9A%E8%A2%AB%E6%A3%80%E6%B5%8B%E5%88%B0/ https://superuser.com/questions/451018/how-can-i-query-an-ntp-server-under-windows https://github.com/krabelize/openwrt-random-mac-changer/tree/master https://github.com/CHN-beta/rkp-ipid https://www.sunbk201.site/posts/crack-campus-network 这个配置会自动拒绝所有发往 80 端口的连接，对上网体验影响很大。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n具体可以参考这篇论文\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n这个方法可行性比较低，没有已知的部署案例。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-09-23T21:49:21Z","image":"/2023/09/csust-network-guide/20231011111126_hu_205eb763ec973318.webp","permalink":"/2023/09/csust-network-guide/","title":"长沙理工大学：校园网共享指南"},{"content":"Recently, I took a 28 km bike trip.\nI usually enjoy short bike trips. While 28 km might not seem like much to some, it’s enough to showcase how bike-friendly Changsha is.\nLet’s dive into the details.\nOverall Impressions Changsha isn’t designed for bikes.\nThe city was originally intended to be car-centric. In the past, people were too poor to own cars and used bikes instead, making it appear more bike-friendly. As wealth increased and more people bought cars, problems arose. Now, the city is trying to balance its development by improving public transport and becoming more bike-friendly.\nToday, Changsha blends American-style car-centric design with Western European human-centric elements: wide roads built for cars with little space for bikes on older streets but newer roads often include dedicated bike lanes.\nInfrastructure Road quality is generally good but many are under construction due to public transport projects. These areas can be dangerous and poorly maintained with chaotic traffic.\nMost roads lack dedicated bike lanes; you’ll need to share the road with horrible traffic. Some roads have blue arrows indicating bike paths, it\u0026rsquo;s better than nothing , but still, not actual bike lanes\nIn most cases, the roads are suitable for cycling. If sharing the road feels unsafe, you can use the sidewalk.\nParking a bike here isn\u0026rsquo;t easy; theft is common so ensure your lock is strong and reliable.\nDrivers Most drivers pay attention to cyclists but always stay alert as accidents can happen due to careless drivers or parked cars blocking paths—a frequent annoyance caused either by poor road design or inconsiderate drivers.\nClimate Changsha\u0026rsquo;s climate is harsh—hot and humid summers that cause sweating or heatstroke and mild yet still cold winters unsuitable for cycling. Locals joke there are only two seasons here in Changsha: Summer and Winter. Comfortable spring and autumn weather has become rare in recent years likely due to climate change.\nConclusion Currently, Changsha isn’t very bike-friendly: the infrastructure needs improvement, some drivers aren’t considerate of cyclists, and the climate poses challenges. The city aims to improve its conditions for both bikers and pedestrians but progress has been slow.\nDespite these shortcomings, I’m glad Chinese cities are evolving positively over time—I hope our city continues this trend towards greater happiness and better living conditions.\n","date":"2023-09-19T23:13:28Z","permalink":"/2023/09/is-changsha-bike-friendly/","title":"Is Changsha a bike friendly city?"},{"content":"江城武汉，国 gal 最高城也。\n这次去武汉，巡礼三个国产 Galgame：《三色绘恋》《恋爱绮谭》和《高考恋爱100天》。\n于是乎挑了一个早上开车一路从长沙狂奔到武汉，到取水楼那订好的酒店住下了。\n当时三伏天还没过去，看了下天气，最高35℃，其实已经很热了。但对于在长沙这种天气极度抽象的地方熬了这么多年的我来说，武汉的天气反倒是可以接受的。（再次证明了长沙的气候就是依托答辩）\n不浪费时间，随便找了家店吃午饭就往中山公园里怼，圣地巡礼正式开始！\n三色绘恋 应该是2021年接触到的这部 Gal，剧情是真的胃疼，每次推一小段就会因为不忍心看后面的剧情而关掉这个游戏，加之这游戏在 Steam 里叫 Tricolor Lovestory，自然的就按照字母顺序排到了后面，也相应的减少了我打开它的次数。于是直到最近我才把这个游戏给推完。\n游戏本体非常优秀，百万字的剧情文本，加上几百张高质量的CG和全程配音，定价却只要11块，还时不时的打折。后面制作组搞事情弄出来的 Trash End 就毁了这么好的一个 IP，实在是可惜了。\n师贰高级中学 这是主催的母校，在游戏里竟然是媲美华师一附中的存在，然而现实里就是一所很普通的高中，特色就是这个很夸张但没卵用的拱门。顺带一提，这所学校正在改建，看宣传图似乎是要改的面目全非了，再晚几年可能就完全无法辨认。\n邱诚和墨小菊的上学路 现实中的航天路，由于店面已经面目全非，而且一侧的店铺已经完全拆除了，已经几乎无法辨认。找了一圈这里大概是比较像的地方。\n据说是文芷家原型 现实中是电业新村，门的造型和游戏里非常相似。\n邱诚和墨小菊所在的小区 现实中是地质家属小区：\n顺便在旁边那家副食店买瓶水，证明我来过（\n中山公园 这里我拍的都是视频，为了不耽误加载，只好用截图代替。\n没碰上喷泉表演真可惜了。\n利北社区 迟菓住的小区，u1s1确实比较老旧了，名字的由来应该是利济北路。但在这么市中心的位置，价格也真不便宜啊。顺带一提，只要从这个社区出来过一条马路就是邱诚和墨小菊住的地方，真有够近的。\n游戏中完全是 1:1 还原了这个小区：\n江城市第六十八初 迟菓读的初中，游戏里也是1:1的还原，甚至连旁边的刘记腰花面都没有落下。\n汉街上的「稻当劳」 别问了，我没有在这里买草莓新地。\n轻轨「循礼门」站 根据游戏中的报站，下一站是江汉路，可以确定是二号线，但实际上武汉轻轨应该是一号线，并不经过游戏中出现的场景，有点出戏。\n江城市风景 那张CG我找不到了，并且这个还是夜景，这是在长江一桥的江中心位置拍摄的，当然，是用无人机。\n和武汉官方的宣传视频不太一样的是，很多建筑的灯光是关着的，导致现在拍出来画面没有官方拍的时候灯光拉满来的好看。\n恋爱绮谭 恋爱绮谭是我在暑假前才接触到的游戏系列，当时玩过以后，实感相见恨晚，也很高兴能看见国 Gal 在铺天盖地的压力和江河日下的大环境下，仍能保持自己的那一份相对崇高的追求和社会责任感。\n恋爱绮谭的场景设定其实都和现实差距很大，没有像三色绘恋「利北社区」那种1:1还原的场景，但依旧能看出原型，巡礼是值得的。\n苹果湖中学总校 恋爱绮谭主要场景之一，苹果湖中学，原型是水果湖高中。这所学校就在湖北省委旁边，所以是禁飞区，我甚至没法飞无人机进去航拍一下。既然在湖北省委旁边，自然少不了那些官二代、红二代，这所学校在网上可谓是流言四起，显得非常神秘。\n充能国安路 官方设定集里的原型是鸣笛1988商业街，在现实里是一条非常冷清的商业街，入驻的商户没有几家，也看不到除我以外的任何一个顾客，当然也没有游戏里「充能国安路(CNGal)」那样的二次元周边店。我想知道制作组是怎么找到这么小众的商业街的。而且这条商业街特别小，附上航拍图：\n就是那个不规则的四边形。而且从游戏里的图来看，制作组还混合了日本某个商店街（也不知道是哪一个）的样式进行了二创，简直是一点都不像。\n关于在游戏第二部里出事的奶茶店，在这个位置倒是有一家茶颜，我进去点了杯筝筝纸鸢，证明我来过，顺便点亮「武汉」徽章：\n苹果湖中学分校 设定集里的位置在现实中是菱角湖公园，完全就不是一个东西嘛……\n这是苏半夏（用怪异）就读的学校，位置就在鸣笛1988的旁边，符合苏半夏和顾伟从分校出来就能到充能国安路的设定。\n孱陵路 现实里是公安街，这条街道是一个典型的「老破小」街区，很脏，很乱，但地段其实特别好，生活也很方便。\n我到公安街的时候已经十点半了，在武汉跑了一天，拖着疲惫的身子从大智路地铁站出来，走了一阵，一进到公安街，一股阴森的感觉扑面而来。辅以游戏中的故事，代入感极强。这里一定要晚上来，白天来，这种感觉就会尽数失去。\n个人觉得最像游戏里的一处是这里：\n简直就是游戏里潺陵路33号的入口，可惜旁边没有卖鱼头汤的店，要不然代入感还能更强。走进这种地方，我其实觉得特别亲切，我小时候，也天天要经过这样的街区，也曾住过一段时间像潺陵路33号这样的房子。总觉得繁华的街区皆是幻境，在幻境中呆久了，便会愈发的分不清幻境与现实，而偶尔看看这种地方，却可以让我感到无比踏实。\n江城大桥 原型是武汉长江二桥，据制作组称，选择武汉长江二桥是因为一桥画出来太平平无奇了。当时是中午，拍的时候光线实在是太差，凑合着看看吧。\n也不知道钟齐北救起顾唯的地方是武昌江滩还是汉口江滩，但好像只有汉口江滩这边有芦苇丛，所以姑且算作是汉口江滩。那么下面就是顾唯被救起的地方：\n高考恋爱100天 这游戏一共有61个结局，我只解锁了其中5个，这次来巡礼很大程度上只是顺便。\n不过说回游戏，这确实是个很优秀的作品，既有游戏性剧情也很丰富，国 Gal 最大的优势便是题材和场景对于本土玩家的「亲切」感，这部就把这两个优势发挥得淋漓尽致。有点像是「中国式家长」剧情更丰富、CG 更多的微操版。\n唉，我高考的时候怎么就没有「木馨的护身符」和「1977年的回忆」这种神仙道具呢。\n武汉长江大桥 这个场景其实还挺iconic的，尤其是对面的电视塔，游戏里经常出现。\n华懿高级中学 原型是华中师范大学第一附属中学，由于戒备实在森严，只好飞个无人机进去拍一圈走人了，属实有点遗憾了。\n要是他们真有老宿舍那我翻围栏都要翻进去找一本「1977的回忆」\n最后…… 在武汉的三天过得非常扎实，基本上去了所有我想要看到的地方。但无奈时间的问题，像是「雨娘传说」的公交站，江景别墅的原型……还是有些地方没能去成，时间紧的时候，做些取舍终究还是很无奈的。\n国 Gal 因「亲切」深得我心，这种题材的亲切、生活环境的亲切，是非本土 Galgame 永远无法企及的。正如前面提到，我很高兴看到国 Gal 能够在重重压力下依然保持自己的追求，为我们带来优秀的作品。说来也怪，在如此差的环境下，我们依然在一些方面有所建树。人们总是去歌颂这些建树，默认苦难的合理性，却从来无人过问，是什么造就了如此差的环境。\n希望未来能看到更多优秀作品，也希望我们能早日看到我民族真正解放之日。\n","date":"2023-08-19T18:28:26Z","image":"/2023/08/wuhan-trip/cover_hu_57906180d5388760.webp","permalink":"/2023/08/wuhan-trip/","title":"江城武汉圣地巡礼：《三色绘恋》《恋爱绮谭》《高考恋爱100天》"},{"content":"不知从什么时候开始，我的生活就慢慢的被推荐算法淹没，推荐视频、猜你喜欢……，几乎每天，我都或多或少的被他们所影响。我曾半开玩笑：「网速越快，其传递的信息就越少」，甚至有些一语成谶。这并不是互联网能传递的信息变少了，而是越来越快的网速、越来越准的推荐算法养废了我们，夺走了我们从网上获取信息的能力与主动权。\nRSS 已是信息获取手段中的老古董了，但它的体验真的一点都不老古董：相反，用它来获取信息，体验极佳——不光无广告，还能让那些分散在一个一个网页上的信息自动跑到你面前，岂不美哉？我没有经历过那个时代，但听闻当年的大家，人人都拿着 Google Reader（Google 打造的 RSS 阅读器）读他们想读的内容，倒也真想回到那个年代体验一番。\n可惜 Google Reader 这一产品早就关停了，曾经大多数网站都提供的 RSS 订阅源也悉数消失，想要重新拾起 RSS，就需要一点折腾了。\nRSSHub：万物皆可 RSS GitHub 仓库 这是 DIYDogDIYGod 大佬发起的项目，就和它的标语一样，万物皆可 RSS，这个项目能通过爬取网页内容的方式生成 RSS 信息流，从而通过 RSS 订阅本不支持 RSS 的网站。\n由于是爬取，难免会受到目标网页反爬取策略的影响，而有的目标网页（比如大陆的政府网站）会屏蔽他国 IP 的访问，亦或者屏蔽掉风险 IP。这些因素就比较考验机房了，但只要不是被特别「照顾」的 IP，一般问题不大。出于这些原因，我在分别在洛杉矶和上海部署了 RSSHub。\nDocker 部署 RSSHub 非常简单，首先拉取已经写好的docker-compose.yml：\n$ mkdir rsshub \u0026\u0026 cd rsshub $ wget https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml然后检查有无需要修改的配置：\n$ vim docker-compose.yml我最终修改完成后，配置如下：\nversion: \"3\" services: rsshub: image: diygod/rsshub:chromium-bundled restart: always ports: - \"1200:1200\" environment: NODE_ENV: production CACHE_TYPE: redis REDIS_URL: \"redis://redis:6379/\" depends_on: - redis redis: image: redis:alpine restart: always volumes: - redis-data:/data volumes: redis-data:为什么要新建一个 Redis 镜像？主要是懒得配置容器互联，而 RSSHub 用 Redis 占不了多少资源，遂直接写进一个docker-compose.yml里，省去容器互联的麻烦。\n启动编排：\n$ docker compose up\t# 老的写法是 docker-compose up随后使用 Nginx 反代localhost:1200至域名，部署 SSL 证书，RSSHub 就全部搭建完成了。\n反爬严格网站的部分解决 前面已经提到由于 RSSHub 的工作原理是爬取，其势必会受到不同网站反爬策略的影响。以 B 站为例，如果仅仅部署 RSSHub 而不采取任何措施，当你订阅时，大概率会出现「521 - 风控校验失败」的提示。\n这时，先去查找 RSSHub 的文档，看看相应的网站是否有 Cookie 可以被设置为容器的环境变量，对于大部分需求，只要环境变量配置正确，就可以有效缓解反爬问题。\n还是以 B 站为例，查阅 RSSHub 文档，可以发现有一些额外的环境变量需要配置。1\n按照文档，打开对应的网页，按下 F12 打开开发者工具，转到「网络」面板，刷新网页，就可以找到 dynamic*new 请求，复制整个 Cookie（或者 SESSDATA=xxx；字段），修改docker-compose.yml文件，将BILIBILI_COOKIE*你的B站UID: \u0026quot;SESSDATA=xxx\u0026quot;添加到environment部分，即可完成配置。\n配置好的docker-compose.yml看起来像下面这样：\nversion: \"3\" services: rsshub: # two ways to enable puppeteer: # * comment out marked lines, then use this image instead: diygod/rsshub:chromium-bundled # * (consumes more disk space and memory) leave everything unchanged image: diygod/rsshub:chromium-bundled restart: always ports: - \"1200:1200\" environment: NODE_ENV: production CACHE_TYPE: redis REDIS_URL: \"redis://redis:6379/\" BILIBILI_COOKIE_你的B站UID: \"SESSDATA=xxx\" depends_on: - redis redis: image: redis:alpine restart: always volumes: - redis-data:/data volumes: redis-data:修改文件并保存，重启编排：\n$ docker compose up -d --force-recreate # docker-compose up -d --force-recreate配置完成后，即可正常订阅 B 站 Up 主投稿等相关路由。\nRSS 阅读器推荐 RSSHub 可以解决掉大多数订阅源的问题，接下来推荐几个 RSS 阅读器，解决的是最后一步如何呈现到设备上的问题。\nWindows Fluent Reader 我目前在用的 RSS 阅读器，开源小巧，遵循 Fluent Design，如果需要 Windows 上的免费 RSS 阅读器，那么大概率就是它了。需要注意的是，这是开源软件，但在应用商店里需要付费才能下载，不想付费则可以直接在 GitHub 上下载其安装包安装，当然，如果喜欢，鼓励大家支持这个项目。\nGithub仓库 ThunderBird 这个不是 RSS 阅读器，但也提供了 RSS 功能，比较适合打造邮件 RSS All in one。\nThunderBird 是由 Mozilla 基金会开发的一款开源邮件和新闻聚合客户端，已经有快 20 年的历史。\n官网 MacOS 和 iOS NetNewsWire 开源，Swift UI 原生编写，几乎完美的 RSS 阅读器，说实话我很惊讶这位作者维护这个项目的时间跨度。\nNetNewsWire 是由 Brent Simmon 出于爱好和支持 RSS 发展开发的 RSS 阅读器，遗憾的是，由于是 Swift UI 编写，只支持 Mac OS 和 iOS。\n官网 Github仓库 Reeder 这个就是收费 App 了，但功能做的很不错。作为「骨灰级」应用，Reeder 一度被人称为 iOS 与 macOS 上最好用的 RSS 阅读器。不光设计精致，还支持如桌面小组件等各种 Mac OS 和 iOS 上原生的功能，如果你的预算充足，可以考虑。\n官网 Fluent Reader 又是之前提到的 Fluent Reader 也提供了 Mac 版本，实测在 Mac OS 上体验也还不错，在 iOS 上虽然看起来是原生 UI，但实际上是 React 写的跨平台版本，而且还需要收费，如果想要支持这个项目，可以考虑购买。\n链接：\nGithub仓库 Github仓库（Fluent Reader Lite） Linux NewsFlash NewsFlash is a program designed to complement an already existing web-based RSS reader account.\nIt combines all the advantages of web based services like syncing across all your devices with everything you expect from a modern desktop program: Desktop notifications, fast search and filtering, tagging, handy keyboard shortcuts and having access to all your articles for as long as you like.\n这是一个很现代化的 RSS 阅读器，一般用 flatpak 安装，也有人为其制作了 Snap 封装的版本，不过几乎不怎么更新维护。它的界面很好看，对在线服务2支持的很全，而且是原生运行，非常推荐。\nGitlab 仓库 Flathub页面 Fluent Reader 又双叒是 Fluent Reader，跨平台这么容易吗。\n有人给它制做了 Snap 封装的 App，Ubuntu 可以直接去应用商店下载使用。官方仓库里提供了 AppImage 给其它分支使用。\n安卓 Fluent Reader 又双叒叕是 Fluent Reader，在安卓上，Fluent Reader 依然是贴合 iOS 的 UI，用起来有点牛头人的感觉，若不在意这一点，体验倒还不错。\nGithub仓库 FeedMe 评论区网友的推荐，FeedMe 支持的服务繁多，功能齐全，界面也较为现代化，一样支持 FreshRSS 等在线 API。\nGithub 仓库 如果有其他好用的 RSS 阅读器欢迎在评论区留言。\n总感觉还缺点什么？ 理论上来说，解决了订阅源的问题，还解决了呈现在设备上的问题，我们已经还原出 Google Reader 的体验了，但我在实际使用中，总是觉得缺少了一些特性，体验并不完整。\n这个特性就是「同步」。我所希望的，是我在 A 设备上阅读，阅读进度可以同步到 B 设备上，在 A 设备上收藏的文章，打开 B 设备，能原封不动的呈现在我眼前。\n同时，还有一个体验上的要求：我希望我在拉取 Feed 时更加快速，不需要等待 RSSHub 抓取网页。\n于是，一个自托管的 RSS 聚合服务就很有必要了。\n以 FreshRSS 完善体验 FreshRSS 是一个免费，自托管的 RSS 聚合器，相似的项目还有 Tiny Tiny RSS（TTRSS），选择 FreshRSS 是因为它提供两种 API，和各个 RSS 客户端配合的更好。\nGithub仓库：https://github.com/FreshRSS/FreshRSS\n部署 部署 FreshRSS 的过程也很轻松。\n创建目录：\n$ mkdir freshrss $ cd freshrss创建docker-compose.yml：\n$ vim docker-compose.yml\t# 或者任意编辑器编辑docker-compose.yml如下：\nversion: \"3\" services: freshrss: image: freshrss/freshrss:latest container_name: freshrss restart: unless-stopped ports: - \"9999:80\" # 将9999更改成需要的端口 volumes: - ./data:/var/www/FreshRSS/data - ./extensions:/var/www/FreshRSS/extensions environment: PUID: 0 PGID: 0 CRON_MIN: \"1,31\" TZ: \"Asia/Shanghai\"最后执行：\n$ docker compose up\t# 老的写法是 docker-compose up随后反代端口，部署 SSL 证书。初始设置时，数据库选现有的数据库类型，如果没有部署数据库，直接选 SQLite 即可。至此，FreshRSS 部署完成。\n如果之前有订阅源，将其以 OPML 格式导出，然后导入 FreshRSS 就可以获得几乎无缝的体验。\n![FreshRSS](截屏2023-07-18 15.17.39.png)\n如果有现成的 PHP 环境而不想用 Docker 部署，还可以像安装 Wordpress 一样安装好 FreshRSS。\n设置 FreshRSS RSSHub 充当的是提供订阅源的中心，而 FreshRSS 充当的是一个阅读订阅源的「Hub」，帮助我们集中管理订阅源，同步各设备间的阅读进度。现在订阅源已经集中管理起来，同步个设备间的阅读进度就需要 FreshRSS 提供的 API 了。\nFreshRSS 提供 GReader 和 Fever 两种 API，具体的启用方法如下：\n登入 FreshRSS 进入「设置」-\u0026gt;「认证」开启「允许API 访问」 进入「账户」在页面底部设置一个 API 密钥 编辑./freshrss/data/config.php中的base_url，改为你的域名根目录地址，比如我的就需要改成https://rss.l3zc.com/ 转到https://example.com/api/查看检测是否通过 设置各设备上的客户端 NetNewsWire 部署完成后，在手机上和电脑上支持的应用里使用设置好的用户名和 API 密钥登陆，就可以享受到全程丝滑的 RSS 体验了，下面以 NetNewsWire 为例：\n打开NetNewsWire添加账号的选项卡，NetNewsWire贴心的集成了FreshRSS，可以很方便的添加账号：\nNetNewsWire 要求 Greader 的 API，直接在 /api 上复制就可以了。\nFluentReader 在设置中选择 Google Reader API：\n然后填入相关信息：\nAPI端点直接从/api网页上复制 Google Reader API 的 API 端点即可 用户名填写安装 FreshRSS 时设置的用户名 密码是前文设置的 API 秘钥 即可设置完成。\n其他的客户端设置大同小异，无外乎上面两大类，可以参考上面的方法进行设置。\nRSS 订阅什么呢 我们已经装好了 RSSHub，这极大的方便了我们的订阅以及丰富了我们的订阅源。RSSHub 的官方文档中维护着一份详细的支持列表，支持的项目不可谓不繁多：媒体、博客……甚至大学通知，Twitter 更新都能覆盖。\n以订阅「湖南省政府采购网」的「采购公告」为例，首先需要在 RSSHub 的文档中找到「湖南省政府采购网」以获取其订阅的「路由」：\n查询文档可知我们所需要的路由是/gov/hunan/notice/:type，其中:type是一个必选参数，我们需要获取的是「采购公告」所以:type应该是cg，最终需要的路由就是/gov/hunan/notice/cg。将这个路由附加在我们部署（反代）RSSHub 的网址后，即可得到完整的订阅地址，例如：部署rsshub的网址是https://rsshub.app，则最终的订阅地址为：https://rsshub.app/gov/hunan/notice/cg，将其加入 FreshRSS 的订阅即可。\n需要注意的是，FreshRSS 似乎不支持自动转换订阅链接里的非 ASCII 字符，如果你的订阅链接里含有这些字符，如https://rsshub.app/sspai/tag/派早报，则建议在浏览器内先访问一下，再将转换后的链接粘贴进 FreshRSS 以转换链接中的非 ASCII 字符。\n对于原本就有 RSS 的网站，推荐使用 RSSHub Radar，这是一款浏览器插件，可以实现 RSS 订阅源的自动嗅探，而不必在网站上四处寻找。推荐它是因为，它不光可以嗅探 RSS 链接，如果目标网站可以用 RSSHub 订阅，这个插件可以自动匹配支持的 RSSHub 路由。\nGithub 仓库 最后…… 经过了这一番折腾，基本体验到了当时人人都用着 Google Reader 的乐趣。即便如此，属于 Google Reader 的时代终究还是过去了，那个人人都可以从网上收获纯粹的知识与快乐的时代，也已然一去不复返。这些年来网速越来越快，但给我的上网体验却越来越差。大多数人都开始上网的时候，内容农场，推荐算法……只要有利可图，互联网精神，那个曾经作为互联网基石的精神，就全被这些追逐利益的资本和官商勾结的政府抛在脑后。我甚至可以说：至少在中国，那个曾经「互联网」的理想已死。\nRSS 的没落只是大环境的缩影，「技术」固然需要进步，但没有与之相匹配的「人文」，这种进步就会成为一场灾难。以我们现在的状态来看，赛博朋克真的离我们不远——技术进步，不但不能消除不平等，反而会加剧压迫与控制。\n即使大环境再怎么黑暗，我们依然能看到一线生机，依然会有人去发扬几乎被大环境抛在脑后但弥足珍贵的互联网精神，散发光和热，通过自己的方式捍卫互联网的开放与自由。\n感谢所有这些开源项目的贡献者，也向所有热爱分享的同路人致敬。\n参考 https://sspai.com/post/63202\nhttps://docs.rsshub.app/\nhttps://typecho.l3zc.com/archives/20/\n以及这篇文章里所有提到的链接。\n近期 RSSHub 经历了一次大重构，相应地，新增的路由所需的环境变量配置可以在路由对应文档处找到，而不需要翻阅「部分 RSS 模块配置」这一部分。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n无论是自托管还是非自托管。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-07-17T20:33:00Z","image":"/2023/07/rsshub-freshrss-information-flow/20231011105121_hu_fe5d2177608978ac.webp","permalink":"/2023/07/rsshub-freshrss-information-flow/","title":"重新捡起 RSS：RSSHub + FreshRSS 建立我的信息流"},{"content":"音乐是我生活中不可缺少的一部分，每次听自己想听的音乐，心情都会变得无比舒畅。\n我喜欢随机播放音乐，给自己寻找一些新鲜感。为了听到自己「想听」的音乐，随机到我不喜欢的音乐时，我自然会选择性的跳过，直达契合自己先下想听的那首曲子。\n时间一长，我发现：有些曲子，似乎不是什么想不想听的问题——几乎每次听歌遇到这些曲子，我都会选择跳过，很多都是第一次收藏以后就再也没有听过了。即使如此，我也不忍心将他们移出我的歌单，因为，那至少是我曾经「喜欢」过的曲子。思来想去，我依旧还是遇到他们就选择性的跳过，即使这样更加麻烦。\n这些所谓「喜欢」的音乐也影响到了推荐算法，很快，我的「每日推荐」「每周新发现」等歌单，被那些「似乎喜欢」的音乐充斥。每次听算法推荐的歌单，都有一种在逛 CSDN 的感觉，可以算作是「屎里刨金」吧。面对这种情况，我常常对推荐算法失望透顶，却又不得不承认，那些「似乎喜欢」的音乐，影响了推荐算法的成果。\n是我对「喜欢」这首歌的概念定义错了。对于那些听了一次就不再听的歌，我终于明白了，终究还是我「不喜欢」他们啊。给那些根本就「不喜欢」的歌按上红心，收藏起来，越积越多，甚至越发影响自己听那些真正「喜欢」的歌。这不是敝帚自珍，本末倒置吗？\n是时候清理那些「似乎喜欢」的歌了。\n","date":"2023-07-12T14:03:21Z","permalink":"/2023/07/really-a-loved-song/","title":"真的「喜欢」这首歌吗"},{"content":"中国向有斗士和隐士两类散文家，其最大的区别在于斗士把散文当利剑，隐士拿散文当雕刀。斗士惯有特立独行，宁为玉碎的血性，也许他的剑术并不高明，却一定刺中要害。「特殊的时代一定会产生特殊的文体」，鲁迅式与茅盾式的散文的现实性和战斗性，实在是他们当时所处大时代的造物。要在他们的散文里寻觅矫情自饰的小情调，「小摆设」，则不免徒费无益。他们是把散文当「投枪」与「匕首」的，才不会把它变成高逸人士手里的小玩意，去「专论苍蝇之微」。正如阿英所说：「在中国的小品文活动中，为了社会巨大目标而探索的作家，在努力的探索着这条路的，除了茅盾、鲁迅以外，似乎还没有第三个人。」\n因而，正当大时代而一味的「品赏」「幽默」与「闲适」，就显得十分不合时宜了。不是吗？曾几何时，「幽默」的老舍就遇到过难堪的尴尬，他怎么会想到「幽默」竟会给他带来「危险」！他那篇《「幽默」的危险》既是一次辩白，也是在为一己的幽默正名。这自然起因于鲁迅对林语堂所办《论语》半月刊的批评，而老舍当时常给《论语》写稿。当国家身处内忧外患之际，林语堂倡导「幽默」、「性灵」，「以自我为中心，以闲适为格调」，自然便有了专事玩弄之嫌。眼里从不糅沙子的鲁迅，批评林语堂将幽默导向「将屠户的凶残，使大家化为一笑，收场大吉。」也就顺理成章。可要是单从鲁迅 1934 年 6 月 18 日写给台静农的那封信来看，他当时对老舍的幽默是更看不上眼的。他说：「文坛，则刊物杂出，大都属于 ‘小品’。此为林公语堂所提倡，盖骤见宋人语录，明人小品，所未前闻，遂以为宝，而其作品，则已远不如前矣。如此下去，恐将与老舍半农，归于一丘。其实，则真所谓‘是亦不可以已乎’者也。」这实在有点冤枉了老舍，因为即便当时来说，老舍与林语堂的幽默路数也毕竟是有区别的，「林语堂的文章是幽默而带滑稽，老舍则幽默而带严肃。」\n与鲁迅比，郁达夫要豁达许多，他认为，「清谈，闲适，与幽默，何尝也不可以追随时代而进步呢？」可见，在他眼里，一个作家是否追随时代而进步，并不在乎他的「文调」是「性灵」、「闲适」、「幽默」的，还是道文壮行、挥戈反日的。其实，鲁迅也并不像有些人出于逆反心理想象的那样，是只会「横眉冷对」的「铁板」一块。在散文写作理念上，他还是蛮「前卫」的。他认为散文只要达到了真情实感的流露，写作上「是大可以随便的，有破绽也不妨。」同时，鲁迅的深刻犀利却也是旁人所望尘莫及的，他一针见血地指出，散文的幻灭在于「模样装得真。」换言之，在鲁迅看来，散文最贵在「真」，尤忌「瞒」和「骗」的装腔作势。\n散文写作又实在是多元的，远非「斗士」「隐士」两类可以囊括。恰如梁实秋所说，「有一个人就有一种散文。」以鲁迅、周作人虽为血缘兄弟，却「文调」迥异，即可见事实也是如此。一个人的散文写成什么样，或他会如何来写，跟他的散文观，其实也就是性格，是血脉相连的。所以，梁实秋强调，散文的「文调就是那个人。」「文调的美纯粹是作者性格的流露。」他以为「散文是没有一定格式的，是最自由的。」要「美在适当」。周作人则率先提出，现代散文是「记述的，是艺术性的，又称作美文，」且「须用自己的文句与思想。」朱自清主张「意在表现自己」，崇尚写「独得的秘密」。\n再比如，沈从文一味要在散文里「写我自己的心和梦的历史。」并特别强调，「把文学附庸于一个政治目的下，或一种道德名义下，不会有好文学。用文学说教，根本已失去了文学的意义了。」坚持文学的纯艺术性，像他的同道何其芳、李广田、萧乾，直至他的弟子汪曾祺，均如是；章依萍则代表「海派」作家直言不讳地表示，「所谓文人的著作，在高雅之士看来，诚为不朽之大业，而在愚拙之我看来，在资本主义之下，一切的著作，无非皆是商品而已。」坚持文学的商品性。像与之归于一派的张爱玲、苏青等，也都明确地说，他们是为生活、为钱而写作。在今天看来，即便是为稻粮谋，却写得一手好文章，已无可厚非，不太再会轻易指摘为思想格调不高或人品低下了。\n正是从这个角度也说明，诚如梁遇春所说，「自从有小品文以来，就有许多小品文的定义，当然没有一个是完全对的。」可我还是最心仪他以 26 岁年轻生命留下的那份洒脱与率真，以及只能是天赋的灵性与悟感。他以为，散文就是「用轻松的文笔，随随便便地来谈人生。」而且，比起诗来，散文「更是洒脱，更胡闹些罢！」我颇以为然。\n其实，追踪 20 世纪中国现代散文的脚迹，无论是早期的「语丝派」，「论语派」，赞美母爱的「冰心体」，「跑野马」的徐志摩散文，还是被一度奉为新经典的杨朔、秦牧、刘白羽三家散文，直至海峡对岸立志要「剪掉散文的辫子」的余光中，甚或近来的「大文化散文」也好，「小女人散文」也罢，至少在一点上是一致的，即「我手写我口」。不管何种「文调」，无论向杂文倾斜的硬邦邦抨击时政的，还是抒情感怀到软绵绵无病呻吟的，或触景生情得悲歌哀怨、如泣如诉的，散文在某种程度上，是可以作为灵魂的避难所或精神的栖息地而存在的。艺术是独立的，散文须是个性的。\n2005 年 5 月 23 日于中国现代文学馆\n","date":"2023-07-11T17:16:36Z","permalink":"/2023/07/repost-gan-wu-jing-dian/","title":"转载：感悟经典"},{"content":"由于马一龙最近的吐血操作，Twitter 用户又一次大量出逃，我愿称之为「Twitter Exodus」。见此情景，隔壁的小扎坐不住了，连夜提前自家的竞品的发布日期，7月6日10点我们就能看到它了。\nMeta 家的竞品名叫「Threads」，乍一看介绍就是个文字版的 Instagram，继承所有 Ins 上的 Followers 和 Followings。「又是一个平平无奇的产品，全靠同行衬托……」——这是我当时粗看介绍给它的评价。\n可是 Threads 没这么简单。\nThe new standalone app will be based on Instagram and integrate with ActivityPub, the decentralized social media protocol. That will theoretically allow users of the new app to take their accounts and followers with them to other apps that support ActivityPub, including Mastodon.\n据报导，Threads 将会在未来以接入 ActivityPub 的方式接入 Fediverse，消息一出，许多（ActivityPub）实例的站长都表达了不满，或直接声称将会在自己的实例上屏蔽 Threads，或在站内发起投票以决定是否屏蔽之。\n什么是 Fediverse？ Fediverse 即 Federation 和 Universe 的组合，中文译名叫「联邦宇宙」。顾名思义，「联邦宇宙」就是由多个相对独立的实例组合而成，这些实例的互通方式和电子邮件比较相似，实例加入或者离开这个网络对其余的实例以及整个网络都没有影响，你还是可以和这个网络上其他所有人互通。基于这个特性，与其叫做「联邦」，叫「邦联」更合适。\n只要在一个联邦宇宙的实例上注册账号，比如一个 Mastodon 账号，理论上你就可以和联邦宇宙内其它任何实例上的任何账户通信（包括那些非 Mastodon 实例，GNU Social, Friendica, Hubzilla, Diaspora, etc.）\n为什么要集体抵制 Threads？ Masto zealots: We’re open, federate with us!\nInstagram: Great, we’re building a new thing to join you.\nMasto zealots: Not that kind of open!\n各实例之所以集体抵制 Threads，最主要的理由便是担心 Threads 会「夺舍」：先是倚仗大公司的资源优势，提供比其它实例更好的早期体验，等到垄断了内容创作者，再断开与 Activity Pub 的连接。Threads 本身就有 Instagram 的用户群打底，想要这么做，是很容易的。\n即使上述的想象没有发生，下面的问题，就涉及到了联邦宇宙本身：\nAdmins who are planning on federating with Threads, what is your plan when Libs of Tik Tok sends thousands of far right users to harrass one of your users?\n——@siege@octodon.social\n@StarKiller 你好！目前，Threads与Fediverse尚未连接，长毛象中文站不会立即屏蔽Threads的域名。然而，一旦开始联邦，如果发现Threads对用户体验造成了不可接受的影响（例如无法控制攻击性言论和滥用、向外部站点投放广告、不遵循远程嘟文删除请求、大幅增加服务器负载等），我们将考虑立即在实例级别隐藏或封禁Threads。\n对于Mastodon用户数据流向Threads的担忧，请参考以下嘟文中的第2条。 https://m.cmx.im/@strawberry/109437505\n——@strawberry@m.cmx.im\n联邦宇宙设计的理念之一就是赋予大家平等的社交权力，为了实现这一点，在设计之初，甚至牺牲自己的体验，刻意弱化了自己的一些功能，现在 Meta 进军联邦宇宙，带来大量的名人和社交媒体影响者，与联邦宇宙连接，Meta 完全可能执意自己的商业价值，破坏这种平等，补全联邦宇宙缺失的体验，仗着这种优势给予那些「Far right users」随意攻击联邦宇宙上他人的途径。\n对于实例的管理员们，草莓县的管理员几乎已经阐述清楚了他们的担忧，和一般的恶意实例一样：向外部站点投放广告、不遵循远程嘟文删除请求、大幅增加服务器负载……，Meta 毕竟是一家商业公司，如果这有利于他们利润最大化，那么这些情景完全可能发生。\n最后就是大家都要担心的隐私和数据流向 Meta 的问题。在隐私方面，Meta 并不是一家声誉很好的公司。相反，Meta 就是因为隐私问题才沦落到今天这个地步，至于我们能看到的隐私有多糟糕，这两张图就可以形成鲜明的对比：\n2018 年美国总统大选时，当时还叫 Facebook 的 Meta 爆出了Facebook-剑桥分析数据丑闻，其在未经用户同意的情况下获取数百万Facebook用户的个人数据，这些数据主要用于政治广告，也就是说，左右选举1。商业公司之所以能提供免费的服务，就是因为我们的数据所能创造的价值（比如干预总统选举）远超开发维护产品的成本。现在 Meta 接入联邦宇宙，不就相当于把我们的数据（帖子，用户名这些虽然公开但还是很有价值的数据）让 Meta 不费吹灰之力免费拿走吗？而 Meta 甚至不需要征得我们的同意。\n抵制可能带来的副作用 对人们的去留起决定性作用的，不是花里胡哨的功能，不是大部分人不会细看的隐私政策，而是这个平台所创造的社区，更本质的说，就是这个平台上的人。\nI have to keep posting on twitter because that\u0026rsquo;s where my audiences are.\n为什么马斯克如此胡作非为却仍能让人们留在 Twitter 上？就是因为 Twitter 的王牌——十几年的用户和内容积累。Threads 同理——成千上万的，有趣的人都在使用这个服务，因为 Meta 的问题把这些人拒之门外，对于他们来说是极为不公平的。\nThreads 的潜在好处 Threads 掀起了一股很大的热度。这对普通用户接触到联邦宇宙显然是一大利好，想想新人大量涌入联邦宇宙实例时的困惑，或许 Threads 真的可以 Make their life easier。\nActivity Pub 的初衷，是像电子邮件一样，把社交媒体去中心化。电子邮件就可以作为 Threads 的参照，如果经营得法，Threads 完全可以成为 Gmail 一般的服务，而 Gmail 即使发展到现在，电子邮件这一协议既没有消亡也没有变成 Gmail 内部专属的协议，而 Gmail 的出现也让普通人更容易的接触到电子邮件，某种意义上降低了电子邮件的使用门槛。\n总结 Threads 尚未正式上线，对于其功过不可过早的盖棺论定。目前来看，Gmail 大概是最能窥见 Threads 未来的产品，Threads 也大概率会走上类似 Gmail 的发展路线。无论现在如何分析，都只是对 Threads 的预测，我很期待 Threads 将来会怎么发展，那么现在，就等它上线了。\n延伸阅读 Not that kind of \u0026ldquo;Open\u0026rdquo;：本文的一个参考。\nIs Gmail killing independent email?：讲到 Gmail 扼杀独立电子邮件的现状，可以一窥 Threads 的未来。\n详见https://zh.wikipedia.org/wiki/Facebook-剑桥分析数据丑闻\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-07-05T13:12:05Z","image":"https://blog-img.l3zc.com/20231216110724.webp","permalink":"/2023/07/opinions-on-meta-thread/","title":"一些关于「Threads」的看法"},{"content":"今天在图书馆借了一本沈从文的《湘行散记》，其中的一段很有意思：\n在那旅馆中住下，一面听他詈骂佣人，一面使我就想起在北京城圈里编《国语大辞典》的诸先生，为一句话一个字的用处，把《水浒》、《金瓶梅》、《红楼梦》以及其他所有元明清杂剧小说翻来翻去，剪破了多少书籍！若果他们能够来到这旅馆里，故意在天井中撒一泡尿，或装作无心的样子，把些瓜果皮壳脏东西从窗口随意抛出去，或索性当着这旅馆老板面前，作点不守规矩缺少理性的行为。好，等着你就听听那作老板的骂出稀奇古怪的字眼儿，你会觉得原来这里还搁下了一本活生生的大辞典！\n连学者都不曾听过老板骂出的古怪字眼，肯定也没能放在今天的汉语词典里，更不用说当时湘西的客栈老板，没有受过良好的教育，之所以能骂出这些稀奇古怪的字眼，除了当地的口口相传，归根结底，还是中国人从无到有，造词和遣词造句的智慧。\n前些天我做过一个中文词汇量测试和一个中文识字量测试，识字量的结果可能还行，词汇量测试的结果实在不是非常好：\n（By the way，这俩加起来可能还没我英语词汇量大）\n（这玩意不准啊，刚又去测了两遍结果都是8000个词汇量）\n之前我一直很好奇，为什么一些文字功底深厚的作家，总能给出让我眼前一亮的遣词造句的手法呢？现在我算是理解了——和英语一样，只要词汇量和识字量达到一定程度，碰到自己需要的场景就能够融会贯通，从而彻底的从单纯的使用这门语言升华为「Master」这门语言。\n在我的回忆里，从幼儿园到高中，给我们用来打好汉语基础的时间并不多，学生们总是疲于奔命，几乎没有什么机会能够启发学生们体味汉语的魅力。或许，给予学生们足够的时间与适当的引导，让学生们自己热爱上语言的魅力，让兴趣成为学生们最好的语言老师，就是语文课最理想的解决方案吧。又想到我高中的语文学习状态，所剩下的，只有哀叹矣。要是我回到语言最本真的地方，尽情感受这语言的魅力，提升自己的文字功底，该有多好！到头来，我高中三年学的语文，大多是一些我从未擅长过的应试技巧，只剩下一点点可怜的语文素养提升罢了。\n我试着去写，然这篇文章所传达出的意思，始终和我想要表达的意思有所出入，也许这正是我对中文「Master」的不够深吧。可惜那终究是过去，我能做的，也只能从现在开始，是时候好好的重新审视这一门语言，提升自己的词汇量和遣词造句的能力了。\n","date":"2023-06-29T17:16:57Z","permalink":"/2023/06/qian-ci-zao-ju/","title":"遣词造句"},{"content":"Clash 内核是开源的，我在搜索 Clash for Windows 时，遇到托管在 Github 上的项目，自然也会认为其是开源的，并且我还用它用了相当长的一段时间。\n虽然托管在 Github 上，但没有开源版权申明，也没有源代码。这种做法十分具有误导性，很容易让人误以为这是一个开源项目而放心的下载使用，直到看到空空如也的仓库才会猛然醒悟。\n这个项目拥有超过 55k 的 Stars，不知里面有多少是和我一样，被托管在 Github 上这一做法误导的呢？我想数量绝对不会小。\n为了节省成本和提高知名度，托管在 Github 上无可厚非。但对于上网代理这种敏感的工具，我会选择多留一个心眼，这种不开源的软件，我是不敢用了。\n","date":"2023-06-10T15:06:36Z","permalink":"/2023/06/clash-for-windows-is-not-opensourced/","title":"Clash for Windows 不是开源软件"},{"content":"我大概从2013年开始接触到了 Minecraft ，算下来，今年正好是我接触 Minecraft 的第十个年头。\n熟悉 Docker 以后，我着手开始把我现在跑的服务容器化，从某种意义上，这非常「优雅」——可以很方便的管理各个服务，还不用担心各种环境不兼容的问题。\n暑假将至，为了方便和朋友们联机玩 MC，遂自行搭建一个服务器，顺便进一步熟悉 Docker 和 Docker Compose。\n服务器选择 服务器有两个要求，一是性能要足够强，二是距离要足够近，目前我手头有三台机器，分别位于香港和洛杉矶，不是性能不够就是距离太远，延迟太高。所以，都无法满足需求。\n最近恰逢618，各大云主机厂商都有活动，遂购入一台某大厂轻量服务器，位于上海，2C4G5M，对于一个入门 MC 服务器来说完全足够。当然，买了这一个服务器不可能只是跑跑 MC，别的一些对带宽要求不高的服务我肯定也会放在上面。\n那么直接 Deploy，似乎用的还是 AMD 的新 EPYC，还行。\n安装 Docker 相比于一键脚本，我个人还是偏好手动安装 Docker。个人为了方便直接用了 Root，这不是最佳实践，尽可能用普通用户并在必要的时候用sudo。\n添加 PGP 密钥:\n$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg向source.list添加软件源：\n$ echo \\ \"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \\ $(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list \u003e /dev/null更新软件包缓存并安装 Docker：\n$ apt update $ apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin启动 Docker:\n$ systemctl enable docker $ systemctl start docker至此 Docker 已经安装完成，顺遍装好了 Docker Compose。\nDocker 换源 国内服务器这点非常蛋疼。\n换源还要有一个命令行的文本编辑器，于是我决定先装个 Vim：\n$ apt install vim编辑/创建/etc/docker/daemon.json：\n$ vim /etc/docker/daemon.json编辑成如下内容:\n{ \"registry-mirrors\": [\"https://mirror.ccs.tencentyun.com\"] }https://mirror.ccs.tencentyun.com是某大厂的内网镜像，内网拉取速度极快，还不计流量，不在内网里的服务器无法使用，应当换成下列镜像：\nhttps://hub-mirror.c.163.com https://ustc-edu-cn.mirror.aliyuncs.com https://mirror.baidubce.com 随后重启 Docker 服务即可完成换源：\n$ systemctl restart docker粗略部署 我部署服务的原则是先 Get it to work，再 Polish。\n对于 MC 这种 community driven 的游戏来说，社区的力量是强大的，基本上什么样的需求都能在社区里找到对应的解决方案。我直接采用了 itzg/docker-minecraft-server。\n不得不吐槽的是，这个项目的文档写得实在是没有那么友好，摸索了一下，总算是把这个服务基本的跑起来了。这时我的docker-compose.yml如下：\nversion: \"3\" services: mc: image: itzg/minecraft-server ports: - 25565:25565 environment: EULA: \"TRUE\" tty: true stdin_open: true restart: unless-stopped volumes: # attach a directory relative to the directory containing this compose file - ./minecraft-data:/data这样的 Docker Compose 配置能以最新的版本把一个基础的 Vanilla Server 跑起来，只能勉强满足几个人的联机需求，肯定也没几个人会将这样的配置用到生产环境。\n进一步调整 要进一步调整，要先确认调整的方向，否则就是无头苍蝇，误打误撞，没有目标，十分痛苦。实际感受一番后，我大致整理出了此时配置的问题，有些是 Vanilla 客户端的问题：\n版本不固定 缺少基本的性能数据 图标和 MOTD 需要调整 没有白名单 不能装插件 有正版验证(无所谓，我有正版) 有了这个方向，我就可以有目标的去调整这个 Server 的配置。接下来要做的，就是查阅这个项目的文档，做出自己需要的修改。\n固定版本 说实话 MC 的版本更新还挺频繁的，前一个版本尚未体验下一个版本就会出现。我暂时先固定这服务器的 MC 版本为1.19.4，日后充分游玩再慢慢升级。\n同时 Vanilla Server 实在是太垃圾，顺便将其换成 PAPER 岂不美哉？分别设置VERSION和TYPE两个环境变量即可。藉由 Paper 的优点，这样也同时解决了服务器插件和性能数据的问题。\n白名单 设置ENABLE_WHITELIST和ENFORCE_WHITELIST两个环境变量，即可强制服务器核查白名单。同时，不要忘记将自己加入白名单，由于服务器的 OP 会被自动加入白名单，只需要将自己提前设置为 OP 即可，设置OPS即可做到这一点。\n图标和 MOTD 设置ICON和MOTD两个环境变量即可自定义服务器的图标和标语。\n正版验证 设置ONLINE_MODE变量即可控制正版验证的开关。\n需要注意的是，关闭ONLINE_MODE后，服务器会根据玩家的离线 UUID 判断身份，离线 UUID 和在线 UUID 不同，此时添加 OP 和黑白名单都需要改用离线 UUID 进行。\n最终的 docker-compose.yml version: \"3\" services: mc: image: itzg/minecraft-server ports: - 25565:25565 environment: EULA: \"TRUE\" TYPE: \"PAPER\" VERSION: \"1.19.4\" VIEW_DISTANCE: 8 ENABLE_WHITELIST: \"TRUE\" ENFORCE_WHITELIST: \"TRUE\" OPS: \"\" ONLINE_MODE: \"TRUE\" SERVER_NAME: \"Pub of NightCity\" MOTD: \"Want to have a drink?\" ICON: \"\" OVERRIDE_SERVER_PROPERTIES: \"TRUE\" tty: true stdin_open: true restart: unless-stopped volumes: # attach a directory relative to the directory containing this compose file - ./minecraft-data:/data一些杂七杂八的事情 RCON 的连接 服务器运行后，若要在不进入游戏的情况下管理服务器，就需要用到 RCON。方法很简单，使用这个项目绑定的 rcon-cli 即可：\n$ docker exec -i rcon-cli注意将\u0026lt;name_of_container\u0026gt;换成自己的容器名。\n作者还推荐了一个叫做rcon-web-admin的项目，打算过一阵子尝试。\n安装插件 Paper 支持 Bukkit 的插件，还有自己的插件，插件数量上完全无需担心。\n我们在配置docker-compose.yml时，已经做了 bind 操作，会在docker-compose.yml所在目录的相对路径下创建一个叫做minecraft-data的文件夹，并绑定到容器的data目录，将下载好的插件.jar文件丢进./minecraft-data/plugins目录就完成了插件的安装。\n我选用了 World Edit，Grief Prevention 和 Dead Chest 三个插件，保证原汁原味的生存体验。\n最后 如果你有开服经验并且偏向手动修改server.properties，将OVERRIDE_SERVER_PROPERTIES设置为FALSE即可将server.properties的控制权交还到我们手中，这也是一种配置的手段。\nDocker 开服还是相对容易的，社区已经造好了轮子，免去了很多不必要的麻烦。稍后我会继续 play around with the server，继续探索这个游戏无限的可能性。\n","date":"2023-06-09T13:52:54Z","image":"https://blog-img.l3zc.com/Moby-Minecraft.webp","permalink":"/2023/06/build-a-mc-server-with-docker/","title":"Docker Minecraft 开服记"},{"content":"何为博客？\n广义上的博客，便是当人们将自己原本留在心里，写在日记本，取自书上的东西加以整理加工，写成一篇文章时，就自然而然的形成了博客。一开始还不叫博客，甚至还没有公开发表，公开发表了，便是博客的雏形。\n自互联网出现，这套过程被搬到了网上，就成了标准意义上的「Weblog」。\n再回头看看我写的这个标题，连我自己都忍俊不禁，为自己不假思索起的标题感到些可笑——没有上网，怎么能叫 BLOG 呢？十分荒唐，但也不全无道理。之所以把标题起的不假思索，大抵是因为郁达夫的行文风格令我不由自主的将其与博客联系起来。在我看来，郁达夫发表的这些文章，无论怎么看，都太像是一个博客。\n以下节选自郁达夫的《记风雨茅庐》：\n自家想有一所房子的心愿，已经起了好几年了；明明知道创造欲是好，所有欲是坏的事情，但一轮到了自己的头上，总觉得衣食住行四件大事之中的最低限度的享有，是不可以不保住的。\n……\n自搬到杭州来住后，于不意之中，承友人之情，居然弄到了一块地，从此葬的问题总算解决了；但是住呢，占据的还是别人家的房子。去年春季，写了一篇短短的应景而不希望有什么结果的文章，说自己只想有一所小小的住宅；可是发表了不久，就来了一个回响。一位做建筑事业的朋友先来说：“你若要造房子，我们可以完全效劳。”。\n……\n四面一凑，于是起造一个风雨茅庐的计划即便成熟到了百分之八十，不知我者谓我有了钱，深知我者谓我冒了险，但是有钱也罢，冒险也罢，入秋以后，总之把这笑话勉强弄成了事实，在现在的寓所之旁，也竟丁丁笃笃地动起了工，造起了房子。\n……\n却也涂上了朱漆，嵌上了水泥，有点像是外国乡镇里的五六等贫民住宅的样子了；自己虽则不懂阳宅的地理，但在光线不甚明亮的清早或薄暮看起来，倒也觉得郭先生的设计，并没有弄什么玄虚，和科学的方法，仍旧还是对的。\n看到郁达夫「从发表文章到找到“知音”」的过程，不禁觉得倍感亲切，换而言之，博客的初衷，不就是如此吗？不得不感叹：原来我们今天在做的事情，至少一百多年以前，甚至更早，人们就已经在做了。倘若郁达夫能上网，这篇文章肯定会出现在他的博客上吧。\n","date":"2023-06-08T18:52:26Z","permalink":"/2023/06/yudafus-blog/","title":"郁达夫的博客"},{"content":"从某一天开始我的睡眠质量忽然急转直下，正好一直想要 Apple Watch，遂直接下单一块来监测睡眠。\n这是我的第一块 Apple Watch，在此之前，小米手环、卡西欧、AmazeFit以及小米手表都在我的手腕上戴过一阵。但这块手表不一样，买了它我就相当于被苹果生态绑架，唉（bushi）。\n下单 5月11号在苹果官网下的单，选的银色铝金属表壳，耐克雪峰白配黑表带，显然不是标准配置，于是订单被送到上海保税区的工厂组装。\n一天用来组装，一天用来清关，清关后终于到了 EMS 特快专递，而且还是航空件。「这下应该马上到了」，果然，邮政的效率从来没让我失望过——南京飞到长沙用了 11 个小时，怕不是用车拖着飞机在地上走？\n总算，四天，我的快递，经过「特快专递」「空运」到了我的手上。\n开箱 当天是一个温和的天气，邮政送到校内驿站，正好我的另一个快递也到了，于是就屁颠屁颠的跑过去取快递。\n当了一下久违的爱撕机膜人，开箱撕膜真的有一种特殊的喜悦和魅力，让人上瘾。不管怎样，简单设置一下以后 Apple Watch 就这么戴上了。\nApple Watch 的整个设置真的简单，掏出 iPhone 扫一扫手表上的图案，剩下的全都交给设备完成就好。头一次见到手表设置的时候会把手机里所有的 App 对应的手表版装上去的，难怪用了这么久才把设置圆环跑完。Anyway that‘s good。\n在苹果官网上买，最大的原因是为了定制这只表的外观。官网上看不觉得，直到线下才发现不锈钢和铝金属的质感完全不是一个量级，难怪要把不锈钢边框的版本买贵这么多，真有你的，厨子。话说回来，铝金属边框也有好处，划伤没有不锈钢那么明显，要说质感的话，也勉强能算是别具一格吧，搭配某些表带可能会更好看。第一次带这种表，铝金属依然是最佳选择，只是以后有机会再买 Apple Watch，我肯定会买成 Ultra 或者不锈钢的版本。\n这几天的体验 先说结论，Apple Watch 是唯一能比小米手环还让我满意的可穿戴设备。我对穿戴设备的要求无非就是这些：穿起来舒服是刚需，这是让我愿意将之长期佩戴的基础。外观漂亮不是那么重要，但也是一个长期佩戴的加分项。功能上最基本的是健康监测与和手机的互联，不那么重要的就是系统流畅度和应用的丰富程度了。\n穿戴体感 \u0026amp; 外观 不论是智能手表还是别的手表，戴在手上或多或少都有一种「存在感」。我之前戴在手上的东西里，除了一个很轻的装饰品，唯一令人满意的是小米手环。Apple Watch 在这点上令人满意，虽然表盘很大，但戴在手上几乎感觉不到什么异样的感觉，让我愿意长期将其戴在手上。这点上它和我之前戴过的小米手表形成的对比非常强，明显感觉到 Apple Watch 在这点上下了功夫。\n外观上就不赘述了，毕竟是 Apple Watch，带出去至少不会丢人，小米手环我尚觉得不错，Apple Watch 更无需多言。\n健康监测 \u0026amp; 与手机互联 健康监测是 Apple Watch 最大的卖点，也算是我买它最大的理由事实上 Apple Watch 默认状态下监测的数据就是全天候无感的，非常舒服。但我也不得不吐槽其中一个数据——睡眠检测，不光睡前要先按睡眠专注模式不说，起来掐掉闹钟继续睡还直接不记录闹钟之后的数据，这样的体验真就是依托答辩。\n与手机互联上 Apple Watch 是所有设备里做的最好的，没有之一。所有数据全程无感同步，应用会自动唤起相应的手表版，可以和手机互相解锁，进入手机的连接范围内就从来没有连接失败过……，这些都是只有 Apple Watch 上才有的体验。\n系统流畅度 \u0026amp; 应用的丰富程度 毕竟是 S8 芯片，系统是真的流畅，怎么用都感觉不到卡顿，况且苹果的优化也很让人放心，也无需多言(iPhone 除外，要吐槽这咖喱味拉满的 iOS 我能专门写一篇文章）。\n关于应用的丰富程度，我其实不怎么用第三方应用，苹果就是这样，你在它自己的生态里，保证你用得很舒服，一旦你想跳出他那个生态，那可能就会「生不如死」。本着这个理解，我只是装了少量的第三方应用，本身也用不着这些应用，何必要去装上呢？而我装的第三方应用里，甚至大部分都是手机里应用的 Watch 版。\n","date":"2023-05-18T15:45:33Z","permalink":"/2023/05/apple-watch-series-8-hands-on/","title":"Apple Watch Series8 初体验"},{"content":"一年前，网上多了一个给自己写字的地方。过了一年，也算是写了不少字了。回想起从当时还是初中生的我懵懵懂懂的开设自己的第一个博客，到现在我真实的在博客上记录内容的第一年，不由得感叹，时间过得真快。\n为什么开站？ 旅程总有个开始的理由，但也不排除说走就走。\n这得问问当初在 Github Pages 上笨手笨脚尝试部署我的第一个静态博客的我：没有什么理由，Because that\u0026rsquo;s cool.\n于是我学了点 HTML、JS 和 CSS 。然后花了点时间搞清楚 Hexo 的主题到底是怎么运作的，跌跌撞撞拿着一个 Hexo 主题修改，竟然也勉强改出了我想要的版本。当初不知 Webpack 为何物的我竟然对着一堆 .min.css 和 .min.js 一个一个改了半天，回想起来只能一笑了之。\n做一件事情不需要理由，只要没有显著的反对理由，那就放手去做吧。\n这一年发生的一些事 2022.04：\n开站，在 Github Pages 上发出一声 Hello World。\n19岁\n~~（跟别人）~~参加一些竞赛：挑战杯，创青春，创新创业\n2022.06：\n六级出分，虽然成绩不太漂亮，但大一下就能过也算不错了\n参加了个形式主义的院学代会\n2022.07：\n拿到 Azure 学生服务器，博客框架换成 Wordpress\n早上五点起床搬到新校区，累死我了\n2022.08：\n拿到驾照\n开学，看新兵蛋子军训咯\n2022.09：\n接手学长祖传的一个团队收拾烂摊子\n院学生会里当了个副部长\n2022.10：\n给新兵蛋子新同学们办开学典礼\n核酸、核酸，天天核酸\n校运会被抓壮丁\n2022.11：\n弄了台新电脑，原来的 1715 暂时可以休息了\n11.24，逝者安息，不要沉默，不要麻木\n2022.12:\n为了防止出现更大规模的抗议，政府把我们请回家了\n阳了一次\n2022.01:\n长途旅行，徒步虎跳峡，玩丽江……\n过年部门微信群里沙雕红包接力\n2022.02：\n买了个新的显示器和手柄，这下电竞寝室了\n统计数据 我一共更换了三次统计平台，所以没有连续的统计数据，只能凑合着看看了\n由于Google Analytics很容易被屏蔽，所以只能大致的估计一下数据，先借由 Umami一个月的访问量，再大致估算一下自己的访问量，大概能得出过去一年，自己大概收获了 8000 个左右的访客，以及大约 10000 的 PV。\n对于一个刚开设一年，没有备案且没有被百度收录的网站，这已经算是不错了。\n这一年，我一共写了 27 篇文章，新增评论 18 条，平均下来，每个月写了 2.25 篇文章。\n我经历的转变 开站早期，我为了博客的 SEO 和规避敏感话题，发表的全都是些半吊子的技术博客。而现在看来，真是有些委屈了自己。\n关于自我审查，我写过一篇文章，从此之后，我不再自我审查，这下，这个博客终于发挥了它原本的用意——不是为写而写，而是有感而发，若是连自己有感而发的冲动都要被自我审查磨灭，那就更别提写别的了。\n私以为，语言的意义，在于用最精炼的话，传递最准确的信息。写文章是一场修行，写得详略得当，条理清晰，语言儒雅，是这场修行的终点。从前我写博客一定要写出字数的执念，在写了很多的啰嗦话以后，终于也放下了。\n……\n其他一些话 这一年我的博客从 Hexo 换到 Wordpress，最近又想换到 Hugo 了，但苦于已经运行了这么久，SEO 业已做了一年，再换一套博客系统实在是太过于折腾，也就 Stick with Wordpress 了。\n博客托管的地方也尝试换了很多，香港 Azure，Cloudflare，Racknerd，BandWagon。兜兜转转一圈，踩了不少坑，又回到了香港 Azure，果然平平淡淡才是真吗。\n我很后悔我没有在一开始尝试更多的技术栈，这也是我今年要做的事情。为了改出好看的主题和需要的功能我去学了怎么写 PHP，为了部署 Umami 我去学了怎么用 Docker Compose……搭建博客本就是一个学习的过程，学的越多，写的越多；写的越多，学的越多。\n最后 回顾这一年，总有一种“我怎么才做了这么点事”的感觉。\n我真的把太多的时间耗费在了公事上，于自己提升之事却做的太少。我已经对于学生会这个东西越发失去兴趣。刚刚进入大学一心想服务同学、提升自己的激情也在一次次毫无意义的形式主义活动下被磨灭，回想起来，也许当时的我真的太天真了……即使我很想在学生会有所作为，这个大学处处充斥的形式主义、官僚主义却会把每一个激情四射的人变得忧郁而只想混吃等死的行尸走肉，用现在的话来说，叫“躺平”了。\n穷则独善其身，达则兼济天下。以我现在所处的境地，我真的应该好好的考虑独善其身的问题。\n","date":"2023-05-02T22:28:18Z","permalink":"/2023/05/1st-anniversary/","title":"开站一周年"},{"content":"Stable Diffusion 是去年就出来的东西了，我没有去早点玩这个东西是因为当时我的电脑算力真的不够，我直接用 Mid Journey 的 Discord 群组凑合体验了一下，换了新电脑自然要玩玩这个东西。\n部署 我直接部署stable-diffusion-web-ui，毕竟这已经是一个成熟的方案了。\nClone 仓库\ngit clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git修改webui-user.bat：\n@echo off set PYTHON= set GIT= set VENV_DIR= set COMMANDLINE_ARGS= --xformers --medvram call webui.bat我用的 RTX 3060 Laptop 有6G显存，所以选用--medvram参数。\n执行用户，注意这套脚本要使用普通用户（非管理员）执行。\ncd stable-diffusion-webui webui-user.bat这套东西只在 Python 3.10.6 上测试过，当时用 Python 3.11 时安装过程出现了报错，如果现在用的是 Python 3.11 记得换成 Python 3.10.6，修改环境变量，然后重启电脑。\nDiffusionWrapper has 859.52M params 正常情况下，这套脚本会自动下载所需要的依赖。记得我当时在部署的时候是半夜，挂着终端代理，这个脚本跑了半天。第二天起来，依然卡在昨天晚上的地方，也就是DiffusionWrapper has 859.52M params。\n上课回来，在网上一搜索，才发现遇到这个问题的人还真不少，Github 上也有人在stable-diffusion-webui的官方库里提了 issue，看起来是hugging-face的file-download.py出现了bug，而非stable-diffusion-webui本身的问题。这是解决方案：Github上的解决方案。\n定位到\u0026lt;INSTALL_FOLDER\u0026gt;\\stable-diffusion-webui\\venv\\Lib\\site-packages\\huggingface_hub\\file_download.py的 1262 行，将其修改为：\nblob_path = os.path.join(storage_folder, \"blobs\", etag[3:])重新运行webui-user.bat，这次 webui 顺利启动了。\nstable-diffusion-webui跑在本地默认的端口号是7860，访问http://localhost:7860就可以看到这套 Web UI 了。\n找模型 部署工作至此已告一段落，但stable-diffusion-webui部署下来自带的模型生成的图片并不符合我的需求和口味，我相信大部分人也不会只用这个默认的模型，那么随后的一件事就是找模型。\n去哪找？ 起初我也不知道去哪找，于是就傻乎乎的 Google 了一下：stable diffusion anime model。别说，还真奏效了。搜出来的结果里立刻就出现了Hugging face和Civit-AI。Civit-AI还能直观的看到每个模型的预览图。\n除此之外，Reddit 等论坛上，像我一样的个人博客上，都可以看到网友们的模型推荐，用这种方式找模型也很不错。\nProblem solved.\n找到的模型 就这么去了 Civit-AI 的首页，第一眼就被counterfeit模型吸引了。\n除此之外，Anything也是非常流行的模型，也被我收入囊中。\n可以自己训练模型吗？ 先说结论：理论上来说，可以。但我这个 3060 Laptop……还是算了吧。\nStable diffusion 有几种主要的训练方法，Textual Inversion, Hyper Network, Dream booth, Lora。即使是配置要求最低的 Lora，也要求至少 8G 的显存，而 3060 Laptop 只有 6G 显存。既然如此，就不折磨自己了，还是直接用训练好的现成模型吧，感谢社区。\n开始用 一开始我在 CivitAI 上下载下来Counterfeit-V2.5模型，CivitAI 上只有一个 4.1G 的CounterfeitV25_25.safetensors文件。我将其下载下来丢进了\u0026lt;INSTALL DIR\u0026gt;\\stable-diffusion-webui\\models\\Stable-diffusion文件夹，刷新一下Web UI的模型列表就看到了这个模型，于是我就很顺利的加载了这个模型开始用了。\n这……不对啊 先来看看这个时候的生成效果：\n这……不对啊。怎么感觉我被这个模型的样图给骗了？\n来看看作者生成的样图：\n我们用的真的是同一个模型吗？可以看到我和作者生成了一张大体十分相似的图片，那是我用和作者相同的 Prompt 和种子生成的，作者生成的图片，不论是画面细节，还是色彩，都和我一开始用这个模型的时候生成的几乎完全不是一个东西，难道我是下错模型了？\n找问题 我在论坛里翻找遇到相同问题的帖子，发现其实遇到同样问题的人还真不少，大多数人都抱怨生成的图片细节不够，色彩不够鲜艳。根据我的经验，肯定是少装了些什么东西。\nEasyNegative EasyNegative 可以被看做一个 Super Prompt，用于改善模型生成图片的质量。\n谷歌 EasyNegative 第一个出来的就是为counterfeit-v2.5模型设计，于是我便下载下来使用了。链接附上：gsdf EasyNegative\nThis is a Negative Embedding trained with Counterfeit. Please use it in the \u0026ldquo;\\stable-diffusion-webui\\embeddings\u0026rdquo; folder. It can be used with other models, but the effectiveness is not certain.\n这套 EasyNegative 同样适用于 AbyssOrangeMix2，anything等模型，我愿称之为必备。\n到了这一步，我总算是知道为什么所有人的 Prompt 里总要有个EasyNegative了，原来是个 Super Prompt。\n装好 Easy Negative，生成的图片就正常多了。\n但总感觉色彩还是不好看啊……是不是还缺了什么？\nVAE 我在 Hugging Face 上看了一下，这里模型作者提供了远远不止一个的文件。\nVAE 的全程是 Variational Autoencoder。旨在帮助用户更好的渲染图像，其中也包括了色彩的部分。而不知出于什么原因，作者只在 Hugging Face 上提供了他的 VAE。\n装好 VAE，再次生成图像，这下的图像终于完全正常了。\n这几天生成的图片 这是我挑选的一些图片\n阴间的图片 其实上面最后一张图的手指已经是有生成问题的，而生成的图片里还有更阴间的图片。\n玩玩插件 这套 WebUI 还有插件可玩，这几天又心血来潮玩玩比较出名的插件。\n至于怎么安装插件，都是在这套 Web UI 的 Extensions 里。一是从官方仓库里拉取插件列表，二是自己找到插件的仓库链接拉库下载即可。\n我们来玩玩插件。\ncontrolnet controlnet 可以通过草图控制画中人物的姿势，理论上可以解决上面生成的人物阴间的问题。\n","date":"2023-04-12T12:48:34Z","permalink":"/2023/04/play-around-with-stable-diffusion/","title":"玩了几天 Stable Diffusion"},{"content":" 我有出门散步的习惯，每当累了，我就出门到处转悠。\n说到散步，这也算是一种冥想吧，慢慢走在路上，不需要考虑任何事情，感受时光流逝，四季更迭，感受这个世界真实存在的东西。\n这三年来，我身边曾习以为常的很多东西，大多是防疫相关的各个东西都慢慢消失。一开始是自然的，再到后来，就是被强行抹去了。为了防疫，这套围栏存在了三年。三年来，我们对不能从这里出去习以为常，当最近一次散步经过，我却发现，这些围栏已经化为时代的眼泪——被拆除了。\n我自高中以来就挤时间在学校散步，到了大学，这种校园内的漫步就成了常态。\n在学校里待的时间长了，总有出校门的冲动，新校区远离市中心，自然不如老校区周围繁华，但也有在市中心见不到的东西，显得更加的真实。\n这个核酸检测点，自我搬到新校区来就一直存在。它在新校区旁边不远的一个繁华的商业广场边上，只要我们要去那个商业广场，就必然要经过这里。现在这个核酸点早已不再做核酸，这个过去我们司空见惯的条幅，竟也成为了这不堪回首之时代的仅存的记忆。\n阴天适合骑车，从新校区出来沿着车少的路一路骑行，铁栏后的厂房，路边停满的卡车，新鲜的红土地，从小到大熟视无睹的苏联式住屋——离市中心这么远，自然就是工业区了。看到这番景象，想起我小时候住的地方，登时感到怀念不已。这些学习苏联建起的建筑，见证了中国的工业化。\n再往前走到了一条大路上，车并不算多，这也算是我专挑车少的路走的回报。一直往前骑，在一个小区后拐弯，就能碰到一条长长的断头路——在六车道的公路上，没有一台车的干扰，可以在路中间自由驰骋。路边零星能看到为公交预留的停靠港，只是站台并没有建好。或许是当时经济发展势头好，城市做了自己的扩张规划以后兴建了这条路吧。只可惜，现在想要城市发展到用上这条路，恐怕要比计划的晚上10年了。\n路边上有一个小村，没有被周边的宽阔马路分割成几个部分，还保持了相当不错的森林覆盖率。村口农家乐院里有一颗树，长势很好，以树干的粗壮程度来看，至少也有两百岁了吧。这么看来，这颗树逃过了大大小小的战火和政治运动，还躲过了旁边的公路和两条高铁的建设。要是城市真的发展到这里而砍掉这棵树，也得比计划的晚上十年吧。而十年过去以后又会是一副什么样的光景，这棵树能否活下去一事，突然就变得充满希望了。这么看来，这棵树竟也有不少福气。\n星期二的下午是学校的公休，用于给教师做“统战”，是工作日难得的休息时间。这难得的休息时间，领导却还开会搞形式主义，我当然嗤之以鼻。\n从这种会议上逃走，类似于旷课做自己喜欢的事。平日里整日的在学校里忙得头昏脑涨，即使放假也舍不得抽上半天时间出去玩，哪有这么好的机会能让我心安理得的出去玩？就像从喧嚣的凡尘里逃走——若是不逃出学校，恐怕我就得被迫去参加这次会议了吧。\n一路乘地铁“出逃”，原本心情的喜悦被难受取代——人太多了，多到我喘不过气来，经过侯家塘，我实在支撑不住出站，终于看到了与此前不同的景象，相对较老的摩天大楼，六七十年的老社区……我终于没有被禁锢在那个牢笼里。\n从侯家塘站一路走到白沙古井，再走到天心阁——长沙几乎没有百年社区，为了抵抗日寇的侵袭，文夕大火焚毁了这里的一切。无厘头的走着，但我并不觉得空虚，甚至一路走到了黄兴路步行街，方才打道回府。\n之所以如此钟爱散步，是为了寻回“自我”。在经历了军事化的中学教育，好不容易来到大学，却没有发现期待中知识的殿堂。疫情之后，大学把自己围了起来，昔日校园里随处可见的社会人士全无踪影。这不是一种保护，而是一种囚禁。现在的大学，像中学一样，通过围墙轻而易举的扼杀了大学本应有的无限的可能性，扼杀了“希望”。之所以如此喜爱散步，之所以会有逃出校园的欲望，就是想要在散步中，寻找无限的可能性，寻找“希望”，让自己知道“原来，除了按部就班的上课、开会，还有无限的可能性，无限的希望等着我去探索，去发现。”\n大学教育中学化，中学教育军事化，我几乎不能再找到比这更适合的形容现在教育的句子。每一次散步回来，我都感到欣慰和一种发自内心的平静，让我能更有力，更积极的去应对各种困难，即使深处这江河日下的社会，在中学化的大学校园里，我已经感受到了自己的存在和对自己的掌控。在这日渐干涸的土地上，我仍能坚守最后一片绿洲。\n久旱的甘霖，何时才能降临？\n","date":"2023-03-30T15:47:59Z","image":"https://blog-img.l3zc.com/20231011110255.webp","permalink":"/2023/03/disappearing-public-memories/","title":"散步小记"},{"content":" 《广西大叔一招把酸果变香甜 一年赚百万》\n《广西夫妇做片状腐竹 一天收入七八百》\n《山东大哥全年供应鲜嫩韭菜 年销售额3个亿！》\n\u0026hellip;\n这些是央视新闻最近的标题，明显可以看出来央视是在针对最近严重的失业问题以及“孔乙己文学”做宣传。\n关于这则买土豆的新闻，它的真实性是存疑的，1天赚9000？你真的卖过土豆吗？我本想看看网友们有才的评论，打开评论区却发现评论早已被精选，并不意外。\n且不论这则新闻的真实性，忽然如此高强度的输出这些所谓的“励志”新闻，明显就是政府面临如此严重的失业问题不作为而借官媒开脱的产物：你们失业都是你们自己不努力，关我屁事？\n当时我看到这些新闻的标题，总觉得似曾相识，我初中时做过一些历史题目，其中有两个给我留下的印象特别深刻：第一个题目引用了上面这张人民日报在 1958 年 8 月 13 日的头版头条；第二个题目则是引用了这个时期的新闻，单凭印象的话，大概是“广西农民成功将苹果树与小麦嫁接”之类，并令我们反思为什么会出现这种新闻。当初不觉得有什么，才几年过去，现在想起来，这种题目竟是无比的开放、大胆，不经感慨道：这种题目是否还能出现在今天学生们的试卷上呢？\n关于为什么这两个时期的新闻如此相似，主要便是如下几点：\n都是有目的的政治宣传 都非常浮夸而不切实际 所谓有目的的政治宣传，前者是为了转移政府制造了失业问题而解决失业问题不力的矛盾，后者则是营造“革命形势一片大好”的氛围；所谓非常浮夸而不切实际，前者相比后者倒是有了一些进步，听起来至少比 1958 年的新闻真实多了。当然，这也至少证明公众的总体认知水平相比六十多年前还是提升了。但这依然不影响他们是同一个东西的事实。\n“在社会主义制度无比优越！只要努力，早稻就能亩产三万六千九百多斤！不能亩产三万六千九百多斤？那是因为你反革命！”；“社会主义制度无比优越！只要努力，每个人都能年入过亿！不能年入过亿？那是因为你反革命！”。社会主义制度怎么会出问题呢？出了问题那也是你的问题。取得了一些成就？那是因为社会主义制度无比优越！跟你有什么关系？\n为什么一则 2023 年的新闻，和 1958 年的新闻竟然如此相似？\n若不容忍不同的意见存在，那么这个唯一存在的意见必然错误。而这个错误若持续得不到修正，造成的后果将是灾难性的。大跃进的后果我已无需多言，而今天，我们不论是宣传机器的作为、舆论环境的高压，还是其折射出的社会本质，都越来越接近于 1958 年的状态。今天的中国，不论是人口数量还是经济体量，与 1958 年的中国相比都高出好几个量级，若是对现状持续视而不见，一旦导火索被引燃，造成的后果与 1958 年相比绝对有增无减。\n兜兜转转六十多年，本以为是新时代，殊不知新时代的外衣下，还是那个荒唐的败絮。\n","date":"2023-03-25T20:59:31Z","permalink":"/2023/03/new-great-leap-forward/","title":"早稻亩产三万六千九百多斤"},{"content":"这一阵子，我将我的博客服务器迁移到了美国，然后采用了 Cloudflare 作为我的全球（除了中国）CDN。\n我的博客原本架设在香港微软云上，而且服务器是我以学生身份免费领取的，可最近，这台服务器的表现越来越不尽如人意。香港地理位置非常好，网络也发达，理论上把博客架设在这里，可以给中国大陆的访客非常良好的体验，事实上，在我的博客开设初期，中国大陆的访客体验确实很好。\n之所以说体验良好，主要是因为这三个方面：性能够用，大陆直连，免费。\n所谓性能够用，但仅仅是勉强够用的水平。微软云针对学生免费的 B1S 实例，1C1G，硬盘 IO 经过实测只有几十mb/s，不说是金刚盘，也可以算是石头盘了。就这个性能，跑个 Wordpress 都费劲，我将博客缓存后方才勉强应付了架设初期的访问量。\n所谓大陆直连，其实这仅适用于电信。在我刚拿到这个服务器的时候，实测 Traceroute 全程 59.xx 开头的 IP，妥妥的 CN2 线路。至于其他两个运营商就没那么好了，全都走东京 NTT 线路。\n这么看下来，免费反而是最货真价实的优点了。微软云免费的学生额度有 100 刀一年，据官网介绍，这 100 刀用完，并且你还是学生，那么第二年可以再次申请。相当于是免费承包了学生时代的服务器。\n当时刚拿到服务器的时候，微软云的这三个优点让我没有不选择它的理由，但随着我的博客运行半年多，这台服务器的问题就慢慢开始突出了。\n首先就是让人非常难受的性能问题：如果说1C1G还能勉强说得过去的话，那么这个石头盘就真的太难受了。随着我的博客访问量逐渐增加，也就自然而然的引来了各路 Bot 的骚扰。这台服务器的综合性能甚至弱到了，只要有人用 1 秒一次的频率爆破我的后台，我的网站就会接近瘫痪。即使不瘫痪，TTFB 也会比正常情况下多1秒以上。\n性能问题甚至已经影响到了我的 SEO ：我已经多次收到邮件，提示我网页的打开速度太慢，需要优化，与此同时，我博客上来自谷歌的流量也显著降低，大概是因为搜索权重因为打开速度降低了不少。\n即使性能如此糟糕，在相当长的一段时间里，我也还是通过缓存等办法勉强维持了网页体验的整体质量。但微软云随后进行了一波令人吐血的操作：换线路。原本电信直连的香港直接并入了东京 NTT（刚去看了一下竟然变成绕新加坡了？），Traceroute 一下全都变成了 AS4134，CN2 直接变成 163。真有你的，微软云。这下，Azure 的网络优势也几乎尽数失去。\n就算不好用，但是它免费啊，要什么自行车？\n免费真的那么好吗？微软也不是慈善机构，能在香港这种热门的地方提供免费的服务器属实已经非常良心了。我还能要求什么呢？**我还能要求什么呢？**通过前面的换线路事件，我大概也见识到了，对于免费的产品，我们真的无法要求什么，甚至连最基本的要求都不行。不光如此，只要微软政策一换，我就立马无法继续白嫖。\n在我的博客上线半年多以后，我发现，我已经没有理由再选择白嫖微软云学生机了。\n那么，物色一个新的机器，成为了必要的选择：\n起初我想寻找一个香港 CN2 直连的 VPS，但看了看价格，还是算了吧。最经典的搬瓦工，香港 CN2 要 899 刀一年，这显然不是我这个小破站能承受得起的。即使是更便宜的美国 CN2，仅仅 1C1G 的配置，也需要 49刀一年。换算成人民币需要 350 元一年。\n更要命的是，CN2 网络因为承载量小，防御能力几乎没有，这就意味着我的博客要是遭到 DDOS 攻击，几乎完全无法防御。要是硬是想要防御，就得上 Cloudflare 这一类 CDN，但这样，CN2 线路的优点就不复存在。\n实现快速似乎需要投入太多成本。这时我开始问自己，我真的需要很快的速度吗？我的访客，大部分都有挂代理的能力，即使是搜索引擎流量也大部分来自 Google。这样一来，Cloudflare 带来的直连速度的劣势得到了很大的缓解，而且，我还可以借助这一点过滤一些低质量的访客。\n牺牲大陆直连的速度，加速挂代理访问的速度，却又不完全被大陆封锁，同时不需要带着狗牌自我审查，这不正是我想要的吗？\n","date":"2023-03-18T19:23:55Z","permalink":"/2023/03/why-i-moved-to-cloudflare/","title":"我为什么迁移到了Cloudflare"},{"content":"前些天看到了阮一峰老师的旧文章，不由得感叹江河日下。\n当时阮老师的评论尤为犀利，再看看今天的阮老师，博客变成了《科技爱好者周刊》的发布地，再也不见这些犀利的评论。我并不觉得科技爱好者周刊有什么问题，相反，我个人也是阮老师博客的订阅者，我也很喜欢阮老师的博客。只是，阮老师从写真正的博客变成专注《科技爱好者周刊》，几乎意味着其不再发布令人眼前一亮的、富有创造力的个人观点与感想，而只是按照一个模板，半机械性的堆砌内容。\n从这个意义上来说，阮老师的博客已死。\n回头一想，我自己进行自我审查也已经有了相当长的一段时间，小到上网评论，大到高考作文，只要涉及敏感问题，我的第一反应是避而不谈，如果不得不谈，我也会尽力炮制一个“安全的”观点，替代我的真实观点。这种做法在我读高中时最为常用，我将其理解为“明哲保身”。\n可怕的是，在经历了多年的自我审查后，我为时间如此长的自我审查付出了沉重的代价：我似乎失去了对社会事实评论的勇气，甚至能力——高中时的我很少在写作文时发表自己独到的见解，因为那些见解涉及敏感问题；微博上，我从不为任何时事发声，因为我担心这会为我带来不必要的麻烦；即使在不受审查的平台上，我也需要在发表自己的观点时鼓足勇气，因为我担心被大陆的警察“开盒”。\n久而久之，我的高中作文变成了死板的套式，再也不见任何亮点。无论在何处，我不再抛出独到的见解。\n这不是因为我不想，而是时间足够长的自我审查后，我对于这些事情评论的能力已经丧失。即使我已经放弃自我审查，短时间内我依然无法写出一针见血的评论。这种“失能”甚至如癌细胞一般，不受控制地扩散到了我更多的领域，这些领域涉及的方面非常广，从学习到生活，几乎无孔不入。\n审查是一件非常可怕的事情。\n有的人认为，审查只是确保社会稳定，防止“有害”内容产生的必要手段。而真相是，当人们进行了足够多的自我审查，人们就失去了没有被审查时的创造力和勇气。\n当戴了一生镣铐的人忽然被释放，他看似自由的步伐也不会超过昔日镣铐的束缚。\n别再自我审查。\n","date":"2023-03-11T20:47:50Z","permalink":"/2023/03/no-longer-prosper/","title":"别再自我审查"},{"content":"众所周知，Azure 的服务器在部署的时候只会分配一个动态的 IPv4 地址，在其上架设的网站自然也不会支持 IPv6。为什么花这么大的劲折腾网站的 IPv6 支持？这是一种必然趋势，当然，也是为自己的网站 Future Ready。\n为服务器申请一个公网 IPv6 地址 于是我们首先要为服务器申请到一个公网 IPv6。\n微软对 IPv6 的重视程度似乎没有那么高，在不久前，为服务器添加 IPv6 还需要动用 Powershell 部署 Load Balancer 实现，具体有多复杂可以看看这篇文档，属实是非常劝退。\n好在现在微软已经为 Azure 引入了原生 IPv6 支持，但部署起来依然相对繁琐，而且相当的不友好，之前甚至连文档都没有，不过现在终于把文档给补上了。\n添加 IPv6 地址空间和子网 根据文档，首先为现有的虚拟网络分配一个子网空间：\n登录到 Azure 门户。 在门户顶部的搜索框中，输入「虚拟网络」。 在搜索结果中，选择「虚拟网络」。 在「虚拟网络」中，选择你自己的虚拟网络。 在「设置」中选择「地址空间」。 选中「添加其他地址范围」框。 输入「2404:f800:8000:122::/63」。 选择「保存」。 在「设置」中选择「子网」。 在「子网」中，从列表中选择子网名称。 在子网配置中，选择「添加 IPv6 地址空间」框。 在「IPv6 地址空间」中，输入「2404:f800:8000:122::/64」。 选择「保存」。 申请一个公共 IPv6 地址 在搜索栏里搜索「公共 IP 地址」，然后按以下配置新建一个 IP：\n设置 值 IP 版本 选择「IPv6」。 SKU 选择「标准」。 IPv6 IP 地址配置 名称 随意 空闲超时(分钟) 保留默认值「4」 订阅 选择你自己的订阅 资源组 选择你的资源组。 在本示例中，资源组的名称为 myResourceGroup 位置 选择你服务器所在的位置，例如我的 East Asia 可用性区域 选择「区域冗余」 将 IPv6 添加到机器上 打开机器的管理面板，停止服务器。转到网络选项卡，在「网络接口」边上打开你的网络接口。\n然后，在网络接口的设置里选择「IP配置」选项卡，选择添加一个 IP 配置。并在弹出的选项里填入以下内容：\n设置 值 名称 随意 IP 版本 IPv6 专用 IP 地址设置 分配 保留默认值「动态」 公共 IP 地址 选择「关联」 公共 IP 地址 选择你新建好的 IPv6地址 完成后确定保存就可以启动服务器了，这时你的服务器已经拥有并可以使用 IPv6 地址。\n修改 Nginx 配置 如果这时使用纯 IPv6 网络环境访问部署在这台服务器上的网站，发现还是无法访问，就需要修改 Nginx 配置。\n将以下两行插入到 Nginx 配置的 Server 块中实现监听 IPv6 的功能。\nlisten [::]:80; listen [::]:443 ssl http2;插入正确的Nginx配置文件看起来应该类似这样：\nserver { listen 80 default_server; listen [::]:80 default_server; listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name wordpress.l3zc.com www.l3zc.com l3zc.com; index index.php index.html index.htm default.php default.htm default.html; root /www/wwwroot/wordpress.l3zc.com; if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 permanent; } ssl_stapling on; ssl_stapling_verify on; #省略以下部分 ...... ...... }修改网页内容 此时托管在这台服务器上的网站已经可以通过 IPv6 访问了，但此时使用纯 IPv6 打开这个网站很有可能会得到一个不完整的页面。这是因为你的网站上还有外挂在 CDN 上的资源：例如图片和一些前端文件，而 CDN 不支持 IPv6 访问。这时就要根据具体情况替换网页内容上的外挂资源。\n我这里的实际情况是：\nCDN 前端资源库支持 IPv6 访问，无需作任何修改。 大部分图片托管在腾讯云对象存储并外挂在网页上，经测试这项服务默认并不支持 IPv6。 其它资源均通过服务器本身加载。 搜索得知腾讯云对象存储有一个双栈域名，使用这个域名即可达到目的。于是就开始了批量替换：登进 WP 后台，每个文章打开代码编辑器，把图片的链接批量替换，更新文章。一气呵成。再次打开文章测试，所有的资源都正常加载。\n更简单直接的方法？ 如果你的网站在大陆已经备案，那么添加 IPv6 支持的最简单办法就是全站 CDN，上述内容全都不用考虑。\n不过这种办法还需要想到其它的问题，例如，怎么设置缓存刷新周期，不过这就不是这篇文章考虑的问题了（才不是因为我没有备案用不了大陆的 CDN）。\n","date":"2023-02-02T14:40:19Z","permalink":"/2023/02/enable-ipv6/","title":"为Azure服务器上运行的网站启用IPv6支持"},{"content":"这是我 2023 年第一次旅行，准确的说，是这三年闹剧过去以后的第一次真正意义上的旅行。\n这次旅行从长沙出发，最远到达丽江，来回实际行驶的里程超过 4600 公里。什么概念呢？作为对比，从哈尔滨到海口的总里程是3800公里。\n规划 这么长的行程，自然要仔细规划。\n关于国内的地图不好用这件事我几乎无力吐槽。2010 年时，我曾踏上一次长途旅程——从海南到三亚，当时我们使用还在大陆运作的谷歌地图规划路线。而今天使用百度地图规划路线，规划的体验却和十几年前的谷歌地图相差甚远。谷歌地图因为失去在大陆采集数据的资质停止更新，甚至想用都用不了。无奈只能使用勉强用手机规划一条路线。\n一开始我对这条路线应该怎么走并无头绪。于是我请出了 ChatGPT 为我献上旅行计划一则：\nChatGPT 还真就给我制定了一个看起来像模像样的旅行计划：\n看起来是不是非常靠谱？要真靠谱我早就把这一部分一笔带过了。\n第二天直接从凤凰开车开到大理？然后在云南和各市之间反复横跳？我严重怀疑 ChatGPT 对中国地理的了解程度。不管怎样，这份旅行规划过于离谱，肯定是不能用的。不过，其中列出的景点倒是算有参考价值。\n用 ChatGPT 规划行程的计划泡汤，无奈只好自己慢慢摸索。本次旅行的主要目标是去云南度假，避开长沙的寒冷。所以，赶在下一轮寒潮之前到达云南是很有必要的。驾车从长沙到昆明有两种大体方案：大体上贴着沪昆高速，以及先走一段杭瑞高速。由于杭瑞高速正好经过凤凰，一个不错的歇脚点，并且后面的行程更好安排，选择这条线路作为大体上的行程显得更加合适。\n于是根据这条路线，我大致规划出了这次到达云南之前的行程。\n出发前 2022 年的夏天，我顶着酷暑拿到了驾照。\n考完驾照以后一直在开车，但开过的路况却仅限于市内路况。无可奈何于学业和这三年来疫情防控的闹剧，我们一直在忍受。\n当时还处在感染大潮轰轰烈烈的时期，各种新闻与小道消息与社交媒体，无一不在反映一件事：那就是很多人都染病了，多到能够让街上的人甚至比所谓的“放开”之前都少上不少。人们都在家里养病，谁有心情出去旅游？\n不过那时我和我的家人都已慢慢从感染中恢复过来，我们感到的已经不再是肉体上的疲倦，更多疲倦来自精神上。趁着这一轮感染潮消退之前，也就是三年以来最大的一波旅游潮到来之前，我们应当尽快将计划付诸实践。\n后来的事实证明，这是一个正确的选择。\n买点东西随后出发 出发前的物资补给很简单：\n3桶泡面 3盒自热米饭 一箱矿泉水 6瓶红牛 其他一些零散的零食 以及最后的把油加满，直接走人。\n出发 凤凰古城 这是我第一次开上高速，当然，实习期内只能在经过实习期的老司机陪同下上高速，好在高速上并不是很堵。第一次上高速很容易累，于是乎在开了一个小时的时候进服务区换人了，在换人以后边聊天边开的时候。高速上忽然堵车，还好雷达起了作用踩了一脚急刹。在吃完午饭简餐后一口气到达凤凰古城，很累，住在一家还不错的店子里，只可惜这家店位置不是很好，离景区有15分钟路程，只能在晚上去吃晚饭以后顺便看看夜景。尽管之前来过一次，夜景没有让我失望，虽然凤凰的店在3年时间里倒闭了不少，但很多不以盈利为目的，底子扎实的小店还是保留了下来。文艺气息很浓，很多有趣的店藏在深深的角落，文静，安宁。我很后悔，我没能抓住机会，去其中之一喝几杯杯咖啡或酒，坐在一个角落里慢慢休息，慢慢去感受这座古城。\n吃饭的时候喝了点，晚上在古城里散步，繁华的 Tourist Attraction 旁，喧闹的古城商业，安静的小巷里，时不时可以发现店铺转让的公告。上一次来凤凰古城是在2015年，当时正值劳动节，城内人山人海，一眼所及的店铺无不生意红火。现在同是旅游高峰期，人流却不到2015年时的一半。\n凤凰古城在2015年前后经历了两次较大的挫折：第一次是2013年时臭名昭著的古城收费事件，在2016年结束。第二次便是这一次的三年疫情了。\n两次事件都对凤凰古城的客流量造成了毁灭性的打击，其中以2013年古城收费事件为甚，这次人祸造成的客流骤减甚至直接导致凤凰古城内爆发示威游行。这是当时的一篇报导：\n当时的报导还真是正常且真实得多，不过这都是另一个话题了。\n好在现在生活正在慢慢恢复正常，凤凰的客流量也得以恢复的机会。总让我想起一句来自 Cytus 2 背景图的一句话：\nKeep moving on.\n即使天塌下来，生活也还要继续。生活无论如何都要恢复正常，人们努力的将塌下来的天支撑起来，在第二天早上，大家起床，喝到了早晨的第一杯咖啡。\n镇远古城 从凤凰出发，不久便进入了贵州铜仁，转眼间所有的车牌都变成了“贵C”开头，这对我们来说还有些不习惯。虽然自我们从长沙出发以来海拔一直在缓慢上升，但因幅度不大，我们并没有明显感受到。不过，自进入贵州以来，由于北风被山脉挡住，天气逐渐放晴，这才让我们意识到，我们已经穿越了省界。\n凤凰到铜仁的路程比较顺畅，到了中午饭点时，我们赶到了铜仁。\n这是铜仁解放路上的一个步行街，只要在中国生活过，都知道一个城市的解放路是这个城市最繁华的地带，然而导航依然无视堵车的风险，将我们带到了这里，正值中午，我们也决定在此歇脚吃饭。\n铜仁的车牌以“贵C”开头，其在贵州省内的地位与桂林于广西、湘潭于湖南的地位类似，在城市建设方面，铜仁自然不会差。铜仁原名“铜人”，相传元朝时有渔人在铜岩处潜入江底，得铜人三尊。《大明一统名胜志·贵州名胜志》卷四铜仁府：“元置铜人大小江等处蛮夷军民长官司。盖境西南有大江，西北有小江，当其合流之处，崖高数十仞，挺然立于中流，相传有渔者没其底，见三足如鼎，得铜范儒、道、释三像，故以铜人名崖。及置长官司，始易‘人’为‘仁’。” 张澍《续黔书》卷三：“元始置铜人大小江等处，其曰铜仁者，则明洪武初改之之误也。”\n铜仁有相对悠久的历史，顺理成章成为了一座旅游城市。其周边的梵净山，思南石林都是值得一看的景点。奈何梵净山乃避暑胜地，而这次来的时间是冬天，并非一个好的参观时间点，遂放弃参观。\n如果你想在铜仁解放路上找到一家具有当地特色的餐馆，可能会有些失望。和许多城市一样，解放路上大多是商业店铺，老字号饭店由于承担不起高昂的房租，已陆续搬至租金更便宜的地方。这条路上唯一醒目的饭店居然是麦当劳，无奈之下，我只好进去买了点东西填肚子。\n在铜仁短暂停留后我们再次出发了，然而，这一次的行程可就没有那么顺利了。在我看来，从铜仁到镇远，才算真正的进入贵州。这一段路十分颠簸，像是原本想要提质改造成宽阔的公路，但因资金链断裂而停工，最终被过路的大车压得坑坑洼洼。在这段路上，我们的平均车速不超过每小时10公里，其难走的程度可想而知。\n只要最终看到的风景足够好，再难走的路都不虚此行。然而，镇远并没有给我惊喜。我可以明显感觉到这里原来只是一个普通到不能再普通的小镇，将苏联式的房子加上马头墙，刷上白漆，贴上“青砖”，就包装成了一个古镇。镇上的人文气息少之又少，完全不能给人一种沉浸感，没有大城市的繁华，却依然非常浮躁和喧嚣。这不禁让我想要以这一句话评论这个古镇：取了大城市糟粕，却未能学到大城市的精华。\n唯一值得看的，是环绕在这个“古镇”周围的山水。\n镇远毕竟地处偏远的贵州，其景色、文化底蕴、旅游氛围完全不能与湖南凤凰相比，奇怪的是，镇远古城竟然被评为5A景区，而凤凰古城仅仅被评为 4A 景区，难道是因为凤凰古城的收费事件？\n镇远县位于贵州东部，属黔东南苗族侗族自治州。从地图上看，东邻的湖南湘西中部有一凸出部分，恰像一个楔子，插入贵州东部凹处。镇远县就处在这个凸凹结合部上。不知哪朝哪代哪位先生称镇远为湘黔门户，这一点上，与湖南凤凰无二。据史书记载，镇远古称“竖眼大田溪洞”，属“鬼方”。从夏到商，世居着荆、梁二州的西南，泛称“荆蛮”。追本溯源，古代的镇远，地处历史上“五溪蛮”和“百越人”聚居的结合部。宋绍定元年，公元1226年，赐名镇远州，“镇远”这一名称从此沿用至今。镇远有被誉为有“长江三峡之雄伟，桂林山水之秀丽”的国家风景名胜区舞阳河三峡景区，也有可同四川九寨沟媲美而被古人惊叹为“或不得游则有为恨者矣”的铁溪风景区,有广为历代名人盛赞的镇远二十奇景，还有野趣神韵堪与湖北神农架相比的高过河幽地。除此，镇远还有众多千奇面怪、千姿百态的溶洞兀峰、奇石奇景荟萃。\n看到这一段话，我自然的联想到我的出生地永州。永州拥有丰富的文化底蕴，柳宗元被贬永州时，永州的美景待他不薄，“千山鸟飞绝，万径人踪灭。孤舟蓑笠翁，独钓寒江雪。”。欧阳修游览零陵时，亦曾写下“画图曾识零陵郡，今日方知画不如。”的吟咏。不仅如此，永州的自然美景也毫不逊色，九嶷山乃属国家森林公园，而其中的炎帝陵更是极富竞争力的景点，加之永州毗邻桂林，有世界级的顶级旅游目的地为伴，发展旅游业不说不费吹灰之力，也绝非难事。\n小城永州自有小城的格调，泛舟潇湘，每天下午在河边悠闲钓鱼的人不计其数。富有文艺气息的小店散落在此，藏在永州的各个小巷。这是一个生活节奏缓慢的慵懒城市，活脱脱一个逃避凡尘的绝佳地点。\n奈何，永州并未能抓住这些绝好的发展机遇，错过多次发展旅游的风口，在毫无区位优势的前提下，发展的重心竟然落在工业上，沦为一个不伦不类的城市。\n镇远与永州相比，并不是什么好地方，既没有永州古时零陵郡的建制，也没有永州湖广要道的区位。甚至不久前还仅仅只是一个普普通通的小县城，在相对短的时间内却成为5A级景区。相比之下，永州的旅游体验比镇远有过之而无不及。\n这趟旅途让我充分的体会到一点：冲着5A景点去旅行，还不如抽签决定去哪个景点，旅游体验决不比5A景点差。\n贵阳 一大早离开镇远古城后我们赶往贵阳。铜仁到镇远的烂路令人印象深刻，在走国道还是高速的问题上算是让我们坚定的选择了全程后者。\n于是我们很顺利来到了贵阳。\n作为省城，贵阳自有光鲜亮丽的一面。但也免不了“千城一面”的单调。这是我在贵阳黔灵山顶的景观亭拍下的贵阳城景，其实，在岳麓山上鸟瞰长沙，你也会看到大同小异的景色：光污染的摩天大楼，大道平整宽阔，小道穿城而过。无非如此。\n从酒店到黔灵山的路上遇到几个施工地点。这也是在别的城市能够看到的：不统一的城市规划导致每三五年，城市道路挖了又填，填了又挖。不光阻塞交通，切断人行道，还有噪声和烟尘污染。总让我感觉回到了前几年长沙地铁还在兴建时，我家周边的环境。\n贵阳在网上给我留下的另一个深刻印象是花果园，号称是全亚洲最大的住宅区。于是，即使在贵阳只能停留一天，即使开车一上午累的只想趴在酒店休息，我还是在从黔灵山返回酒店后不久搭公交车前往了花果园。\n花果园亚洲最大住宅区的名号名不虚传，可以说简直就是黑压压一片。\n摩天大楼实际上是反人类的，它并不宜居，同时会造成非常多的额外问题。然而在贵州花果园，这样黑压压的摩天大楼数以百计。堪称世界上最大的“人造灾难”。\n以色列 Isaac Meir 教授曾经写过一篇文章，系统地总结摩天大楼的各种缺点，简单的总结下来有如下几点：\n能耗巨大，摩天大楼是天然的温室，加之内部人员与器件所散发的热量，致使其必须依赖大型空调散热 成本太高，建造摩天大楼所需要的成本比一般高楼多得多。 安全问题，如果发生紧急情况，电梯无法使用，高层的人员如何撤离到地面？ 社会问题，摩天大楼会对基础设施造成巨大的挑战，下楼的麻烦也减少了人们出门的频次。 既然明知摩天大楼有如此多的缺点，为什么人们还是热衷于摩天大楼？为什么一栋栋摩天大楼总能得到足够多的资源拔地而起？显然不是因为中国和沙特阿拉伯一样钱多到没处花。\n不只是在贵阳，而是全国各地，尤其是近几年经济不景气，烂尾楼从来是不缺的。上面图中出现的花果园双子塔，虽然看上去光鲜亮丽，实际上已经沦为一个烂尾花瓶。\n2015年封顶的建筑，下面的商业层却是完全的废弃状态，充斥居无定所的游民，场面一度让我认为我在赛博朋克的烂尾楼下。而旁边供开发商高层享乐的花果园白宫，则是外表上就恢弘大气，内部据透露亦极尽奢华。\n倒是大楼的另一边，开着一家类似酒店的场所，让我还能找到这栋大楼的一点实际用途。\n远看一栋大楼，近看败絮其中。\n政府支持求政绩，开发商们饱私囊。\n银行放贷有恃无恐，来日崩盘有人来救。\n那么究竟是谁来救？只有政府的巨额税收。\n建设摩天大楼需要耗费的大量资源，一切都因为腐败而被腐蚀成一个空壳。只有那些开发商们赚足了钱，政府也因此获得了政绩，银行也收获了利息。只有我们，要为这一切荒谬的投入买单，却享受不到实际的好处。\n黄果树瀑布 从花果园回来以后，一夜无话。\n第四天是赶路的一天，这一天的赶路还算顺利。由于冷空气加速南下，我们决定赶在冷空气之前加速前往下一站。这样一来，这一天就需要直接从贵阳赶到昆明。\n贵州大部分是山区，旅游资源实际上非常丰富，自然风景有前面提到的梵净山，黄果树瀑布等，人文资源一样也不缺，西江千户苗寨等地在来贵州之前我就已经耳熟能详。如果只是在贵阳住一晚上，相当于直接略过了贵州的旅游资源，即使时间很赶，我们还是决定去黄果树瀑布看看。\n一大早从酒店出发，边开车边啃面包，一路无事到达了黄果树瀑布景区。碰巧赶上为了恢复旅游，贵州全境景区门票免票。花了三个小时在黄果树景区游玩。\n从景区出来时碰到了一位景区工作人员，他给我介绍了黄果树景区极盛时的状况：黄果树景区本身就有完善的接待设施，接待能力很强。旅游高峰期时，一天的接待量可达到六万游客。此时，景区内观光巴士车来车往，栈道上人山人海，水泄不通。黄果树景区内著名的景点水帘洞，甚至需要排队1小时才可游览。我在参观时，发现去往水帘洞的路上，出现了一个标示牌，上书“因最大安全承载量问题，水帘洞景区需要排队进入，预计需等待一小时”。而今天的黄果树景区，游客稀少，进入水帘洞完全无需排队。据称，即使免门票，目前的游客接待量也只有每日三千。\n从黄果树景区出来时会经过一段有意设计的路线，引导你经过景区的纪念品商店区。这个商店区非常庞大，从其使用的痕迹依稀可见往日的繁荣，如今到处都是关门歇业、门面转让的告示，只有寥寥数家商户苦苦支撑，盼望政策放宽后的人潮，只可惜，折腾了这么久，大家口袋里真的还有钱来消费吗？\n之后便是与寒潮赛跑快马加鞭赶往云南。贵州与云南交界的山区本身就对寒潮起到了很好的阻隔作用，又因为焚风效应，实际上几乎完全抵消了寒潮的影响。\n所谓云南有所谓“彩云之南”的称呼，进入云南，真的就如换了一片天。天空很蓝，而且是以周计算的，连续的蓝。\n云南的日照时间很长，可以算作是“中国的阳光地带”，从长沙到昆明，感知相当强烈。在长沙生活的人盼着出太阳的时候，昆明人大抵在盼着下雨。\n下午五点，我们还在路上，太阳依然很高，实际上我们不光在和寒潮赛跑，也在和太阳赛跑。\n我们几乎全程在向西开，跨越的纬度几乎足以制造一个小时的时差。地球是倾斜转动，北半球正值冬季，越往南走，白昼就越长。昆明的下午5点，几乎是长沙的下午三点。\n抚仙湖 抚仙湖是云南第三大湖，和省会昆明只有一山之隔，水质非常清澈，是昆明人的度假胜地。\n《地理·中国》曾拍过一期节目讲解抚仙湖，链接附上：https://tv.cctv.com/2015/05/30/VIDE1432970526664662.shtml\n抚仙湖周围不乏开设小吃摊的本地人，藉由抚仙湖连续的好天气，以及周围宁静的氛围，小吃和音乐总能让我忘却很多生活中的琐事。若是要我给这种氛围一个评价，我将回答：还会再来的。\n这是拿不拿在当天发布的新歌，氛围真的是可以影响心情的魔法，而心情是能让歌变得无限好听的魔法。\n虎跳峡 虎跳峡是世界上最深最大的峡谷之一。\n网上能找到的关于虎跳峡的评价里，很大一部分人自述来的动机是因为国家地理的安利，然而我在网上搜了一圈，并没有找到国家地理相关的文章，也许是某期节目吧。\n虎跳峡的高路徒步线路是世界级的徒步线路——强度不大，风景很好。\n这条徒步路线相当成熟，几乎是每逢岔路，必有路牌。路牌通常是客栈老板所设，其上也是他们客栈的名字，简单来说，就是广告。当好几个客栈，乃至十几，几十个客栈在同一个地方打广告时，这些广告竟然也像是被施了魔法，变得有趣了起来。\n虎跳峡中途有一客栈，名曰 Halfway。疫情之前诸多国际友人来到这里，欣赏其观景平台的“日照金山”，久而久之，这里就变成了世界著名的观景平台。而因其位置非常好，在这里蹲厕可以看到雄伟的虎跳峡绝壁山峦，于是大家都给它一个笑称，曰“天下第一厕”。\n在湖南生活了这么久，几乎不知道干冷是什么感觉。每逢湖南降温，其必然是又湿又冷，气温还没降到零度，湿冷所带来的“魔法攻击”就能让人赶到寒冷无比。直到这次徒步，路已结冰，一看天气，才察觉温度已到零下，我方才体会到干冷的感觉——原来，干冷是只需要穿点衣服就能挡住的。\n丽江 Fun fact：虎跳峡在香格里拉，不是丽江！\n丽江是全国旅游发展很早的城市，毕竟是江泽民时代就已开始发展。\n丽江本身的城市建设，我是觉得没什么问题的。本身没有高楼大厦，规划也还算整齐，活脱脱一个宜居的城市。而丽江古城，商业化气息就非常严重了，甚至有肯德基和麦当劳。\n此地气候非常好，我们在此游玩的时间里，天气非常适宜：在高原上，天空都矮了下来，蔚蓝无暇。空气适宜，因为污染被高山阻挡——作为一个旅游城市，丽江几乎没有什么高污染产业了。\n丽江古城内有一些自古城成为景点就一直开下来的老店，味道和环境都属于上乘。不知怎么的，高原的食材就是比平原上产量少，质量却比平原上的视频高不少。在丽江古城，沐浴在阳光下，享用高原醇美的食材。抑或在夜晚到来，在古城熙熙攘攘的氛围里慢慢用餐，都是不错的选择。\n古城总是有一种魅力，看见古城的繁华，总能让人忘却一切现代社会的糟粕，令人回到过去，享受当年美好的繁华。\n在这里，你会发现，时间并非总是线性发展。\n城内之精华是木府，顾名思义，即木家府邸。木府是当年木氏土司修建的府邸，崇祯十二年（1639年），徐霞客游至丽江时，曾在其游记中描述木氏土司府“宫室之丽，拟于王者”，足见其规模壮大。\n木府的规模壮大，得益于当年中原王室的支持。处处都是“敕造”，足可见到木氏土司和中原王室的关系良好。\n土司的地位约等于藩王，皇帝坐的是龙椅，藩王就坐一把“虎椅”\n1996 年，木府在主要来自世界银行的贷款下被修复。能够在当时的经济水平下修复成如此水平，已经非常不容易。\n登上高处，可以欣赏到几乎半个丽江古城。\n在丽江古城，能明显感觉到来自国外的客流正在慢慢恢复，起码，你能在街上看到前来参观游览的外国人了，虽然肯定不如三年前的水平，但至少正在慢慢恢复。\n听本地人说，丽江古城相当于丽江的市中心，是夜生活的好地方。我特别留意了这一点：夜晚来到丽江古城，只见夜店、酒吧到处开张，十分损害古城的氛围。虽说酒楼瓦肆和迪厅夜店本质上并无区别，但我相信来到这里的外地人，都是受够了大城市的喧嚣，想来感受古色古香的氛围的吧。可惜，晚上经过迪厅密集的古城街区时，人们便会感受到这种格格不入，大失所望。\n大理 云南曾经有过一段政权叫做“大理国”，在两宋时期存在。疆域落在今天，遍及中国、老挝、缅甸、越南，当然，大部分在中国。大理即是大理国的首都。\n（图片来自维基百科）\n首都的建制自然豪华，而我们到达大理时，过年的人流已经将大理挤得水泄不通，在大理歇脚的计划只好作罢。\n古城周围停车总是非常紧张，就拿我们在大理短暂停留的时间来说，吃了个中饭，花了大概半个小时，却被迫在每小时10元的停车场停车。这个价格，已经比肩闹市中心的紧俏停车场了。也许是我们赶到大理时已经接近新年吧。\n大理三塔，佛教建筑也。就在214国道旁边，还是非常著名的景点。这里在大理国时期扩展为890间屋子、11400尊佛像、三阁、七楼、九殿及百厦，被称为“佛都”。大理国22代国王中，就先后有9位到崇圣寺出家为僧。\n你大概也在网上听过“虽不信佛，但敬佛”的人，我大概也算其中之一吧。此次参观，也算让我更加敬佛了。\n回程 在昆明过年 赶到昆明的那一天正好大年三十，于是我们顺理成章的在昆明过年了。\n省城的接待能力普遍不会很差，昆明也不例外，加上非常多的人在春节时实际上会离开省城回到自己的家乡过年，省城的接待压力反而会有所减少。于是我们便可以一个相对便宜的价格住下来。\n前面提到过昆明是全国全年日照时数最多的城市之一，现在看来，名不虚传。我们在此过年，很大一部分原因是这里的气候——夏无酷暑、冬无严寒、气候宜人，具有典型的温带气候特点。现在，这个春城的名号，是我们留在这里的最大理由。\n昆明是中国的战略大后方，抗日时期，即使日寇再凶猛，也未能攻下昆明城。当时，中国最好的大学——北大，清华，南开，在此共组国立西南联合大学，昆明一城，就荟萃了全国最精华的教育资源，如果昆明有意识，也一定会受宠若惊吧。\n大年初一在官渡古镇，人潮涌动，完全觉察不到是大年初一——几乎所有的店铺都照常营业，人们也享受这里的生活。这里刚好在举行什么“美食文化交流节”，看到老长沙臭豆腐的摊位前人满为患，我甚至有些想笑：这东西真有这么好吃吗。\n百色 花了两天时间到百色，中间曾经去过一个叫做普者黑的破地方。我的评价是，吸引的来人，但留不住人。反倒是百色，打破了我对其之前的印象。\n从昆明一路向西下高原，就会到达广西，到了广西，第一站便是百色。\n进入百色，市容整齐，气候宜人，倘若是抛弃那些热门的“养生”城市，百色倒是一个非常不错的住家的地方。毕竟靠近海洋，纬度也低，气候终年不会太冷，湿度也是无需担心的。\n翻看百色建制的历史，就会发现百色的建制几乎是一路绿灯——从直隶厅到县，从县到市，不断升级。百色是革命老区，除开城市自然发展的因素，这大概也是革命老区的专属待遇吧。\n在黎平待上最后一晚 黎平是我们此行的最后一个驻留的地方，为什么要在这里再停一个晚上？其实没有什么特殊的原因，若是打开地图，规划百色到长沙的路线，你就会发现黎平刚好就在这两个地点的中点。黎平地处湘、贵、桂的交界，看上去也像一个很好的中转站。\n至于风景，我们无暇观看。尽管黎平有各种侗族大寨等，我等也只能在酒店附近转转。于是我们看到的人文景观便只有翘街了。\n黔东南人有一特色菜名曰牛瘪，具体就是将牛宰杀后，把牛胃及小肠里未完全消化的内容物拿出来，挤出其中的液体，加入牛胆汁及佐料放入锅内文火慢熬，煮沸后将液体表面的泡沫过滤后食用。至少，我这个外地人是觉得难以接受的。\n近期香港流行起“两送饭”，黎平人其实也有自己类似的两送饭——炒好的牛瘪以食品袋装好直接带回家，就是一道现成的菜，价格和同样份量的食材差不多，还不用洗碗，何乐而不为？我体验了下，其实味道很不错，只是不论是烧菜店面的卫生环境，还是什么措施都不采取，直接用普通的塑料食品袋盛装这一做法，实在是让人担心，第二天自己会不会拉肚子呢（苦笑）。\n沪昆高速上的大堵车 第二天早上出发，本以为只要6个小时我们就能赶到长沙，没成想，这成了我们这次旅途中最难熬的一段。\n每逢新年，像是沪昆高速这种全国高速的大动脉就会拥堵不堪，从前觉得没什么，直到自己体验过一遍，才知道拥堵有多严重。从前有一错觉——高速堵车再怎么也没城市堵车严重。上到高速才发现，过年高速上那种水泄不通的堵车，显然不是一般人可以接受的。具体有多堵呢？看看就知道了。\n从早上10点出发，一直到凌晨两点，一直被卡在高速上，我看，几乎是没有什么别的情况能让我们（轮换）开这么久的车了。回来之后我才发现我的脚已经淤青——踩刹车踩的。\n旅行总觉得学之甚少 都说读万卷书，行万里路，这一趟行程满打满算也接近空间距离上的“万里”了。但每次行程下来，我总觉得，我学到的甚少。每个自然、人文景观，对我来说，似乎更多意义上是一个过眼云烟，甚至连放松身心的作用都没有起到很多。现在想想，为什么行万里路之后，收获如此之少呢？也许就是因为读书没有破万卷吧。\n在虎跳峡，壮观景色之外，其中蕴含的地理知识也许更能让人迷醉。在丽江古城，除了古时的繁华，历史近在眼前的感觉或许更让人心生满足。行万里路之前需要读万卷书，或许这句话也有这样的意义吧：当从万卷书内汲获的知识在现实中找到参照和实践，心中生现的满足感和安然是让人赶到自己和世界真实存在的最好慰藉。\n这篇游记从1月开始撰写，一直到4月中旬才接近完成。回看我最初写下的文字，总是对我那近乎流水账的文笔感到羞愧。这3个月的时间里发生了不少事，有一段时间我也经受巨大的压力，压力却也不总是带来坏处，它没有击垮我，反而让我更加成熟。\n这不是一篇完美的游记，也永远不会是一篇完美的游记，在撰写它的过程中，我学会了精炼文字，学会了更加成熟的语风，学会了在不那么理想的环境下写作……。这篇游记对于我来说，已经超越了一篇游记的意义——它一直在见证我的成长，即使这并非我原本的目的。\n为什么要旅行？也许我已经有了答案。\n","date":"2023-01-11T22:57:34Z","image":"https://blog-img.l3zc.com/202304021408390.webp","permalink":"/2023/01/2023-new-year-trip-archive/","title":"长沙到丽江，2023年的第一次旅行"},{"content":"Traceroute 是一个很常用的网络 debug 工具，它（应该）会列出你的数据包在到达最终目的地的路上经过的所有路由节点，如果你 traceroute 我的网站，你会得到看起来像这样的内容：\ntraceroute通过 Time To Live或者 IPV6 下的 Hop Limit实现追踪的效果\n这个数值的用意是通过限制数据包能通过的最长「逻辑距离」（最多能通过几个节点），防止数据包在网络故障的情况下在网络上被无限循环广播。每当数据包经过一个节点，这个数值就会减少，这个值减小到0时，路由节点就会丢弃这个数据包：举个例子，网络故障的情况下，一个 IPV4 数据包的 TTL 为65，经过64个节点时，其TTL会等于65-64=1，经过第65个节点时，TTL 会降为0，那么，第66个节点在发现这个数据包的 TTL 为0时就会将其直接丢弃。\n但做到这一步并没有解决所有问题：出于礼貌原因，当一个数据包丢失了，我们还要想办法通知发送这个数据包的人——既然一个数据包能够从发送者到达丢弃它的服务器，那么丢弃它的服务器和发送者之间一定是可以通信的。\n那么 traceroute 的设计思想是：首先设置一个极低的 TTL，并向目标服务器发包，小幅增加这个 TTL，再次向服务器发包，重复这个步骤，直到可以到达目标服务器为止，通过这个做法，traceroute就可以通过前面提到的，数据包被丢弃后的「回执」向我们展示我们与目标服务器之间的「路径」。\ntraceroute 工具通常还会贴心的帮你查询好对应 IP 的反向 DNS，便于我们查看途径节点的相关信息。尽管设置 IP 的反向 DNS 并非必须，大多数运营商都会设置反向 DNS 以方便用户或者他们自己 Debug。\n重要的是，如果买下一个 IP 区段，你便可以将这个区段内的 IP 的反向 DNS 改成 Whatever you want。于是乎，一位仁兄突发奇想，买下了一个 IP 区段，于是就有了下面的 TraceRoute 民谣:\nPS C:\\Users\\l3zc\u003e tracert -h 100 bad.horse 通过最多 100 个跃点跟踪 到 bad.horse [162.252.205.157] 的路由: 1 \u003c1 毫秒 \u003c1 毫秒 \u003c1 毫秒 192.168.0.1 2 2 ms 1 ms 1 ms 192.168.1.1 3 5 ms 4 ms 4 ms 100.66.128.1 4 4 ms 4 ms 4 ms 58.20.125.137 5 5 ms 4 ms 4 ms 119.39.126.117 6 * 27 ms 27 ms 219.158.98.69 7 32 ms 30 ms 30 ms 219.158.5.158 8 29 ms 30 ms 31 ms 219.158.16.66 9 172 ms 175 ms 174 ms 219.158.98.10 10 179 ms 175 ms 174 ms ix-xe-8-2-5-0.tcore1.sqn-sanjose.as6453.net [63.243.205.93] 11 226 ms 225 ms 236 ms if-ae-1-2.tcore2.sqn-sanjose.as6453.net [63.243.205.2] 12 222 ms 222 ms * if-ae-51-2.tcore2.ct8-chicago.as6453.net [64.86.79.14] 13 224 ms 225 ms 225 ms if-ae-22-2.tcore1.ct8-chicago.as6453.net [64.86.79.2] 14 223 ms 223 ms 223 ms if-ae-8-2.tcore2.tnk-toronto.as6453.net [66.110.48.1] 15 223 ms 223 ms 223 ms if-ae-2-2.tcore1.tnk-toronto.as6453.net [64.86.33.89] 16 225 ms 224 ms 225 ms 64.86.33.58 17 223 ms 223 ms 223 ms 67.223.96.90 [67.223.96.90] 18 225 ms 224 ms 224 ms bad.horse [162.252.205.130] 19 228 ms 228 ms 229 ms bad.horse [162.252.205.131] 20 239 ms 237 ms 235 ms bad.horse [162.252.205.132] 21 244 ms 245 ms 248 ms bad.horse [162.252.205.133] 22 243 ms 243 ms 243 ms he.rides.across.the.nation [162.252.205.134] 23 248 ms 249 ms 249 ms the.thoroughbred.of.sin [162.252.205.135] 24 263 ms 259 ms 261 ms he.got.the.application [162.252.205.136] 25 267 ms 268 ms 267 ms that.you.just.sent.in [162.252.205.137] 26 266 ms 266 ms 266 ms it.needs.evaluation [162.252.205.138] 27 267 ms 266 ms 267 ms so.let.the.games.begin [162.252.205.139] 28 275 ms 274 ms 274 ms a.heinous.crime [162.252.205.140] 29 280 ms 280 ms 280 ms a.show.of.force [162.252.205.141] 30 292 ms 293 ms 292 ms a.murder.would.be.nice.of.course [162.252.205.142] 31 293 ms 290 ms 290 ms bad.horse [162.252.205.143] 32 301 ms 302 ms 302 ms bad.horse [162.252.205.144] 33 297 ms 296 ms 297 ms bad.horse [162.252.205.145] 34 308 ms 307 ms 307 ms he-s.bad [162.252.205.146] 35 309 ms 309 ms 308 ms the.evil.league.of.evil [162.252.205.147] 36 314 ms 314 ms 313 ms is.watching.so.beware [162.252.205.148] 37 322 ms 323 ms 322 ms the.grade.that.you.receive [162.252.205.149] 38 327 ms 326 ms 326 ms will.be.your.last.we.swear [162.252.205.150] 39 327 ms 329 ms 330 ms so.make.the.bad.horse.gleeful [162.252.205.151] 40 331 ms 331 ms 331 ms or.he-ll.make.you.his.mare [162.252.205.152] 41 339 ms 339 ms 339 ms o_o [162.252.205.153] 42 345 ms 346 ms 346 ms you-re.saddled.up [162.252.205.154] 43 348 ms 348 ms 348 ms there-s.no.recourse [162.252.205.155] 44 351 ms 350 ms 350 ms it-s.hi-ho.silver [162.252.205.156] 45 363 ms 363 ms 361 ms signed.bad.horse [162.252.205.157] 跟踪完成。 PS C:\\Users\\l3zc\u003e这是这首民谣的原曲：\n某位仁兄甚至用这个做了一份他的简历：\n如何实现？ 看起来很美好，但是这如何实现？\n我们可以轻松的更改 Reverse DNS 的设置。最大的问题是，如何让数据包按照我们希望的路线穿行。\n在物理上将节点按顺序连接显然不现实，现在能被想到的有两种办法：要么在单个节点上将很多虚拟的接口按顺序分配 IP 并串联起来并将他们用作「节点」，要么在用户网络层上做手脚，生成假的「超限」消息，凭空生成一条不存在的路由线路。\nhttps://github.com/benjojo/traceroute-haiku\n这个仓库是 benjojo 进行实验的项目，利用了第二种方法，用GO语言写一个TUN/TAP，接管所有的网络流量，并生成假的「超限」消息。\n自己动手 我们来写一个程序，彻底理解这个项目。\n我之前没有使用过 Go 语言。已知的 Go 项目里我最熟悉的是 Clash 的 Mac 版本。Clash 有强大的分流功能，以及为了兼容性，编写了一套 TUN 模式。用来作为切入点学习非常合适。\n参考 https://blog.benjojo.co.uk/post/traceroute-haikus\n","date":"2023-01-10T12:11:29Z","permalink":"/2023/01/traceroute-haiku/","title":"Traceroute俳句"},{"content":"也许你曾经尝试过使用诸如滴答清单、Notion 的软件来构建一套 Todo List 系统，但实际操作起来却发现：心血来潮时，就往清单里丢几个任务，过了一会，心情不好了，就对这份自己构建的 Todo List 束之高阁。\n是的，清单软件很棒，但若是你真正的去使用他时，会发现清单软件总有一些缺点让你感到不适——每个人的使用习惯不一样，商业化的产品不可能去专门配合每个人的使用习惯。\n不幸的是，即使你从0开始，自己开发一套属于自己的工作流系统，完美的Todo List也是无法实现的。如果你遇到了上面所提到的问题，那么这是一个不争的事实：这些应用程序都要求远高于你期望的，持续的投入。没有一个Todo List能够减少对某种程度的自律的需要。\n我很抱歉，非常抱歉。\n","date":"2023-01-08T22:41:16Z","permalink":"/2023/01/%E6%B2%A1%E6%9C%89%E5%AE%8C%E7%BE%8E%E7%9A%84todolist/","title":"没有完美的Todo List"},{"content":"安装Electron SSR很简单，下载好deb文件安装就可以。\nsudo dpkg -i electron-ssr.deb由于Electron-SSR作者已经删除了这个项目的仓库，故目前只有Fork来的备份可用。\nhttps://github.com/qingshuisiyuan/electron-ssr-backup\nReadme这一部分只提到了libsodium等少量依赖，于是直接执行安装命令时dpkg提示有依赖问题。所以，安装所必要的依赖：\nsudo apt install libcanberra-gtk-module libcanberra-gtk3-module gconf2 gconf-service libappindicator1 libssl-dev libsodium-dev实际上apt提供了自动解决依赖问题的选项：\nsudo apt --fix-broken install在安装需要依赖的deb包后执行即可解决依赖问题。\nElectron-ssr在解决依赖问题后成功运行，可以正常显示图形界面，订阅、更新节点。但无论怎么调整Ubuntu的网络设置都无法魔法上网。查看electron-ssr的.config目录发现其后端使用的是python版本的ssr，调取错误日志发现其竟然提示没有安装Python。\n怎么可能没有Python？Ubuntu肯定自带Python。经过排查发现：\n输入python3可以正常调用python3.10 输入python会提示未知命令 electron-ssr默认调用的是python而不是python3 上网一查才发现，Ubuntu自22.04版本开始不再将Python加入$PATH。故手动创建symlink：\nsudo ln -s /usr/bin/python3 /usr/bin/python再度打开Electron SSR测试，发现可以正常魔法上网，问题解决。\n别忘了将Ubuntu网络设置中的代理设置调成自动。\n可以学到什么？ 不带版本号调用python命令是一个坏实践，以后应当避免这种行为。\n","date":"2022-11-04T23:32:37+08:00","permalink":"/2022/11/ubuntu-22-04-electron-ssr-troubleshoot/","title":"Ubuntu 22.04 Electron SSR Troubleshoot"},{"content":"1960年，谁也不会想到美苏冷战时期军用的 ARPANET 会发展成为现在世界上最重要的基础设施之一。互联网从少数人手里的玩具变成了每日生活中必不可少的工具。中国政府的数据显示，截至2022年8月31日，中国网民数量达到10.51亿，是世界上最大的互联网用户群体。\n这是网民？ 是的，没错，这些人是中国网民。\n是\u0026hellip;\u0026hellip;吗？\n我们只不过是一群用上了 iPhone 的秦朝人罢了\n——网友\n90%的中国“网民”，只不过是一位用上了网络的大清子民而已。而淘宝，用一种直截了当的说法，地位堪比——赛博供销社。\n互联网技术成功的普及到了全世界，与之相应的价值观——互联网精神，却不得不向传统价值观妥协。我们前脚迈入了乌托邦，后脚却还停留在那个混沌而蒙昧的旧世界。\n互联网精神？ 互联网精神，来自互联网的最初设计：对等、开放、容错、共享、去中心、自组织、非商业，等等。\n我很怀念十年前的互联网，那时候包容共享开放还是主流，Censorship 并没有现在这么极端，大家在各大论坛、贴吧以及当时欣欣向荣、并未被禁止的个人博客上分享自己高质量的经验见解，和谐共处的讨论。流氓软件、内容农场、假冒网站没有充斥在搜索引擎上。那时候上网，不说受益匪浅，也至少能发现有价值的信息，以及在讨论中收获纯粹的快乐。\n看看现在，垃圾内容和审查制度大行其道。制造各种狗屁不通全靠编文章的自媒体与内容农场，低俗降智的直播短视频平台，脱胎于电视购物洗脑污染的直播带货，充斥着内容农场、沙雕小编生产的文字垃圾的搜索引擎，各路巨头打造自己的 All in One Apps，开展新时代的“圈地运动”，将曾经自由的网民们看作价值的载体，大肆圈定自己的势力范围，恨不得挤占用户所有的上网时间。\n人们上网的时间越来越多，但从网上获得的却越来越少。再难看到到有趣的故事让人灵魂共鸣，再难听到独到的见解让人醍醐灌顶，再难学到有用的经验帮你解决各种各样的问题。互联网越是发展，发展到仿佛每个人都在当下充沛的信息流冲击下大量获取信息，但你所获得的只是所谓“获取信息”的快感，只是在缓解互联网奶头乐毒瘾而被迫做出的举动。推荐算法的出现甚至让你所看到的、所想到的，只是权力想要让你看到、想到的。\n互联网早已经不是一个让所有人平等、自由、快捷的提升自己获取知识收获快乐的渠道，只是一个更加黑暗的现实世界，披着互联网的外衣，收割更多人的韭菜。\n技术？人文？ 技术终究只是技术，他就摆在那里，没有人文属性。20世纪，人们惊呼电视会毁了下一代，可这并没有发生。21世纪，人们惊呼电脑会毁了下一代，可这也未曾发生。现在，人们惊呼手机会毁了下一代，可以预见到，这也绝不会发生。技术从不会毁掉任何一个人，真正会毁了一个人乃至全人类的，乃是属于人文因素的，人们自甘堕落的，颓废。\n为什么要限制未成年人只能在周末每天玩手机游戏一个小时？是为了让那些家长认清就算没有游戏你的孩子照样是个废物。\n互联网并不要求每个人具有互联网精神，但，互联网精神才是让互联网能够被称为互联网的核心所在。\n这样的网络，只配被称为“赛博” 没有互联网精神的互联网不能被称作互联网，而只是现有内容的另一种表达形式。把原本放在橱窗和货架上的商品搬上屏幕，再做一个配送服务？把原来大家在线下讨论问题搬到线上，现在拉一个群？把原本衣锦还乡的典故旧貌换新颜，变成衣锦发微博微信小红书？\n我们只不过是一群用上了iPhone的秦朝人而已。技术进化了，推动社会进步的关键人文因素却没有进化，每每找一本描写古代社会生活之著作，看看古代的社会生活，其与现在之相似无不让我有一种恍若离世之感，在中国几千年的历史里，尽管技术更新迭代，社会生活从没有改变，我们的社会也从未允许过这样的改变。中国虽然引进了互联网的技术，却一如既往的顽固，从未让这种技术改变社会生活。这样的网络，只能被称为“赛博”，而不能被称作“互联网”。这样的网民，只能被称作“赛博原始人”。\n真正的网民？恐怕1亿都是乐观估计 苹果官网在哪看\n淘宝吗\n……\n在中国，真正的网民又有几何？政府和巨型企业联合，个人网站和私人论坛了无生存之地，ICP牌照制度挤压个人网站的生存空间，只有大公司的网站能够生存。近期传出的中国大陆互联网白名单的试点，虽然令人担忧，可悲的是，人们已经不再在乎了。\n平时上网的时间基本都花在了 BAT 三大巨头的APP上，即使开启了白名单制度，也没什么吧。\n这是一种悲哀。1994年，中国正式接入互联网。2022年，中国却在打造自己的网络，与互联网精神背道而驰，离互联网越来越远。中国的网民们呆在与局域网没有差别的小圈子里，浏览着几家大公司与政府的网站，使用他们的服务，过着高级版的朝鲜局域网生活。\n这更是一种无尽的黑暗，我们看似接入了互联网，更多的人在实质上却只接入了赛博，我们何尝不像是赛博朋克2077的世界，将自己孤立成一个个与世隔绝的封闭子网。\n按照互联网的定义，真正遵循互联网精神的民众可能具有如下的行为：\n运营自组织的网站 使用真正遵循 P2P 精神的下载器 经常在网上分享自己的见解与想法，抑或是git commit等 \u0026hellip; 这样的网民，在如今的中国，可谓是少之又少。即使有，也很难在简体中文圈子里抱团——这样的人太少了，与其这样，我们不如使用通用的英语与全世界的同路人交流，享受互联网的乐趣。\n赛博朋克真的离我们很远吗？ 这就是赛博朋克，巨型企业和政府通过技术监控着人们的一举一动，更好的技术没能用于造福众人，而成为了金字塔顶端一小撮人的敛财工具。权贵们运用技术巩固他们的地位，玩弄他们的权力。而普通的人民却只能在这种绝望的阴影下怀揣着希望努力生活，人们无法反抗，无法打破铺天盖地的绝望。\n变革？ ","date":"2022-10-05T17:22:22Z","permalink":"/2022/10/%E4%B8%AD%E5%9B%BD%E7%9C%9F%E7%9A%84%E6%9C%8910%E4%BA%BF%E7%BD%91%E6%B0%91%E5%90%97/","title":"中国真的有10亿网民吗？恐怕连1亿都不到"},{"content":"1949年，哈佛语言学家齐夫（George Kingsley Zipf）做了长篇小说《尤利西斯》的词频统计。该书的长度是260,430字，总共用到了29,899个单词。它是单词量最大的文学作品之一。\n他发现，单词的出现频率有规律地下降。词频第二名的单词的出现频率，是第一名的二分之一，第三名的出现频率是第一名的三分之一，第四名是四分之一，第十名是十分之一，第1,000名是千分之一，以此类推。\n这被称为 Zipf 定律，即任何单词的词频，与该单词在词频表中的排名保持一个固定比例。\n这个定律有两个重要推论。\n一种语言的常用词汇只包含少数单词。例如，在英语中，单词 the 占所有文本的7%，最常见的10个英语单词占到了所有文本的23%。 对于当今世界的大多数语言来说，仅仅100到150个常用单词，就占所有文本的一半左右。在希腊语的《圣经新约》中，319个单词占全书近80%的内容。\n当你掌握了这些高频常用词以后，遇到的所有词汇几乎都是低频词。 还是以希腊语的《圣经新约》为例，319个单词占文本的近80%，但剩下的20%包含了5118个不常用的单词，其中大部分单词只使用了一次。\n推论二注定了精通一种外语是一件麻烦事。学习者入门以后，就不得不花大量时间，记住那些出现频率很低的词汇。以布朗大学语料库为例，该语料库一共包含了53,076个单词，其中36,135个单词在语料库的所有文献中出现次数不超过三次，它们占了词汇量的68%，但是仅仅在5%的场合使用。\n更麻烦的是，这些不常见的词往往很重要，能够提供句子的关键信息。越少见的词对于了解句子含义越重要。\n学习者遇到不认识的单词，可以通过上下文去猜测含义。但是，一项研究表明，如果要从上下文中正确猜中单词含义，阅读者必须能够理解文本中至少95%的内容。\n对于布朗语料库来说，15,851个单词可以覆盖语料库97.8%的内容。这差不多就是英美大学生掌握的单词数量。这意味着，如果你记住了15000个单词，再遇到不认识的单词，就可以较有把握得猜出它的含义。\n但是，对于外国人来说，想要通过几年学习，掌握15000个左右的英语单词，绝非易事。\n即使按照每天记忆30个单词，全年无休的速度计算，从零开始记忆15000个单词也需要500天也就是比一年半还要多的时间。事实上，在实际操作中，能达到这个速度的学习者非常罕见，以我为例，进入高中时，我的词汇量在3000到4000，读高中的时间里，由于我的词汇量对我的英语成绩并不构成瓶颈，我在任何时候都没有刻意去记单词。高中毕业时，我的词汇量仅6000到7000，这意味着高中三年里，在不刻意记单词的情况下，平均下来我每天新增的词汇量不足三个。按照这个速度从零开始记忆15000个单词需要花费15年时间。\n","date":"2022-09-08T23:58:49Z","permalink":"/2022/09/why-it-takes-so-long-to-learn-a-foreign-language/","title":"为什么学习一门外语这么难？"},{"content":"自从把博客系统换成 Wordpress 以后，又是缓存，又是精简，又是各种替换，为了优化网站的速度不可不谓花了一番心思，然而在 iPhone 上，我的网站的打开速度却依然时快时慢。在之前两个月里，我一直认为是服务器的性能问题所致。直到有一天我看到并且为网站部署了 OCSP Stapling。\n为什么偏偏在 iPhone 上就打开慢？ 你可能已经注意到我使用了「打开」而非「加载」，如果你调用 iPhone 上 Safari 的开发者模式查看一个网页的 Handshake 时间，你就会发现一个不容忽视的 1 秒，至于这一秒都花在了哪里，我们先来看看 OCSP 究竟是什么。\nOCSP 的概念 先从 SSL 证书的有效期说起 曾经我有一个困惑，为什么没有永久有效的 SSL 证书？难道是单纯因为商业原因？其实并不是，主要原因是为了安全。每次签发机构（CA）签发 SSL 证书时，CA 都会为这个 SSL 证书生成一个私钥。就像家里任何一把钥匙一样，HTTPS 证书的私钥有丢失、泄露的风险，当网站的私钥丢失时，网站应该向证书 CA 申请将他们的证书加入到证书吊销列表（CRL）里。当用户访问 https 站点时，浏览器会自动向 CA 请求吊销列表，如果用户访问的站点提供的证书在 CRL 里，浏览器就不信任这个证书，因为私钥泄漏后，攻击者可能拥有同样的证书。\n所以，如果证书永久有效，随着越来越多的私钥丢失，吊销列表也越来越大（因为只有加进去的，没有剔出去的），这既给 CA 的服务器增加流量压力，也会增加浏览器需要下载的数据量。而一旦有效期只有一年或几年，那么CA就可以将那些已经过期了的证书从 CRL 里剔除，因为反正浏览器也不信任过期证书。这种问题也就随之消失，于是，今天看到的证书，有效期都随着安全等级的提高而加长，但除非自签，没有永久有效的证书。\n这和 OCSP 有什么关系？ OCSP 即 Oline Certificate Status Protocol，是用于替代 CRL 的协议，解决了一些 CRL 协议存在的问题，以下信息来译自 Wikipedia：\nOCSP 响应通常比典型的 CRL 响应更小，这意味着对于客户端和服务器更小的网络负担。\nOCSP 响应中需要解析的数据更少，因此客户端需要的运行库比解析典型的 CRL 响应更少更简单\nOCSP 中，服务器可以记录主机在何时验证过特定的证书，由于请求不强制加密，相关信息可能被第三方获取。\n简单来说，OCSP 做的就是 CRL 的事——验证这个网站的 https 证书是否处于被吊销的状态。\n所以为什么打开慢？ 我们搭建个人网站时大都没有很高的预算，例如我的网站原本托管在免费的 Github Pages 上，预算能省则省，更别提动辄几千一年的 SSL 证书了。于是你看到的非商业性质的个人网站大都采用了免费的 Let\u0026rsquo;s Encrypt 证书。而 Let\u0026rsquo;s Encrypt 的 OCSP 服务器 ocsp.int-x3.letsencrypt.org 线路非常垃圾，实测中部地区联通 traceroute 以供参考：\n可以看到服务器在香港，线路却绕美国。这导致 一个很简单的 OCSP 查询请求需要 1 秒的时间来返回结果。这意味着无论你的服务器性能有多强，网络延迟有多低，只要部署的证书是 Let\u0026rsquo;s Encrypt，网站在 iPhone 上的加载时间就绝对不会快过一秒。这还不是最坏的情况，因为各种莫名其妙的原因，Let\u0026rsquo;s Encrypt 的 OCSP 服务器域名会时不时的被 GFW 通过 DNS 污染等方式阻断，这就导致客户端在一部分时间里根本无法查询 OCSP。\n但为什么只有 iPhone 会加载慢呢？ OCSP 协议有一个很要命的问题：用 https 的人越来越多，验证证书有效性的需求自然会越来越大，OCSP 服务器难道硬扛访问量？当然不是，不同浏览器都会有不同的 OCSP 验证超时时间，超时就先默认证书有效继续进行访问。但是有些\u0026quot;「注重用户体验」 的浏览器，比如 Chrome，自己在浏览器内部做了个本地列表，通过每次浏览器更新实现列表更新。直接查本地的列表速度就非常快了，当然也不存在什么 CA 的 OCSP 服务器被屏蔽的问题。缺点是并非实时更新。但并非所有浏览器都是所谓「注重用户体验」的浏览器，比如 Safari 就默认开启 OCSP 验证。自然无法避免这种中国特色的问题。Chrome 在全球有超过 70% 的市占率，而受 Chromium 开源项目的影响，国内一众「安全」「极速」浏览器都不存在这种问题，这几乎覆盖了国内桌面端所有用户群体。而苹果要求包括 Chrome 在内的所有 iOS 应用都要使用 Webkit 内核，这直接干死了所有的 iPhone 用户。\n怎么解决？ 总不可能要求所有 iPhone 用户都自己关掉 OCSP 吧？那么解决方法就是——换证书。怎么可能，要是我真换了证书你也就看不到这篇文章了。虽然换证书，比如 Trust Asia 证书的确可以解决问题。但我不想因为换一个证书而告别 Let\u0026rsquo;s Encrypt 自动续期和支持泛域名的特性。\n终于可以谈到 OCSP Stapling 了，即 OCSP 封装，想要开启 OCSP Stapling 非常简单：首先到亚洲诚信提供的 https 检测服务检测自己的证书链是否完整，若是不完整则修复证书链后将修复好的证书重新部署，完成操作后在 Nginx 配置里加上如下两行：\nssl_stapling on; ssl_stapling_verify on;然后重启 Nginx 服务，大功告成。由于我自己使用的是 Nginx，Apache 请自行搜索相关方法。\n然后，iPhone 用户也能愉快的访问你的网站而无需忍受恼人的 GFW 干扰 Let\u0026rsquo;s Encrypt 的 OCSP 服务器。\n那么效果如何呢？\n可以看到，开启 OCSP Stapling 后，查询验证结果所需要的时间大幅缩短，反映到网站打开速度上是非常明显的感知。\n什么东西这么牛逼？ OCSP 封装，顾名思义，即服务器缓存 OCSP 服务器的验证结果，并且在与客户端 SSL 握手时直接发送缓存结果。\nOCSP装订，是TLS证书状态查询扩展，作为在线证书状态协议的替代方法对X.509证书状态进行查询，服务器在TLS握手时发送事先缓存的OCSP响应，用户只要验证该响应的时效性而不用再向数字证书认证机构(CA)发送请求，可以加快握手速度。\n我的服务器线路虽然亦非很好，但比 Let\u0026rsquo;s Encrypt 的弟中弟线路好到不知道哪里去了。开启 OCSP Stapling 后，客户端只需要验证服务器事先缓存的 OCSP 查询结果的有效性，免去了向“神优化”的服务器发请求的痛苦，速度自然会快上一大截，在有 OCSP 强制验证的浏览器上初次打开网页的效果尤为明显，统计数据显示，在开启 OCSP Stapling 后，新访客量明显有所提高，大概是拜 OCSP Stapling 节省的大量握手时间所赐。\n为什么不默认开启 OCSP Stapling？ 听上去 OCSP Stapling 简直就是完美的万金油优化——每个网站都开启 OCSP Stapling，既提升用户的访问体验，也为 OCSP 服务器减轻负担。那为什么新的 Nginx 配置文件不默认开启 OCSP Stapling 呢？其实这是一个很简单的问题。\n不是所有网站都有 SSL 证书 OCSP Stapling 并非在所有情况下都能提供更好的访问体验 现存方案中 OCSP 并不是唯一的证书验证方案 引入新功能时通常是需要谨慎的，Nginx 用户群体非常复杂，不同用户不同需求 参考 为什么https证书要设有有效期？ 找不到了 Wikipedia 玩个机吧 头图来自：KeyCDN\n","date":"2022-08-17T13:19:36Z","image":"https://blog-img.l3zc.com/202310112239503.webp","permalink":"/2022/08/%E6%B5%85%E8%B0%88-ocsp-stapling/","title":"浅谈 OCSP Stapling"},{"content":"最近想要解放设备们的 CPU，让科学上网的体验变好一点点，顺手实现一些杂七杂八的功能满足折腾欲。在学校里我有一台 OpenWRT 的普通路由器，用起来非常不错，OpenWRT 基本可以实现所有我想要的功能，但毕竟是普通路由器，CPU 性能太弱，所以我的需求就定在了一款 CPU 性能更强的，能运行 OpenWRT 的 ARM 软路由，于是 Nano Pi R2S 进入了我的视野。\n要是软路由有排名，那 R2S 绝对是经典中的经典。小到无论如何都可以塞进弱电箱的体积，足够强大的性能和上手的容易程度都是软路由里数一数二的。虽然价格可能是49入国军，就不放出来了，但是只要我对这玩意有需求，那也不是不能接受。\n上手 好了，现在我们搞到了这 R2S，简单来上个手：\nR2S 外观非常简洁，没有多余的 IO，虽然原本不是作为软路由设计，但在设计上却给人一种天生为软路由而生之感：一个 WAN 一个 LAN 两个 RJ45 网口，一个 Micro SD 卡插槽，一个 USB 2.0 接口，完美覆盖软路由几乎所有使用场景。\nR2S 原本是作为边缘服务器设计，被我们硬生生的玩成了软路由。\n一体成型的金属外壳，非常有高级感，很有工业风，手感不错。由于 R2S 挑卡，挑电源（看到后面你就知道了）在购买机器时我直接买了已经经过测试的 Micro SD 卡和电源组合套餐，理论上来说，我不会遇到 SD 卡、电源与机器不兼容的问题。\n刷个 OpenWRT 跑起来！ 先来看看这玩意儿的硬件规格：\nCPU: Rockchip RK3328, Quad-core Cortex-A53 DDR4 RAM: 1GB Network： 10/100/1000M以太网口 x 1 USB3.0转10/100/1000M以太网口 x 1 USB2.0 Host: Type-A x1 MicroSD Slot x 1 MicroUSB: 供电和Slave功能 Debug Serial Port: 3.3V TTL电平，3Pin 2.54mm间距排针 PC Size: 55.6 x 52mm Power Supply: DC 5V/2A Temperature measuring range: 0℃ to 80℃ OS/Software: U-boot，Ubuntu-Core，OpenWrt 这个硬件规格，装 Ubuntu 当服务器还是免了，但是跑个 OpenWRT 当路由器使绰绰有余。\n由于使用 Micro SD 卡作为启动介质，R2S 的刷机非常容易：取出 SD 卡，用读卡器接上电脑，把镜像烧写进 SD 卡，再把 SD 卡装回 R2S，完成。对于用 Ultra ISO 刻过 Windows 系统盘的老油条来说全都是熟悉的操作，完全没有任何难度可言，即使是新手也能很轻易的学会。让我们快进到登入 OpenWRT 的后台：\n（此处应有Nice）\n狗都不用 R2S 官方编译的 OpenWRT，不仅没有中文翻译，没有好看的主题，各种插件还需要自行安装。懒得在官方固件上瞎折腾则可以直接选择别人打包好的固件。我使用了 BigDongDong 打包的带 Docker 固件，能满足我的所有需求。\n让这玩意加入我的家庭网络 要想让 R2S 加入我的家庭网络，有两种大致的方案：第一种，也是最直截了当的办法，即直接拿 R2S 当主路由使用；第二种方法稍微复杂，用 R2S 当旁路由，将原来主路由的网关指向旁路由。这两种方案各有优缺点，将 R2S 当主路由配置简单，只要你想，只需要将 R2S 接入光猫和原来的路由器之间，然后启动路由器，什么都不需要配置，直接开始上网。代价是这会让网络架构多一重出故障的概率，虽然这个概率很小。将 R2S 用作旁路由配置稍微复杂，但能实现某些设备直接走主路由，其余设备走旁路由的效果，缺点就是某些只有作为主路由才能实现的功能（比如你要建站而你原来的主路由不支持端口转发）无法实现。\n我无法接受让 R2S 作为旁路由的行为，想到数据包在两个路由由之间来回窜个两次才能被发出去情景，我还是选择了第一种方案——我不需要那么稳定的网络，大不了多重启几次。于是这就是新的网络拓补图：\n图片懒得自己画所以来源于网络，无线路由器那里那个 WAN 请自行脑补成 LAN。\n为了让 R2S 能尽可能的与我的设备交互（比如控制某个设备是否启用科学上网），以及尽可能的减少 NAT 和网段的套娃，我们需要对原来的路由器进行一些设置，首先查看路由器是否有类似 AP模式（无线接入点模式）的功能，如果有那么直接启用这个模式就行。如果我的路由器有这个选项那我就不需要写下面这个部分了，只可惜，这 TP-LINK 电子垃圾并没有。\n手动把原来的路由器设置成交换机 我不得不手动设置这个路由器，不过还好这并不是一件难事：首先把原本接在路由器 WAN 口的网线插到 LAN 口里，你没看错，LAN 口。然后登入原路由器的后台，关掉原路由器的 DHCP 服务器，打开原路由器的 LAN 口设置把原路由器的 LAN 口 IP 设置成与 R2S同一网段下的一个IP，例如：我的 R2S 的 IP 是 192.168.2.1 ，所以我将原路由器的 LAN 口 IP 设置成 192.168.2.2 。设置好以后重启路由器，所有设备就和 R2S 同一个网段了，在 R2S 的后台也可以看到这些设备。这些操作的本质是把路由器变成一个带无线功能的交换机。\n至此，基础的网络配置已经全部完成了，本来就很乱的弱电箱更乱了。\n终于可以正式开始折腾了 现在折腾的基础已经有了，那就开始折腾吧。\nPasswall 科学上网 其实原本想用 Clash，不过 Clash 有多吃资源上网一搜就知道。\n关于 Passwall 怎么使用网上一搜一大把，这里我直接写我的用法：\n导入机场的订阅开启自动更新订阅，每天一更新 选择一个位于香港的节点作为主节点 开启自动切换，设置新加坡和美国的节点为 Fallback 节点（故障转移） 开启 ChinaDns-NG 过滤被污染的 DNS 结果 最后把之前所有设备上设置的 DoH 和 DoT 取消，让他们的 DNS 服务器直接指向 R2S，万事大吉，所有设备都可以科学上网了。出于强迫症我将家用摄像头排除在代理列表外，搞定。\n青龙面板 既然这固件自带 Docker，那总得用起来吧？Docker 能干嘛？青龙面板安排。操作其实也很简单：把青龙面板的镜像拉取到 SD 卡上，然后部署启动容器启动就行。\n另外需要额外安装一些依赖，例如 Python 的 requests 库，Node.js 的 base64 库等，这里我随意贴一份依赖列表，可以自行取用：\n# Node.js 下的依赖 crypto-js prettytable dotenv jsdom date-fns tough-cookie tslib ws@7.4.3 ts-md5 jsdom -g jieba fs form-data json5 global-agent png-js @types/node require typescript js-base64 axios moment # Python3 下的依赖 requests canvas ping3 jieba PyExecJS aiohttp至于其他依赖基本可以看脚本运行的错误日志对症下药地安装，这里就不贴出来了。\n那么现在青龙面板有了，拿他干什么呢？\n目前只是拿它跑跑脚本拿京豆，佛系看到什么功能就加上，虽然用的是家用 IP，被风控的概率比较低，但我还是尽量不多开脚本，且不说会不会被风控，毕竟这东西还是主路由，总不能一天到晚太占性能导致我的上网体验变差吧？如果真是这样那就舍本逐末了。\n至于脚本从哪里来，可以自行在 Github 上搜索依赖库拉库安装，说不定以后还要去 Gitee 上再找找，只能说，但愿 Github 不要被完全阻断导致一部分大佬往 Gitee 上跑。这里贴一个我用的库\nhttps://github.com/okyyds/yydspure/tree/master\n直接用定时任务拉库就行。\nql repo https://github.com/okyyds/yydspure.git \"jd_|jx_|gua_|jddj_|jdCookie\" \"activity|backUp\" \"^jd[^_]|USER|function|utils|sendNotify|ZooFaker_Necklace.js|JDJRValidator_|sign_graphics_validate|ql|JDSignValidator\" \"master\"稳定性、效果和问题 为了稳定，暂时就折腾这么多了。\n那么稳定性怎么样？目前来看很好，没有遇到网上的各种烧坏，重启之类的问题，设置 Crontab 每周重启一次，非常稳定，这里有一个坑点： R2S 使用 Type-C 接口供电，却不支持 PD 协议。并且，虽然官方的技术规格里只需要 5V2A 的电源，但实际上需要尽量选择高于这个规格的电源，比如我的电源是 5V3A 的非 PD 协议电源，这就导致 R2S 的配套电源选择范围很窄，尽量选择店家 R2S 套餐里配好的电源。以下是一些网友的情况：\n前面也提到了 R2S 挑卡的问题，出于一些原因，R2S 与某些SD卡的兼容性欠佳，可以去 R2S 官方 Wiki 上找找兼容的 SD 卡列表。\n效果如何？不需要多说，因为家里的宽带只有 100 兆，任何一个软路由都可以轻松跑满。因为我的机场屏蔽了意义不大的测速，晚高峰（大概是晚高峰，周六下午六点半） Youtube 的话可以轻松跑到 12 万。\n这个速度和机场有比较大的关系，不过，只要5万以上，4k 就能随便拖着看，再往上意义不大。再就是青龙面板的效果，前面大家也都看到了。\n那么问题？其实问题主要集中在 IPV6 上，换上 R2S 后，哪怕我将所有 IPV6 相关的服务全都设成中继模式也没有办法正常使用 IPV6，而原来的路由器只要设置成桥模式即可，这个问题暂时没有找到解决方案。\n最后 总体上，R2S 达到了我的预期，基本满足了我的需求，是一件我相对满意的产品。折腾乐趣无穷，但切莫上头，软路由这种东西，搞清自己的需求，不要忘记折腾原本的目的，够用就好，否则就是一个痛苦的无底洞。至于这个尚未解决的 IPV6 问题，佛系解决，实在不行看看能不能用 IPV6 NAT。\n","date":"2022-08-16T17:22:19Z","permalink":"/2022/08/nano-pi-r2s-hands-on/","title":"Nano Pi R2S 上手，小小升级一下家庭网络环境"},{"content":"我从未去过漫展，并且可能在今后相当长的一段时间里也不打算去了。看到一位推友发送的广州漫展的情况后，我的心情却不比当年 Pixiv 被墙更加简单。\n我们到底需要什么样的漫展？ 在维基百科上搜索“漫展”，你会发现这个词条之中文版是一个年久失修的词条。所以我们来看看英文版：\nAn anime convention is an event or gathering with a primary focus on anime, manga and Japanese culture. Commonly, anime conventions are multi-day events hosted at convention centers, hotels or college campuses. They feature a wide variety of activities and panels, with a larger number of attendees participating in cosplay than most other types of fan conventions. Anime conventions are also used as a vehicle for industry, in which studios, distributors, and publishers represent their anime related releases.\n最初的漫展在1975年举行，是位于东京举行的 Comiket。上面这段话大致的翻译是：漫展是将焦点放在动漫，漫画以及日本文化上的展览。通常分多日在会议中心、酒店、校园等地举行，分为各种活动。漫展中参加 Cosplay 的人数远比参加其他活动的人更多。漫展也被当作二次元商业活动的载体，签售等各种商业活动都可以通过漫展进行。\n可以看出，漫展在中文和英语环境下都是一个较为冷门的词汇。就连在编辑战频发的维基百科都少人问津。在我的印象里，漫展是一个传播ACG(Anime, Cartoon, Gaming)文化之地。虽然这类文化大抵起源于日本，但像英文维基百科片面的将其归结于日本文化显然非常偏激。\n漫展在官僚主义、形式主义、和沙文主义三座大山的夹缝中求生存、图发展，漫展的堕落是中国畸形的文化现象的缩影。\n审查并非一定是政府行为，亦可以是民间自发行为，过度的审查让原本正常生长的文化变成了畸形的文化，这已经不是第一次：民国时期的散文诗作者抒情之地，建国后大部分却变成了刻意拍马屁的垃圾；京剧是我国国粹，文革时期极端的审查与文化专制让京剧畸形发展出了面目全非的样板戏；藏传佛教本是至美的纯粹信仰，过分的审查却将其变成了政治意味浓厚的工具。毫不夸张的说，过分的审查本质上是在同化文化，是对多元文化的不容忍，简单来说，这就是在破坏文化。\n我们到底需要什么样的漫展？我们需要的，只不过是未经污染的一片净土，是一片原汁原味的文化，可是在极端的审查下，连对多元文化基本的保留，基本的原汁原味都成了奢望。\n你不是不看漫展吗？ 若是问及这在现实世界中对我的影响，可以说是几乎为零。我虽然喜爱二次元文化，但就我痴迷的程度而言，我甚至不配被称为ACG爱好者。我一苦逼大学生的生活状态，直截了当的说，与那些花天酒地的大学生相比，我过得可能更接近于苦行僧。毕竟从第一句话我就说了：我从未去过漫展，在夏日祭事件后环境每况愈下的情况下更加不打算去。\n在我的意识里，一种声音告诉我：等某一天我喜爱的某个东西，比如最近在玩的 Cytus 2 被拉清单，或者说发生更加难以接受的事国内进一步封闭互联网，我才会站出来发声。现在的事对你没什么影响，事不关己，高高挂起？但我却不得不提到这首著名的墓志铭：\n在德国，起初他们追杀共产主义者，我没有说话，因为我不是共产主义者；\n接着，他们追杀犹太人，我没有说话…，因为我不是犹太人；\n后来，他们追杀工会成员，我没有说话…，因为我不是工会成员；\n此后，他们追杀天主教徒，我没有说话…，因为我是新教徒；\n最后，他们奔我而来，却再也没有人站起来为我说话了。\n这是一位牧师的墓志铭，相信很多人都看过。对于每况愈下的沉默是可怕的，不在沉默中爆发，就在沉默中灭亡。不如我来仿写一下这首诗墓志铭：\n起初他们打压“娘炮”，我保持沉默，因为我不是“娘炮”。\n接着，他们打压明星，我保持沉默，因为我不追星。\n后来，他们审查游戏，要求游戏必须拿到版号，我保持沉默，因为我玩的游戏没有受到影响。\n此后，他们借着莫须有的“夏日祭”事件对漫展施压，我保持沉默，因为我不看漫展。\n最后，他们只允许高唱赞歌，整个民族却不再容忍其他文化了。\n别再洗白文化审查 Freedom of speech is that you could say anything you want, but it doesn\u0026rsquo;t mean I have to listen to it.\n言论自由的意思是：你可以发表任何你想要发表的言论，但这并不代表我一定要听。社会文化同理，我们的社会可以有“正能量”的主流文化，但并不代表我们的社会不能有其他文化。畸形的文化审查就是对文化的破坏。在中国，审查并非单纯的一种制度，而是一种现象，中国的审查现象是官僚主义、形式主义和沙文主义互相结合的产物。为什么会有人为这种畸形中的畸形现象洗白？长期只接受单一的文化，人的思想就会愈发偏激，愈发地不能接受其他文化，不能容忍文化多样性的存在。当一个国家，一个民族不能容忍多样性时，势必造成灾难性的后果。想想纳粹德国是如何发动二战以及他们在二战中的各种反人类行为，你就能明白这一点。\n及时行乐。情况虽然不容乐观，但我们依旧可以掌控当下。与其等待文化被阉割，不如尽早的感受多元文化。前面已经反复提到，中国的审查现象是一种十分畸形的现象，与其担惊受怕不断自我审查，不如趁早、趁更加开放的时候感受文化。不得不说，现今社会在倒退，Totally reversing all the progress we\u0026rsquo;ve made，让人看不到希望，我们能看到的，只有黑暗，一眼望不到头的黑暗。\n历史的车轮滚滚向前？ 刚被历史的车轮碾过，好不容易爬起身来，却发现历史在开倒车。\n我们本应在上世纪80年代迎来一个更加开放的社会，可我们没有。我们本应在20世纪初加入WTO后逐渐转型，我们亦在20世纪初呈现了短暂的繁荣，没有畸形的政治正确，没有过分的审查，青年一代朝气蓬勃，踌躇满志，整个社会呈现出变革的态势。现在回想起童年时的社会生活，虽然亦有审查，但绝无现在的压抑之感。我们能明显的感觉到，当时的社会正在进步，理论上来说，十几年过去，我们应当迎来一个更为进步、开放的社会。十几年后的今天，社会却事与愿违，正加剧着偏激与极端。\n最黑暗的时候\u0026hellip; 虽然正在陷入无尽的黑暗，但人们还是努力生活，努力在生活中寻找幸福感。在1940年，也就是第二次世界大战最激烈，法西斯看上去就要征服世界的时候，人们依然会憧憬战后的生活。即使生活在绝望里，人们还是会以这句话安慰自己：\nThe darkest hour is before the dawn.\n最黑暗的时候往往是清晨第一丝曙光前。即使黑暗看上去无尽，但总有一天，它会到头，即使生活在绝望中，也切莫放弃对生活的信心。在每况愈下，充满无力感时，这是我们能做且唯一能做到的。\n最后\u0026hellip; 我想看到我们的社会是包容的，而不是越来越偏激，越来越有攻击性。当然，这也没那么容易。社会变革是痛苦的，山雨欲来风满楼，这是变革前的阵痛吗？我们究竟何处去？是更加光明，还是更加黑暗？也许现在我不该考虑这个问题，要下雨了，赶紧收衣服去。\n","date":"2022-08-11T11:44:17Z","permalink":"/2022/08/my-thoughts-on-anime-shows-in-china/","title":"在中国，漫展已经失去了灵魂"},{"content":"出于种种原因，Gravatar 在国内的访问极其不稳定，而 Wordpress 和 Typecho 都使用 Gravatar 作为头像源，这导致网站的上文章出现评论时，页面会因为几个 Gravatar 头像而一直处于加载状态。为了解决这个问题，我尝试自行搭建 Gravatar 镜像并将其更换到 Wordpress 和 Typecho，彻底而完美的解决了问题，并且水出了一篇文章。\n为什么不直接关了 Gravatar？一句话：没有灵魂。Gravatar可能是世界上使用范围最广的通用头像，若是直接关了 Gravatar，评论里的人就失去了“灵魂”，只剩下一个冷冰冰的人物模具。\n回到正题，想要替换 Gravatar 源，首先你得有一个 Gravatar 源。在一开始的时候，我在网上找了一圈 Gravatar 源，并对它们进行了逐一测试。结果就是发现他们不是太慢就是早已失效，例如网上满天飞的 V2EX 源 https://cdn.v2ex.com/gravatar/ 在国内就已经被封锁。于是我决定自行搭建一个 Gravatar 镜像。\n更新：使用 Cravatar 实际上，Gravatar 有一个完美的本土化方案——Cravatar，Cravatar 的 API 将会按照 Cravatar 头像 \u0026ndash;\u0026gt; Gravatar 头像 \u0026ndash;\u0026gt; QQ头像的顺序为用户匹配头像。并且，Cravatar 的 API 调用方式与 Gravatar 完全兼容。\n并且，Cravatar 官方也给出了一份简明的指导：\n你可以很方便的为 WordPress 集成 Cravatar 头像服务，只需要将以下代码加入你的插件或主题的 functions.php 里即可。\nif ( ! function_exists( 'get_cravatar_url' ) ) { /** * 替换 Gravatar 头像为 Cravatar 头像 * * Cravatar 是 Gravatar 在中国的完美替代方案，你可以在 https://cravatar.cn 更新你的头像 */ function get_cravatar_url( $url ) { $sources = array( 'www.gravatar.com', '0.gravatar.com', '1.gravatar.com', '2.gravatar.com', 'secure.gravatar.com', 'cn.gravatar.com', 'gravatar.com', ); return str_replace( $sources, 'cravatar.cn', $url ); } add_filter( 'um_user_avatar_url_filter', 'get_cravatar_url', 1 ); add_filter( 'bp_gravatar_url', 'get_cravatar_url', 1 ); add_filter( 'get_avatar_url', 'get_cravatar_url', 1 ); } if ( ! function_exists( 'set_defaults_for_cravatar' ) ) { /** * 替换 WordPress 讨论设置中的默认头像 */ function set_defaults_for_cravatar( $avatar_defaults ) { $avatar_defaults['gravatar_default'] = 'Cravatar 标志'; return $avatar_defaults; } add_filter( 'avatar_defaults', 'set_defaults_for_cravatar', 1 ); } if ( ! function_exists( 'set_user_profile_picture_for_cravatar' ) ) { /** * 替换个人资料卡中的头像上传地址 */ function set_user_profile_picture_for_cravatar() { return '您可以在 Cravatar 修改您的资料图片'; } add_filter( 'user_profile_picture_description', 'set_user_profile_picture_for_cravatar', 1 ); }自建Gravatar镜像：Nginx 反代 Gravatar 官方源 注意：这一部分仅适用于服务器在海外的同学，如果服务器在国内请直接绕道去看后面的部分\n首先声明，为了方便管理网站，我使用了宝塔面板。在宝塔面板里使用你想要的域名新建一个网站，纯静态，数据库和FTP都不需要。完成后，转到这个网站的设置，找到反向代理选项，新建一个新的反向代理，填入目标 URL 为 https://secure.gravatar.com提交保存即可。到了这一步，尝试访问指派给网站的域名，别忘了加上/avatar，如果出现了默认 Gravatar 头像即代表配置成功。\n配置成功后，除非你想看到 Chrome “不安全”的提示，否则别忘了给刚刚搭建好的镜像申请一个 SSL 证书。通常情况下直接使用 Let\u0026rsquo;s Encrypt 即可，打开网站的 SSL 选项，用 DNS 验证的方式申请一个 SSL 证书后开启强制 HTTPS 即可。到这一步，我们自己的 Gravatar 镜像就搭建完成了。\n更换博客上的 Gravatar 源为国内可访问源 Wordpress 对于 Wordpress，Google 上搜索到的相关文章大部分都通过修改主题的functions.php文件，加入如下的函数来实现。\nfunction getV2exAvatar($avatar) { $avatar = str_replace(array(\"www.gravatar.com/avatar\",\"0.gravatar.com/avatar\",\"1.gravatar.com/avatar\",\"2.gravatar.com/avatar\"),\"cdn.v2ex.com/gravatar\",$avatar); return $avatar; } add_filter('get_avatar', 'getV2exAvatar');实测在 MDx 主题上这种方法无效，故使用了另一种方法：打开网站目录，找到/wp-includes里的link-templates.php，在这个文件中搜索“gravatar”，大约在这个文件4378行的位置就可以发现 Gravatar 的链接，替换链接为国内可访问的镜像源即可。\n至于插件，暂时没有找到还在更新且能完美实现这个功能的插件，如果有欢迎评论。\nTypecho 对于 Typecho，方法与 Wordpress 大同小异，找到网站根目录，打开/var/Typecho/目录下的Common.php文件。大约在 836 行左右的地方可以找到 Gravatar 官方源的地址，替换为国内可访问源即可。\n不过，某些 Typecho 主题可能不会调用 Typecho 的模板函数，而是使用主题内的函数，这时需要对主题文件作额外的修改。回到网站根目录，打开/usr/themes/下你的主题根目录，主题获取 Gravatar 的相关代码一般在comments.php里，打开comments.php搜索\u0026quot;avatar\u0026quot; 找到 Gravatar 官方源的地址替换为国内可访问源即可。\n推荐的Gravatar源 目前只推荐自建源和七牛云源，后续可能会寻找新源，如果有欢迎评论。\nhttps://gravatar.l3zc.com\t#自建源，已停用 https://dn-qiniu-avatar.qbox.me/avatar/\t#七牛云源，很快，推荐需要注意的是 你可能已经注意到，在 Typecho 自带的模版函数里，调用 Gravatar 源时不需要加/avatar，这是因为 Typecho 自带的函数里已经自动为之加上。同理，有的源调用avatar的路径可能是/gravatar，应用到网站上时需要做出相应的修改。\n","date":"2022-07-23T22:26:34Z","permalink":"/2022/07/replace-gravatar-source-on-my-blog/","title":"替换Wordpress和Typecho的Gravatar源为国内源实现国内加载Gravatar"},{"content":"我爱城市，但不是我现在所居住的这个片区。冷冰冰的高楼大厦掺入烟火气，若即若离的人情味，这才是我心目中理想的城市该有的样子。我爱这些光鲜亮丽的大楼，更爱这无情与有情的反差——当冷冰冰的技术将 What makes us human 一点一点的剥夺时，那些让人是人的元素显得愈发可贵和美丽。\n是的，我说的就是赛博朋克。高技术，低生活，以及由此衍生的人们之间的联系。现在的我们正生活在赛博朋克的城市里，与未来只不过是程度的高低。当人们需要靠着生活中的“小确幸”来获得一点幸福，众人就已经沦为行尸走肉，在大多数时间，状态与机器并无差别。飙车、泡吧……你可以在大都市活的很痛快，却很难在大都市活的幸福。技术的发展让人们活的更痛快，却在某种程度上剥夺了人们活的幸福的权利。\n城市的核心，是人。我望着我周围的一片光鲜亮丽的钢筋水泥森林，以及钢筋水泥下那些为了蝇头小利而破口大骂的人们，我真的感到呼吸困难。\n城市的核心是文化，是人，而非崭新却散发着有害化学味道的钢筋水泥森林。\n高楼林立，光鲜亮丽却鲜有人迹的城市是可怕的。\n我所在的这个片区，甚至可以称得上光鲜亮丽,可生活在这里的人们大都疲于奔命。我希望感受城市的美好，却只能在这浮躁里迷失漂流。我们何去何从？\n我真的生活在真实的世界吗？还是一直被周围的幻象欺骗？当 AI 能够 24 小时比真人更加卓越的满足你的一切情感需求，真人还有存在的意义吗？当人们完全依赖 AI 提供给我们的便利和情感的满足，当真实不再能带给我们快乐，当我们的一切需求都由别人说了算，由巨头公司，威权政府控制，说断就断？真的到了那时，我们怎么拯救自我？\n我们在科技上越来越强大，富有，在精神上，甚至在物质上都变得越发荒芜。\n","date":"2022-07-20T20:26:24Z","permalink":"/2022/07/when-we-are-closer-to-cyberpunk/","title":"当我们愈发接近赛博朋克"},{"content":"众所周知，我闲的蛋疼为了对比不同的博客系统并找出最适合我的那一个，我的博客设立了三个版本，一个是 Hexo、一个 是Typecho、一个是Wordpress。这三个版本的博客各有特点，写作和发布文章的方式是各有千秋，功能的多少和轻重也互不相同。因此，尽可能的减少文章“移植”到不同的博客系统的工作量成为了刚需。\n用 Markdown 写作 自从第一次使用 Hexo 搭建博客而第一次使用 Markdown 写作以来，我的写作变从未离开过 Markdown。不光不需要考虑排版的问题，不需要时不时就操作一下鼠标的感觉体验过了就真的离不开。再者，我还在使用 Hexo 作为我的一套博客框架，必须使用 Markdown 写作，写好的 Markdown 直接发布在 Hexo 博客上，不需要任何的二次修改。因此，肯定是用 Markdown 写作了。在确定了写作的主题后，我会用 Hexo 生成一个 Markdown 文件。\n之后，我会使用 Typora 编辑这份 Markdown 文件，写好文章。\n发布到 Hexo 文章写好以后，下面就是刻进骨子里的操作:\ncd blog hexo g export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890 hexo d直接将文章发布到 Hexo 博客。为什么在有了 Typecho 以后我还是在使用看上去不那么方便的 Hexo？就像 Markdown，只要配置得当，Hexo 对 Markdown （Github Flavoured Markdown）近乎完美的支持可以让我更专注于写博客本身，不需要考虑任何关于格式方面的问题。\n发布到 Typecho 现在还是相对简单的部分。Typecho 虽然支持 Markdown，但对于 Github Flavoured Markdown 支持的程度显然没有 Hexo 好，例如- [x]在使用 Hexo 时就可以正确渲染，但 Typecho 就不能识别。这时我们便不得不用 HTML 替换掉原本的 Markdown 代码。\n这里我使用了 Markdown 要是你在黑土地看这篇文章，你可能会发现上面的 Checkbox 并没有被正确渲染，如果直接以 HTML 代码替换掉这个 Checkbox，显示的效果如下：\n这里我使用了 HTML 替换好以后文章方可正常显示。\n发布到 Wordpress Wordpress 的编辑器真的是个大麻烦。不光默认没有代码高亮，也是个连 Markdown 都不支持的东西。不过好在 Wordpress 的编辑器支持插入自定义的 HTML 内容。经过简单的尝试，在将 Markdown 文章转换成 HTML 格式直接粘贴在 Wordpress 的 HTML 内容编辑器后切换回可视化编辑器会直接变为 Wordpress 经典编辑器，这使得我想要进一步编辑文章添加一些 Wordpress 特有的区块时很不方便。所以，在 Typora 里直接复制文章粘贴到 Wordpress 的默认编辑器里，随后更改渲染错误的地方替换为自定义 HTML 代码块。\n对 Typecho 和 Wordpress 的小修小补 你可能会注意到，我写文章的时候时常需要添加代码块和 Mermaid 流程图，hexo-theme-cactus自带代码高亮，而我又通过修改主题加入了mermaid.js，但 Typecho 和 Wordpress 默认都无上述两个功能。为了尽可能的减少文章“移植”到不同的博客系统的工作量，我对这俩货进行了一些小修小补。\nWordpress 我采用的 Wordpress 主题是 MDx，并不带有代码高亮功能，因此我使用了 enlighter.js 官方提供的 Wordpress 插件。安装这个插件后，Wordpress 编辑器里会多出一种名叫 Enlighter 的区块，使用它作为代码的载体即可实现代码高亮的功能。这款插件提供的自定义样式选项不足，这个区块本身的样式又过于棱角分明，与 MDx 圆润的边角格格不入。好在这款插件的 CSS 文件能够被找到，只要学过 CSS ，修改出一个圆润的边角也不是什么难事。\n打开博客的安装目录，找到/wp-content/plugins/enlighter/resources/enlighterjs里的enlightenjs.min.css文件，编辑这个文件，找到其中的enlighter-default类，修改padding参数为10px，添加border-radius参数为10px后保存，就可以得到一个圆润的高亮代码块。\n说到 Mermaid，虽然 Wordpress 原生不自带 Mermaid，但只要装一个插件就能实现支持 Mermaid 流程图，直接在 Wordpress 的应用商店里搜索 Mermaid 即可。\nTypecho 我采用的 Typecho 主题是 Story，代码高亮功能是自带的，但很遗憾，Typecho 并不支持 Mermaid，同时我似乎没有找到为Typecho 添加 Mermaid 的插件。这意味着我们只能自己去添加这个功能。\n给我等着，我先去学一会 PHP，这事没完！\n","date":"2022-07-12T14:34:06Z","permalink":"/2022/07/my-blog-workflow/","title":"同时发布三个版本的站点？我的博客工作流及对每个版本的优化方案"},{"content":"从安卓手机换到 iPhone 就想要改掉清理后台的习惯，查阅了一些资料，知道 iOS 后台机制不需要用户介入，在使用中也实行了这一点，奈何心里总有幽灵作祟，总是会感觉到不清理后台续航会降低，手机会发热，进而管不住清后台的手。\nLet me be as clear as I can be: the iOS multitasking bar does not contain \u0026ldquo;a list of all running apps\u0026rdquo;. It contains \u0026ldquo;a list of recently used apps\u0026rdquo;. The user never has to manage background tasks on iOS.\nFraser Speirs\n在网上搜索到的大部分中文内容会引用 Fraser Speirs 在他的一篇博客里很明确的指出的内容：iOS 的 Multitasking bar 实际上是 A list of recently used apps，所以，你不需要清理后台。但当我顺藤摸瓜找到这篇博客的原文时，却发现这篇博客发表时间在 2012 年。10 年过去了，这篇文章的内容自然是经不住沧海桑田，早已过时，情况早已发生了微妙的变化，苹果早就加入了各式各样的后台机制。这就衍生出了两个问题，苹果的后台机制是否真的会影响 iPhone 的续航和发热？杀后台是否有助于提升使用体验？\n有趣的是，作者在某个时候关闭并存档了他的博客，在他的存档里却并未出现这篇文章，这意味着作者可能刻意删除了它。既然这种流传已久的说法是基于一篇早已过时的文章，结果自然是不可信的，根据这篇文章得出结论，是一个不负责任的营销号行为，我能做的唯有查找更新的资料以及亲身实践。\n查找资料 Some apps perform work for a short time while in the foreground and must continue uninterrupted if they go to the background. Other apps defer that work to perform in the background at a later time or even at night while the device charges. And some apps need background processing time at varied and unpredictable times, such as when an external event or message arrives.\nApple Developer Docs\n苹果不会也不能一刀切死后台，相反，针对不同应用对后台运行的需求，苹果举了五种场景的例子。\nContinue Foreground Work in the Background\nDefer Intensive Work\nUpdate Your App’s Content\nWake Your App with a Background Push\nRequest Background Time and Notify the User\n为了用户体验，苹果对应用的后台限制非常严格。针对这五种场景，苹果设计了多样且易于使用的 API 来满足不同的需求，在默认情况下，当一个 App 进入后台时，系统会给 App 最多5秒的时间来进行回写数据等操作，随后系统便会将这个 App 挂起（Suspend），5秒的时间对于大多数 App 来说已经足够。当 App 需要在后台完成更多操作时，可以参照苹果给出的 5种场景设计 App 的后台策略。例如：一个新闻类 App 可以在收到新闻时被系统唤醒到后台接收这则新闻，调用application(_:didReceiveRemoteNotification:fetchCompletionHandler:)，App 便可以取得至多 30 秒的时间完成接收新闻的操作。同时，App 完成操作后必须要调用endBackgroundTask(_:) 以告知系统自己完成了操作。否则在超过30秒后，系统便会杀死（Kill） App 的进程。得益于 AppStore 严格的审核，上架的 App 基本都经过了规范的编写。\n又例如：某网盘需要备份用户今天新拍摄的照片，这是一个密集且工作量大的工作（不知道怎么翻译，原文是 Intensive Works），那么调用BGProcessingTask以计划一个备份工作，系统会自动根据用户充电的时段、睡觉的时段等信息训练出来的模型自动选择最佳的时段来执行计划好的 Intensive Works。\nSchedule these types of background tasks using BGProcessingTask, and the system decides the best time to launch your background task.\n如你所见，得益于苹果给开发者提供的一套强大易用的 API 以及 AppStore 对于应用在上架前严格的审核，iOS 的后台机制在保持对应用严格限制的情况下却没有增加开发难度，在开发文档里，出现的最频繁的一句话是。\nThe system decides the best time to launch your task.\n苹果将自己用心开发的优质 API 提供给开发者，这些 API 看似简单，实则需要有大量的技术沉淀，看似简单的“选择最佳时间”，背后却充斥着大量的机器学习算法，既然开发者直接调用现成优质的 API 就能将用户体验提升几个层级，那么何乐而不为呢？在同一个开发者付出相同的工作量的情况下，开发 iPhone App 能够实现同功能 Andriod App 高出几个层次的质量，这也难怪早期 iPhone 在抢占市场份额时，App Store 能够在审核如此严格，抽成如此高的情况下涌现大量优质应用。AppStore 里应用调用后台的规范程度也就不必多言了。完全可以像谷歌一样用1倍的努力把体验做到90分，却还是要花10倍的努力把体验做到极致，这很苹果。\n杀后台是否有助于提升使用体验？ 我们已经知晓苹果的后台机制是十分智能的，可后台机制再智能也依旧有失灵的时候。这就是第二个问题，杀后台是否有助于提升使用体验？\n可以说，除了能让心里更好受，以及可能在这几个咖喱味十足的iOS版本提升滑动桌面的顺滑度以外，杀后台无助于提升使用体验，甚至会降低使用体验。\n滑动关闭后台应用程序可能会降低iPhone的续航时间，除非是无响应的情况，否则不应该强制关闭应用。\nCraig Federighi\n当应用程序被从“后台”划掉，其会被移出RAM，这样，应用程序将不会再运行。按照苹果的逻辑，前面所提到的一系列智能的后台机制都不会运作。不仅如此，重新从闪存载入APP会增加电量的消耗且徒增发热，比从直接从RAM“解冻”APP更加费时。这么一看，Craig说的是不是很有道理？是的，在Craig所处的环境里，这句话绝对可以称得上是“金玉良言”。\n可惜在中国，情况有些许不同。第一种情况是流氓应用，以中国第一产品经理的微信为例，在之前很长一段时间里（可能现在也是）微信会通过某种手段尽可能延长自己的后台存活时间，甚至于后台活动超过前台使用的时间。这自然会使耗电量增加。从后台列表，准确的说，是最近使用的应用列表强行杀掉微信，的确可以避免这种情况的发生。但微信在国内的地位不必我多说，从后台划掉微信会大幅增加微信的启动时长，每次打开微信看到“连接中……收取中”转圈转个老半天可比耗电更烦人。再者，没有人会希望为了省电而错过女朋友或者上司只打一次的微信电话。这种时候，停用微信的后台刷新可能是一个更好的选择。\n类似的情况发生在国内被墙的服务上，在没有代理的情况下，除非开发者专门对此作过优化，国内被封锁的服务、应用会出现一个较为尴尬的问题：按照计划，这些应用需要更新内容，但因遭到GFW的封锁，一直收不到服务器的回应，于是一直运行，直到触发系统的时间限制。前面已经提到过，这种情况下，APP会被系统“杀死”。对于第二种情况，解决方法有二：一是做好分流，24小时挂代理。二是和微信一样，停用这些应用的后台刷新。但无论如何，不要从后台直接杀死这些应用，因为直接杀死这些应用造成的体验远比耗电更糟。\n写个总结 在写这篇文章时，我发现，越是写下去，越是背离了写这篇文章的初衷，即“提升使用体验”。技术为人文服务，智能手机归根结底只是我们手边的一个工具，与其费尽心机省电，不如按照自己觉得舒服的方式使用手机。耗电也好，卡顿也好，都由技术的进步解决。我们可以因兴趣使然研究这些技术问题，但绝不能让这些技术问题成为我们生活的全部，放下手机，放下这些技术问题，我们还有很多更有意义的事可以做，很多人可以聚，很多地方可以去玩。\n参考 Choosing Background Strategies for Your App\nBackground Tasks\nbeginBackgroundTask(withName:expirationHandler:)\nExtending Your App\u0026rsquo;s Background Execution Time WWDC2019: Advances in App Background Execution\nDo iOS apps run in the background?\nMisconceptions About iOS Multitasking\niOS Multitasking Misconception\n题图来自：https://www.macworld.com/article/667789/iphone-xs-review.html\n","date":"2022-07-09T14:55:10Z","image":"/2022/07/do-i-need-to-force-kill-apps-on-iphone/20231011110457_hu_866faa8542cee1fa.webp","permalink":"/2022/07/do-i-need-to-force-kill-apps-on-iphone/","title":"我需要清理iPhone的“后台”吗？在2022年看iPhone的后台机制"},{"content":"最近拿到了 Azure 的学生服务器，Hexo 缺少好看而功能完备的主题，于是我开始筹建我的动态博客网站。我将分别使用我所提到的博客系统一段时间，看哪一个更适合。\n我不想把这篇文章写成维基百科，所以我尽量的只讲我的体验和理解，你可以很容易的在网上查到这些博客框架的相关资料。\nHexo 优点 直接生成静态网站，轻便，稳定，快速 原生支持Markdown 方便托管，可以托管在如Github Pages等平台上节省服务器费用 缺点 静态网站没有后台，不方便管理 很难实现跨设备编辑，除非部署Github自动化等 插入图片比较困难，需要配合图床和如Pic Go等软件进行 对新手不友好，实际使用过程中改改主题的源码实现某些功能是难免的事 样例：L3ZC主站\nHexo是一个基于Node.js的静态博客框架，这个就不消说了，光从它35k的stars就可以知道大家有多喜爱这个框架。\nHexo直接生成静态网站，这意味着无比快速。原生支持Markdown，配合一个简洁的Markdown编辑器如Typora，可以让你集中精力到内容本身，这毫无疑问可以提高写文章的效率。只有静态网站可以被托管到Github Pages上，这也就是为什么我当初选择了Hexo作为自己博客的博客框架，而后为了迎合Hexo，我开始用Markdown写作，做了自己的图床，试着修改Hexo主题，即使我还没开始学Java Script。自从用上了Hexo，我爱上了用Markdown写作，以至于后面切回Wordpress的古腾堡编辑器的时候我都很不适应。\nHexo 自身的特性决定了它新手不友好，他没有原生的评论系统，实现一个功能要对主题的源码进行改动，这可不是人人都会并且愿意的，新手很容易过分纠结网站的外观和功能而忽略了内容本身。Markdown 难以插入图片，需要额外建立图床，这也是相对麻烦的事情。Hexo 没有后台，只能通过命令行生成网站，这就意味着你别想在移动设备上编辑文章，也不能在两台电脑之间交替编辑（当然如果配合坚果云等那另说）。\n即使有这些缺点，Hexo 依然是一个优秀的博客框架，即使用上了动态博客框架， 我也依然不会放弃使用 Hexo 写作。\nTypecho 优点 小巧快速 原生支持Markdown 提供了友好的图片插入功能，当然你也可以用图床 缺点 新手不友好，虽然比Hexo已经好很多 移动设备不好编辑文章 样例：L3ZCの黑土地\n对于个人博客用途的网站，个人认为 Typecho 是一个相对理想的选择，不像 Wordpress 那么重，也不像 Hexo 那么折腾，并且原生支持 Markdown 。\nTypecho 是动态博客框架，有原生的后台和评论系统，不像 Hexo 这种静态博客框架想要实现评论功能都要修改主题源码，原生支持 Markdown 让 Typecho 用起来非常舒服，如果计划从 Hexo 迁移到 Typecho，绝对无需担心出现不适应的情况，我完全可以像在 Hexo 写博客一样，在 Typora 里写好文章，然后直接复制粘贴到 Typecho 的文章编辑页面，设置好文章标题和标签等直接点击发布，大功告成。如果是第一次使用 Typecho，也大可不必担心图床的问题，Typecho支持上传附件，足以让你在完全不用任何图床的情况下写出一篇图文并茂的文章。嫌默认主题不好看？可以去网上找一找 Typecho 的主题，基本都可以找到自己想要的主题，烂大街的 Handsome 就是一个很好的例子。\n对于个人博客来说 Typecho 几乎完美，但也不是没有任何问题，例如，新手必须要学习怎么写 Markdown。移动设备不好编辑文章等等。总之Typecho 是一个比较适合我的博客框架。\nWordpress 优点 界面好懂，新手友好 后台管理很容易，只要能上网，很容易就可以在任何时间地点用任何设备更新网站 用户基数大，主题、插件丰富，实现某个功能很容易 缺点 不原生支持Markdown 出了名的重，速度相对比较慢，占用服务器资源 样例：L3ZCの试验田\n全世界 30% 的网站都在使用 Wordpress，这可不是吹的。Wordpress 的功能有多丰富可想而知。\n这些 Wordpress 网站不光包括博客网站，还有论坛，甚至电子商务网站，你没看错，Wordpress 就是能实现很多功能。也更容易实现华丽的效果，如果你的网站有这种需求，那么 Wordpress 是个不错的选择。Wordpress 对新手很友好，从部署网站开始，不仅可以直接使用 Wordpress 官方提供的托管服务，得益于 Wordpress 庞大的用户基数，很多服务器提供商更是直接提供了一键部署 Wordpress 到服务器的功能。部署完成开始写作，Wordpress 的编辑器直观好懂，很容易就能上手写出图文并茂的文章。Wordpress 有功能丰富的后台，很容易就能完成博客的管理，即使在手机上也是如此。用户多就是任性，主题和插件多的挑不过来，直观好用。\n当然，缺点也很明显，Wordpress 非常臃肿，速度会相对较慢，在服务器性能低和网络差的环境下则更明显。其次是不原生支持Markdown这一点让我非常恼火，在Typora里写好的文章复制粘贴到 Wordpress 的编辑器里大概率需要重新排版，这也导致我很不愿意在 Wordpress 上多发表文章，排版这种基础的东西都需要花费精力，自然就没法好好写文章了。\nBlogger 先用一段时间再说。\n","date":"2022-07-04T17:28:43Z","permalink":"/2022/07/comparison-of-different-blog-systems/","title":"Wordpress？Typecho？还是Hexo？哪个博客系统适合我？"},{"content":"我成功薅到羊毛，拿到了Azure的学生赠送额度，重新拥有了VPS，当前的博客是基于Hexo构建，静态网站的局限性让我考虑了设立动态网站的可能。\n什么？Azure有学生免费羊毛？ 这些天我一直在寻找一个适合我的虚拟服务器，我只是想搭建一个网站而已，我是学生，无法承受每月动辄一两百配置却低的可怜的正价服务器，看到Azure有羊毛可以薅那真是再好不过了。Azure有两种试用方式，第一种赠送200美刀，但需要信用卡，我一学生怎么可能有Visa卡？第二种方式赠送100美刀，只需要学生邮箱账户，既然只需要建站，100刀用一年其实不成问题，实际使用基本感觉不到很大的差异。\n先打开Azure学生免费申请入口，点击免费开始使用，填入你的教育邮箱账号（支持中国大陆的教育邮箱账号，良心），收邮件验证一下，你的免费额度就可以领到了。什么？学校没有给你教育邮箱？自己去要，什么东西都要塞你手上吗？据这个页面上的介绍，每年100刀用完以后，如果你仍然是学生，可以再次申请到100刀的额度。如果这句话是真的，不出意外，那么学生时代就不需要额外为云服务器付费，想想就很香。\n这服务器怎么样呢？ 真要我说的话，一般。\n在中国大陆，开 Azure 服务器一般会选择 South East Asia（新加坡）或者 East Asia（香港）两个数据中心。这两个数据中心却没有一个为大陆的网络环境做过优化（虽然这也不能怪人家），简单说，联通连香港数据中心会绕路新加坡，电信连新加坡数据中心会绕路香港，移动则都会绕路东京，想要一个数据中心三大运营商的宽带都不绕路约等于做梦。\n更坑爹的是，新加坡数据中心因为这个原因常年爆满根本开不到服务器。大部分时候只能选择香港数据中心，我也不例外。不过他们的服务器的网速倒是挺快，万兆网用来从Github上Clone之类的挺舒服，听我一句劝，不要跑测速，一跑就是一美刀（哭死）。\n顺带一提，上下行不对等那肯定是没有独立 IP 流媒体解锁就别想了。因为在用别的上网方案，所以暂时没有用这玩意来科学上网，过一阵子可能会装上不同的协议测个速。另外服务器跑分什么的有时间就弄。\n回到正题 终于要说我的两个新动态网站了。本站新增了两个动态网站，分别是基于 Wordpress 的L3ZCの试验田和基于 Typecho 的L3ZCの黑土地，加上基于 Hexo 的L3ZC主站，三者并行。\n其中，试验田是全新的网站，主要发布技术类文章，日后可能会做出频繁的改动；黑土地则追求稳定与快速，并且与主站保持一致的样式，在时机成熟的时候可能会与主站的角色互换；主站是基于Hexo构建的静态网站，托管在 Github 上，长期稳定存在。\ngraph TB A[发布文章] --全部--\u003e B[主站] B -- 技术类 --\u003e C[试验田] B -- 所有 --\u003e D[黑土地]To Do List 有一大堆要做的事，例如修好黑土地的评论系统，做好SEO等。总之，有得忙活了。\n","date":"2022-06-28T22:41:07Z","permalink":"/2022/06/new-site-on-azure/","title":"在拿到了Azure的学生免费额度以后，我增设了两个新站点"},{"content":"室友天天开黑，这就算了，还老是用外放，不得已，只能让他们打不爽，从根本上阻止他们开黑，还我寝室一个安静的环境，至少，让他们按时睡觉。\n寝室的网络环境 路由器 一台捡垃圾的小米CR6608，刷入了 OpenWRT ，承担我们寝室所有的网络流量，由于是一所垃圾大学，校园网限制一套餐一终端，寝室里又只有一个网络口，大家都用我的套餐，整个寝室的网络控制权当然在我的手上。\n室友上网的设备 其余三个室友都打英雄联盟，其中两个使用笔记本，一个是台式机，没有无线网卡，而且台式机恰巧是打的最凶的那位。\n决定采用的方案 首先，肯定不能彻底阻断寝室网络与英雄联盟服务器的连接，这样明显感知太强，容易被发现，其次由于另外两个室友都是笔记本电脑，发现丢包率太高肯定会开热点换移动网络，所以最终的方案确定为模仿GFW对网站随机丢包的干扰模式。\n具体行动 首先先给每个室友分配静态的IP地址，原因看到后面你就知道了。\n上网查找资料，可以知道英雄联盟所使用的端口:\n项目 端口号 League of Legends Game Client 5000 - 5500 UDP Patcher and Maestro 8393 - 8400 TCP PVP.Net 2099 TCP PVP.Net 5223 TCP PVP.Net 5222 TCP HTTP Connections 80 TCP HTTPS Connections 443 TCP Spectator Mode 8088 UDP and TCP 向路由器的iptables里添加以下随机丢包的规则：\n# Block LOL iptables -I FORWARD -p udp --dport 5000:5500 -m statistic --mode random --probability 0.3 -j DROP iptables -I FORWARD -p tcp --dport 8393:8400 -m statistic --mode random --probability 0.3 -j DROP iptables -I FORWARD -p tcp --dport 2099 -m statistic --mode random --probability 0.3 -j DROP iptables -I FORWARD -p tcp --dport 5223 -m statistic --mode random --probability 0.3 -j DROP iptables -I FORWARD -p tcp --dport 5222 -m statistic --mode random --probability 0.3 -j DROP iptables -I FORWARD -p tcp --dport 5233 -m statistic --mode random --probability 0.3 -j DROP iptables -I FORWARD -p tcp --dport 8088 -m statistic --mode random --probability 0.3 -j DROP关于如何在 OpenWRT 上自定义 iptables 规则，有两种方法，第一种方法，打开 系统 -\u0026gt; TTYD终端 将上面的命令一行一行复制进去回车，用这种方法，规则会在路由器重启或者 iptables 重启后失效，第二种方法，打开 网络 -\u0026gt; 防火墙 找到 自定义规则 选项卡，将上述内容粘贴到这个页面已有内容的后面，注意不要覆盖文本框里原先的内容，完成后点击页面下方的 保存并应用，这样即使是重启路由器也不会重置 iptables 规则。\n这些 iptables 规则用到了 ipopt 模块，而一些固件不会默认安装 ipopt 模块，如果发现 iptables 对这些规则报错，请看后文的安装 ipopt 部分。\n生效后，室友打英雄联盟就会在校园网本就1%到5%丢包率的基础上增加30%的丢包率。经过室友的盲测反馈（我怎么可能会让室友知情呢？！）放技能总是放不出去，打的非常不爽。\n但是这种方法似乎不适用于室友开加速器的情况，所以我们可以针对这种情况直接限制室友所有的流量，也就是说，不论室友的电脑发出什么数据包，都能享受到30%的丢包率，除非室友开热点，当然台式机是不可能的，这种方法就可以让所有的加速器都失效。前提是，室友的ip地址必须要提前确定，这也就是为什么需要提前给室友的电脑分配静态IP。\n向路由器的iptables里添加以下规则\n# Block specific roommate iptables -I FORWARD -s 你室友的内网ip -m statistic --mode random --probability 0.3 -j DROP # 以此类推即可“照顾”室友所有的流量。\n很好，现在每天11点我都会准时更新防火墙规则，至少让寝室安静一点。\n授人以鱼不如授人以渔 这些参数都是些什么？\niptables iptables是运行在用户空间的应用软件，通过控制Linux内核netfilter模块，来管理网络数据包的处理和转发。\n——维基百科\n简单点说：iptables是Linux的防火墙软件，可以通过设定的规则过滤掉特定的数据包达到防火墙的目的。OpenWRT基于Linux，自然也用iptables作为防火墙。\n-I FORWARD iptables有所谓的“五链”和“四表”。\n“五链”是指 netfilter 定义的 5 个规则链。每个规则表中包含多个数据链：INPUT（入站数据链）、OUTPUT（出站数据链）、FORWARD（转发数据链）、PREROUTING（路由前数据链）和POSTROUTING（路由后数据链），防火墙规则存储在这些数据链里。\n“五链”的结构如下：\ngraph LR A[PREROUTING] --\u003e B[路由决策] B --\u003e C[FORWARD] B --\u003e D[INPUT] D --\u003e E[Local Process] E \u0026 C --\u003e F[POSTROUTING]四表分别是：\nfilter：过滤整个数据包，在 INPUT、FORWARD 和 OUTPUT 链可用 nat：控制数据包的地址转换，在 PREROUTING 、INPUT、OUTPUT 和 POSTROUTING 链可用 mangle：修改过滤数据包中的原数据，在 PREROUTING、INPUT、OUTPUT、FORWARD 和 POSTROUTING 链可用 raw：控制 nat 表连接追踪机制的启用与否，在 PREROUTING、OUTPUT 链可用 路由器的功能是转发数据，这些数据显然经过 FORWARD 链，故规则都在 FORWARD 链上添加。在 iptables 上使用 -I 参数插入规则时，默认会插入 filter 表，也就是我们需要的表。\n-p xxx \u0026ndash;dport xxxx 使用 iptables 时，-p 参数用于指定规则适用的协议，\u0026ndash;dport，即destination port的缩写，支持范围匹配，可以匹配数据包所去往的端口，这里参照英雄联盟所使用的端口和与之对应的协议一一阻止。\n-m statistic \u0026ndash;mode random \u0026ndash;probability 0.3 这些都是自定义的 丢包参数，可以实现很多其他的功能，因为iptables功能太多，故这里不做赘述，感兴趣的话可以自行查阅iptables相关的教程。\n-j DROP iptables 可以对符合规则条件的数据包做多种处理：\nACCEPT：允许数据包通过 DROP：丢弃数据包 REJECT：拒绝数据包通过 LOG：记录日志 DNAT：目标地址NAT SNAT：源地址NAT MASQUERADE：地址欺骗 REDIRECT：重定向 需要随机丢弃数据包，自然是选择DROP。\n特定时间自动添加/删除丢包规则 在路由器的 Crontab 里添加如下规则\n#Automatic Block 0 0 23 * * ? iptables -I FORWARD -p udp --dport 5000:5500 -m statistic --mode random --probability 0.3 -j DROP 0 0 23 * * ? iptables -I FORWARD -p tcp --dport 8393:8400 -m statistic --mode random --probability 0.3 -j DROP 0 0 23 * * ? iptables -I FORWARD -p tcp --dport 2099 -m statistic --mode random --probability 0.3 -j DROP 0 0 23 * * ? iptables -I FORWARD -p tcp --dport 5223 -m statistic --mode random --probability 0.3 -j DROP 0 0 23 * * ? iptables -I FORWARD -p tcp --dport 5222 -m statistic --mode random --probability 0.3 -j DROP 0 0 23 * * ? iptables -I FORWARD -p tcp --dport 5233 -m statistic --mode random --probability 0.3 -j DROP 0 0 23 * * ? iptables -I FORWARD -p tcp --dport 8088 -m statistic --mode random --probability 0.3 -j DROP #Automatic unblock 0 0 7 * * ? iptables iptables -D FORWARD -p udp --dport 5000:5500 -m statistic --mode random --probability 0.3 -j DROP 0 0 7 * * ? iptables -D FORWARD -p tcp --dport 8393:8400 -m statistic --mode random --probability 0.3 -j DROP 0 0 7 * * ? iptables -D FORWARD -p tcp --dport 2099 -m statistic --mode random --probability 0.3 -j DROP 0 0 7 * * ? iptables -D FORWARD -p tcp --dport 5223 -m statistic --mode random --probability 0.3 -j DROP 0 0 7 * * ? iptables -D FORWARD -p tcp --dport 5222 -m statistic --mode random --probability 0.3 -j DROP 0 0 7 * * ? iptables -D FORWARD -p tcp --dport 5233 -m statistic --mode random --probability 0.3 -j DROP 0 0 7 * * ? iptables -D FORWARD -p tcp --dport 8088 -m statistic --mode random --probability 0.3 -j DROP即可实现每天晚上11点自动添加丢包规则，每天早晨7点自动删除丢包规则。\n补充：安装 ipopt 模块 部分固件可能存在没有ipopt模块的问题，而这些规则大部分都使用到了这个模块，这种情况下需要手动安装。\nipopt 的安装有两个选择，一般出于稳定性考虑会安装用户层的iptables-mod-ipopt，而内核级的kmod-ipt-ipopt则在设备 CPU 性能孱弱或存储空间不够用的情况下选择。\n内核级的模块一般需要预先编译固件才能安装，而用户层只需执行以下opkg命令即可：\nopkg install iptables-mod-ipopt后期计划 后续可能会写一个每天指定时间自动添加，自动删除iptables规则的脚本，实现应该相对容易。最近要期末考试，备考要紧。\n其次可能会补充iptables的常用功能解说。\n","date":"2022-06-26T23:34:25Z","permalink":"/2022/06/use-iptables-to-ban-lol-in-dorm/","title":"在OpenWRT路由器上使用iptables对英雄联盟随机丢包"},{"content":"生活相对有规律，比较自律，早睡早起，锻炼身体，甚至每天绝大部分上网时间都没有花在游戏上，可能这就是你的样子，人们根本就不会觉得这种人会和网瘾扯上关系。很多情况下，事情并非如此。\n我到底是怎么了？ “瘾”这个词，并不形容短期心理状态，而形容长期大脑的变化。你绝对在某一时刻体验过短时间内多巴胺爆棚的快感，并且从此喜欢上了这个状态，这并不是上瘾，仅仅是喜欢。更进一步，你可能并没有察觉到你的大脑里正在发生的某些事情，成瘾的过程无法被大脑察觉，你的大脑可能在尝到这种快感以后发生了微妙的变化，产生了对这种状态的依赖，这时才算是真的成瘾。\n既然成瘾无法被大脑察觉，如果不去刻意感知，绝不会知道自己正在上瘾。自很早以前，在打开 YouTube、Twitter 等网站时即使知道自己正在虚度光阴，即使屏幕上的内容毫无乐趣也于我无用，我也还是会继续看下去，并且不知不觉的看掉一个下午。在逛 AppStore 的时候，通常都是为了用一个 App 而用一个 App，即使不需要用到这个 App，我也会下载下来，摸索许久。在找资源、信息的时候，即使我用不到这个资源、信息，我也会不断收集。即使还有更要紧的事要做，即使这对我无意义甚至有害，我却无法停下。\n这算生病吗？ 大脑倾向于寻找更多的多巴胺，自然也想要重复获得多巴胺的体验。物极必反，太多的多巴胺亦不是一件好事，人类进化出一套平衡机制：当你获得太多的多巴胺时，大脑就会产生与多巴胺作用相反的物质来平衡。飞的越高，摔得越惨，放在这里简直再也合适不过，大脑体验多巴胺爆棚的极乐之后，会立刻陷入生与多巴胺作用相反的物质所带来的痛苦反噬的深渊。这种感觉实在是太过于痛苦，大脑倾向于找到更多的多巴胺来平衡痛苦反噬，却又引发更多的痛苦反噬，从而陷入恶性循环。\ngraph LR A[想要获得多巴胺] --\u003e B[获得多巴胺] B --\u003e C[产生痛苦反噬] C --\u003e D[痛苦] D --\u003e A这就是上瘾，一个无法挣脱的泥潭。其实任何东西成瘾都可以算作是生病，就像吸毒一样，即使你已深知吸毒的危害，即使毒品让你的身体承受很大的痛苦反噬，你也还是想要吸毒，因为那里有大脑迫切需要的多巴胺。得不到多巴胺的痛苦远甚于做这件让你获得多巴胺的事所带来的痛苦。\n人们从来没有认真思考过这种现象是否是病，从某种意义上来说，这已经算是生病了。\n还是接着开头说 我曾经把大把的时间花在上网上，看上去，我在学习。表面上，陷入这恶性循环的人看上去会很健康，包括生活方式。他们可能看起来在努力的工作，努力学习。他们自己也不知道自己已经患病。注意区分，两种人很容易混淆，一种是大脑已经因为长期食用 Dopamine snacks 发生变化，一种则是纯粹的追求舒适的感觉，大脑没有变化。这里所讨论的人属于第一种。\n从书籍到文章，从文章到博客，从博客到微博客，从微博客到视频，再从视频到短视频，网络连接的速度越来越快，人们接受信息的媒介却变得越来越浮躁，每当学到一些新的东西，人类的大脑就会产生多巴胺奖励自己，信息媒介的不断进步把获得多巴胺的门槛变得越来越低，简单的来说，既然能以更小的代价获得短期快乐，那么大脑就不愿意花更大的价钱去买长期来看更好但更贵的长期稳定的快乐了。\n不停的学新东西？听上去很好啊？ We’re now in a day and age of Twitter and Facebook. We’re getting bite-sized, pithy wisdom, which is really hard to absorb.\n——Naval\n我们所看到的短信息，即使看上去是十分正确的大道理，十分有用的小知识，实际上全然无用，正所谓大道理只能自己悟出来，听别人讲大道理是没用的。别人是在自己经历和实践上加以理解的基础上总结，我们却不能通过别人的总结反推出理解。\n大多数人被误导：可以通过别人所发出的感悟学习到一些道理。事实上，从来都没有这一回事。只有彻底明白某个道理的人才能发出感悟。想要从发出的感悟回溯被想明白的道理无异于从三条杠看出天地轮回——都是自己的感悟，而非他的。当对问题的认识越透彻（这是一个笼统的感觉，只是借用了中文的这种表达方式），达到某个高度，才能从那个高度出发，发表一些本质上的感悟。这些感悟通常不具备实际的指导价值，可以透过现象看本质，即通过低层次的知识领悟高层次的知识，但若要通过高层次的知识倒退出作者是怎么从低层次的知识获得感悟，除瞎猜外，别无他法。\n自我感动改变不了看这些内容学不到东西的事实。\n这就像是吸毒 为了满足大脑对多巴胺不断增长的需求，我开始熬夜，我虚度光阴。得到了需要的多巴胺却开始懊悔。\n一天不熬难受，熬了难受一天\n——我室友\n陷入前面提到的死循环的人症状就像是吸毒，虽然知道毒品的危害，却因为过度的痛苦不得不再次吸食毒品。一些药品剂量大了就会变成毒品。一些本来对我们有益的举动走火入魔就会变成追寻多巴胺的痛苦恶性循环。\n既然这就像是吸毒，也许我们可以以戒毒的方法消除这种看上去不像是成瘾的成瘾 根据 WHO 发布的一段关于如何戒烟的视频，为了戒烟，吸烟者需要克服尼古丁上瘾，从大脑里移除条件反射和打破潜意识的想法，以及移除社交上的关系纽带。显然，戒除这种看上去不像是成瘾的成瘾要比戒烟容易，因为我们不需要完成第一个挑战以及最后一个挑战，我们只需要移除条件反射和潜意识里的想法，充其量算上克服我们的某个上瘾，学习怎么脱离某个事物生活。\n我会试着去做出一些改变：\n戒除早晨起来拿起手机玩的条件反射 戒除闲下来就想要碰电子产品的条件反射 戒除睡前“不能就这么睡了”进而拿起手机的习惯 当然，仅仅做出这些改变还远远不够。究其根源，瘾的形成是因为更强烈的快感冲淡了其他一切能获得的快乐。那么更进一步，想要彻底戒除成瘾，我们需要重拾那些能给我们带来快乐的小事，体验虽然小但是稳定的幸福感。不去追求一时的极致欢乐，自然也不会跌入痛苦的谷底而陷入恶性循环。\n","date":"2022-06-22T22:22:01Z","permalink":"/2022/06/my-thoughts-on-addictions/","title":"看上去没有病，就真的没有病吗？我对“瘾”的思考"},{"content":"音乐是几乎我生活中不可分割的一部分，我也不吝惜向音乐软件里付钱，用每月少量的钱换来舒适的音乐体验，我认为很划算，这些年跌跌撞撞用过四款音乐软件，想起来也算是回忆了。\nQQ音乐 小时候的我，住在一个悠闲而慵懒的小城。\n独钓寒江雪。\n2015年，梦开始的地方，那时的我拿着一台充话费送的手机，跑着安卓2.3，第一次体验到听音乐带来的快乐，轻快的吉他声在我耳边响起，我在蓝天白云下自由的奔跑，跑累，瘫在地上。\n越是长大，我越是感到忧郁。\n气压越来越大，温度越来越高，我的呼吸愈发困难，小城的慵懒与我无缘，整天与我陪伴的只有培训课与作业，而音乐是我唯一的空间，只可惜，这点空间，我都无缘享受太久。\n网易云音乐 2017年，初中开始，我渐渐的转向了网易云音乐，出于某些原因，我不得不搬走，要论宜居度，那么我搬去的绝对不是一个宜居的地方。\n除了崭新却散发着令人作呕的气味的钢筋水泥森林和宽阔却死气沉沉的道路，这里什么都没有。\n是的，比温馨的小城市更可怕的是光鲜亮丽而处于文化荒漠中的“大”城市。\n手机变成了一台当年的价格屠夫，耳机变成了一副Ear Pods，论外文歌曲，网易云音乐显然比QQ音乐更加适合。当时的网易云音乐，评论区里还充满着有趣的灵魂，或许，交流一下，就没那么不开心了。\n都说，“山雨欲来风满楼”“黑云压城城欲摧”，乌云已经压了过来，空旷的广场上没有给我遮雨的地方。\n也许，在设计时就没考虑有人会在广场上走吧。\n雨没有落下，但是阴天更可怕。凉风刮来，落叶飘零，街上本就不多的行人更加难觅踪迹。想要Peace of mind？恐怕只有这种时候了。\nApple Music 一台划痕遍布，看上去就很沧桑的 iPhone 6 到了我的手上。\n这段时光有些不堪回首。但总是忍不住回忆。说实在的，这一年，课业压力并不繁重。但放假安排可并不这么想，假期一再缩水，一周两天变成半个月两天，再到两年后的一个月两天。\n迟早是要来的。\nApple Music 简洁，没有冗余的功能，更重要的是，没有评论区。原先，网易云的评论区里有很多有趣的灵魂，那时甚至算得上没有被发现的宝藏。只可惜，好地方总会被人发现，用的人多了，就容易变味。那种感觉，与看见一个又一个自然景观被开发成不伦不类的旅游景点无异。\n那些年，我见过多少原本险以远的地方，被开发成不伦不类的旅游景点。\n烈日可以烤焦一切，包括人。不幸的是，烈日天在此地并不少见。\n动辄39度的天气显然不是什么好受的天气，有空调的教室里很舒适，我不否认这一点。烈日炎炎，愈是炎热，空气中的味道愈是复杂，石板铺就的地面被烤出的“石头味”，水塘里散发的“水味”，植物蒸腾的“草地味”…… 楼下传来割草机的声音，原本生长旺盛的杂草就这么倒下。太阳的炙烤放大了这种味道，一种比血腥还难闻味道。是的，植物也有血腥味，当走过那片刚被割过的草地，唯一的反应就是快些跑开。其实，这些杂草，很“美”，整齐划一的马尼拉草不过他们的陪衬罢了。\n奇怪的动植物要保护起来，奇怪的人却受到排挤。\n总有一种力量想要扫清一切所谓的“杂草”，好不容易找到的一小片领地，总是这么容易失去。\nSpotify 2021年，高三的我接触到了 Spotify 。\n没有人会爱我，包括我的家人，没有人值得信任，包括自己的亲人。接受现实，没有人会喜欢你。即使没有人会喜欢你，即使全世界都站在你的对立面，也得犹然笑之。\n而宋荣子犹然笑之，且夫举世誉之而不加劝，举世非之而不加沮。\n我如是告诉自己。要像宋荣子一样，当所有人都不值得信任的时候只有自己最值得信任。家长真的值得信任吗？他们所谓的为你好，不过一厢情愿的自我感动，他们所谓的给了你最好的，为你牺牲，为你付出，不过连他们自己都不曾发觉的自我感动的遮羞布。自私是人的本性，事实无可避免，当你想要去信任某个人，最好先考虑清楚那个人是否值得信任。\n高三的我，不断的质疑自己，怀疑我所经历的、所看到的一切。\n第一次接触到 Spotify ，用到 Spotify 的免费版。Spotify 免费版广告重重，听歌体验很差，迁移过来，毫不夸张的说，我立刻回到了我原先使用的音乐软件。当时我不想使用 Spotify ，真的不想，99刀一年的价格实在是超出了我的接受范围。再者，我没有 Spotify 接受的付款方式。\n高中阶段在忧郁的情绪里结束的高考以一个不怎么理想的成绩结束了，我没有如释重负的感觉，也没有兴奋，再也找不到无忧无虑。直到这种时候，顶着与父母在填报志愿时吵架的压力，在与5人合租的账号上开始听起 Spotify。虽然 Spotify 锁区，但曲库足够全，音质也是可以接受的水准。\n听歌让我心情变好，但总是驱散不去我心头的阴霾。也许根本就不存在，也许没必要，谁知道呢。（未完待续）\n","date":"2022-06-14T16:00:52Z","permalink":"/2022/06/music-apps-i-use/","title":"那些年用过的音乐软件"},{"content":"一直都在用VS Code，奈何以前太懒可惜高中的时候很忙，很长一段时间里一直只把VS Code当作自己的文本编辑器，大学有了写C/C++的需求，Xcode实在太大，于是转战在线编辑器repl.it，然而这类Cloud Based IDE链接不够稳定，也没有办法离线作业，于是我开始寻找一个轻量化的C语言开发环境满足我的实际需求。\n声明 本文基于intel Mac，M1 Mac自行安装/执行对应的版本/命令~~主要还是因为我太穷了(狗头)~~其实现在这些工具大部分都适配了M1，应该不会有什么问题\n默认你已经装好了VS Code，没有自行去VS Code官网下载安装\n本文所提到的是Visual Studio Code，不是Visual Studio，如果分不清请自行搜索两者的区别\n安装C/C++编译器 在Mac上，我用的C/C++编译器是clang，相比于gcc，clang运行更快，能在程序出现语法错误编译失败时提供更加明确的错误信息和处理建议（这点我在Windows上用gcc时深有体会，gcc给的信息总是非常的confusing）。\n先检查你的Mac是否自带clang编译器，执行clang -v或者clang --version，没有出现clang的版本号则需要安装clang，执行：\nxcode-select --install按照提示安装完成。\n安装VS Code相关扩展 在VS Code里安装以下拓展（括号里的是作者）\nC/C++(Microsoft) Code Runner(Jun Han) 简体中文拓展：Chinese(Simplified)（可选） 新建并配置工作区 新建一个文件夹作为工作区，注意文件夹名称不能出现中文和空格！！，这里根据我的需求，新建一个名为C_Homework的文件夹，随后在VS Code的菜单栏里选择：文件-\u0026gt;打开文件夹，并信任此文件夹中文件的作者。\n测试C/C++环境是否正常 打开后在VS Code左侧文件面板中刚刚创建好的文件夹里新建一个C/C++文件，以.c/.cpp作为拓展文件名，例如hello.c/hello.cpp，然后写一个基本的C/C++程序\n#include int main(){ printf(\"Hello VSCode!\"); return 0; }完成后按command + S保存文件，如果在之前的步骤里正确安装了Code Runner，则可以方便的编译运行代码，点击右上角的运行图标或者在编辑区右键选择Run Code，如果配置正确即可看到输出。注意Code Runner只是帮你简化了在控制台输命令的过程，所以需要自行保存文件后才能运作，当然也可以在设置成运行前自动保存。\n配置Debugger以调试程序 进入左侧的Debug菜单，点击上方运行与调试按钮，选择C++(GDB/LLDB)-\u0026gt;C/C++: clang 生成活动文件以生成tasks.json文件\n再次进入Debug菜单，点击创建lauch.json文件，选择C++(GDB/LLDB)以创建launch.json，将以下配置粘贴到launch.json里，覆盖掉原本的内容\n{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 \"version\": \"0.2.0\", \"configurations\": [ { \"name\": \"clang++ - Build and debug active file\", \"type\": \"cppdbg\", \"request\": \"launch\", \"program\": \"${fileDirname}/${fileBasenameNoExtension}\", \"args\": [], \"stopAtEntry\": true, \"cwd\": \"${workspaceFolder}\", \"environment\": [], \"externalConsole\": true, \"MIMode\": \"lldb\", \"preLaunchTask\": \"C/C++: clang 生成活动文件\" //没有安装简体中文插件则自行在task.json里复制粘贴换掉 } ] }这里我将\u0026quot;externalConsole\u0026quot;项设置为true，避免在debug需要输入的程序时找不到地方输入的尴尬。\n替换后按command + S保存，以后碰到你需要debug的程序，打好断点，在VS Code的上方菜单里选择运行-\u0026gt;启动调试就可以痛苦的愉快的debug了。\n","date":"2022-06-10T19:42:57Z","image":"https://blog-img.l3zc.com/visual_studio_code.png","permalink":"/2022/06/use-vscode-on-mac-to-build-c-programs/","title":"在Mac上使用VS Code搭建轻量化C/C++开发环境"},{"content":"网上大部分基于Hexo搭建个人博客的教程都是在Windows环境下实现的，Mac OS的教程很少，然而，Mac OS下完成这个任务远比Windows要容易。\n准备工作 安装 Homebrew Homebrew 是一个社区驱动的包管理器，它能方便我们安装我们需要的环境。在中国大陆，推荐使用镜像源安装 Homebrew，下面以中科大镜像源为例。\n设置环境变量：\nexport HOMEBREW_BREW_GIT_REMOTE=\"https://mirrors.ustc.edu.cn/brew.git\" export HOMEBREW_CORE_GIT_REMOTE=\"https://mirrors.ustc.edu.cn/homebrew-core.git\" export HOMEBREW_BOTTLE_DOMAIN=\"https://mirrors.ustc.edu.cn/homebrew-bottles\" export HOMEBREW_API_DOMAIN=\"https://mirrors.ustc.edu.cn/homebrew-bottles/api\"运行中科大 Homebrew 安装脚本：\n/bin/bash -c \"$(curl -fsSL https://mirrors.ustc.edu.cn/misc/brew-install.sh)\"如果你的网络环境良好（不在中国大陆），可以略过设置环境变量的步骤并直接使用正常的安装脚本：\n/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"安装 Git 和 Node.js Homebrew安装完成后，安装 Git 和 Node.js：\nbrew install git brew install node测试所需组件是否安装成功 依次输入下面的命令\nnpm -v node -v git --version 出现npm、Node.js和git的版本号即代表安装成功。\n安装 Hexo 使用 npm 命令安装 Hexo：\nnpm install -g hexo-cli等待安装完成后初始化博客：\nhexo init blog这条指令的作用是在你目前所在的目录下（默认是你的home目录）新建一个名为blog的文件夹（你可以将这条命令中的blog替换成任何你想要的名字），并在内初始化你的博客。之后所有的操作都在这个文件夹下进行，请确保在执行后文的操作前已经切换到了这个文件夹（cd blog）。\n待初始化完成，切换到blog文件夹中，即可生成和预览博客。\ncd blog hexo g hexo s执行hexo s命令后，通过浏览器访问http://127.0.0.1:4000可以预览你的博客，预览功能会实时监测博客的文件变化，并实时反馈在浏览器上，在调试博客前端时非常好用。\n部署到GitHub 执行hexo g命令后博客静态文件会生成在public文件夹下，只需要将这些文件上传到你的静态网站托管服务即可将站点发布到公网，本文用到的托管服务是Github Pages，下文提到的用户名均指你的Github用户名。\n添加SSH Key到github 若之前使用过相关功能且已经配置过请跳过此步。\n配置Git用户名和账号：\ngit config --global user.name \"username\" git config --global user.email \"example@example.com\"其中 username 是你的用户名，example@example.com是你 Github 的登录邮箱。\n然后通过终端命令生成 SSH Key：\nssh-keygen -t rsa -C \"example@example.com\"如果已经创建过会出现 Overwrite (y/n)? n提示可以输入 n，没有创建过的话三个回车就好，执行完成后会在~/.ssh/id_rsa.pub目录下生成 需要使用的 key，也就是公钥。\n到账户主文件夹下同时按Command+Shift+.显示隐藏文件，找到.ssh文件夹，打开id_rsa.pub，将里面的内容全部复制。\n打开GitHub_Settings_keys 页面，新建New SSH Key，Title随意填，Key就把刚才复制的内容全都粘贴上去。然后点Add SSH Key即可。\n完成这些工作以后可以通过以下命令测试是否配置成功：\nssh git@github.com 出现你的Github用户名代表配置成功。\n上传至 Github 在Github上新建一个仓库，Repository Name 填你的用户名.github.io，仓库状态设为 Public，点击 Create Repository 创建新的网站仓库。\n安装 Hexo 的扩展 hexo-deployer-git，注意一定要在你的博客文件夹下执行：\nnpm install hexo-deployer-git --save编辑博客安装文件夹下的_config.yml文件，翻到底部，修改deploy部分为：\ndeploy: type: git repo: git@github.com:你的用户名/你的用户名.github.io.git branch: master修改完成后按Command + S保存，此时就可以使用hexo d把存在本地的博客deploy到Github上了：\n#生成博客 hexo g #将博客推送到指定的地方，在这里是我们的Github仓库 hexo d 虽然我也不知道是为什么，即使我们已经加好了 SSH 公钥，并且填入hexo-deployer-git的仓库信息也是 SSH 链接，第一次执行hexo d命令时还是可能要求你输入你的Github账号和密码，这里如果输入你的账号和密码会出现如图所示的报错，这是因为 Github 在2021年 8 月 13 日停止了使用密码认证的支持，在Gihub的Developer Settings页面上新建一个 Personal Access Token 代替密码就可以顺利 deploy。\n新建一个 Token(classic)，并赋予这个 Token 操作 repo 的权限，有效期可以设置为 No expiration。\n其实出于安全考虑更推荐使用目前处于 Beta 阶段的 Fine-grained tokens ，它提供了更精细的 Token 权限控制，例如可以只允许这个 Token 访问特定的仓库，而非传统 Token 的全部仓库。出于安全考虑，Fine-grained tokens 最高只能设置一年的有效期。\n打开仓库的 Github Pages 功能 成功上传后，博客仓库里应该会出现文件，这时只需在仓库设置里开启 Github Pages 功能就可以了。\n打开仓库的 Settings -\u0026gt; Pages，将 Build and deployment 项下的 Source 设置为「Deploy from a branch」，Branch 选择「master」，单击 Save 保存，Pages 功能就被打开了，每次hexo d，更新后的网页都将被自动部署到 Github Pages。\n执行完毕后，打开你的用户名.github.io就能看到你的博客了。\n绑定自定义域名（可选） 其实到这一步就可以开始写博客了，默认的 github.io 的域名是可以更换的：\n首先自行申请一个域名，登陆到域名申请的后台，添加一条CNAME解析记录：你的用户名.github.io。\n打开存放博客的Github仓库，进入Settings页面在pages选项里的Custom domain里填入你的域名，点击Save，勾选Enforce HTTPS，即可通过自定义域名访问你的博客。\n开始写作 生成一篇新文章：\n$ hexo new \u003c/code\u003e\u003c/pre\u003e\u003cp\u003e执行后会在\u003ccode\u003eblog/source/_post\u003c/code\u003e文件夹里生成一个名为\u003ccode\u003e\u0026lt;title\u0026gt;.md\u003c/code\u003e的文件，打开它即可使用 Markdown 开始写作\n\u003cp\u003e\u003cimg alt=\".md 文件里的 Front Matter\" class=\"gallery-image\" data-flex-basis=\"1057px\" data-flex-grow=\"440\" height=\"158\" loading=\"lazy\" sizes=\"(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) calc(100vw - 40px), (max-width: 1279px) calc(100vw - 280px), 960px\" src=\"/2022/05/mac%E7%8E%AF%E5%A2%83%E4%B8%8B%E4%BD%BF%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2/20220502195744_hu_9a5670a73e1e1098.webp\" srcset=\"/2022/05/mac%E7%8E%AF%E5%A2%83%E4%B8%8B%E4%BD%BF%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2/20220502195744_hu_fc2ff9ea4ed99d72.webp 360w, /2022/05/mac%E7%8E%AF%E5%A2%83%E4%B8%8B%E4%BD%BF%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2/20220502195744_hu_9a5670a73e1e1098.webp 696w\" width=\"696\"\u003e \u003cp\u003e值得一提的是，Hexo生成时真正显示的标题是\u003ccode\u003e\u0026lt;title\u0026gt;.md\u003c/code\u003e文件的 Front matter 里 title 项的标题，文件名影响的是生成后文章的永久链接。\n\u003cp\u003e写作完成后执行：\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003e#注意以下命令需要切换到blog文件夹(cd blog)执行 $ hexo g $ hexo d\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e即可将文章发布，根据主题的不同，最好在执行\u003ccode\u003ehexo g\u003c/code\u003e前先执行：\n\u003cpre\u003e\u003ccode class=\"language-shell\"\u003e$ hexo clean\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e以避免潜在的问题。\n\u003ch2 id=\"hexo常用命令\"\u003eHexo常用命令 \u003c/h2\u003e\u003cpre\u003e\u003ccode class=\"language-bash\"\u003e#注意以下命令需要切换到blog文件夹(cd blog)执行 hexo n \"文章名称\" =\u003e hexo new \"文章名称\" #这两个都是创建新文章，前者是简写模式，下同，new后面加一个draft可以生成草稿 hexo p =\u003e hexo publish #发布草稿 hexo g =\u003e hexo generate #生成 hexo s =\u003e hexo server #启动服务预览 hexo d =\u003e hexo deploy #部署 hexo server #Hexo 会监视文件变动并自动更新，无须重启服务器。 hexo server -s #静态模式 hexo server -p 5000 #更改端口 hexo server -i 192.168.1.1 #自定义IP hexo clean #清除缓存，网页正常情况下可以忽略此条命令\u003c/code\u003e\u003c/pre\u003e","date":"2022-05-30T16:27:30Z","image":"/2022/05/mac%E7%8E%AF%E5%A2%83%E4%B8%8B%E4%BD%BF%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2/cover_hu_f8072877c13b7273.webp","permalink":"/2022/05/mac%E7%8E%AF%E5%A2%83%E4%B8%8B%E4%BD%BF%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2/","title":"Mac OS环境下使用Hexo搭建个人博客"},{"content":"某天在网上闲逛，发现一位名为linfangzhi老哥写的Github项目——CSUST_network_autologin。于是白嫖下载了一份用来在图书馆上网，但是这个项目只发布了Windows版，没发给手机和电脑用，所以，为了折腾满足需求，自己动手，丰衣足食。\n管你怎么样先Fork一份再说 古语有云：“管你怎么样先fork一份再说“（大雾），这个项目的源码公开，原理非常简单，就是模拟帮你填个账号登陆让你上网，所以说，整个项目最有价值的东西其实就是登陆上长沙理工大学办公区网络的账号和密码。\n“既然这个项目源码公开，那直接在源码里找到账号密码不就可以了吗？”\n还真不行。\n账号信息不会公布（公布是不可能公布的，这辈子都不可能公布）\n——linfangzhi\n事实上，他也确实做到了这一点，当你打开项目仅有的一个main.py文件就会看到如下的代码片段\ninit(autoreset=True) account_info = [[]] # 隐私内容linfangzhi学长早就把核心的account_info信息删去，留下一个摆着好看的坯子供你欣赏。他把这一个应用打包成了exe程序，只能用，不能看到隐私内容。\n可是我有iPad和Mac要登陆就只能洗洗睡了吗？\n想办法找到账号信息 先试着直接拆开exe程序 有的exe程序可以直接用7-zip解压，然而这个不行\n去网上找了一些方法，终于感觉此路不通，放弃\n抓取登陆的时候发送给认证服务器的数据包 长沙理工大学的认证服务器用的是万年http，没有s\n估计学校没有想到觉得有人会在校园网里抓别人的包，这意味着抓包会省不少事，只需要把程序发出的流量都引到抓包软件上就可以直接获取到裸奔的账号信息。这个办法的可行性明显高得多，实际操作起来也更容易。\n那就抓包吧 这个项目发布了exe文件，可我只有Mac，所以我在Crossover里运行这个项目，不过需要一个简单的python环境，crossover默认的wine容器环境完全没有问题。于是我把用于Steam的容器用作这个exe的启动器就可以。\n至于抓包，Mac上有很多优质的应用，这里用到了Proxyman\n弄好Proxyman以后在容器的Internet设置里设置一下本地的代理服务器让所有的流量都走Proxyman，这样就可以在Proxyman里看到所有的包\n如前面所说，长沙理工大学的上网认证页还在用着http，账号密码都在裸奔。其实用https也只是多一个安装证书解密https的步骤。所以，到了这一步，直接在Crossover里打开exe文件，在Proxyman里观察这个程序发出的网络请求。\nPOST /eportal/?c=ACSetting\u0026a=Login\u0026protocol=http:\u0026hostname=192.168.7.221\u0026iTermType=1\u0026wlanuserip=10.171.184.114\u0026wlanacip=192.168.132.254\u0026wlanacname=JPL-ME60-1\u0026mac=6a-72-0c-e8-4e-15\u0026ip=10.171.184.114\u0026enAdvert=0\u0026queryACIP=0\u0026loginMethod=1 HTTP/1.1 Host: 192.168.7.221:801 User-Agent: python-requests/2.18.4 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive Content-Length: 74 Content-Type: application/x-www-form-urlencoded DDDDD=%2C0%2Cxxxxxx\u0026upass=xxxxxx\u0026R1=0\u0026R2=0\u0026R3=0\u0026R6=0\u0026para=00\u00260MKKey=123456很明显，这个POST请求就是python的requests库发出的登陆请求。因为linfangzhi学长不希望公布账号信息，我把账号信息都换成了xxxxxx。\n将这段请求的原文还原一下（就是解码）可以得到下面的内容：\n查看项目里放出的源码：\ndata = { 'DDDDD': ',0,{}'.format(account), 'upass': '{}'.format(pswd), 'R1': '0', 'R2': '0', 'R3': '0', 'R6': '0', 'para': '00', '0MKKey': '123456', } requests.post(url=post_url, data=data)可以轻易的知道账号和密码就在图中两个xxxxxx所在的位置。\n登陆和测速 在iPad上填入账号信息尝试登陆\n在长沙理工大学图书馆A馆二楼测速\n速度还能接受。虽然用4G也可以实现相似的速度，但是免流量，加上找出来密码的成就感，还是划算的，\n有一个小问题 每次连上半个小时就大概率会掉线，DHCP续租后又可以重新上线，可能是DHCP租约太短的原因，暂时还没有找到解决办法，可能以后会试着写一个自动续租的脚本来勉强解决问题。\n（20220525更新：这个问题似乎被解决了）\n最后\u0026hellip; 如果想要账号密码可以在评论区留下邮箱2333\n","date":"2022-05-21T13:45:26Z","permalink":"/2022/05/how-csust-bg-network-passwd-leaked/","title":"从某个项目里找出csust办公区网络的密码"},{"content":"昨晚，也就是2022-05-07晚上，正准备刷学校强制要求的智慧树上的垃圾网课，却发现智慧树引入了一个刷课脚本的检测机制。直接打断了我的刷课进程。随后试图绕过这个机制，然而事情似乎并没有那么简单。\n20220518更新：到现在，Greasy Fork上还在更新的脚本基本都实现了屏蔽检测的功能，可以直接下载使用。\n摸爬滚打 经过一番摸爬滚打，大致掌握了一些信息：\n不论是通过Tamper Monkey还是通过开发者工具控制台注入脚本都会被检测到（废话） 在检查元素时，发现了一些奇怪的JS，毫无可读性可言，但又正在运作，应该是经过混淆 在禁用了一些名称可疑的奇怪JS后问题并没有解决，难道检测机制直接写在index.html里了？ 试图替换页面上的JS 没办法了，那就一个一个JS的看吧。\n这么乱怎么读？那就先用工具规范一下格式\n先从第一个开始找吧，本来准备一个一个找，然而第一个脚本就出现了一些意想不到的东西。\n将所有一眼就知道是检测的机制给替换成无意义的输出\n然后替换网页上原始的脚本\n似乎是成功了，不过脚本刷课自动切换的功能似乎失效。\n是在帮同学刷课，暂时手动切换，今天先鸽了，最近事情多是真的忙。\n","date":"2022-05-08T17:03:16Z","permalink":"/2022/05/fuck-zhihuishu/","title":"尝试绕过智慧树对刷课脚本的检测"},{"content":"Github的repo有个自定义域名的功能，其实就是在repo的根目录下生成一个CNAME文件，里面放着自定义的域名，然而Hexo每次deploy都会把这个CNAME文件覆盖掉，结果就是自定义域名失效了。\n解决方案很简单，把repo里的CNAME文件下载下来，放到Hexo的/source目录里，个人猜测deploy是增量更新，只需经过第一次的deploy就不会出现丢CNAME的情况。\n","date":"2022-04-30T18:07:38Z","permalink":"/2022/04/resolve-githubpages-cname-hexo/","title":"解决Hexo deploy到GithubPages时自定义域名失效的问题"},{"content":"世界，你好！\n『我只记得，我好像看过一幅漫画，讲述一枚鸡蛋和一只小鸡的故事，在那副漫画中，小鸡说了一句‘Hello World’』\n","date":"2022-04-30T16:16:01Z","permalink":"/2022/04/hello-world-0/","title":"Hello, World!"}]