惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

Peng's Blog

通过《Resilient AI Supercomputer Networking using MRC and SRv6》理解协议层面的故障检测 经典论文MP-RDMA(多路径RDMA)阅读 Vibe paper不负责指北 SPFC参考文献阅读《CONGA》 读《Uno:数据中心间和数据中心内拥塞控制与可靠连接的一站式解决方案》 Lenovo Legion Y9000P 在 Linux 下只有 30W:从现象、WMI 到驱动补丁 理解《From ATOP to ZCube》中的ZCube网络拓扑 集合通信原语学习 Zotero在Wayland下侧边栏无法拖动的解决办法 再读CAVER 我读的第一篇论文--NSDI_26_CAVER 在archlinux下使用万象拼音实现更智慧的中文输入法 Traefik实现单Docker容器托管多个静态网站 严谨与温度并存:北航宋友老师程设课的学习感悟 Android Studio全流程换源指南 解决linux系统下pipewire作为音频服务器持续播放声音中断问题 在ThinkBook 16+ 2025上安装archlinux驯服记录【基本信息与触摸板修复】 「行云流水」在挂载移动硬盘时自动启动Syncthing开始同步的丝滑体验 自建图床和PicGo闹不愉快?干脆自己写个脚本,深度整合到KDE右键菜单! btrfs各压缩等级速率测试脚本,选择最适合你的压缩级别 别当冤大头,Adobe全家桶破解源头方案:修图剪辑不求人,盗版网站也得从你这儿进货! 轻松配置aria2下载器,通过systemd设置开机自启并与浏览器集成 Git Commit 规范指南
Pengs.top浴火重生!备案、服务器迁移与全站Docker化
Pengbo · 2025-12-23 · via Peng's Blog

这学期刚刚进入大学,着急忙慌的博客也没怎么更新。要不是有一天突然发现中国移动ban掉了pengs.top,可能也不会腾出手来折腾。但是我做就要做绝,这一把顺带着给域名做了备案、更换了服务器(其实是砍预算)、以及最主要的——全站Docker化。

诶?WC!

一天我像往常一样下课走去食堂,心血来潮想看一眼过去这么久了pengs.top的访客情况如何,可是当我往浏览器里输入umami服务的地址后,竟然看到了Connection was reset 的恐怖字样。我立刻去看主域pengs.top 发现也是如此。能正常打开其他网站,我也没把锅往广电还有移动头上扣。到了食堂,我连上了校园网,再测试又正常访问。校园网是移动联通电信鹏博士教育网混合出口,我于是开始怀疑起中国移动,叫了几个人帮我测试都是连接已重置,这几乎是实锤了。

随后我又更细致地测试了一下,问题似乎只在北京移动的网络环境下出现。考虑到北京有自己的城域网,加上之前的作业让网站的访问量骤升了数百,我觉得倒有些合理,但这不能洗脱中国移动的罪恶。经控制变量法测试,北京移动阻断了二元组(pengs.top,ip),意味着如果使用ip裸连或者用cloudflare小黄云进行代理就好了。但是我不愿意浪费我这么好的iij线路走cloudflare,也不想配置运营商分流,于是就忍心让北京移动用户无法访问pengs.top了。

解决问题

毕竟pengs.top上运行着很多我自己日常要用的服务,不能在手机流量下正常使用总归不舒服,于是我想尽办法去解决这个问题。

更新:2025年12月24日发现中国移动还是ban了,没招了,我还是继续扯皮吧

备案

我想就算要刚中国移动,我好歹自己得是合法的,像原来那样海外主机+cloudflare域名托管+无备案简直容易被倒打一耙变成非法网站。我都成年了,不能这样没名没分的 于是又一次踏上了艰难的备案流程,不过好在比较顺利,这一次以自己的身份办的,中间没有卡壳。这里要感谢BUAASubnet的摩尔福斯提供的备案授权码!

于是,在2025年12月9日,pengs.top第二次拿到了ICP备案,这一次是京ICP备2025154912号-1

然后公安网备懒得做了额。

10086

打了好几次10086,态度很好,但是一点用都没有。

第一回打过去对面说登记一下,让技术人员联系我。

然后等了一两个礼拜杳无音讯。

中间我发现了互联网信息服务投诉平台,抱着试一试的心态我就给中国移动投诉了。某天上午9点,接到了回电。可是糟糕的是我是南京的手机号,导致工单被派发给了南京移动,10086告诉我查询没有异常。我告诉客服我在北京,她让我加区号010再打一下10086, 结果接线的还是南京的,客服尝试给我转接到北京移动,可是失败了。后来又尝试了一次,依旧如此,无奈之下我只能放弃。

壮士断腕,直接换云

几经周折我也是没辙了

这域名不能就这么废了啊,我还要作传家宝呢。看了眼原先vmiss服务器的到期时间,26年2月就到期了,我寻思着干脆换国内服务器得了,反正备案也已经有了,但是又被高昂的价格,小到离谱的带宽劝退了。其实也有很多新客福利,但是都只能优惠一两年,像我这种懒人,不想频繁重装整个一套服务 所以最终还是打消了这个念头。我又想直接续费vmiss了,但是某天突然想起来:

我是尊贵的大学生啊!

于是Github Azure的学生权益薅起来,这里有点很烦的是你航被美10043法案制裁,导致我到现在github的payment information还是被锁(如下图)

屏幕截图_20251223_220416

我真担心哪天把我大号给扬了,但发了工单也无人问津,唉。

不管怎么说,教育优惠拿到了,至少Github Copilot在手。这玩意儿是真好用啊,后面还会再讲到。

接着开Azure的学生也全是糟点。我自己的个人账号和原来薅E5订阅的管理员账号绑定了,E5订阅被吊销后我的个人账号就有了一些奇怪的租户问题,一度非常无解,而且要开工单需要登陆,但是我TM压根无法登陆。

于是后来我又专门注册了一个outlook账号和我的Github账号关联起来。但是验证学生资质又卡住了,我真的无语。Azure没有给我的edu邮箱发激活邮件,起初我以为是学校的邮件系统给我拦了,问了才知道也没拦截。所以我又开了个工单。

客服让我通过这个链接🔗进行验证,又要了我的学信网报告,折腾了半天总算学生订阅也激活了。

我以为可以咔咔开干了,结果发现我开不了机器,或者准确来说,开不到我想要的。

网上关于Azure VPS的测评不多。ping0.cc有一个VPS延迟的24小时监控 是我参考的主要依据,搜索azure结果大致如图:

屏幕截图_20251223_235726

综合来看,新加坡(Southeast Asia)的表现最好,其次是Japan West、Japan East、East Asia(香港)。

此处还有Azure官方的测试页面 可以测试延迟和速度。我使用的网络下,依然是新加坡表现最好,延迟不到100ms。测试下载速度却差距悬殊。新加坡跑满了20MB/s的带宽,其他的均在2MB/s以下。上传差距不大,均为10MB/s.不过我无法确定分别是通过什么运营商的网络连接的,学校网络出口有负载均衡。

所以比较一圈下来,发现新加坡的机子比较香。我就通过创建免费虚拟机的链接试图去创建,这个链接进去会自动应用适合免费范围的策略,且可选地区是齐全的。但是,就在要确定创建的时候,又报错了

thumbnail_Outlook-kynxsqg2

选的是East Asia而不是Southeast Asia其实是因为破防了,想着香港也行吧,结果发现新加坡,香港,日本都是清一色的这个报错。

一怒之下又开了工单,把材料交上去。就在对面要我继续补充细节的时候,我突然发现又可以开了,就稀里糊涂开了。估计免费机是有配额的。

看看新家园

配置与成本

SKU: Standard_B2ats_v2

CPU: EPYC™ 7763v 2核

内存: 1GB

硬盘: 64GB

网络: 有静态ipv4*1 无ipv6 每月免费流量为出站单向计算15GB 带宽未知,目前来看够用。

费用: 实际消耗0元。

Azure学生认证每一年有100刀的额度。其实感觉上还是有点紧,因为从9月开始Azure已经取消提供免费的动态ipv4地址了,使用ddns的路子行不通了,只能消耗100刀的额度租静态ipv4地址了。

静态ipv4地址的价格是$0.0036/小时,一年约32$,假设我每个月再有5$消耗在流量上,那么根据 带宽-定价 最高收费档(因为实际上我只有免费的15GB流量,而非前100GB免费)$0.12/GB 那么我每个月只能超出15GB再用40GB左右,这是相当少的。后续我可能通过观察流量消耗情况套个CDN啥的。

注:关于如何查看路由首选项,请看Microsoft的这篇教程,如果你是照着我说的做的,那么应该得到是通过Microsoft网络。

总结来看,除了流量减少了以外,其他方面属于是升配降费(降为0)

旧机子怎么办?

其实一开始想搭建一个节点上网的,可是目前手上还不缺梯子。而且对于一台陪伴pengs.top走过了三年的机子,终归有点舍不得最终将它作为节点,把这个ip糟蹋了。毕竟我一直以6.6折的价格用了这么久,还找老板免费加了10GB硬盘......可能就静静地等到它过期被释放掉吧。

建设新服

升级系统

Azure在免费区域里提供的系统映像最新好像只有Debian 11,对于我这种archlinux用户来说还是太古早了。通过将apt源依次换成Debian 12与Debian 13的同时执行apt updateapt upgrade可以顺利地完成升级。

启动bbr与性能优化

毕竟是生产环境,不太敢用网上那种魔改版BBR/锐速的一键脚本,linux内核早就内置bbr了,不过启用前需要先启用tcp_bbr内核模块。

使用以下命令可以立刻启用tcp_bbr模块并在下次开机时也自动激活:

1
2
modprobe tcp_bbr
echo "tcp_bbr" > /etc/modules-load.d/tcp-bbr.conf

注意,到这里为止,我们只是加载了内核模块,并没有真正改变拥塞控制算法

我把以下文件写入了 /etc/sysctl.d/99-network-optim.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
net.ipv4.ip_local_port_range = 30000 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_tw_buckets = 20000
net.ipv4.tcp_max_syn_backlog = 2048
net.core.netdev_max_backlog = 1000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_sack = 1

# 设置TCP拥塞控制为BBR
net.ipv4.tcp_congestion_control = bbr
# BBR依赖fq队列调度器(必须配置)
net.core.default_qdisc = fq

这里面参数的大小有待考量,不一定科学,我查看了ArchWiki对于sysctl配置的建议,结合我小内存的现实情况给出了这些参数。

此外还有一些系统优化的配置在/etc/sysctl.d/99-system-optim.conf,同样不保证科学

1
2
3
4
5
6
7
8
9
10
11
vm.dirty_ratio = 20
vm.dirty_background_ratio = 5
vm.dirty_writeback_centisecs = 1000
vm.swappiness = 20
vm.vfs_cache_pressure = 60
vm.min_free_kbytes = 65536
vm.oom_kill_allocating_task = 1
vm.panic_on_oom = 0
fs.file-max = 500000
fs.noatime = 1
kernel.sched_autogroup_enabled = 0

文件写入完成后可以通过sysctl --system 加载这些配置使之生效。

服务统计

我需要知道哪些服务需要迁移。这其实又是一个浩大的探勘工作,毕竟vmiss的服务器已经年久失修了,基础设施像是一个神话,数据库的账号密码我也不记得了,可能硬编码在某处,反正能跑()

我运行了以下命令查看了端口开放情况:

1
ss -tulnp

接着又看了一下 已经以docker形式运行的服务

1
docker ps

接着还对照了DNS解析列表以及/etc/nginx/sites-enabled 终于梳理出了十余个站点/服务,清理了若干已经废弃的dns记录。

因为怕服务器遭到攻击,这些服务的细节不能公开。

Dockerize!

这里的Dockerize指将原先基于源码/二进制可执行文件/系统级软件包运行服务转变为统一由一个Docker Compose进行编排的过程,与Github上的Dockerize项目无关

为什么要这么做?

光是把杂乱的各项服务梳理出来已经很麻烦了,为什么还要费劲全部Docker化呢?其实是出于安全性,可迁移性与易管理性的考虑做出的大胆的决定。

  1. 安全性

已经有很多人听说了Next.js的CVE-2025-55182这个漏洞了吧。CVSS 10.0 满分意味着 攻击者只要可以使用网络访问受害者,无需任何权限,无需用户交互,即可自动化地完成攻击并完全控制系统

很不幸原来的服务器也中招了,因为umami访客统计使用了next.js.

幸运的是umami被我部署在了docker中,环境不完整,攻击者释放的木马未能成功执行。发现这个问题也是因为docker ps看到umami一直在restart.

通过重新拉取umami的docker映像,木马很容易就被解决了,同时更新了版本。这让我对Docker的安全性大加赞赏。

  1. 可迁移性

大白话是我可以随时拎包跑路,更方便地在多家服务商之间切换。蹭新客福利,虽然只有几年,到期再换就是了

这是因为利用docker的目录映射,我把所有的配置文件,数据库等等统一映射到了一个目录下,如果需要迁移,只要用rsync就能把数据与配置一股脑传走 ,在新机子上使用docker compose up就把服务都拉起来了。

事实上,在从vmiss迁移到azure的过程中,我就是现在本地docker环境中一遍遍测试,确保没有问题之后才把整个目录rsync到服务器上的,整个过程都很顺利,只要在hosts里把所有pengs.top的条目指向本地就好了。

所有文件都在一个目录下也让我备份的时候不再需要备份整个系统,而只要像这样拉取一个目录就好了,检修的时候信息密度也更高:

1
sudo rsync --partial -avz --delete --info=progress2 root@pengs.top:<服务器上的目录> <本地位置>
  1. 易管理性

通过docker ps我可以看到各服务是否在线,资源占用如何。我可以更方便地升级映像使服务版本更新。

通过把服务全部写入docker-compose.yml,我可以清楚地看到我到底跑了多少服务(没错,因为之前看到有好玩的东西就喜欢拿过来跑,结果过一段时间我自己都忘了),它们的配置文件在哪里,端口映射关系如何。

执行

对于没有多少云原生技术基础的我而言,让我从0开始编排服务难如登天,好在有Github Copilot了, 真是帮了我大忙。我主要的任务是清楚地描述我需要什么,当它限于某一处问题时从宏观的角度定位问题的根源。因为不便透露服务细节,我就记录一些踩过的坑还有学到的要点吧。

  1. Docker开机自启动服务

可以使用以下systemd服务单元

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Unit]
Description=Custom Docker Compose Services
Requires=docker.service
After=docker.service network.target network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/docker-services
ExecStart=/usr/bin/docker compose -f <docker-compose.yml位置> up
ExecStop=/usr/bin/docker compose -f <docker-compose.yml位置> down
Restart=always
RestartSec=5
TimeoutStartSec=600

[Install]
WantedBy=multi-user.target
  1. Docker对于端口以及路径的映射

<宿主机路径/端口>:<容器内路径/端口>

  1. 如果要用rsync拉取或推整个docker目录,先docker compose down,要不然很容易导致postgresql等数据库数据出错

  2. Docker中使用Traefik报错 client version 1.24 is too old. Minimum supported API version is 1.44

解决方案:

编辑/usr/lib/systemd/system/docker.service

[Service]下增加一行

1
Environment=DOCKER_MIN_API_VERSION=1.24
  1. 如何使用Traefik通过Cloudflare DNS验证申请泛域名证书并dump出证书pem?

参考我的Traefik配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
traefik:
image: traefik:v3.0
container_name: traefik
restart: unless-stopped
env_file: .env
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"

- "--certificatesresolvers.cf.acme.dnschallenge=true"
- "--certificatesresolvers.cf.acme.dnschallenge.provider=cloudflare"
- "--certificatesresolvers.cf.acme.email=${TRAEFIK_ACME_EMAIL}"
- "--certificatesresolvers.cf.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.cf.acme.dnschallenge.resolvers=1.1.1.1:53"

- "--entrypoints.websecure.http.tls.certresolver=cf"
- "--entrypoints.websecure.http.tls.domains[0].main=${TRAEFIK_TLS_DOMAIN_MAIN}"
- "--entrypoints.websecure.http.tls.domains[0].sans=${TRAEFIK_TLS_DOMAIN_SANS}"

- "--serversTransport.insecureSkipVerify=true"
ports:
- "${TRAEFIK_HTTP_PORT}:80"
- "${TRAEFIK_HTTPS_PORT}:443"
environment:
- "CLOUDFLARE_DNS_API_TOKEN=${CF_DNS_API_TOKEN}"
- DOCKER_API_VERSION=${DOCKER_API_VERSION}
volumes:
- "./traefik/letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`<traefik面板地址>`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_DASHBOARD_USER}:${TRAEFIK_DASHBOARD_PASSWORD}"

这会把acme返回的结果放在./traefik/letsencrypt下,随后使用ldez/traefik-certs-dumper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

cert_dumper:
image: ldez/traefik-certs-dumper:v2.8.3
container_name: cert_dumper
restart: unless-stopped
entrypoint:
- sh
- -c
- |
apk add jq
while ! [ -e /letsencrypt/acme.json ] || ! [ -s /letsencrypt/acme.json ]; do
sleep 1
done
traefik-certs-dumper file --version v2 --watch --source /letsencrypt/acme.json --dest /letsencrypt/live --domain-subdir --crt-name "fullchain" --crt-ext ".pem" --key-name "privkey" --key-ext ".pem"
volumes:
- "./traefik/letsencrypt:/letsencrypt"
networks:
- proxy

然后你就会在./traefik/letsencrypt/live下得到熟悉的fullchain.pemprivkey.pem.

原谅我已经记不得太多排障的细节了,先写到这里吧。

新服务推出

本次服务器迁移带来了一些新的服务,简单介绍一下:

  • list.pengs.top : 原先alist的翻版,但是改用openlist了 存储后端从最早的E5订阅的Onedrive for Business换到了阿里云盘,在阿里云盘限制了第三方API后,现在转向了E3订阅的Onedrive for Business,不用担心容量不够。

  • paste.pengs.top : 我托管的开源的pastebin,可以上传一些小文件,支持阅后即焚,加密选项使用AES-256在浏览器加解密,我无法获知内容

  • nezha.pengs.top : 服务监控,服务器掉线了来戳我。

祝大家圣诞节快乐

2025年12月25日

{·B·}