# FreeBSD Jail 容器中的 Minecraft 服务器

* 原文：[Minecraft Server in FreeBSD Jails Container](https://vermaden.wordpress.com/2025/04/05/minecraft-server-freebsd-jails-container/)
* 发布时间：2025/04/05
* 作者：𝚟𝚎𝚛𝚖𝚊𝚍𝚎𝚗

今天——应我儿子的要求——我们来讲讲如何在 FreeBSD Jail 容器中运行 Minecraft 服务器。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-logo.png)

这有点像 Linux 上的 Docker/Podman，但安全性更高。

## 准备工作

首先我们将在 **/jail** 路径下创建环境，并获取所需的 FreeBSD **基本系统** 版本。

今天我们将使用 FreeBSD 14.2-RELEASE 版本。

```sh
host # mkdir -p /jail/minecraft /jail/BASE

host # VER=$( freebsd-version | awk -F '-' '{print $1 "-" $2}' )

host # fetch -o /jail/BASE/${VER}-base.txz https://download.freebsd.org/releases/amd64/14.2-RELEASE/base.txz
```

接下来我们将创建专用的 Minecraft FreeBSD Jail，并为其填充独立的 **基本系统** 内容。

我们还会复制 **/var/run/dmesg.boot**，因为 Minecraft 服务器需要使用它。

```sh
host # tar -C /jail/minecraft --unlink -xvf /jail/BASE/14.2-RELEASE-base.txz

host # cp /var/run/dmesg.boot /jail/minecraft/var/run/
```

## 创建

现在我们将设置基础 FreeBSD Jail 配置。

这些配置将作为所有其他 Jail 的默认值，除非我们重新定义它们。

```ini
host # cat /etc/jail.conf
exec.start      = "/bin/sh /etc/rc";
exec.stop       = "/bin/sh /etc/rc.shutdown";
exec.consolelog = "/var/log/jail_console_${name}.log";
exec.clean;
mount.devfs;
```

现在配置我们的 Minecraft Jail。

我们将使用局域网接口 **em0** 和 IP 地址 **10.0.0.210**。

```ini
host # cat /etc/jail.conf.d/minecraft.conf
  minecraft {
  # 全局
    exec.start = "/bin/sh /etc/rc";
    exec.stop  = "/bin/sh /etc/rc.shutdown";
    exec.consolelog = "/var/log/jail_console_${name}.log";
    exec.clean;
    mount.devfs;
    host.hostname = ${name};
    path = /jail/${name};

  # 自定义
    ip4.addr = 10.0.0.210;
    interface = em0;
    allow.raw_sockets;
    allow.sysvipc;
    devfs_ruleset=210;
    allow.mount;
    enforce_statfs=1;
    allow.mount.devfs;
    allow.mount.procfs;
    allow.mount.fdescfs;
  }
```

下面你还会看到宿主机上的规则集 **/etc/devfs.rules**。

```sh
host # grep -A 4 minecraft /etc/devfs.rules
[minecraft=210]
add include $devfsrules_jail
add path 'fd*' unhide
```

现在我们可以启动我们的 Jail 了。

```sh
host # service jail onestart minecraft
Starting jails: minecraft.

host # jls
   JID  IP Address      Hostname                      Path
     1  10.0.0.210      minecraft                     /jail/minecraft
```

你也可以使用我提供的工具 [**jmore(8)**](https://github.com/vermaden/jmore)。

```sh
host # jmore
JAIL       JID  TYPE  VER     DIR              IFACE   IP(s)
----       ---  ----  ---     ---              -----   -----
classic    -    std   13.2-R  /jail/classic    em0     10.0.0.199
ctld-two   -    vnet  13.2-R  /jail/ctld-two   ${if}b  -
ctld       -    vnet  13.2-R  /jail/ctld       ${if}b  -
fbsdjail   -    std   13.1-R  /jail/fbsdjail   wlan0   10.0.0.43
iscsi      -    vnet  13.2-R  /jail/iscsi      ${if}b  -
minecraft  1    std   14.2-R  /jail/minecraft  em0     10.0.0.210
minio      -    std   14.0-R  /jail/minio      em0     10.0.0.133
nfsd       -    vnet  14.1-R  /jail/nfsd       ${if}b  -
other      -    std   14.1-R  /jail/other      em0     10.0.0.199
sambajail  -    vnet  14.1-R  /jail/sambajail  ${if}b  -
unfs3      -    vnet  14.1-R  /jail/unfs3      ${if}b  -
```

为了让 Minecraft Jail 在启动时自动运行，需要在 **host** 系统的 **/etc/rc.conf** 文件中添加如下内容：

```ini
host # grep jail /etc/rc.conf
jail_enable=YES
jail_devfs_enable=YES
jail_list="minecraft"
```

## 配置 FreeBSD Jail

现在我们进入 Minecraft Jail。

使用 **jmore minecraft c** 相当于执行了知名的命令：

```sh
env PS1='minecraft # ' jexec minecraft /bin/sh
```

示例：

```sh
host # jmore minecraft c
minecraft #
```

接下来进行一些基本配置，例如设置 DNS 或将 **pkg(8)** FreeBSD 包管理器切换到 **latest** 分支：

```sh
minecraft # echo nameserver 1.1.1.1 > /etc/resolv.conf
minecraft # mkdir -p /usr/local/etc/pkg/repos
minecraft # sed -e 's|quarterly|latest|g' /etc/pkg/FreeBSD.conf > /usr/local/etc/pkg/repos/FreeBSD.conf
minecraft # pkg search -o minecraft
games/minecraft-client         Client for the block building game
```

现在安装其他所需的包，因为 Minecraft 服务器需要通过 FreeBSD Ports 构建：

```sh
minecraft # pkg install gitup bsddialog ccache portconfig openjdk21 tmux jless
```

由于需要通过 FreeBSD Ports 构建 Minecraft 服务器，并且许可需要手动接受（或忽略）（**译注：并不需要**），因此接下来使用 **gitup** 工具获取 FreeBSD Ports 树。

在 **make config** 阶段选择选项 **DAEMON** 。

```sh
minecraft # gitup ports
(...)
#
# Please review the following file(s) for important changes.
#       /usr/ports/UPDATING
#       /usr/ports/mail/dspam/files/UPDATING
#
# Done.

minecraft # cd /usr/ports/games/minecraft-server

minecraft # make config

 +------------|minecraft-server-1.21.4|--------------+
 | 'F1' for Ports Collection help.                   |  
 | +---------- RUN [select at least one] ----------+ |
 | | new (*) DAEMON     Run as a service           | |
 | | new ( ) STANDALONE Run the .jar file directly | |
 | +-----------------------------------------------+ |
 |                [  OK  ]     [Cancel]              |
 +---------------------------------------------------+
```

## 构建

接下来我们将构建 Minecraft 服务器。

```sh
minecraft # echo DISABLE_LICENSES=yes >> /etc/make.conf

minecraft # env BATCH=yes make build install clean
(...)
When you first run minecraft-server, it will populate the file
/usr/local/etc/minecraft-server/eula.txt

It is required to read the EULA, and then set eula=true

- Configuration files can be found in /usr/local/etc/minecraft-server/
- Log and debug output files can be found in /var/log/minecraft-server/
- World files can be found in /var/db/minecraft-server/

Without daemon option:
- To run the server, run /usr/local/bin/minecraft-server
- To edit java's parameters, edit /usr/local/etc/minecraft-server/java-args.txt
- To run with a specific version of Java, set environment variable JAVA_VERSION,
  for example:
    export JAVA_VERSION=22
    /usr/local/bin/minecraft-server
  or:
    JAVA_VERSION=22 /usr/local/bin/minecraft-server

With daemon option:
- The service has been installed with the name 'minecraft'
- To adjust maximum memory usage (-Xmx), use minecraft_memx= in /etc/rc.conf
- To adjust initial memory usage (-Xms), use minecraft_mems= in /etc/rc.conf
- To add other java parameters, use minecraft_args= in /etc/rc.conf
- To run with a specific version of Java, use minecraft_java_version= in /etc/rc.conf
- To see the interactive console, type service minecraft console

===>  Cleaning for minecraft-server-1.21.4
```

## Minecraft 服务器配置

按照 **pkg-message** 中的建议，我们将在 **/etc/fstab** 文件中添加额外的虚拟文件系统。

同时，我们还要确保这些文件系统在 Jail 启动时通过 **/etc/rc.local** 文件被挂载。

```sh
minecraft # cat << FSTAB >> /etc/fstab
        fdesc   /dev/fd         fdescfs         rw      0       0
        proc    /proc           procfs          rw      0       0
FSTAB

minecraft # echo 'mount -a' >> /etc/rc.local

minecraft # mount -a

minecraft # mount
zroot/jail on / (zfs, local, noatime, nfsv4acls)
devfs on /dev (devfs)
fdescfs on /dev/fd (fdescfs)
procfs on /proc (procfs, local)
devfs on /dev (devfs)
```

我们不会修改 Minecraft Jail 的主 **/etc/rc.conf** 配置文件来添加所需的 Minecraft 服务器选项。

同时，我们将“接受”EULA，并在 **/usr/local/etc/minecraft-server/server.properties** 文件中创建基本的 Minecraft 服务器配置。

你也可以在 **/usr/local/etc/minecraft-server/java-args.txt** 文件中配置额外的 Java 参数。如果默认值对你的情况太小，请自行增大。

```sh
minecraft # cat << RC >> /etc/rc.conf
minecraft_enable=YES
minecraft_mems=1024M
minecraft_memx=1024M
RC

minecraft # echo eula=true > /usr/local/etc/minecraft-server/eula.txt

minecraft # cat << MINECRAFT > /usr/local/etc/minecraft-server/server.properties
enable-jmx-monitoring=false
rcon.port=25575
level-seed=
gamemode=survival
enable-command-block=false
enable-query=false
generator-settings={}
enforce-secure-profile=true
level-name=world
motd=FreeBSD Minecraft Server
query.port=25565
pvp=true
generate-structures=true
max-chained-neighbor-updates=1000000
difficulty=easy
network-compression-threshold=256
max-tick-time=60000
require-resource-pack=false
use-native-transport=true
max-players=20
online-mode=false
enable-status=true
allow-flight=false
initial-disabled-packs=
broadcast-rcon-to-ops=true
view-distance=10
server-ip=
resource-pack-prompt=
allow-nether=true
server-port=25565
enable-rcon=false
sync-chunk-writes=true
resource-pack-id=
op-permission-level=4
prevent-proxy-connections=false
hide-online-players=false
resource-pack=
entity-broadcast-range-percentage=100
simulation-distance=10
rcon.password=
player-idle-timeout=0
force-gamemode=false
rate-limit=0
hardcore=false
white-list=false
broadcast-console-to-ops=true
spawn-npcs=true
spawn-animals=true
log-ips=true
function-permission-level=2
initial-enabled-packs=vanilla
level-type=minecraft\:normal
text-filtering-config=
spawn-monsters=true
enforce-whitelist=false
spawn-protection=16
resource-pack-sha1=
max-world-size=29999984
MINECRAFT
```

## 启动

现在是时候启动已安装并配置好的 Minecraft 服务器了。

```sh
minecraft # service minecraft start
Starting minecraft.

minecraft # service minecraft status
minecraft is running.

minecraft # sockstat -l4
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
mcserver java       33227 103 tcp4   10.0.0.210:25565      *:*
root     syslogd     7809 5   udp4   10.0.0.210:514        *:*
```

看起来服务器运行正常——但如果不正常，可以使用以下命令进行调试。

```sh
minecraft # su mcserver -c '/usr/local/bin/java -Xmx1024M -Xms1024M -jar /usr/local/minecraft-server/server.jar nogui'
```

## 连接 Minecraft 客户端

首先 – 确保你的客户端版本与 Minecraft 服务器版本一致 – 我这里是 **1.21.4**。

我的情况是，Minecraft 客户端是在某台随机的 Windows 电脑上启动的，如下所示。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-client-1.png)

点击 **多人游戏** 按钮。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-client-2.jpg)

然后点击 **添加服务器** 按钮 – 我们将添加基于 FreeBSD 的 Minecraft 服务器。

输入你喜欢的 Minecraft 服务器名称和 IP 地址。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-client-3.jpg)

稍等片刻，我们的基于 FreeBSD 的 Minecraft 服务器将出现在列表中。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-client-4.jpg)

现在点击 **加入服务器** 按钮加入服务器。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-client-5.jpg)

我们会看到 **正在连接服务器…** 的提示。

……片刻之后，我们就成功加入了 Minecraft 服务器。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-client-6.png)

## 用户

由于我不是 Minecraft 专家，我花了一些时间才找到在该服务器上定义“管理员”的方法。

幸运的是，我有一个可行的解决方案 🙂：

当我在这里写关于我自己的 **jmore(8)** 工具时 [New jmore(8) FreeBSD Jails List/Manage Tool](https://vermaden.wordpress.com/2024/11/22/new-jless-freebsd-jails-list-manage-tool/)，我最初把它叫作 **jless(8)**，但有人提醒我这个名字已经被一个处理 JSON 的工具占用了。我们稍后会用到它 🙂。

当有人连接到我们的服务器时，他的 **名字** 和 **uuid** 会被添加到 **/usr/local/etc/minecraft-server/usercache.json** 文件中，如下所示。

```json
host # cat /jail/minecraft/usr/local/etc/minecraft-server/usercache.json | tr ',' '\n'
[{"name":"antuan"
"uuid":"0d61326c-dfd1-3fa8-ba9d-249d402fb700"
"expiresOn":"2025-05-05 14:04:15 +0000"}
{"name":"antek"
"uuid":"4b520bac-4b31-3c41-8f9b-2781763e5c88"
"expiresOn":"2025-05-05 09:16:08 +0000"}]

host # jless /jail/minecraft/usr/local/etc/minecraft-server/usercache.json | cat
[
  {
    "name": "antuan",
    "uuid": "0d61326c-dfd1-3fa8-ba9d-249d402fb700",
    "expiresOn": "2025-05-05 14:04:15 +0000"
  },
  {
    "name": "antek",
    "uuid": "4b520bac-4b31-3c41-8f9b-2781763e5c88",
    "expiresOn": "2025-05-05 09:16:08 +0000"
  }
]
```

用 **bat(1)** 命令显示颜色后看起来效果更好。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-jless.png)

现在 – 要让这些用户成为“管理员”，我们需要将他们添加到 **/usr/local/etc/minecraft-server/ops.json** 文件中，并且重启 Minecraft 服务器才能生效。

```json
host # jless /jail/minecraft/usr/local/etc/minecraft-server/ops.json | cat
[
  {
    "uuid": "4b520bac-4b31-3c41-8f9b-2781763e5c88",
    "name": "antek",
    "level": 4,
    "bypassesPlayerLimit": false

  },
  {
    "uuid": "0d61326c-dfd1-3fa8-ba9d-249d402fb700",
    "name": "antuan",
    "level": 4,
    "bypassesPlayerLimit": false
  }
]
```

权限等级 **4** 是记录中最高的权限等级。

![](https://vermaden.wordpress.com/wp-content/uploads/2025/04/minecraft-jless-admins.png)

现在我儿子拥有了他需要使用的所有命令，例如 **/gamemode** 或 **/time** 🙂。

## 总结

欢迎随意分享你对个人 Minecraft 服务器其他所需配置的想法。

## 更新 1 – FreeBSD Jail 与 Linux Podman

我没想到第一句话会成为评论的焦点，因此在这里补充一些细节。我们来讨论一下 FreeBSD Jails 和 Linux Podman 容器在安全性上的差异。

**隔离性：** 对于无 root Podman 来说，如果启用了 SELinux/AppArmor，它的隔离性似乎与 Jail 在同一水平。但如果没有 SELinux/AppArmor，Jail 提供了更好的隔离性。当你在 Podman 中启用 SELinux/AppArmor 并再添加 MAC 框架（如 **mac\_sebsd** / **mac\_jail** / **mac\_bsdextended** / **mac\_portacl**）时，Jail 的隔离性更高。

**内核系统调用暴露面：** 即使是无 root Podman，除非通过 **seccomp**（SELinux）限制，否则仍有“完全”的系统调用访问权限。Jail 对系统调用的使用有限制，不需要额外工具就能实现；在 FreeBSD 上结合 MAC 框架还可以进一步缩小系统调用的可用范围。

**防火墙：** 你无法在无 root Podman 容器内运行防火墙。而在 VNET Jail 中，你可以运行完整的网络栈和任何防火墙（如 PF 或 IPFW），独立于宿主机运行，这意味着安全性更高。

**总结：** FreeBSD Jail 通常在默认情况下比 Podman 容器更安全，如果花时间添加额外的安全层，其安全性会更高。

市场存在时间也是一个重要因素。

Jail 自 1999/2000 年引入以来已经投入生产环境，已有 25 年历史，久经考验。Docker 从 2014 年开始流行，时间短约 10 年，但我们要比较的是 Jail 与 Podman。Podman 的无 root 支持首次出现在 2019 年晚期（1.6 版本），因此在市场上的时间不足 6 年。

这意味着 Jail 是所有方案中最经受考验的。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://translated-articles.bsdcn.org/2025-nian/minecraft-server-freebsd-jails-container.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
