MoreRSS

site iconJustYY | 小赖子修改

小赖子的英国生活和资讯,以及投资和个人生活。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

JustYY | 小赖子的 RSS 预览

WordPress安全加固: 禁止在 wp-content/uploads 目录中执行PHP

2026-08-13 22:02:20

WordPress的上传目录必须允许写入媒体文件,却没有执行PHP代码的必要。本文介绍如何通过Apache全局配置禁止在`wp-content/uploads`中访问和执行PHP类文件,并使用`.htaccess`作为第二层保护,同时分析两种方式的优缺点、`Options -ExecCGI`的作用及配置验证方法。这项加固不能代替漏洞修复和及时更新,但可以切断恶意文件上传后被执行为Web Shell的常见攻击路径。
我目前维护着8个WordPress博客,从服务器配置、系统升级到日常备份和安全防护,基本上都是自己动手完成。这几年也遇到过几次规模不大的安全事件,好在发现和处理得比较及时,目前并没有造成太严重的损失。 每一次事故后的排查、复盘和总结,都是一次很好的学习和提升机会,也让我逐渐意识到:服务器安全没有真正意义上的“一劳永逸”,更不能因为系统已经稳定运行多年就放松警惕。及时更新WordPress及插件、妥善管理密钥、收紧文件权限、检查日志和备份,以及禁止在上传目录中执行PHP,这些看似琐碎的措施,往往能够在关键时刻阻断攻击链。安全本质上是一项需要长期坚持、不断完善的工作。

WordPress安全加固: 禁止在 wp-content/uploads 目录中执行PHP

正常情况下,WordPress需要向wp-content/uploads目录写入图片、视频等媒体文件。这种设计虽然方便,却也形成了一个非常重要的安全边界:这个目录必须允许Web应用写入,但保存在其中的文件绝对没有执行PHP代码的必要。 如果某个存在漏洞的插件、主题或自定义上传接口允许攻击者把PHP文件写入上传目录,攻击者接下来就可能尝试通过浏览器直接访问这个文件。一旦Apache把它交给PHP解释器执行,一个普通的文件上传漏洞就可能升级为远程代码执行,甚至变成一个以Web服务器用户权限运行的Web Shell。 禁止在uploads目录中执行PHP并不能修复最初的漏洞,但它可以切断这条常见的攻击链。这是一项成本低、影响小的纵深防御措施,应该和及时更新WordPress、限制文件权限、检查日志、验证备份等措施一起使用。WordPress官方的安全加固指南同样强调,安全依赖多层防护,而不是某一个单独的设置。

方法一:使用Apache全局配置

我的服务器在/var/www目录下运行着多个WordPress网站,因此我创建了下面这个Apache配置文件:
/etc/apache2/conf-available/wordpress-uploads-no-php.conf
配置内容如下:
<DirectoryMatch "^/var/www/(?:[^/]+/)*wp-content/uploads(?:/|$)">
    <FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)$">
        Require all denied
    </FilesMatch>
</DirectoryMatch>
外层的DirectoryMatch把规则限定在/var/www下面的WordPress上传目录中。它也会覆盖uploads下面常见的年份和月份子目录。 内层的FilesMatch会以不区分大小写的方式检查文件名,并拒绝通过HTTP直接访问以下扩展名的文件:
  • .php
  • .php5.php7.php8以及其他带数字后缀的PHP扩展名
  • .phtml
  • .phar
真正起到拒绝访问作用的是Require all denied:任何匹配的文件都不能通过Apache直接访问。Apache官方文档也介绍了如何使用DirectoryMatchFilesMatchRequire all denied对文件系统中的内容进行访问控制。 启用并检查配置:
a2enconf wordpress-uploads-no-php
apache2ctl configtest
systemctl reload apache2
不要跳过configtest。Apache应该输出:
Syntax OK

是否还需要加入Options -ExecCGI

可以把它作为额外的防护措施:
<DirectoryMatch "^/var/www/(?:[^/]+/)*wp-content/uploads(?:/|$)">
    Options -ExecCGI

    <FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)$">
        Require all denied
    </FilesMatch>
</DirectoryMatch>
Options -ExecCGI禁止Apache通过CGI机制执行该目录里的程序。但它本身并不能禁用PHP-FPM、mod_php或其他所有可能的处理器。因此,这是一项附加加固措施,不能代替FilesMatch中的拒绝访问规则。 Apache的CGI文档说明,ExecCGI正是用于允许目录执行CGI程序的选项

方法二:使用.htaccess作为第二层保险

我还在每个网站的wp-content/uploads/.htaccess中加入了下面的内容:
<FilesMatch "(?i)\.(?:php[0-9]*|phtml|phar)(?:\.|$)">
    Require all denied
</FilesMatch>
这里不需要再写DirectoryMatch,因为.htaccess中的规则会自动应用于它所在的目录以及下面的所有子目录。 Apache会在处理请求时读取.htaccess文件,而服务器的AllowOverride设置决定了其中允许使用哪些指令。Apache的配置文件文档对此有更详细的说明。 这个表达式比前面的规则更加严格,还会拒绝下面这类可疑的双扩展名:
shell.php.jpg
backdoor.phtml.png
payload.phar.gif
在PHP处理器配置正确的情况下,.php.jpg本来不应该被当作PHP执行。但上传目录没有合理的理由保存带有可执行扩展名的文件,因此直接拒绝这类文件更加稳妥。它的代价是,即使这个文件实际上是一张图片,只要文件名包含这些可疑扩展名,同样会被拒绝访问。 如果添加这个.htaccess后网站返回500 Internal Server Error,可以检查Apache错误日志:
tail -n 50 /var/log/apache2/error.log
出现500通常意味着当前目录对应的AllowOverrideAllowOverrideList设置不允许使用这项指令。 不要仅仅为了让这个安全规则生效,就把服务器改成AllowOverride All。如果自己拥有服务器管理权限,应该优先使用Apache全局配置。

Apache全局配置和.htaccess的优缺点

方式 优点 缺点
Apache全局配置 一条规则可以保护所有网站;由root用户控制;不依赖AllowOverride;被入侵的WordPress进程通常无法修改;配置更集中,性能也更好 需要服务器管理权限;修改后必须检查配置并重新加载Apache;路径表达式必须和服务器上的实际目录结构匹配
上传目录中的.htaccess 可以按网站部署;适合共享主机;不需要重新加载Apache就能生效;可以作为全局规则之外的第二层保险 只有允许覆盖配置时才会生效;每个网站都要单独维护;Apache需要在请求过程中检查相关文件;如果应用拥有目录写权限,攻击者可能删除或篡改它
Apache指出,启用覆盖配置后,它可能沿着请求对应的文件系统路径逐级查找.htaccess文件。因此,在自己能够控制服务器的情况下,使用全局配置在性能上也更加合理。 所以,我把服务器级别的规则作为真正的安全边界,而把.htaccess当作第二层保险。

不要假设配置有效,一定要实际测试

可以在其中一个网站的上传目录中临时创建一个测试文件:
printf '%s\n' '<?php echo "SHOULD-NOT-EXECUTE";' \
  > /var/www/example.com/wp-content/uploads/security-test.php
然后访问它:
curl -i https://example.com/wp-content/uploads/security-test.php
预期返回结果是:
403 Forbidden
最重要的是,响应中绝对不能出现SHOULD-NOT-EXECUTE。 同时还应该检查同一目录中已有的JPEG或PNG图片是否仍然能够正常访问:
curl -I https://example.com/wp-content/uploads/path/to/existing-image.jpg
测试完成后立即删除临时文件:
rm /var/www/example.com/wp-content/uploads/security-test.php
以后如果修改了Apache、PHP-FPM或虚拟主机的重要配置,也应该重新执行这项测试。没有经过验证的安全设置只是一种假设,还不能算是真正有效的安全控制。

这项防护不能解决什么问题?

这项措施的目的非常明确,也有清晰的能力边界。它不能:
  • 修复WordPress、主题或插件中的漏洞;
  • 阻止存在漏洞的应用把恶意文件写入服务器;
  • 阻止已经通过其他PHP文件运行的恶意代码;
  • 阻止插件通过PHP的includerequire在服务器内部加载恶意文件;
  • 代替恶意软件扫描、日志检查、备份和合理的文件系统权限。
它能做的是,禁止通过Web直接访问上传目录中带有危险扩展名的文件。对于最基本的上传型Web Shell,这可能已经足以阻止其运行;但如果网站曾经遭到入侵,仅凭这个设置绝不能证明服务器已经安全或已经清理干净。

最终建议

如果自己管理Apache服务器,应该把全局配置作为主要防护措施。如果上传目录确实没有运行CGI程序的合法需求,还可以加入Options -ExecCGI作为额外的纵深防御。 只有在服务器原本就允许使用覆盖配置的情况下,才建议保留.htaccess作为附加保护。不要为了支持这份.htaccess而放宽服务器的整体安全配置。 最重要的是,仍然要及时更新WordPress核心、主题和插件。禁止在uploads目录执行PHP可以降低某一条攻击路径造成的影响,却不能修复最初允许攻击者上传文件的漏洞。 [show_file file=""] [show_posts keyword="wordpress"] 英文:Hardening Wordpress: Disable PHP Execution in wp-content/uploads/

他们看到的是景点, 我看到的是童年

2026-08-12 23:45:27

2024年4月,我带着媳妇孩子短暂回到厦门,也重返自己生活到高考前的故乡鼓浪屿。小时候宽阔悠长的街道,如今显得狭窄拥挤;熟悉的海边音乐、龙头路小吃,以及攒零花钱买海蛎煎的记忆,却依然清晰。多年后带着在英国长大的孩子故地重游,我才发现:变小的或许不是鼓浪屿,而是童年的世界;真正回不去的,也不是故乡,而是那个尚未离开故乡的自己。 《多年以后,我带着老婆孩子回到鼓浪屿》 《鼓浪屿还是那座岛,我却不再是当年的少年》 《回到鼓浪屿,寻找那个没有离开故乡的自己》 《他们看到的是景点,我看到的是童年》 《鼓浪屿:故乡依旧,童年已远》 《小时候很宽的路,长大后怎么变窄了》 《从一份海蛎煎,到带着妻儿重回故乡》 《再回鼓浪屿:街道变窄了,时间也变快了》 《记忆里的鼓浪屿,再也回不去了》 《长大后再回鼓浪屿,才读懂什么叫故乡》
[caption id="attachment_72251" align="alignnone" width="550"]01 01[/caption]

不是鼓浪屿的街道变小了,而是我们长大了

前几天翻到两年前在鼓浪屿拍的照片,我随手发了一句:小时候觉得鼓浪屿的街道又宽又大,长大后再回来,却觉得有些狭窄和拥挤。也许不是街道变小了,而是我们长大了。 朋友看到后问我:“赖博士回国了?” 我说:“上次。” 这个“上次”,已经是2024年4月。那一次,我带着媳妇和孩子短暂回国,去了北京、厦门和福州。整个行程很赶,在厦门也只待了三四天,但无论时间多紧,鼓浪屿总是要回去看一看的。 因为那里不只是一处旅游景点,也是我真正意义上的故乡——高考以前,我人生中绝大多数的时光都生活在这片土地上。

小时候很宽的路,如今怎么变窄了

小时候,我总觉得鼓浪屿的路很宽、很长,仿佛怎么走也走不完。一个孩子的世界本来就很小,所以家门口的一条街、一段斜坡和一个转角,都可以大得像整个世界。 长大以后,每次再回去,我却总有一种奇怪的感觉:自己好像变得很大,而街道变得很小。 小时候觉得遥远的地方,如今走不了多久就到了;记忆里宽敞的道路,现在看起来窄窄的,两边挤满了游客、店铺和各式各样的招牌。 鼓浪屿似乎还是那个鼓浪屿,却又早已不是我小时候的鼓浪屿了。 这些年,岛上的旅游商业化越来越浓。尤其是龙头路一带,各种小吃店、伴手礼店和网红店一家挨着一家,有些地方甚至显得拥挤而脏乱。过去那些带着生活气息的小店,许多已经不见了;即使卖的还是相似的小吃,吃进嘴里,也很难再找到小时候的味道。 当然,也可能并不全是食物变了。人的记忆本来就会给童年加上一层滤镜。真正回不去的,也许不是当年的味道,而是当年那个只需要攥着一点零花钱,就能获得巨大满足的自己。 [caption id="attachment_72252" align="alignnone" width="550"]02 02[/caption]

整座岛曾经有自己的背景音乐

我一直记得,小时候沿着海边的马路走,每隔二三十米,路旁便藏着一个小喇叭。 那些喇叭里会播放钢琴曲和熟悉的旋律,有《鼓浪屿之波》,也有后来韦唯演唱的《鼓浪屿》。海风、浪声和音乐混在一起,构成了我对故乡最深的声音记忆。 那时候没有耳机,也没有手机里的播放列表,但整座岛仿佛有自己的背景音乐。走到哪里,旋律就跟到哪里。 多年以后,在别的地方偶然听到这些歌,我还是会在一瞬间想起鼓浪屿的海、弯弯曲曲的街道,以及那个在岛上慢慢长大的自己。

那份攒起来买海蛎煎的零花钱

小时候,我很喜欢吃鼓浪屿街边的海蛎煎。 有一次,我拿着平时一点点攒下来的零花钱去买,小摊老板看我把钱掏出来,还笑着打趣我: “这么小就知道存钱,是要留着以后娶老婆啊?” 那时候的我,大概只觉得好笑,根本不会想到“娶老婆”是多么遥远的事情。我只关心手里的钱够不够买一份海蛎煎,也只想着赶紧趁热吃掉。 几十年后,我真的带着老婆和孩子回到了这里。 当年那个攥着零花钱买海蛎煎的小男孩,如今已经有了自己的家庭。只是当我再站在同样的街道上时,小时候熟悉的摊贩早已不知去了哪里,当年的味道也只能到记忆里寻找。 [caption id="attachment_72253" align="alignnone" width="550"]03 03[/caption]

他们看到的是景点,我看到的是从前

孩子们属于Z世代,又是在英国土生土长。对他们来说,鼓浪屿可能只是一座游客很多、街道很窄、需要走很多路的小岛。 他们很难理解,为什么爸爸会对一条普通的街道、一首老歌,甚至一份小吃有那么多感触。 这也很正常。 他们看到的是眼前的鼓浪屿,而我看到的,是一层又一层叠在现实之上的从前。 我看到自己小时候走过的路、听过的音乐、吃过的小吃;看到那些已经消失的人和事;也看到一个孩子从这里出发,后来去了很远的地方生活,许多年后又带着自己的家人回来。 孩子们未必能够真正理解我的乡愁,就像小时候的我,也不会理解父辈为什么总爱回忆他们的过去。 但也许有一天,当他们长大,离开自己熟悉的地方,再带着下一代回去时,也会突然明白这种感觉。 故乡从来不只是地图上的一个地点,它更像是我们童年的比例尺。 小时候,街道很宽,日子很长,零花钱很少,一份海蛎煎就足以让人开心很久;长大以后,街道变窄了,时间变快了,身边也多了媳妇和孩子。 不是鼓浪屿的街道变小了,而是我们长大了。 而我们真正怀念的,也不只是从前的鼓浪屿,更是那个还没有离开鼓浪屿的自己。 [caption id="attachment_72668" align="alignnone" width="2048"]两年前的兄弟俩,现在已经长大了很多。 两年前的兄弟俩,现在已经长大了很多。[/caption] [caption id="attachment_72672" align="alignnone" width="1366"]要离开家了,老妈和媳妇在吩咐事情。 要离开家了,老妈和媳妇在吩咐事情。[/caption] [caption id="attachment_72671" align="alignnone" width="2048"]媳妇在鼓浪屿留影 媳妇在鼓浪屿留影[/caption] [caption id="attachment_72670" align="alignnone" width="2048"]两娃第一次回厦门,老大一岁的时候在2013年的时候有回,当时老二还在媳妇肚子里。老大在福州的时候学会走路的,老二的第一次真是记不住了。 两娃第一次回厦门,老大一岁的时候在2013年的时候有回,当时老二还在媳妇肚子里。老大在福州的时候学会走路的,老二的第一次真是记不住了。[/caption] [caption id="attachment_72669" align="alignnone" width="1365"]兄弟俩第一次回厦门 兄弟俩第一次回厦门[/caption] [caption id="attachment_72675" align="alignnone" width="2048"]小时候每天走的路,每天上下学都要走这个陡坡。 小时候每天走的路,每天上下学都要走这个陡坡。[/caption] [caption id="attachment_72676" align="alignnone" width="1477"]鼓浪屿晚上只有市中心那块比较有人气,其它地方都有点黑。 鼓浪屿晚上只有市中心那块比较有人气,其它地方都有点黑。[/caption] [caption id="attachment_72677" align="alignnone" width="1477"]夜景上的厦门 夜景上的厦门[/caption] [caption id="attachment_72678" align="alignnone" width="1477"]厦门/鼓浪屿小吃:海蛎煎 厦门/鼓浪屿小吃:海蛎煎[/caption] [caption id="attachment_72679" align="alignnone" width="1477"]小时候:妈妈总说,如果不好好学习就得去拉板车。我现在只是换了个赛道搬砖,不同行业的牛马。 小时候:妈妈总说,如果不好好学习就得去拉板车。我现在只是换了个赛道搬砖,不同行业的牛马。[/caption] [caption id="attachment_72680" align="alignnone" width="1477"]两娃/酒店 两娃/酒店[/caption] [caption id="attachment_72681" align="alignnone" width="1270"]老妈每次都会做好吃的等我们回去。 老妈每次都会做好吃的等我们回去。[/caption] [caption id="attachment_72682" align="alignnone" width="1477"]最爱沙茶面,但是味道可能和小时候的不太一样了。 最爱沙茶面,但是味道可能和小时候的不太一样了。[/caption] [caption id="attachment_72683" align="alignnone" width="714"]家里太小,只能和媳妇孩子到酒店 家里太小,只能和媳妇孩子到酒店[/caption] [caption id="attachment_72684" align="alignnone" width="1280"]鼓浪屿最有名的除了日光岩就是这个郑成功雕像了,面向大海/金门 鼓浪屿最有名的除了日光岩就是这个郑成功雕像了,面向大海/金门[/caption] [show_file file="/var/www/wp-post-common/justyy.com/2024-china.php"] [show_posts keyword="厦门"]

弟弟的生日礼物: 一套”小码农”装备

2026-08-11 22:55:59

弟弟今年的生日礼物是一套颇具“码农气质”的装备:无线鼠标、无线机械键盘和iPad支架。他喜欢Minecraft和科技产品,也跟着我每天刷力扣,不知不觉已经坚持了500多天。孩子喜欢玩是天性,希望他能在玩中发现兴趣,在兴趣中学习和成长,将来慢慢把对科技的好奇变成真正的创造力。
[caption id="attachment_72251" align="alignnone" width="550"]01 01[/caption] [video width="1280" height="720" mp4="https://justyy.com/wp-content/uploads/2026/08/Ryan-try-new-keyboard.mp4"][/video] 今年年初弟弟过生日,我问他想要什么礼物。他没有要玩具,而是自己挑了一只无线鼠标、一把无线机械键盘,还有一个iPad支架。 看到这份礼物清单,我的第一反应是:这不就是一套标准的“码农装备”吗? 现在的小孩懂得越来越多,选东西也越来越有自己的想法。特别是那把机械键盘,手感和做工感觉比我自己用的还好。相比之下,我的鼠标只是Amazon Basics最便宜的那款,突然感觉自己的装备还不如孩子了(笑)。 生日蛋糕当然也是他喜欢的Minecraft主题。弟弟很爱玩Minecraft(我的世界),听说在游戏里玩得还挺厉害。Minecraft本身也是一个很有创造力的游戏,可以搭建筑、做机关、设计各种复杂的东西。有一次他给我展示了他在游戏里搭建一个二进制的计数器,只是我平时并不怎么玩,也对这个游戏不怎么感兴趣,只知道是微软收购来的。 弟弟从去年开始跟着我刷力扣。现在,我每天都会带着他做一道题,不知不觉已经坚持了500多天。一天做一点,看起来并不起眼,但能连续坚持这么久,本身就是一种积累。很多能力并不是靠某一天突然努力获得的,而是在日复一日的练习中慢慢形成的。 [caption id="attachment_72252" align="alignnone" width="550"]02 02[/caption] 他说,长大以后也想像我一样当软件工程师。 不过从目前来看,他的大部分精力还是花在玩游戏和看YouTube视频上。看的内容也大多和游戏、手机、平板电脑以及各种电子产品有关。孩子喜欢玩很正常,我小时候如果有这些东西,大概也会玩得停不下来。 我并不认为玩游戏和看视频就一定是在浪费时间。兴趣往往就是从“玩”开始的。玩Minecraft可以接触创造、设计和简单的逻辑;关注手机、平板和电脑,也说明他对科技产品有自己的好奇心。但“喜欢使用科技产品”和“能够创造科技产品”之间,仍然隔着很长的一段路。 一套机械键盘不会自动把人变成程序员,刷力扣也不是学习编程的全部。真正重要的是,他能不能慢慢学会主动探索、独立思考,并把脑子里的想法做成真正的东西。 孩子将来是否真的会成为软件工程师,其实并不重要。他现在的兴趣以后也可能发生变化。我更希望的是,他能在玩中发现兴趣,在兴趣中学习,再把学习到的东西变成自己的能力。 至于我能做的,就是继续陪他每天刷一道题,在他愿意探索的时候给他一点帮助。也许多年以后再回头看,这把机械键盘、这只鼠标和这个iPad支架,就是他通往技术世界的第一套装备。 [caption id="attachment_72253" align="alignnone" width="550"]03 03[/caption] [caption id="attachment_72648" align="alignnone" width="1920"]每天带娃刷力扣。 每天带娃刷力扣。[/caption] [caption id="attachment_72647" align="alignnone" width="2048"]这键盘还会发光/和Keychron一样。 这键盘还会发光/和Keychron一样。[/caption] [caption id="attachment_72646" align="alignnone" width="2048"]弟弟的办公桌 弟弟的办公桌[/caption] [caption id="attachment_72645" align="alignnone" width="2048"]弟弟是那种有多少钱就花多少钱的人。 弟弟是那种有多少钱就花多少钱的人。[/caption] [caption id="attachment_72644" align="alignnone" width="2048"]弟弟拿到生日礼物很开心,哥哥生日一般没啥想要的,就给他50英镑现金。 弟弟拿到生日礼物很开心,哥哥生日一般没啥想要的,就给他50英镑现金。[/caption] [caption id="attachment_72643" align="alignnone" width="2048"]机械键盘支持三种模式:无线WIFI/Type C/蓝牙/内置电池 机械键盘支持三种模式:无线WIFI/Type C/蓝牙/内置电池[/caption] [caption id="attachment_72642" align="alignnone" width="2048"]IPAD是轻工作站/没有主机/方便便捷 IPAD是轻工作站/没有主机/方便便捷[/caption] [caption id="attachment_72641" align="alignnone" width="2048"]用IPAD+机械键盘刷题 用IPAD+机械键盘刷题[/caption] [caption id="attachment_72640" align="alignnone" width="1152"]刷题是不是更厉害了 刷题是不是更厉害了[/caption] [caption id="attachment_72639" align="alignnone" width="2048"]弟弟在测试新的机械键盘 弟弟在测试新的机械键盘[/caption] [caption id="attachment_72638" align="alignnone" width="539"]在亚马逊下单买的码农设备。 在亚马逊下单买的码农设备。[/caption] [caption id="attachment_72637" align="alignnone" width="2048"]弟弟的办公桌 弟弟的办公桌[/caption] [caption id="attachment_72636" align="alignnone" width="1152"]没有浪费,基本上都吃了。以往吃不完也会分给同事/朋友。 没有浪费,基本上都吃了。以往吃不完也会分给同事/朋友。[/caption] [caption id="attachment_72635" align="alignnone" width="2048"]蛋糕还行,不会很腻 蛋糕还行,不会很腻[/caption] [caption id="attachment_72634" align="alignnone" width="2048"]这个蛋糕做工不错。 这个蛋糕做工不错。[/caption] [caption id="attachment_72633" align="alignnone" width="1152"]仪式感还是要有的,一年一个重要的日子。 仪式感还是要有的,一年一个重要的日子。[/caption] [caption id="attachment_72632" align="alignnone" width="1152"]开始点蜡烛了 开始点蜡烛了[/caption] [caption id="attachment_72631" align="alignnone" width="1152"]弟弟这两年沉迷于我的世界/Minecraft 弟弟这两年沉迷于我的世界/Minecraft[/caption] [caption id="attachment_72630" align="alignnone" width="1881"]蛋糕上的玩具不能吃的 蛋糕上的玩具不能吃的[/caption] [caption id="attachment_72629" align="alignnone" width="2048"]他最爱的哥哥写的生日卡片 他最爱的哥哥写的生日卡片[/caption] [caption id="attachment_72628" align="alignnone" width="2048"]这个蛋糕+上面的小玩具花了55英镑 这个蛋糕+上面的小玩具花了55英镑[/caption] [caption id="attachment_72627" align="alignnone" width="2048"]弟弟打开哥哥写的生日贺卡 弟弟打开哥哥写的生日贺卡[/caption] [caption id="attachment_72626" align="alignnone" width="2048"]弟弟在玩minecraft 弟弟在玩minecraft[/caption] [caption id="attachment_72625" align="alignnone" width="1152"]车库改成的书房/我的办公地方在楼上卧室改的 车库改成的书房/我的办公地方在楼上卧室改的[/caption] [caption id="attachment_72624" align="alignnone" width="2048"]他现在主要的设备就是 iPAD 他现在主要的设备就是 iPAD[/caption] [caption id="attachment_72623" align="alignnone" width="2048"]弟弟在玩游戏 弟弟在玩游戏[/caption] [caption id="attachment_72622" align="alignnone" width="2048"]弟弟的办公桌 很乱 弟弟的办公桌 很乱[/caption] [caption id="attachment_72649" align="alignnone" width="627"]朋友圈记录娃的成长 朋友圈记录娃的成长[/caption] [show_file file="/var/www/wp-post-common/justyy.com/leetcode.php"] [show_file file="/var/www/wp-post-common/justyy.com/birthday.php"] [show_posts keyword="刷题"] [show_posts keyword="生日"]

8年的力扣不打算续费了: 古法编程最好的时代过去了

2026-08-10 04:15:25

连续续费力扣八年后,今年决定暂时不续了。从2018年准备亚马逊面试,到后来几乎每天刷题,力扣已经成为生活的一部分。AI正在改变程序员写代码的方式,但算法、基本功和长期坚持依然重要。不续费不是因为它没用了,也不是付不起,只是对现在的我来说,边际收益已经没有以前那么高。写篇文章记录这八年的陪伴,以及我对AI时代软件工程师的一些思考。💻

连续续费力扣会员八年后,我决定今年暂不续费。从2018年准备亚马逊面试,到2019年开始坚持每天刷题,力扣早已成为我技术成长的一部分。如今AI已经改变软件工程师的工作方式,工程师的重点正从手工编写代码,转向设计方案、提供上下文、审核AI产出并识别系统风险。力扣和算法能力依然重要,技术面试短期内也不会放弃这种高效的筛选方式;只是对现在的我而言,每年159美元会员费带来的边际收益已经明显下降。不是付不起,而是这笔钱可以花在家庭更需要的地方。当然,如果黑五打折,说不定我又会回来。

连续续费八年后,我决定不再续费力扣会员了

上周,我做了一个不算艰难、但多少有点舍不得的决定:今年不再续费力扣会员了。 力扣会员这些年的价格一直是每年159美元,也可以按月购买,每月35美元。对正在突击准备面试的人来说,按月付费其实很合适,集中刷上一两个月,找到工作以后就可以停掉。而我从2018年第一次购买会员开始,一续就是八年。 [caption id="attachment_72597" align="alignnone" width="1360"]续了8年的力扣 不打算再续了。一个月省两杯咖啡钱。 续了8年的力扣 不打算再续了。一个月省两杯咖啡钱。[/caption]

从一场亚马逊面试开始

[caption id="attachment_72251" align="alignnone" width="550"]01 01[/caption] 2018年我准备找工作,在去亚马逊面试前的那个周末,才临时决定购买力扣会员。那个周末大概刷了二三十道题,自以为准备得还不错。 后来才发现,当时对面试的理解还是太简单了。我以为只要算法题做得足够多就可以,真正参加面试后才知道,对于有经验的工程师来说,系统设计往往比单纯写出一道算法题更加重要。算法题只能证明一部分编码和思维能力,系统设计考察的则是架构、取舍、扩展性、可靠性以及工程经验。 不过,力扣会员还是一直续了下来。 最开始的两年,也就是2018年和2019年,我是通过PayPal付款的。当时网站上似乎还没有这个付款选项,我专门发邮件联系力扣,由客服人工帮我处理。后来才改成直接在网站上按年续费。 从账单记录来看,八年间每年都是159美元。单看一年不算多,但八年累计下来也有1272美元。力扣也陪着我走过了八年的日日夜夜。

从2019年开始,我几乎一天都没有停过

我从2019年3月2日开始,基本上每天都会刷力扣。 所谓“每天刷”,并不是一时兴起坚持几个星期,而是逐渐变成了生活的一部分。每天打开力扣、看题、写代码、提交,已经和吃饭、刷手机一样自然。工作忙的时候少做一点,有空的时候多做几道,但这个习惯一直保留了下来。 去年,我在国际版力扣上漏签了两天。 其中一天是媳妇生日,另一天下落在11月21日,至于当天为什么忘记了,我现在已经完全想不起来了。也就是说,从2019年3月2日到现在,国际版力扣一共只漏了这两天。 不过严格来说,我其实一天都没有真正落下,因为我同时也在刷力扣中国,那两天在中文版上仍然完成了打卡。只是国际版的连续记录断了,看起来多少还是有点可惜。 刷了这么多年以后,做题早已不完全是为了找工作,更像是一种习惯,甚至是每天给大脑做的一点热身运动。

力扣会员到底值不值?

客观地说,力扣会员还是有价值的。 它最大的好处,是可以解锁一些质量较高、比较有代表性的会员题目,其中也包括不少公司的面试题。对于正在准备技术面试的人来说,这部分内容确实有用。 会员提交代码时通常也能得到更快的判题体验。据说会员提交会进入优先队列。平时感觉可能不明显,但在服务器繁忙或者参加周赛时,速度上的差别还是能够感受到。 每年159美元,用来投资自己的职业能力并不算贵。如果它能帮助一个人通过面试、拿到更好的工作,那么这点费用几乎可以忽略不计。 我今年不续费,并不是因为它完全没有价值,而是因为它对我的边际收益已经明显下降了。

2026年,工程师写代码的方式已经变了

[caption id="attachment_72252" align="alignnone" width="550"]02 02[/caption] 尤其到了2026年,软件工程师的工作方式已经发生了很大变化。 现在已经不太需要从头到尾手工编写所有代码了。有人开玩笑把纯手写代码称为“古法编程”,虽然有些夸张,却也反映了现实:今天的AI已经能够完成相当大比例的代码实现,而且速度远远超过人类工程师。 我现在工作中最常见的操作,就是打开VS Code,选择GPT-5.6 Sol,把思考模式设为MAX,再打开“Allow All”,让AI自行读取代码、修改文件、运行测试和检查结果。 接下来,我就在那里等它干活。 [caption id="attachment_72596" align="alignnone" width="2048"]现在AI太强大了,Harness Engineering是最好的AI编程时代 现在AI太强大了,Harness Engineering是最好的AI编程时代[/caption] 有时只要几分钟,有时需要几十分钟。等AI完成以后,我再回来检查它的设计、实现和测试结果。现在的我越来越像测试经理、产品经理加甲方:负责提出需求、补充上下文、判断方案、验收产出,以及在AI跑偏时把它拉回来。 前些年曾经有一名美国工程师偷偷把自己的工作外包给中国工程师,最后被公司发现并解雇。现在我们某种程度上也在“外包”工作,只不过外包对象变成了AI,而且这是公开、合规,甚至受到公司鼓励的工作方式。 当然,这并不意味着工程师已经没有用了。 恰恰相反,AI生成代码的速度太快,一次就可能提交一大坨改动,人类已经很难再像过去那样逐行审查每一行代码。工程师必须把注意力放到更重要的地方:整体设计是否合理,模块边界是否清晰,异常路径是否处理正确,安全性和可维护性是否达标,以及这次修改会不会给系统埋下长期隐患。 AI很擅长把测试“弄绿”,但测试变绿并不等于设计正确。 例如,AI特别喜欢到处添加`try-catch`,有时甚至直接捕获通用异常。这样确实可能绕过当前错误,让测试暂时通过,却可能掩盖真正的问题。AI能够解决眼前的局部任务,但通常缺少对整个系统历史、业务目标和长期演进方向的理解。 这些缺口不能只靠一句更漂亮的Prompt解决。工程师需要通过上下文工程、RAG、设计文档、测试策略和明确的架构约束,把真正重要的知识提供给AI;最后还要依靠自己的判断,对AI的方案负责。教娃编程 vLog: Harness Engineering – 指挥 AI 干活 因此,未来工程师最值钱的能力,可能不再是“能不能快速手写出几百行代码”,而是能不能提出正确的问题、提供完整的上下文、识别AI的错误,并在大量自动生成的代码中抓住真正关键的风险

AI时代,力扣还重要吗?

[caption id="attachment_72253" align="alignnone" width="550"]03 03[/caption] 我认为力扣依然重要,至少短期内不会从技术面试中消失。不过刷题进大厂的时代可能已经过去了,至少只刷题是不够的。 很多公司仍然会考算法题,因为这是成本较低、标准相对统一、执行效率较高的一种筛选方式。面试官不需要了解候选人过去所有项目的复杂背景,只需要给出一道题,在有限时间内观察对方如何分析、沟通、编码和验证。 这种方式当然不完美。 它可能错过一些工程能力很强、但不擅长在45分钟压力下写算法题的人,也可能让一些大量背题、实际工程能力一般的人通过面试。因此,力扣题既可能产生“假阴性”,也不能彻底消灭“假阳性”。 但对于公司而言,招进一个不合格候选人的成本,通常远高于错过一个优秀候选人的成本。算法题虽然有缺陷,却便宜、可控、容易标准化,所以仍然会被广泛使用。 从另一个略显残酷的角度看,刷力扣也带有一点“服从性测试”的意味:候选人是否愿意投入时间熟悉规则,能否在压力下保持思考,并在45分钟内写出一两道正确、可运行的代码。 所以,我不认为AI出现以后,算法和数据结构就不需要学习了。相反,当AI替你写代码时,如果自己没有基本功,甚至无法判断AI写得对不对。只是对于我个人来说,继续付费解锁更多题目,已经不像八年前那么必要了。

不是付不起,而是可以花在更需要的地方

159美元并不是付不起。 只是最近两年孩子上私校,家里的钱包多少有点紧。该花的钱还是要花,但能够节省的地方也应该节省。与其为了维持一个已经用了八年的会员身份继续付款,不如把钱留给目前更需要的地方。 这并不是和力扣告别。我依然会继续刷题,免费题库对我来说已经足够丰富。过去八年积累下来的算法思维和刷题习惯,也不会随着会员到期而消失。 感谢力扣陪我度过这八年。从准备亚马逊面试,到后来换工作,再到如今带着孩子一起刷题,它早已不只是一个面试网站,而是我这些年技术成长的一部分。 [caption id="attachment_72595" align="alignnone" width="494"]力扣不再续费 力扣不再续费[/caption] 当然,话也不能说得太绝。 说不定到了年底黑色星期五,力扣又推出优惠,一年便宜30美元,我算了一下觉得挺划算,然后又默默把会员续上了。 [caption id="attachment_72598" align="alignnone" width="2048"]和媳妇约会喝咖啡刷个题 和媳妇约会喝咖啡刷个题[/caption] [caption id="attachment_72599" align="alignnone" width="2048"]随身带着IPAD,每周末到COSTA喝咖啡刷题 随身带着IPAD,每周末到COSTA喝咖啡刷题[/caption] [caption id="attachment_66760" align="alignnone" width="1536"]这次力扣奖励的衣服是新版的,感觉比之前的质量要好。 这次力扣奖励的衣服是新版的,感觉比之前的质量要好。[/caption] 这8年得到了力扣的T-shirt和卫衣大概有十几件了。 [caption id="attachment_72480" align="alignnone" width="864"]当天还穿了个力扣,应景一下刷个题 当天还穿了个力扣,应景一下刷个题[/caption] 7年前(2019年)在GE工作的时候的一个周六开始的刷题之旅。 [caption id="attachment_66886" align="alignnone" width="1887"]2019年在美国通用电气工作的时候中午吃完饭在湖边着着IPAD刷题 2019年在美国通用电气工作的时候中午吃完饭在湖边着着IPAD刷题[/caption] [caption id="attachment_6474" align="alignnone" width="1600"]刷题过了 Accepted 刷题过了 Accepted[/caption] 照片里,一个是陪我过日子的人,一个是陪我刷了八年的力扣。逛街喝咖啡的间隙,顺手完成了当天的打卡,连续刷题也来到第2718天(从2019年3月2日至今)。每天进步一点点,当时看不出什么,几年以后再回头看,这大概就是坚持和复利的意义。😊 微博 | X | FB [caption id="attachment_72603" align="alignnone" width="1152"]还好约会的时候刷题媳妇不管的。 还好约会的时候刷题媳妇不管的。[/caption]

复利效应(Compound Effect)

每天进步一点点,长期坚持所积累的成长将是巨大的。现在我每天带着孩子一起刷力扣也是如此:一两天,甚至几个月,可能都看不出明显变化,但只要坚持几年,这个习惯一定会让我们受益。活到老,学到老;保持耐心、坚持积累,享受延迟满足带来的回报。 [caption id="attachment_69529" align="alignnone" width="640"]每天10来分钟 带娃刷力扣,每天进步一点点。 每天10来分钟 带娃刷力扣,每天进步一点点。[/caption] 年前在Linkedin上分享刷题火了 (1万6000次喜欢/600多条评论) [caption id="attachment_72608" align="alignnone" width="809"]几年前在Linkedin上分享刷题火了 几年前在Linkedin上分享刷题火了[/caption] [caption id="attachment_66880" align="alignnone" width="713"]从2013年到2024的力扣刷题之路。 从2013年到2024的力扣刷题之路。[/caption] [caption id="attachment_72607" align="alignnone" width="842"]2024年到2026年打卡力扣刷题 2024年到2026年打卡力扣刷题[/caption] [show_file file="/var/www/wp-post-common/justyy.com/leetcode.php"] [show_posts keyword="力扣"]

蜘蛛侠4上映第二天: 在剑桥Everyman看《Brand New Day》

2026-08-09 03:20:38

上周六,我们在《Spider-Man: Brand New Day》(蜘蛛侠4)上映的第二天,来到剑桥Grand Arcade里的Everyman电影院观看。当天市中心交通拥堵,好在电影开始前播放了近半小时广告,让我顺利赶上。三个人的电影票花了50.70英镑,差不多已经可以买一张四人家庭票。由于没有看全前几部电影,部分剧情没有完全理解,媳妇还临时用ChatGPT补充背景。虽然电影长达两个多小时,但也算是一次轻松的周末家庭活动。
上周六,《Spider-Man: Brand New Day》(蜘蛛侠4)在Everyman上映的第二天,我们去了剑桥市中心Grand Arcade购物商场里的Everyman电影院观看。
Spider-Man: Brand New Day 12A · 2 hr. 25 min. Everyman Cambridge in Screen 3 Saturday, 1 August 2026 01/08/2026 13:00:00 A10 · A8 · A9 Adult x 1 £ 20.00 Adult & Child x 1 £ 28.20 Booking Fee £ 2.50 Sub-total £ 45.61 Tax (incl. in ticket price) £ 5.09 Order total: £ 50.70
老大当天上午11点到下午1点在图书馆做义工,结束后便直接去电影院和我们会合。电影票上写着下午1点开始,不过英国电影院通常不会准时播放正片,前面总要先放一大段广告和预告片。这一场也差不多放了30分钟,倒是给迟到的观众留出了充足的缓冲时间。 当天剑桥市中心的草地上正好有活动,路上非常拥堵。我先把媳妇放在Grand Arcade门口,然后再开车去找停车位。停好车后走回电影院,已经是下午1点25分了。幸好广告还没有结束,刚坐下来不久,电影才正式开始。 老二原本也可以一起去,不过他对这部电影没有兴趣,宁愿留在家里。我们三个人的电影票一共花了50.70英镑。再多加两三英镑,其实就可以买一张包含两个大人和两个孩子的Family Ticket。可惜老二不来,这张家庭票也就失去了意义。 Everyman和普通的连锁电影院有些不同,主打的是比较精致的观影体验,影厅里主要是柔软的沙发座椅,还可以把食物和饮料送到座位上。剑桥这家店位于Grand Arcade一楼,2024年才开业。环境和座椅确实比较舒服,不过票价也明显比一般电影院贵一些。[Everyman Cambridge官网] 《Spider-Man: Brand New Day》片长约2小时25分钟,是Tom Holland主演的第四部蜘蛛侠个人电影,也是《Spider-Man: No Way Home》的续集。上一部结尾,所有人都忘记了Peter Parker,而这一部的故事正是从这个设定继续展开。[Sony Pictures官方介绍] 由于我并没有完整看过前面的几部蜘蛛侠电影,所以有些人物关系和剧情背景没有完全弄明白。漫威电影之间的联系越来越多,如果中间漏掉几部,再接着看新片,确实很容易有一种“大家好像都认识,只有我不知道发生了什么”的感觉。 媳妇有些地方也没看懂,于是一边看,一边用ChatGPT查询前面的剧情和人物背景。以前看电影遇到不明白的地方,只能回家以后再慢慢搜索;现在倒是可以在电影院里直接让AI补课了。只是电影中的角色和支线实在太多,即使临时补了一些背景,也不一定能够完全跟上。 正片两个多小时,再加上前面的广告,整场下来接近三个小时。虽然剧情没有完全看懂,但这次看电影本身也算是一场周末家庭活动:老大做完义工后过来会合,老二选择留在家里,我们三个人在拥堵的剑桥市中心赶上了电影,也算是有惊无险。 [caption id="attachment_72696" align="alignnone" width="1600"]Spider-Man: Brand New Day 蜘蛛侠电影
Spider-Man: Brand New Day 蜘蛛侠电影
[/caption] 最后补充一句与剧情无关的观后感: [bctt tweet="PS:女主Zendaya真的很漂亮。"] [caption id="attachment_72588" align="alignnone" width="1538"]电影结束后,老大和媳妇在讨论剧情。 电影结束后,老大和媳妇在讨论剧情。[/caption] [caption id="attachment_72587" align="alignnone" width="2048"]前一天晚上才订的票,只剩下最前排的三四个连续的座了 前一天晚上才订的票,只剩下最前排的三四个连续的座了[/caption] [caption id="attachment_72586" align="alignnone" width="1577"]蜘蛛侠4电影海报 蜘蛛侠4电影海报[/caption] [show_file file="/var/www/wp-post-common/justyy.com/movie.php"] [show_posts keyword="电影"]

《Spider-Man: Brand New Day》剧情简介

几年过去,Peter独自住在纽约,把几乎全部精力都投入到打击犯罪中。他只能远远关注已经开始新生活的MJ和Ned,却始终不敢告诉他们过去发生的一切。长期的孤独和压抑也令他的身体发生变化:感官和力量进一步增强,甚至能够直接从手腕射出蛛丝,但情绪也变得越来越暴躁,逐渐失去控制。Sony官方剧情简介 与此同时,纽约接连发生一系列离奇案件,一个能够侵入并控制他人意识的神秘敌人开始出现。对方不仅知道Peter的真实身份,还利用他对MJ的感情设下陷阱,并试图渗透负责监管超能力者的损害控制局。为了弄清自己的身体变化并阻止这场危机,Peter向Bruce Banner求助,途中又与行事更加冷酷的惩罚者Frank Castle产生交集。Deep Focus Review剧情介绍 这一次的故事没有再把重点放在多元宇宙,而是回到Peter个人的孤独、愤怒与责任之中。他必须面对的并不只是一个看不见的敌人,还有那个被痛苦逐渐改变的自己。即使MJ和Ned已经不再记得他,他仍然选择保护他们——世界遗忘了Peter Parker,但Peter从未忘记自己所爱的人。

把一台积灰的迷你电脑塞进鞋柜: 我的 NUC-8 家庭服务器

2026-08-09 01:26:22

我把一台闲置多年的 Beelink SEi8 迷你电脑安装上 Ubuntu,放在鞋柜里作为家庭服务器,用来运行 STEEM 节点、Node.js 程序、数据库、反向代理及 Cloudflare Tunnel。文章还解释了双重 NAT 导致 NUC-8 可以主动访问树莓派、树莓派却无法反向发起连接的原因,并分享了旧电脑再利用、家庭宽带和服务器散热方面的经验。

把NUC放到鞋柜里当成一个服务器, 那是相当的稳定

去年下半年,我把家里一台已经积灰许久的迷你电脑重新找了出来,安装上 Ubuntu 24.04.4 LTS,然后把它塞进家门口的鞋柜里,当成了一台家庭服务器。 我平时习惯把它叫作“NUC-8”,不过严格来说,它并不是 Intel 自家的 NUC,而是一台 Beelink SEi8 迷你主机。它是我在 2021 年 4 月 25 日从 Amazon 买的,当时花了 466.65 英镑,配置如下: Beelink Mini PC SEI8,Intel Core i5-8259U(最高 3.8GHz),16GB DDR4 内存,512GB NVMe SSD,Intel Iris Plus Graphics 655,支持 Wi-Fi 6 和蓝牙 5.0。

从 Windows 小主机到闲置电脑

这台电脑买来时预装的是 Windows 10 Pro。配置看上去不算差,但实际使用时总觉得速度有点慢,体验并没有达到我的预期。后来我把它放到 Eric 的房间里,让他用了大半年。再后来给他换了 MacBook Air,这台小电脑也就逐渐闲置下来,最后成了一件放在家里吃灰的电子产品。 其实这类迷你电脑最尴尬的地方,不是性能完全不够,而是作为日常桌面电脑不够出彩:和新款笔记本相比,它的响应速度、图形性能和整体体验都显得普通;可如果直接扔掉,又实在可惜。毕竟四核八线程的处理器、16GB 内存和 512GB NVMe SSD,用来运行 Linux 和一些长期在线的服务,仍然绰绰有余。 于是去年下半年,我决定给它换一种活法。

装上 Linux 后,反而变得流畅了

安装 Ubuntu 24.04.4 LTS 之后,这台机器给我的感觉几乎是“重新活了过来”。没有太多不必要的桌面软件和后台服务,整个系统运行得非常流畅。对于服务器用途来说,它的性能不但不落伍,甚至还有相当大的余量。 这一年里,我陆续在它上面部署了不少东西。 我曾经用它运行一个 STEEM 见证人节点;配置了反向代理,并通过 Cloudflare Tunnel 把家里的服务安全地连接到公网;还使用 PM2 长期运行一个 Node.js 机器人程序,监听区块链上的交易,再把需要的数据写入数据库。 平时写程序时,我也会通过局域网,使用 VS Code Remote SSH 直接连接到这台服务器。编译和运行 C++ 程序、测试脚本,或者部署一些需要长期运行的小服务,都可以放到上面完成。和树莓派相比,i5 处理器、16GB 内存和 NVMe SSD 带来的性能优势还是非常明显的,尤其是编译代码和操作数据库时,轻松得多。 就这样,这台原本已经闲置的迷你电脑,在鞋柜里连续运行了将近一年,总体上相当稳定。 后来,我又找出了一块闲置已久、已经积灰的 2TB 硬盘,将它装入 USB 硬盘盒并连接到 NUC-8。这块硬盘采用 ext3 文件系统,主要用于存储 STEEM 区块链节点数据。此外,树莓派 4B 也外接了一块 2.5 英寸的 1TB USB SSD,用来搭建家庭文件共享服务。

家里的网络,也终于配得上这台小服务器了

最近,我又把家里的宽带升级成了全光纤。理论下载速度可以达到 900Mbps,上传速度则是 110Mbps。对于在家中运行一台小型服务器来说,这样的网络已经相当够用。 当然,如果是从公网访问家里的服务,真正决定对外传输能力的主要是 110Mbps 的上传速度,而不是 900Mbps 的下载速度。不过无论是个人网站、API、远程管理,还是我现在运行的这些轻量服务,110Mbps 都已经有很大余量。再加上 Cloudflare Tunnel,服务器主动向 Cloudflare 建立出站连接,不需要在两层路由器上折腾公网 IP 和端口映射,即使家里存在双重 NAT,也照样可以工作。

为什么 NUC-8 能访问树莓派,树莓派却访问不到 NUC-8?

我家目前的网络结构稍微有点特别。 [caption id="attachment_72558" align="alignnone" width="1546"]现在家庭网络的拓扑图 现在家庭网络的拓扑图[/caption]
flowchart TB
    Internet(("Internet"))

    subgraph PL["Plusnet LAN — upstream subnet"]
        Hub["Plusnet Hub 2<br/>Router and NAT"]
        Pi4["Raspberry Pi 4B<br/>Connected directly to Hub 2"]

        Hub <-->|Direct connection| Pi4
    end

    subgraph DL["Deco LAN — downstream subnet"]
        Deco1["Deco 1 — Primary<br/>Router, NAT and firewall"]
        Deco2["Deco 2 — Mesh node<br/>Upstairs office — bedroom"]
        Deco3["Deco 3 — Mesh node<br/>Study room — former garage"]
        NUC["NUC-8 / Beelink SEi8<br/>Ubuntu home server"]
        Pi1["Raspberry Pi Model B Rev 2<br/>~475 MB RAM"]

        Deco1 <-->|Ethernet| NUC
        Deco1 -.-|Wireless mesh| Deco2
        Deco1 -.-|Wireless mesh| Deco3
        Deco3 <-->|Ethernet| Pi1
    end

    Internet <--> Hub
    Hub <-->|Ethernet to Deco WAN| Deco1
Plusnet 路由器是最上游的主路由器。两台树莓派——一台只有约 475MB 内存的老款 Raspberry Pi Model B Rev 2是和NUC-8一样分别连到了两个DECO路游器,一台 4GB 内存的 Raspberry Pi 4B—直接连接在 Plusnet 路由器上(有线/RJ45网线)。 Deco 则连接到 Plusnet 路由器,并继续以“路由器模式”工作,而不是桥接或 AP 模式。NUC-8 通过网线连接到 Deco。因此,Plusnet 和 Deco 分别建立了两个不同的局域网子网。例如,树莓派可能位于 192.168.1.x 网段,而 NUC-8 则位于 Deco 管理的 192.168.68.x 网段。 这就形成了家庭网络中常见的“双重 NAT”。 当 NUC-8 主动访问树莓派时,数据从 Deco 的内网侧发往上游。Deco 会通过 NAT 把连接转换成自己的上游地址,并在连接跟踪表里记录这次请求。树莓派返回的数据因此能够被 Deco 正确地转发回 NUC-8,所以这个方向可以正常通信。 从树莓派4b PING下游的NUC-8和树莓派Model B行不通。
From 192.168.1.XXX icmp_seq=460 Destination Host Unreachable
但当树莓派主动访问 NUC-8 时,情况就不同了。树莓派所在的 Plusnet 网络通常不知道 192.168.68.x 网段应该通过哪台设备到达;即使请求发到了 Deco 的上游接口,Deco 的防火墙也会把它视为从 WAN 侧发起的、没有对应连接记录的入站请求,默认不会转发给内部的 NUC-8。 所以,这并不是数据真正意义上的“只能单向流动”,而是只有 NUC-8 一侧能够主动发起连接。NUC-8 发起连接以后,树莓派的响应仍然可以原路返回;树莓派却不能无条件地主动建立一条通往 NUC-8 的新连接。 如果想让三台机器彼此直接访问,最简单的办法是把 Deco 切换成 AP 模式,或者把两台树莓派也接入 Deco,让所有设备处在同一个子网里。另一种更专业但也更麻烦的做法,是在 Plusnet 路由器上添加一条指向 Deco 的静态路由,并相应调整 Deco 的 NAT 和防火墙规则;但不少家用路由器并不完整支持这种配置。若只需要访问 NUC-8 上的个别服务,也可以在 Deco 上设置端口转发,不过管理起来不如统一子网清晰。

一台旧电脑的第二次生命

回头看,这台 2021 年花 466.65 英镑买来的迷你电脑,作为 Windows 桌面电脑时并没有给我留下太深的印象;可在几年之后,它却以家庭 Linux 服务器的身份找到了更适合自己的位置。 它体积不大、功耗相对可控,性能又远高于普通树莓派。运行区块链节点、数据库、Node.js 服务、反向代理和日常开发环境,对它来说都不是什么大问题。升级到全光纤宽带以后,这套家庭服务器环境也变得更加实用。 唯一需要注意的是,鞋柜毕竟不是标准机房。连续稳定运行近一年是个好现象,但并不能替代温度和硬盘健康监控。鞋柜要保留足够的通风空间,还应定期清理进风口的灰尘,并检查 CPU 温度和 SSD 的 SMART 状态,避免机器因为长期积热而降频,甚至缩短硬件寿命。 对我来说,这次改造最大的乐趣,并不只是省下了购买服务器的钱,而是让一台已经闲置的旧电脑重新有了价值。它安静地躲在门口的鞋柜里,平时几乎感觉不到它的存在,却每天都在替我运行节点、处理数据、托管服务,也承载着我随时冒出来的各种小项目。 对于喜欢折腾技术的人来说,这大概就是家庭服务器最有意思的地方:不一定需要昂贵的机架、专业的机房,甚至不一定需要最新的硬件。一台被遗忘的旧电脑,加上 Linux、稳定的网络和一点耐心,就足以搭起属于自己的小型家庭实验室。 [caption id="attachment_72570" align="alignnone" width="2048"]第一次安装还是加个显示器方便一些。 第一次安装还是加个显示器方便一些。[/caption] [caption id="attachment_72569" align="alignnone" width="1189"]STEEM区块链见证人就跑在这台服务器上 STEEM区块链见证人就跑在这台服务器上[/caption] [caption id="attachment_72568" align="alignnone" width="733"]利用起来,跑上pm2用于管理nodejs程序:监控STEEM区块链然后入数据库。 利用起来,跑上pm2用于管理nodejs程序:监控STEEM区块链然后入数据库。[/caption] [caption id="attachment_72567" align="alignnone" width="877"]这台服务器neofetch显示的信息。 这台服务器neofetch显示的信息。[/caption] [caption id="attachment_72566" align="alignnone" width="1160"]内存和处理器放在WINDOWS上可能勉强用,但是在LINUX上会很流畅。 内存和处理器放在WINDOWS上可能勉强用,但是在LINUX上会很流畅。[/caption] USB存储需要提前下好Ubuntu的镜象,然后从USB启动。 [caption id="attachment_72565" align="alignnone" width="2048"]接上键盘鼠标和显示器,然后需要在另一台电脑上下载好镜像,刷到USB上启动安装。 接上键盘鼠标和显示器,然后需要在另一台电脑上下载好镜像,刷到USB上启动安装。[/caption] [caption id="attachment_72564" align="alignnone" width="1536"]这个NUC-8小机器有个风扇,还是有点噪音。 这个NUC-8小机器有个风扇,还是有点噪音。[/caption] [caption id="attachment_72563" align="alignnone" width="1536"]体积不大,盒子已经被我拆掉了,因为散热更好一些。 体积不大,盒子已经被我拆掉了,因为散热更好一些。[/caption] [caption id="attachment_72562" align="alignnone" width="1536"]从抽屉里找出来的,还能用。 从抽屉里找出来的,还能用。[/caption] [caption id="attachment_72561" align="alignnone" width="864"]小小的鞋柜里塞下两台服务器:树莓派4b和这个NUC-8 小小的鞋柜里塞下两台服务器:树莓派4b和这个NUC-8[/caption] [caption id="attachment_72560" align="alignnone" width="953"]五年前买的小电脑 现在还在发挥余热 五年前买的小电脑 现在还在发挥余热[/caption] [show_file file="/var/www/wp-post-common/justyy.com/home-topology.php"] [show_posts keyword="家庭 网络 拓扑"] 英文:Turning a Dusty Mini PC into a Home Server: My NUC 8's Second Life [caption id="attachment_72582" align="alignnone" width="1086"]NUC-8配置 NUC-8配置[/caption] [caption id="attachment_72583" align="alignnone" width="1074"]树莓派 4b 配置 树莓派 4b 配置[/caption] [caption id="attachment_72584" align="alignnone" width="1089"]树莓派b rev2配置 树莓派b rev2配置[/caption]