博主头像
mxd's Blog

以技术为翼,以生活为魂

FreeBSD做服务器一年了 说说我的感受

优点

防火墙

pf,无论是 OpenBSD 的又或者是 FreeBSD 移植的 pf ,都是个很好的选择。

我记得我之前写过一篇文章 Linux 下,几个防火墙之间的“爱恨情仇” - mxd's Blog,那个文章就是我被逼疯了,再加上当时确实经验不足,写下来的。

而 OB 和 FB 就无需考虑这么多,并且我个人认为 pf,无论是语法、操作还是灵活性(我不确定这个用词是否准确),都是优于 ufw 或者 firewalld 的。甚至 nftables 这种下一代语法,都不如 pf。

来看一个稍微复杂一点的场景:一台同时承担网关、防火墙与端口转发职责的主机,需要对不同网段、不同协议做精细控制。

pf 中,可以这样表达:

ext_if = "em0"
int_if = "em1"

lan_net = "192.168.10.0/24"
srv_web = "192.168.10.10"

set skip on lo

block all
pass out quick keep state

match out on $ext_if from $lan_net to any nat-to ($ext_if)

pass in on $int_if from $lan_net to any keep state

rdr on $ext_if proto tcp to ($ext_if) port {80, 443} -> $srv_web

table <trusted> persist { 1.2.3.4, 5.6.7.8 }
pass in on $ext_if proto tcp from <trusted> to ($ext_if) port 22 keep state
block in quick proto tcp to ($ext_if) port 22

如果换成 iptables,同样的需求就会被拆散到多个表、多个链中:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

iptables -A FORWARD -i em1 -o em0 -s 192.168.10.0/24 -j ACCEPT
iptables -A FORWARD -i em0 -o em1 -d 192.168.10.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

iptables -t nat -A POSTROUTING -o em0 -s 192.168.10.0/24 -j MASQUERADE

iptables -t nat -A PREROUTING -i em0 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.10
iptables -t nat -A PREROUTING -i em0 -p tcp --dport 443 -j DNAT --to-destination 192.168.10.10

iptables -A FORWARD -p tcp -d 192.168.10.10 --dport 80 -j ACCEPT
iptables -A FORWARD -p tcp -d 192.168.10.10 --dport 443 -j ACCEPT

iptables -A INPUT -p tcp --dport 22 -s 1.2.3.4 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 5.6.7.8 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

而在 nftables 中,语法确实更统一了一些,但模型本身并没有改变:

table inet filter {
    chain input {
        type filter hook input priority 0;
        policy drop;

        ct state established,related accept

        tcp dport 22 ip saddr {1.2.3.4, 5.6.7.8} accept
    }

    chain forward {
        type filter hook forward priority 0;
        policy drop;

        ct state established,related accept

        iif "em1" oif "em0" ip saddr 192.168.10.0/24 accept
        iif "em0" oif "em1" ip daddr 192.168.10.0/24 accept
    }
}

table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100;

        oif "em0" ip saddr 192.168.10.0/24 masquerade
    }

    chain prerouting {
        type nat hook prerouting priority 0;

        tcp dport {80, 443} dnat to 192.168.10.10
    }
}

可以看到,在后两者中,你不得不显式去关心数据包经过的路径:进入哪个 hook、命中哪条 chain、是否需要额外补充状态匹配,以及 NAT 和过滤规则分布在哪些表里。这些细节本身就构成了理解成本。

再来看一个极简场景:只允许 SSH 和 ICMP,其余全部拒绝。

pf 中几乎是按意图直写:

block all
pass out keep state

pass in proto icmp
pass in proto tcp to port 22 keep state

对应的 iptables

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

以及 nftables

table inet filter {
    chain input {
        type filter hook input priority 0;
        policy drop;

        ct state established,related accept
        ip protocol icmp accept
        tcp dport 22 accept
    }
}

差异在这种简单场景下还不算明显,但一旦规则数量增加、涉及 NAT、转发、白名单等组合条件时,三者的复杂度曲线就开始分化。

归根结底,iptablesnftables 更接近数据包的处理流程编程,而 pf 更像是在描述网络策略本身。前者强调路径与匹配过程,后者强调意图与结果。

当然,这也是我的主观感受,咱对哪个熟悉那自然是用哪个更好。

ZFS

FreeBSD 原生深度集成了 ZFS,而不是额外安装的文件系统。

系统上,与 zfs 搭配非常密切:

  • 首先,安装器直接支持 root-on-ZFS
  • 启动流程(bootloader)原生支持+理解 ZFS
  • 最重要的是,在fb上,很多系统工具(如 beadm / bectl)都是围绕 ZFS 设计的,保证了生态完美融合

在服务器侧,这带来几个非常实用的能力:

  • 原子升级(boot environment 切换)我不确定这个表述是否正确
  • 快照 + 回滚,注意是系统级,而不是应用级
  • 内建校验(silent data corruption 防护)
  • 存储与卷管理一体化(无需 LVM + FS 组合)

Linux 虽然也能用 ZFS,但更多是一种类似于外挂的方案,或者转而使用 btrfs实现某些zfs的功能(稳定性与行为预期在不同发行版中差异较大)。

Jail

我去,这东西简直是神。

FreeBSD 的 FreeBSD Jail 是一个非常早期且成熟的隔离机制

和常见的 Linux 容器(namespaces + cgroups,例如 Docker)相比,Jail 是系统原生设计的一部分,接口稳定,权限模型更简单直接(没有层层叠加的 namespace 抽象)

典型特点:

  • 独立 IP、文件系统、用户空间
  • 不依赖额外 daemon(不像 Docker 需要守护进程)

在服务器上,这种模型更类似于那种微型 VPS,而不是简简单单的类似于一个容器。

缺点

生态

无论是fb、ob还是netbsd,提到他们都不得不说一个问题,生态。

这个确实是个问题,我个人的桌面系统也在使用fb。甚至也使用过一段时间的solaris/openindiana。发现很多东西都必须依赖 linux 兼容层。

社区

这部分,或者更应该说是问题解决成本

FreeBSD 社区质量很高,但规模明显小于 Linux。

我曾经就遇到过很多问题,就是那种网上搜都搜不到的那种,最后依赖ai和我自己的经验来解决。

linux 那边,一个问题很轻松,很容易就能找到答案的情况下,这边你可能就需要靠自己的经验。

并且,FreeBSD这边的文档,给我的印象是,偏工程化,不太照顾新手。我倒是还好无所谓,都能看懂,但是对于新手来说,那可能就是毛胚房跟精装修领包入住的区别,还是有点问题。很多文档也是英文,首先先不说语言,能不能看得懂的问题,很多人一看到是英文就关闭的现象还是很多。这点在现在llm等大语言模型,翻译模型,不再是靠机翻,有所改变,但是有些专有名词该不懂的对于小白来说还是不懂。

我们应当包容小白,而不是装作一副高高在上的样子,扔给小白诸如《提问的智慧》《别傻傻地提问》这样的文章。

总结

每次我想写这个总结,总是觉得像ai哈哈哈,因为只有ai会写这个,但是我还是写了。

FreeBSD,最大的就是设计哲学,这部分很符合 UNIX 哲学观。

UNIX 哲学是在 UNIX 操作系统长期开发实践中逐渐形成的一套设计理念,由肯·汤普森(Ken Thompson)与丹尼斯·里奇(Dennis Ritchie)等早期核心开发者共同塑造。其核心主张可归纳为以下原则:

  • 小即美:程序应设计得简洁小巧,功能单一明确,便于理解和维护。
  • 一个程序只做一件事:每个工具专注于单一功能,通过组合多个工具协作完成复杂任务。
  • 原型先行:先快速构建可工作的原型,再逐步优化,避免过度设计。
  • 可移植性先于高效性:优先保证代码能在不同平台上运行,性能优化次之。
  • 避免使用不必要的二进制格式或复杂表示:使用简单、文本格式,便于人工阅读和处理。
  • 沉默是金:程序在正常执行时不应产生冗余输出,仅在出错时提示,成功操作无输出,不显示进度等。
  • 避免仅用户界面:应提供命令行接口,确保可通过脚本实现自动化操作。

这些原则在当时的软件设计中相互配合,帮助开发者构建出简洁、高效、可维护的系统。FreeBSD 的开发实践深受 UNIX 哲学影响。FreeBSD 提供高级网络、性能、安全与兼容性特性,这一目标与 UNIX 哲学中“可移植性先于高效性”及“小即美”等原则一脉相承。

FreeBSD 的手册页系统是 UNIX 哲学的典型体现。

FreeBSD给我的感觉就是:一体化、可预测。Linux那边则是:组件化、快速演进。

FreeBSD做服务器一年了 说说我的感受
https://blog.mxdyeah.com/post/freebsd-server-1-year-review
本文作者 mxdyeah
发布时间 2026-05-02
许可协议 CC BY-NC-SA 4.0
已有 2 条评论
  1. 评论头像

    We should be tolerant of beginners, rather than pretending to be lofty and superior.
    —— mxdyeah

    蜜蜂QWQ May 10, 2026 13:07   Windows 10/11 x64 Edition(Windows 10/11 x64 Edition) / Google Chrome 147.0.0.0(Google Chrome 147.0.0.0) 回复
    1. 评论头像

      ヾ(≧∇≦*)ゝ

      mxdyeah 博主 May 10, 2026 13:08   FreeBSD(FreeBSD) / Firefox 145.0(Firefox 145.0) 回复
发表新评论

AD: