从 Codeberg Pages 迁移到 OpenBSD VPS

Lobsters Hottest 新闻

摘要

作者详细描述了因性能问题将静态网站从 Codeberg Pages 迁移到 OpenBSD VPS 的过程,包括设置步骤和个人经验。

<p><a href="https://lobste.rs/s/4wh5ng/migrating_from_codeberg_pages_openbsd">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/25 11:42

# 从 Codeberg Pages 迁移到 OpenBSD VPS 来源:https://nemin.hu/vps/index.html ## 目录 - 背景 (https://nemin.hu/vps/index.html#background) - 选择服务商 (https://nemin.hu/vps/index.html#picking-my-provider) - SSH 配置 (https://nemin.hu/vps/index.html#ssh-config) - 谨慎处理 MIME 类型 (https://nemin.hu/vps/index.html#be-careful-with-mimes) - 升级 OpenBSD 至 8.0-beta (https://nemin.hu/vps/index.html#upgrading-openbsd-to-8.0-beta) - 防火墙 (https://nemin.hu/vps/index.html#firewall) - TLS 证书 (https://nemin.hu/vps/index.html#tls-certificates) - Web 服务器 (https://nemin.hu/vps/index.html#web-server) - 德国式官僚作风 (https://nemin.hu/vps/index.html#german-bureaucracy) - 设置我的 VPS (https://nemin.hu/vps/index.html#setting-up-my-vps) - 发现;或者说,机器人热爱你的冷门内容! (https://nemin.hu/vps/index.html#findings-or-bots-love-your-obscure-content) - 结论 (https://nemin.hu/vps/index.html#conclusion) - 脚注 (https://nemin.hu/vps/index.html#footnotes) 在这篇文章中,我想解释从基于代码托管平台的静态站点托管迁移到完全独立的 VPS 的“如何”与“为何”。这并非真正的教程,主要是因为市面上已有更好的文本介绍如何操作,但我确实链接了其中许多,并指出了我感到困惑或惊讶的地方。此外,如果你正在阅读这篇文章,那么它正是由这台 VPS 提供服务的,打个招呼吧! ## 背景 我写博客已有近八年,这八年来,我一直依赖某种免费托管服务来存放内容。在相当长的一段时间里,这似乎没问题,尤其是考虑到这个和我的另一个网站 (https://oddwords.hu/) 完全没有盈利。然而,近期需求和财务状况的变化终于让我打破现状,实际尝试了一番。 最初,我依赖 GitHub Pages,对于像我这样的网站来说,它几乎是完美的。它免费且几乎无需设置,构建速度极快,拥有无懈可击的正常运行时间(尽管 GitHub 著名地开始在这方面遇到问题 (https://mrshu.github.io/github-statuses/)),而且我可以非常轻松地在它前面放一个便宜的域名,使其比默认的 `nemin32.github.io` 地址更具吸引力。 然而,由于*近期趋势*,并且受到那些受够了的人们集结号 (https://taggart-tech.com/migrate-to-codeberg/) 的鼓舞,我也投身其中,将我的网络存在 (https://codeberg.org/Nemin) 迁移到了 Codeberg。这当然意味着我的两个网站也必须搬迁。幸运的是,这个过程并不特别痛苦(上面链接的文章基本能在 10-15 分钟内帮你入门),所以我很快就设置好了一切。 虽然我以为已经完成了,但可悲的是,我很快意识到尽管这两个服务设计相似,但服务质量却大相径庭。Codeberg Pages 有时真的很难用。我的页面很少超过几百 KB(大部分是几张 AVIF 格式的图片),但加载我的网站有时需要 10-15 秒,浏览器就这么卡着。在任何人产生误解之前,我并非在任何程度上指责 Codeberg。事实上,我非常感激首先有这个选项存在。毕竟,他们是一个(相对较小的)非营利组织,不仅要为我这小破网站服务,还要为更严肃的项目提供服务。考虑到这一点,他们无法总是为我分配计算资源,这并不奇怪。 然而,尽管我同情他们,我仍然受困于这个问题,必须找到某种解决方案。而这个解决方案就是将有用与愉快的东西结合起来:于是,VPS 登场了。 ## 选择服务商 VPS 是一个由云服务提供商公司出租的托管虚拟机。用户群非常广泛,你可以找到各行各业的人使用它们,从学生和爱好者,到非常严肃和大型的企业,他们不想费心处理本地部署方案。如今,如果某人恰好属于前者类别,并且只需要一台拥有少量 RAM 和一个(甚至只是一个)相当快的 CPU 核心的机器,他们有众多提供商可以选择,这些提供商专注于压低价格,以极其低廉的价格向你出租此类虚拟机。 这是一个 (https://lowend-deals.xbit.win/) 收集此类便宜交易的网站。一个突出的例子,只需看看 LowEndBox 的每月 1 美元 VPS 列表 (https://lowendbox.com/blog/1-vps-1-usd-vps-per-month/),名字就说明了预期内容。但如果你愿意四处寻找更不知名的服务商,并且可以进一步调整你的需求(例如,不要求 IPv4 地址),我发现了一家 (https://web.c-servers.co.uk/category/welcome-to-c-servers) 公司,他们会以每年 4.5 美元(注意,是*年*)的价格租给你一台拥有 5GB 存储和大约 400MB RAM 的虚拟机。我认为价格不可能比这更低了。 然而,考虑到无论如何我也不会花很多钱,我决定坚持使用一个知名且值得信赖的选择:netcup (https://www.netcup.com/en)。虽然他们最便宜的选项接近每月 2 欧元,但作为回报,你可以获得不限流量的 100Mbps 连接(只要你善意使用)、30GB 存储空间、为虚拟机制作快照进行备份的选项,以及保证你的钱是交给懂行的人。听起来都很棒……如果不是和他们做生意出奇地复杂的话。 ## 德国式官僚作风 如前所述,我的选择落在了 VPS Pico G11s (https://www.netcup.com/en/server/vps/vps-pico-g11s-iv-12m-nue) 上。起初过程如预期:我把 VPS 加入购物车,输入地址和个人信息,然后在页面间点击,直到我注意到有一个 Netcup 新闻通讯,如果你订阅,可以获得 5 欧元的优惠券。我想着“太棒了,这差不多三个月了”,就注册了。优惠券几乎立刻就到了,我高兴地看到输入后,VPS 的价格从 24 欧元降到了大约 19 欧元。一切似乎都很好,于是我按下了那个友好的大“订单”按钮……结果被弹回了一个错误。显然我选的 VPS 太便宜了,不适用于该优惠券,于是我很不情愿地将其移除,按原价继续操作。毕竟,24 欧元只是一顿精致午餐的价格,我不会因为不能更省钱而放弃一切。 修正了我的交易并再次点击“订单”后,我以为会跳转到支付门户。结果,我只是被告知一个真人会核实我的订单是否合法,我必须等到那时候。考虑到当时已是下午很晚(远超通常的欧洲工作时间),我叹了口气,认命地等到第二天或不管多久。 与此同时,我收到了一封让我觉得非常有趣的电子邮件。它以一种非常严肃和法律化的口吻写成,有冗长的段落干巴巴地描述我的权利和责任,并且说明,通过下订单,我现在有两周时间可以拒绝与 Netcup 签订合同,之后合同才具有约束力。我觉得这相当令人耳目一新,许多公司将其令人讨厌的细节隐藏在使用条款或其他类似文本深处,但这里不是。当然,这让与客户的沟通显得不那么浮夸,但我完全不在意。 然后,最让我惊讶的是,不到十分钟,我的收件箱又响了:我的审核已成功完成,我可以登录门户了。于是我照做了,以为终于可以付款了……结果迎面而来一个巨大的界面,命令我根据 GDPR 声明我处理用户数据的方式。可悲的是,我没有截图,现在也无法访问它了,但基本上就是问我打算处理什么类型的数据。考虑到我建立的是一个简单的静态站点,我声明我不处理任何个人数据,就这样。 到这个时候,我终于可以添加信用卡并为我的服务器付款了。五分钟后,又收到两封电子邮件,我收到了一个指向*另一个完全不同页面*的链接,这个页面(令我大为宽慰)确实允许我访问我的机器了。 ## 设置我的 VPS 虚拟机预装了 Debian 13,系统本身不错,但由于最近对各种 BSD 产生了兴趣,并在 Lobste.rs (https://lobste.rs/) 上看到了 httpd.rocks (https://httpd.rocks/),我决定放弃它,转而尝试 OpenBSD 7.9。 *netcup 提供的镜像列表。所有 BSD 和一些不错的发行版选择……当然,还有 Windows,如果你喜欢的话……*怪人*。* 让我高兴的是,netcup 在其界面上提供了最新的 OpenBSD ISO。只需点击它,虚拟机就会自动加载磁盘并更改启动顺序从它启动。重启虚拟机有点慢(大约需要一整分钟),但我不打算经常重启,所以无所谓。 安装 OpenBSD 是小菜一碟。毫无疑问,在将操作系统安装到机器上时,这是最简单的过程之一。我禁用了 X 窗口系统和游戏集,但保留了其余部分。显然这有点不合时宜 (https://www.bsdhowto.ch/instsets.html),但最坏的情况我只是重装机器,没什么大不了的。 我选择了默认的文件系统。`/var` 空间小得可怜。我认为在安装过程中犯的唯一真正错误是接受默认分区方案,这在 `/home` 上浪费了大约 6GB 存储空间,而我反正不会使用它,而 `/var`(可以说是我最重要的文件夹,因为它包含我网站的代码和日志)最终却只有可怜的 2GB。这是一座我最终必须跨越的桥,但目前还可以。 > **来自未来的注释:** 我确实在解决一个无关问题时重新安装了系统,并将 `/var` 设成了一个大得多的分区。谢天谢地,OpenBSD 的安装又快又简单,这完全是个无痛的过程。 ## SSH 配置 虽然 netcup 界面提供了远程桌面,但用起来并不太愉快。它不仅慢得让人痛苦,而且对接收输入非常挑剔(你需要点击屏幕,而且它似乎偶尔会自己失去焦点),所以我很快决定研究设置 SSH。我不需要找太远,这篇博文 (https://seeminglyrandom.net/posts/setup-openbsd-and-hardening-ssh/) 完美契合我的需求。它描述了如何使系统达到最新状态,以及如何通过禁用可疑的加密套件来设置安全的 SSH。 我为 VPS 生成了一对全新的密钥,因为为所有项目重用相同的密钥是惹上麻烦的好方法。在快速用密码登录并执行了正确的 `ssh-copy-id` 调用后,我禁用了密码登录。然后,我在 `~/.ssh/config` 文件中添加了一个新条目,这样我只需执行 `ssh vps` 就能处理其余部分。这比手动操作方便多了: 前三行不是严格必需的,但它们让长时间连接更易忍受。 ``` AddKeysToAgent yes ServerAliveInterval 15 ServerAliveCountMax 3 Host vps HostName [VPS的IPv4地址] User [用户名] IdentityFile ~/.ssh/id_vps ``` 最后,我将 `openrsync` 符号链接到 `rsync`。这是必要的,因为我的主要 Linux 机器上的 `rsync` 在尝试将文件复制过去时,期望在 VPS 上找到同名的可执行文件。除了这个变通方法,一切都非常整洁,SSH 处理透明。我只需执行 `rsync -av --delete source vps:destination` 就能处理其余部分。 ## 升级 OpenBSD 至 8.0-beta > **来自未来的注释:** 这部分有点时代错位,因为它被放在讨论任何服务器配置之前,但实际上是在我完成配置并完全重写之后写的。原因在于,虽然我最初打算使用经常推荐的 `relayd` 来处理 TLS 连接并为响应添加 HTTP 头(httpd.rocks 也有一个教程 (https://httpd.rocks/relayd.html)),但我在解决一个无关问题时偶然发现了这个 (https://reddit.com/r/openbsd/comments/1vnn5ut/dumb_question_httpd_and_the_need_for_relayd/) Reddit 帖子,其中提到 `httpd` 很快将支持自己设置 HTTP 头(并且它已经能够处理 TLS),这使得 `relayd` 对我来说几乎大材小用。设置几个 HTTP 头来告知浏览器如何缓存内容以及应尽可能少地泄露信息,这既被认为是良好实践,也是提升网站性能的无痛方式。虽然 OpenBSD 7.9 的 `httpd` 没有提供内置机制(因此需要额外的代理服务),但(目前处于测试阶段的)8.0 版本 (https://man.openbsd.org/httpd.conf#header) 已经有了 `header set` 指令。为了能使用这个,我必须将系统从 `7.9-release` 升级到 `8.0-beta`。 虽然初看之下可能很难,但结果发现不过是执行 `sysupgrade -s`,等待系统下载最新的操作系统发布快照,然后自动安装它,而我完全不需要碰任何东西。1 (https://nemin.hu/vps/index.html#fn1) 之后我只剩下两个非常简单的维护任务: - 我需要执行 `pkg_add -u` 将所有软件包升级到兼容 8.0 的版本。这顺利通过。 - 我还需要调用 `sysmerge` 来更新两个发行版之间可能已更改的任何系统配置文件。在我的情况下,只有 `sshd_config`,它默认引入了后量子密码并将 `PermitRootLogin` 更改为 `prohibit-password`。由于这两者都没有影响我对 `sshd` 的使用,我选择不做任何手动干预就接受它们。 基础完成后,是时候让机器执行其预期任务了。不过坦率地说,我能写的任何详细指南都会是 httpd.rocks 的苍白而不精确的模仿,所以我将保持简洁,只评论我认为有趣的地方。如果你觉得我的旅程有任何启发性,我建议你也看看前面提到的指南。免责声明完毕,让我们开始吧: ## 防火墙 ``` ext_if="vio0" set limit states 100000 # 最大状态表条目数 set timeout interval 30 # 状态清除间隔 set optimization "normal" # 连接跟踪的一般优化 set skip on lo # 跳过回环接口 # 防欺骗 antispoof log quick for $ext_if match in all scrub (no-df) # 默认阻止所有 block all # 阻止滥用主机表 table persist file "/etc/pflists/block_table" table persist file "/etc/pflists/ssh_naughty" block in quick from <block_table> block in quick from <ssh_naughty> # 阻止虚假目标地址 table <bogons> { 0.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.0.0.0/24 \ 192.0.2.0/24 224.0.0.0/3 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \ 203.0.113.0/24 \ ::/128 ::/96 ::1/128 ::ffff:0:0/96 100::/64 2001:10::/28 2001:2::/48 \ 2001:db8::/32 3ffe::/16 fec0::/10 fc00::/7 } block in quick on egress from any to <bogons> # 允许 DNS 和 NTP pass out on $ext_if proto {udp tcp} to any port 53 pass out on $ext_if proto udp to any port 123 # 允许 SSH pass in on $ext_if proto tcp from any to any port ssh synproxy state \ (max-src-conn 10, max-src-conn-rate 5/30, overload flush global) pass out on $ext_if proto tcp from any to any port ssh keep state # 允许 Web 服务器相关 pass in on $ext_if proto tcp from any to any port {80 443} synproxy state \ (max-src-conn 100, max-src-conn-rate 30/5, overload flush global) pass out on $ext_if proto tcp from any to any port {80 443} keep state ```

相似文章

与Codeberg相伴一年

Lobsters Hottest

GNU Guix回顾了迁移至Codeberg进行源码托管与协作的一年历程,讨论了决策过程、挑战与成果。