FreeBSD 中文社区 2025 第二季度问卷调查
FreeBSD 中文社区(CFC)
VitePress 镜像站QQ 群 787969044视频教程Ⅰ视频教程Ⅱ
  • FreeBSD 从入门到追忆
  • 中文期刊
  • 状态报告
  • 发行说明
  • 手册
  • 网络文章集锦
  • 笔记本支持报告
  • Port 开发者手册
  • 架构手册
  • 开发者手册
  • 中文 man 手册
  • 文章
  • 书籍
  • FreeBSD 从入门到追忆(第三版:草稿)
  • 编辑日志
  • 目录
  • 致谢
  • 初版序言:好望角与塔吊
  • 再版序言:回到复制粘贴,面向教程本身
  • 三版序言:且有大觉而后知此其大梦也(草稿)
  • 前言
  • 第 1 章 FreeBSD 初见
    • 第 1.1 节 操作系统的历程:UNIX、Unix-like、Linux & FreeBSD
    • 第 1.2 节 FreeBSD 简史
    • 第 1.3 节 谁在使用 FreeBSD?
    • 第 1.4 节 为什么要使用 FreeBSD?
    • 第 1.5 节 Linux 用户迁移指南
    • 第 1.6 节 FreeBSD 桌面发行版
  • 第 2 章 安装 FreeBSD
    • 第 2.1 节 安装前准备(新手入门版本)
    • 第 2.2 节 FreeBSD 安装图解(新手入门版本)
    • 第 2.3 节 UNIX 基础(新手入门版本)
    • 第 2.4 节 命令行基础(新手入门版本)
    • 第 2.5 节 安装 FreeBSD——基于 VMware Workstation Pro
    • 第 2.6 节 安装 FreeBSD——基于 Virtual Box
    • 第 2.7 节 手动安装双系统(先安装 FreeBSD)
    • 第 2.8 节 手动安装双系统(后安装 FreeBSD)
    • 第 2.9 节 安装 FreeBSD——基于 Apple M1 & Parallels Desktop 20
    • 第 2.10 节 安装 FreeBSD——基于 Apple M1 & VMware Fusion Pro
    • 第 2.11 节 Qemu 安装 RISC-V FreeBSD(基于 x86 Windows)
    • 第 2.12 节 云服务器安装 FreeBSD(基于腾讯云轻量云)
    • 第 2.13 节 安装 FreeBSD——基于 Hyper-V
  • 第 3 章 包管理器与 FreeBSD 系统更新
    • 第 3.1 节 FreeBSD 镜像站现状
    • 第 3.2 节 FreeBSD 换源方式
    • 第 3.3 节 gitup 的用法
    • 第 3.4 节 通过 pkg 包管理器安装二进制包
    • 第 3.5 节 通过 Ports 以源代码方式安装软件
    • 第 3.6 节 通过 DVD 安装软件
    • 第 3.7 节 通过 freebsd-update 更新 FreeBSD
    • 第 3.8 节 通过源代码更新 FreeBSD
    • 第 3.9 节 使用 pkgbase 更新 FreeBSD
  • 第 4 章 桌面环境
    • 第 4.1 节 显卡驱动(英特尔、AMD)
    • 第 4.2 节 显卡驱动(NVIDIA)
    • 第 4.3 节 GNOME
    • 第 4.4 节 Mate
    • 第 4.5 节 Xfce
    • 第 4.6 节 Cinnamon
    • 第 4.7 节 Lumina
    • 第 4.8 节 LXQt
    • 第 4.9 节 bspwm
    • 第 4.10 节 IceWM
    • 第 4.11 节 Budgie
    • 第 4.12 节 i3wm
    • 第 4.13 节 CDE
    • 第 4.14 节 Hyprland
    • 第 4.15 节 LXDE
    • 第 4.16 节 Window Maker
    • 第 4.17 节 Fluxbox
    • 第 4.18 节 KDE6
    • 第 4.19 节 主题美化
    • 第 4.20 节 远程桌面
    • 第 4.21 节 root 登录桌面
  • 第 5 章 中文环境配置
    • 第 5.1 节 本地化环境变量
    • 第 5.2 节 Fcitx 输入法框架
    • 第 5.3 节 IBus 输入法框架
    • 第 5.4 节 五笔输入法
    • 第 5.5 节 Firefox 与 Chromium
    • 第 5.6 节 QQ(Linux 版)
    • 第 5.7 节 更换字体
    • 第 5.8 节 金山 WPS(Linux 版)
    • 第 5.9 节 压缩与解压
    • 第 5.10 节 微信(Linux 版)
  • 第 6 章 多媒体与外设
    • 第 6.1 节 声卡
    • 第 6.2 节 蓝牙
    • 第 6.3 节 打印机
    • 第 6.4 节 触摸板
    • 第 6.5 节 音频播放器
    • 第 6.6 节 视频播放器
    • 第 6.7 节 音频图形图像处理
  • 第 7 章 代理服务器
    • 第 7.1 节 HTTP 代理
    • 第 7.2 节 V2ray
    • 第 7.3 节 Mihomo(原 Clash)
    • 第 7.4 节 OpenVPN
  • 第 8 章 账户与权限
    • 第 8.1 节 sudo 与 doas
    • 第 8.2 节 用户与组
    • 第 8.3 节 用户权限
  • 第 9 章 Jail
    • 第 9.1 节 Jail 配置
    • 第 9.2 节 Jail 更新
    • 第 9.3 节 使用 Qjail 管理 Jail
  • 第 10 章 虚拟化
    • 第 10.1 节 通过 BVCP 以网页管理 BHyve
    • 第 10.2 节 使用 bhyve 安装 Windows 11(vm-bhyve)
  • 第 11 章 计算机概论
    • 第 11.1 节 存储卡参数简介与测试
    • 第 11.2 节 总线接口与协议
    • 第 11.3 节 网络基础
    • 第 11.4 节 操作系统
    • 第 11.5 节 MySQL 数据库
  • 第 12 章 引导恢复与 TTY 配置
    • 第 12.1 节 单用户模式与密码重置
    • 第 12.2 节 配置 rEFInd(双系统用)
    • 第 12.3 节 FreeBSD 中文 TTY 控制台
    • 第 12.4 节 引导界面与控制台界面
    • 第 12.5 节 Grub & UEFI 与 efibootmgr
  • 第 13 章 FreeBSD 系统管理
    • 第 13.1 节 FreeBSD src 源码概览
    • 第 13.2 节 FreeBSD 系统概览
    • 第 13.3 节 bsdconfig 系统配置工具
    • 第 13.4 节 SSH 配置与相关工具
    • 第 13.5 节 BSD init 管理服务
    • 第 13.6 节 利用脚本自动生成 BSDlibc 库文本
  • 第 14 章 网络管理
    • 第 14.1 节 TCP 堆栈
    • 第 14.2 节 WiFi
    • 第 14.3 节 USB 网络共享(USB tethering)
    • 第 14.4 节 USB 网卡 & 以太网卡
  • 第 15 章 FreeBSD 防火墙
    • 第 15.1 节 网络参数配置命令
    • 第 15.2 节 Packet Filter(PF)
    • 第 15.3 节 IPFilter(IPF)
    • 第 15.4 节 ipfirewall(IPFW)
    • 第 15.5 节 Fail2Ban(基于 IPFW、PF、IPF)
  • 第 16 章 服务器
    • 第 16.1 节 FTP 服务器
    • 第 16.2 节 MinIO 对象存储服务
    • 第 16.3 节 Gitlab-EE
    • 第 16.4 节 时间服务
    • 第 16.5 节 WildFly
    • 第 16.6 节 Rsync 同步服务
    • 第 16.7 节 Samba 服务器
    • 第 16.8 节 NFS 服务器
    • 第 16.9 节 Webmin
  • 第 17 章 网络服务器
    • 第 17.1 节 Apache
    • 第 17.2 节 Nginx
    • 第 17.3 节 PHP 8.X
    • 第 17.4 节 MySQL 5.X
    • 第 17.5 节 MySQL 8.X
    • 第 17.6 节 NextCloud——基于 PostgreSQL
    • 第 17.7 节 Telegraf+InfluxDB+Grafana 监控平台
    • 第 17.8 节 PostgreSQL 与 pgAdmin4
    • 第 17.9 节 AList
    • 第 17.10 节 prometheus 监控部署
    • 第 17.11 节 MongoDB 80
    • 第 17.12 节 Tomcat
    • 第 17.13 节 Caddy
    • 第 17.14 节 OnlyOffice(基于 PostgreSQL)
    • 第 17.15 节 Zabbix 监控(基于 PostgreSQL)
  • 第 18 章 嵌入式(树莓派、RISCV)
    • 第 18.1 节 树莓派简介与配件选用
    • 第 18.2 节 树莓派安装 FreeBSD
    • 第 18.3 节 树莓派 FreeBSD 配置
    • 第 18.4 节 树莓派与 Linux 兼容层
    • 第 18.5 节 树莓派与 OpenBSD
    • 第 18.6 节 在 RISCV 开发板上安装 OpenBSD
    • 第 18.7 节 Radxa X4(x86)
  • 第 19 章 文学故事
    • 第 19.1 节 BSD 与哲学家 George Berkeley(乔治·贝克莱)
    • 第 19.2 节 加州大学伯克利分校与“Fiat Lux”(要有光)
  • 第 20 章 游戏与科学
    • 第 20.1 节 游戏
    • 第 20.5 节 科研与专业工具
    • 第 20.6 节 我的世界(Minecraft)
  • 第 21 章 Linux 兼容层
    • 第 21.1 节 Linux 兼容层实现
    • 第 21.2 节 Linux 兼容层——基于 CentOS(FreeBSD Port)
    • 第 21.3 节 Linux 兼容层——基于 Ubuntu/Debian
    • 第 21.4 节 Linux 兼容层——基于 ArchLinux bootstrap
    • 第 21.5 节 Linux 兼容层——基于 archlinux-pacman
    • 第 21.6 节 Linux 兼容层——基于 OpenSUSE
    • 第 21.7 节 Linux 兼容层——基于 Gentoo Linux
    • 第 21.8 节 Linux 兼容层——基于 Rocky Linux
    • 第 21.9 节 Linux 兼容层——基于 Slackware Linux
    • 第 21.10 节 RockyLinux 兼容层(FreeBSD Port)
    • 第 21.11 节 Linux 兼容层——基于 Deepin
    • 第 21.12 节 Linux 兼容层与 Jail
    • 第 21.13 节 Linux 兼容层故障排除与未竟事宜
  • 第 22 章 编程环境与软件开发
    • 第 22.1 节 如何报告 Bug
    • 第 22.2 节 如何开发一个 Port
    • 第 22.3 节 如何参与 FreeBSD 开发
    • 第 22.4 节 C/C++ 环境的配置
    • 第 22.5 节 Java 环境的配置
    • 第 22.6 节 QT 环境的配置
    • 第 22.7 节 Python 与 VS Code
    • 第 22.8 节 Rust/Go 环境的配置
    • 第 22.9 节 Shell
    • 第 22.10 节 通过 IDA 7 调试 FreeBSD
    • 第 22.11 节 如何订阅 FreeBSD 的邮件列表
    • 第 22.12 节 code-server 和 clangd
    • 第 22.13 节 Node.js
  • 第 23 章 文件系统与磁盘管理
    • 第 23.1 节 自动挂载文件系统
    • 第 23.2 节 ZFS
    • 第 23.3 节 磁盘扩容
    • 第 23.4 节 NTFS & Fat32
    • 第 23.5 节 Swap 交换分区的设置
    • 第 23.6 节 Linux 文件系统
    • 第 23.7 节 ZFS 磁盘加解密
  • 第 24 章 DragonFly BSD
    • 第 24.1 节 DragonFly BSD 概述
    • 第 24.2 节 安装 DragonFly BSD
    • 第 24.3 节 配置 DragonFly BSD
  • 第 25 章 TwinCAT/BSD
    • 第 25.1 节 TwinCAT/BSD 系统安装与基本配置
    • 第 25.2 节 TwinCAT/BSD 开发环境配置
  • 第 26 章 OpenBSD
    • 第 26.1 节 OpenBSD 概述
    • 第 26.2 节 安装 OpenBSD
    • 第 26.3 节 配置 OpenBSD
    • 第 26.4 节 OpenBSD 包管理器
    • 第 26.5 节 桌面与其他软件
  • 第 27 章 NetBSD
    • 第 27.1 节 NetBSD 概述
    • 第 27.2 节 NetBSD 安装图解
    • 第 27.3 节 NetBSD 换源与包管理器
    • 第 27.4 节 桌面与中文环境常用软件
由 GitBook 提供支持
LogoLogo

FreeBSD 中文社区(CFC) 2025

在本页
  • 准备工作
  • 准备网络接口
  • 准备 pf 防火墙
  • 启用 pf 防火墙
  • 加载必要的 Linux 兼容层内核模块
  • 准备目录
  • 创建 debian jail
  • 下载基本系统
  • 创建 debian jail 实例
  • 启用实例,允许网络访问
  • 更新系统
  • jail 开机自启
  • 创建 Ubuntu jail
  • 构建基本系统并配置
  • 启用实例并允许网络访问
  • 更新系统
  • 创建 AntiX linux jail
  • 下载镜像文件并解压
  • 配置 Antix jail
  • 更新系统
  • 创建 Alpine jail
  • jail 中的 GUI
  • 带 X Server 的终端
  • 内嵌 X Server
  • 共享主机 socket 方式
  • X Server tcp 侦听加 xhost 连接管理
  • VNC
  • 备注
  • 参考资料
在GitHub上编辑
导出为 PDF
  1. 第 21 章 Linux 兼容层

第 21.12 节 Linux 兼容层与 Jail

准备工作

本文会把所有 jail 绑定到虚拟接口 lo1 上,所有的 jail 等同于位于 FreeBSD 下的一个局域网中,FreeBSD 主机相当于该局域网的网关。

所有 jail 的网络活动须经过网络接口 lo1,所以要使用网络就须做网络转发,这里使用 pf 防火墙完成这个工作。

注意

这是获取网络访问的关键。

准备网络接口

# sysrc cloned_interfaces+="lo1" # 增加一个克隆的网络接口 lo1
# service netif cloneup          # 启用克隆的网络接口

准备 pf 防火墙

这里提供两种方式进行配置,请按需选用。

方法一

编辑 /etc/pf.conf,加入:

table <jails> persist
nat pass on em0 inet from <jails> to any -> em0

在防火墙中建立名为 jails 的表,并指定 persist 标志使防火墙总是维持这个表(即使没有相关的规则引用它)。

“表”是 pf 防火墙的一种命名结构,可保存地址和网络的集合。jails 表中的地址可以通过 NAT 访问网络。

可以用 pfctl 对 jails 表进行增减以达到控制网络访问的目的。如:

  • pfctl -t jails -T add 192.168.5.1 把 192.168.5.1 加入 jails 表使其可以访问网络

  • pfctl -t jails -T delete 192.168.5.1 把 192.168.5.1 移出 jails 表使其无法访问网络。

特点是手动管理麻烦,但灵活。

方法二

直接在 /etc/pf.conf 中写下规则:

nat pass on em0 inet from 192.168.5.1 to any -> em0

以允许 192.168.5.1 访问网络,特点是规则固化在配置中,没有特别的需求的话这个挺方便的。

启用 pf 防火墙

警告

无论你想不想使用防火墙,不这样设置你在 Jail 中都没有网络。

# service pf enable
# service pf start

加载必要的 Linux 兼容层内核模块

# service linux enable
# service linux start

这种方式可自动完成 linux 兼容层各个模块的加载

准备目录

# mkdir /usr/jails  # 用于保存建立 jail 的相关文件

创建 debian jail

下载基本系统

这里以 Debian 12(bookworm) 为例:

构建 Ubuntu/Debian

# pkg install debootstrap #安装 debootstrap
# chmod 0700 /usr/local/sbin/debootstrap # 赋予权限。
# mkdir -p /usr/jails/debian
# debootstrap bookworm /usr/jails/debian https://mirrors.ustc.edu.cn/debian/ #此处使用了 USTC 镜像站

示例输出,如下:

I: Retrieving InRelease
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Checking component main on https://mirrors.ustc.edu.cn/debian...
I: Retrieving adduser 3.130
I: Validating adduser 3.130
...
I: Extracting usr-is-merged...
I: Extracting util-linux-extra...
I: Extracting zlib1g...

注意

末尾可能会提示有错误,无视即可。

创建 debian jail 实例

现在用 Debian 12 基本系统创建 jail 实例,命名为 debian。

实例的基本配置

创建 /etc/fstab.debian,内容如下:

devfs      /usr/jails/debian/dev      devfs       rw                      0  0
tmpfs      /usr/jails/debian/dev/shm  tmpfs       rw,size=1g,mode=1777    0  0
fdescfs    /usr/jails/debian/dev/fd   fdescfs     rw,linrdlnk             0  0
linprocfs  /usr/jails/debian/proc     linprocfs   rw                      0  0
linsysfs   /usr/jails/debian/sys      linsysfs    rw                      0  0
/tmp       /usr/jails/debian/tmp      nullfs      rw                      0  0

在 /etc/jail.conf 中,加入以下内容(若无则新建):

debian {                               # jail 名
  host.hostname = debian;              # jail 的主机名
  mount.fstab = /etc/fstab.debian;     # jail 使用的 fstab:启动/关闭 jail 时,挂载/卸载对应的文件系统
  path = /usr/jails/debian;            # jail 使用的根目录
  devfs_ruleset = 4;                   # jail 挂载 devfs 的规则集的值:0 表示无规则集,jail 会继承上级 jail 规则集,
                                       # 只在启用 allow.mount、allow.mount.devfs 且 enforce_statfs 小于 2 时可以挂载 devfs
  enforce_statfs = 1;                  # 设置为 0 时,所有挂载点都是可用的,无任何限制。
                                       # 设置为 1 时,只有 jail 根目录之下的挂载点是可见的。
                                       # 设置为 2(默认值) 时,只能在 jail 目录所在的挂载点上操作,不能挂载 devfs、tmpfs 等。
  allow.mount;                         # 允许挂载文件系统
  allow.mount.devfs;                   # 允许挂载 devfs
  exec.start = '/bin/true';            # 见下
  exec.stop = '/bin/true';             # 见下
  persist;                             # 允许 jail 在没有任何进程的情况下存活
  allow.raw_sockets;                   # 允许 ping 等使用 raw socket,看需要写入
  interface = lo1;                     # 使用 lo1 作为网络接口
  ip4.addr = 192.168.5.1;              # 使用的 ipv4 地址
  ip6 = disable;                       # 禁用 ipv6
}
  • exec.start 指定启动 jail 时运行的命令。

如果是 freebsd 做 jail 一般是 exec.start = 'sh /etc/rc',即使用 FreeBSD 的 rc 系统启动服务。

但是 debian 中使用的是 systemd 作为 init 系统。jail 并不能使用 systemd,所以不能使用相应的命令(service 命令可用),所以在这里用 /bin/true 不做任何事安全的返回 true 就可以。

问题就是(以 sshd 服务为例)在 debian jail 中启用 sshd 服务后( service ssh start ), 如果重启 debian jail,那么 sshd 服务不会再次随 jail 启动而启动。这时可以写成 exec.start = 'service ssh start'。这样启动 debian jail 时可以启动 sshd 服务。

如果要启用更多的服务,则可以编写如下:

exec.start += 'service ssh start'
exec.start += 'service dbus start'
  • exec.stop 停止 jail 时运行的命令。

如果是 freebsd 做 jail 一般是 sh /etc/rc.shutdown jail。

这里同样因为 systemd 的原因用 /bin/true 安全的返回 true 就可以。

启用实例,允许网络访问

  • 启动 jail

# jail -c debian
  • 停止 jail

# jail -r debian
  • 在 pf 防火墙中的 jails 表中加入 jail 的地址,以允许 jail 访问网络:

# pfctl -t jails -T add 192.168.5.1

更新系统

执行:

# jexec debian /bin/bash # 此时位于 FreeBSD!
Debian # apt remove rsyslog  # 此时位于 Debian Jail!
Debian # apt update # 此时位于 Debian Jail!

或者使用

# jexec -l debian /bin/bash -c 'apt remove rsyslog'
# jexec -l debian /bin/bash -c 'apt update'

至此,一个基于 Debian 12 的 linux jail 已经成功建立,同样的方法可以建立基于 debian 和 ubuntu 各版本的多个 jail。

jail 开机自启

开机时启动 jail

# service jail enable

默认启动所有 jail。

另外可以在 /etc/rc.conf 中用 jail_list 变量指定在开机时启动的 jail 的名字,编辑 /etc/rc.conf 写入:

jail_list = "debian"

或执行

# sysrc jail_list+=debian

如果 jail_list 变量为空,则会启动所有在 /etc/jail.conf 中配置的 jail。

创建 Ubuntu jail

ubuntu jail 建立方法同上,以 Ubuntu 22.04(jammy) 为例,

构建基本系统并配置

# mkdir -p /usr/jails/ubuntu
# debootstrap jammy /usr/jails/ubuntu https://mirrors.ustc.edu.cn/ubuntu/

创建 /etc/fstab.ubuntu,内容如下:

devfs      /usr/jails/ubuntu/dev      devfs       rw                      0  0
tmpfs      /usr/jails/ubuntu/dev/shm  tmpfs       rw,size=1g,mode=1777    0  0
fdescfs    /usr/jails/ubuntu/dev/fd   fdescfs     rw,linrdlnk             0  0
linprocfs  /usr/jails/ubuntu/proc     linprocfs   rw                      0  0
linsysfs   /usr/jails/ubuntu/sys      linsysfs    rw                      0  0
/tmp       /usr/jails/ubuntu/tmp      nullfs      rw                      0  0

在 /etc/jail.conf 中写入 ubuntu 的配置,如下:

ubuntu {
  host.hostname = ubuntu;
  mount.fstab = /etc/fstab.ubuntu;
  path = /usr/jails/ubuntu;
  devfs_ruleset = 4;
  enforce_statfs = 1;
  allow.mount;
  allow.mount.devfs;
  exec.start = '/bin/true';
  exec.stop = '/bin/true';
  persist;
  allow.raw_sockets;
  interface = lo1;
  ip4.addr = 192.168.5.2;
  ip6 = disable;
}

启用实例并允许网络访问

# jail -c ubuntu # 启用实例

如果已经在 /etc/rc.conf 中设置过 jail_enable=YES,也可以用

# service jail start ubuntu

开机启动可以参考 debian jail,执行

# sysrc jail_list+=ubuntu

在 pf 防火墙中的 jails 表中加入 jail 的地址,以允许 jail 访问网络:

# pfctl -t jails -T add 192.168.5.2 # 允许网络访问

更新系统

# jexec ubuntu /bin/bash # 此时位于 FreeBSD!
Ubuntu # apt remove rsyslog  # 此时位于 Ubuntu Jail!
Ubuntu # apt update # 此时位于 Ubuntu Jail!

或者使用

# jexec -l debian /bin/bash -c 'apt remove rsyslog'
# jexec -l debian /bin/bash -c 'apt update'

过程和同 debian jail。

创建 AntiX linux jail

AntiX 基于 debian,且不使用 systemd。

下载镜像文件并解压

先安装 squashfs-tools 以解压 linux 文件系统镜像。

# pkg install squashfs-tools

AntiX linux 提供四个镜像版本,full、base、core、net,这里下载 core 版本:

# fetch https://mirrors.tuna.tsinghua.edu.cn/mxlinux-isos/ANTIX/Final/antiX-23.2/antiX-23.2_x64-core.iso
# mdconfig antiX-23.2_x64-core.iso
# mount -t cd9660 /dev/md0 /mnt
# mkdir -p /usr/jails/antix
# unsquashfs -d /usr/jails/antix /mnt/antiX/linuxfs
# touch /usr/jails/antix/dev/fd
# touch /usr/jails/antix/dev/shm

配置 Antix jail

创建 /etc/fstab.antix,内容如下:

devfs      /usr/jails/antix/dev      devfs       rw                      0  0
tmpfs      /usr/jails/antix/dev/shm  tmpfs       rw,size=1g,mode=1777    0  0
fdescfs    /usr/jails/antix/dev/fd   fdescfs     rw,linrdlnk             0  0
linprocfs  /usr/jails/antix/proc     linprocfs   rw                      0  0
linsysfs   /usr/jails/antix/sys      linsysfs    rw                      0  0
/tmp       /usr/jails/antix/tmp      nullfs      rw                      0  0

在 /etc/jail.conf 中写入 (这里只展示 antix 相关部分)

antix {
  host.hostname = antix;
  mount.fstab = /etc/fstab.antix;
  path = /usr/jails/antix;
  devfs_ruleset = 4;
  enforce_statfs = 1;
  allow.mount;
  allow.mount.devfs;
  exec.start = '/etc/init.d/rc 3';
  exec.stop = '/etc/init.d/rc 0';
  persist;
  allow.raw_sockets;
  interface = lo1;
  ip4.addr = 192.168.5.3;
  ip6 = disable;
}

这里 exec.start 设为 /etc/init.d/rc 3。

在 debian jail 部分已经提到,debian 使用 systemd 做初始化系统。这在 jail 中不能使用,所以用 /bin/true 启动,以保证什么都不做,只是安全返回 true 值。

antiX 不使用 systemd 做初始化系统,可以用 rc 进行初始化:在这里 /etc/init.d/rc 3 指定 antix jail 在启动时使用 rc 以第 3 运行级别初始化 jail。即在 debian jail 中提到的服务运行问题在这里并不存在(即可以直接在 jail 启动时运行服务,比如 sshd)。

更新系统

  • 设置开机自启,然后启动

# sysrc jail_list+=antix
# jail -c antix   # 或者使用 service jail start antix 前面已经提到
  • 在 pf 中允许网络访问,方法同上。

# pfctl -t jails -T add 192.168.5.3
  • 现在进入 jail:

# jexec antix /bin/bash     # 物理机(FreeBSD)中
root@antix:/# echo "nameserver 223.5.5.5" > /etc/resolv.conf    # jail 中,注意提示符变化,先设置地址解析,这里使用阿里 DNS
root@antix:/# echo "APT::Cache-Start 90000000;" >> /etc/apt/apt.conf   # `APT::Cache-Start` 是 apt 使用缓存的大小,默认 20m 太小,按提示增大
root@antix:/# apt update         # 可以先修改 `/etc/apt/sources.list.d/` 中的文件以使用镜像站,请参考各镜像站中 debian 的镜像站设置
root@antix:/# apt upgrade
root@antix:/# mandb       # apt upgrade 的时候显示 mandb 有几个权限错误,多执行几遍  `mandb` 命令就是。

创建 Alpine jail

  • 构建基本系统

# fetch http://mirrors.ustc.edu.cn/alpine/v3.17/releases/x86_64/alpine-minirootfs-3.17.1-x86_64.tar.gz
# mkdir -p /usr/jails/alpine
# tar zxf alpine-minirootfs-3.17.1-x86_64.tar.gz -C /usr/jails/alpine/
# touch /usr/jails/alpine/dev/shm
# touch /usr/jails/alpine/dev/fd
  • 创建 /etc/fstab.alpine,内容如下:

devfs      /usr/jails/alpine/dev      devfs       rw                      0  0
tmpfs      /usr/jails/alpine/dev/shm  tmpfs       rw,size=1g,mode=1777    0  0
fdescfs    /usr/jails/alpine/dev/fd   fdescfs     rw,linrdlnk             0  0
linprocfs  /usr/jails/alpine/proc     linprocfs   rw                      0  0
linsysfs   /usr/jails/alpine/sys      linsysfs    rw                      0  0
#/tmp       /usr/jails/alpine/tmp      nullfs      rw                      0  0
  • 在 /etc/jail.conf 中写入,

alpine {
  host.hostname = alpine;
  mount.fstab = /etc/fstab.alpine;
  path = /usr/jails/alpine;
  devfs_ruleset = 4;
  enforce_statfs = 1;
  allow.mount;
  allow.mount.devfs;
  exec.start = '/bin/true';  # minirootfs 里还没有初始化系统,所以还是用 '/bin/true',下面会设置 openrc
  exec.stop = '/bin/true';
  persist;
  allow.raw_sockets;
  interface = lo1;
  ip4.addr = 192.168.5.4;
  ip6 = disable;
}
  • 设置开机启动,然后启动

# sysrc jail_list+=alpine
# jail -c alpine
  • 在 pf 中允许网络访问,方法同上。

# pfctl -t jails -T add 192.168.5.4
  • 现在进入 jail:

freebsd # jexec alpine /bin/sh        # 初始只有 sh,注意 shell 提示符的变化
alpine # sed  -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories    # 修改镜像地址
alpine # echo 'nameserver 223.5.5.5' >> /etc/resolv.conf      #  初始没有这个文件,自建一个
alpine # apk update             # alpine 可以不使用 openrc 而使用程序,但是不能启动各种服务,只有在安装 openrc 后才能启动各项服务,所以最好安装 openrc 以获得更好的体验
alpine # apk add openrc         # 安装 openrc 作为初始化系统
alpine # mkdir /run/openrc
alpine # touch /run/openrc/softlevel      # openrc 提示在 docker/chroot/jail 环境中应该建立这个文件
alpine # exit    # 注意 shell 提示符的变化
freebsd # jail -r alpine    # 先关闭 alpine,以使在 freebsd 宿主机中进行 openrc 配置
  • 修改 /etc/jail.conf 中 alpine 的配置:

alpine {
  host.hostname = alpine;
  mount.fstab = /etc/fstab.alpine;
  path = /usr/jails/alpine;
  devfs_ruleset = 4;
  enforce_statfs = 1;
  allow.mount;
  allow.mount.devfs;
  exec.start = '/sbin/openrc default';  # 此处修改,使用 openrc 作初始化系统,以 default 运行级初始化系统
  exec.stop = '/sbin/openrc shutdown';  # 此处修改,使用 openrc 作初始化系统,以 shutdown 运行级运行关闭任务
  persist;
  allow.raw_sockets;
  interface = lo1;
  ip4.addr = 192.168.5.4;
  ip6 = disable;
}
  • 重启 alpine

# jail -c alpine

jail 中的 GUI

本文环境:Windows 10 物理机,在 virtualbox 安装了 FreeBSD 13.1 虚拟机。

在 FreeBSD 虚拟机中已部署了 4 个 jail,如下。这里有一个 freebsd jail,为和 virtualbox 中的 FreeBSD 虚拟机作区分,我们称其为 freebsd-jail:

Windows 10 物理机 ⇨ FreeBSD 13.1 虚拟机 ⇨ FreeBSD Jail(freebsd-jail) + Debian Jail + Ubuntu Jail + Alpine Jail。

# jls
   JID  IP Address      Hostname                      Path
     1  192.168.5.3     debian                      /usr/jails/debian
     2  192.168.5.4     ubuntu                    /usr/jails/ubuntu
     3  192.168.5.2     alpine                        /usr/jails/alpine
     4  192.168.5.1     freebsd-jail                  /usr/jails/freebsd-jail

在这 4 个 jail 中分别安装 xclock、firefox、chrome、jwm 这几款软件。

在 freebsd-jail、debian、ubuntu、alpine( alpine 使用 vnc 方法不成功,其它方法 xclock、xterm 可运行,firefox 和 chrome 未成功) 都成功了,jwm 用于美化。

技巧

不用安装 xorg。

其中,在 ubuntu 22.04,firefox、chrome 要求用 snap 安装,snap 需要 systemd,不能使用,所以使用 deb 包安装。方法如下:

# wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
# dpkg -i google-chrome-stable_current_amd64.deb
# apt install ./google-chrome-stable_current_amd64.deb

带 X Server 的终端

这里使用 MobaXterm。MobaXterm 默认配置,无多余配置。

确保 X server 已经启用,记下 DISPLAY 值,格式是 hostname:displaynumber.screennumber 这里是 192.168.56.1:0.0

登录 jail(不限方式,可以是 ssh,可以是 jexec;不限用户,可以是普通用户,不一定是 root、wheel 组成员)

$ export DISPLAY=192.168.56.1:0.0  # jail 中,这里是 sh/zsh/bash。csh/tcsh 是 setenv DISPLAY 192.168.56.1:0.0,下同
$ xclock&

4 个 xclock 可独立显示在 Windows 10 桌面上,效果比较理想。

内嵌 X Server

X Server 里的 X Server,这里使用 Xnest/Xephyr、Xnest/Xephyr 对 X11 应用来说是 X Server,对宿主 X Server 来说是 X Client。

  • FreeBSD 虚拟机里安装 Xnest 或 Xephyr。两者择其一即可:

# pkg install Xnest

或者

# pkg install Xephyr
  • 在 FreeBSD 中启用

$ Xephyr :1 -listen tcp  # 不需要 root 权限
  • :1 即上面提到了 DISPLAY 值中的 displaynumber。FreeBSD 系统 IP 为 10.0.2.15,所以完整的 DISPLAY 值为 10.0.2.15:1.0。因为 FreeBSD 系统 X Server 的 displaynumber 值为 0,所以从 1 开始

  • -listen tcp 侦听 TCP 端口

  • 在 4 个 jail 中,采取上面相同的方法

$ export DISPLAY=10.0.2.15:1.0
$ xclock&

四个 jail 可以同时在 FreeBSD 开启的一个 Xnest/Xephyr 窗口中打开 xclock。但是此时的 xclock 因为没有窗口管理器,界面丑,且连最基本的拖动都做不到。可以在执行 xclock 前先执行 jwm,如下。

$ export DISPLAY=10.0.2.15:1.0
$ jwm &
$ xclock&

这里注意 jwm & 执行一次够了,不需要每个 jail 都去执行。这里用 jwm 只是看中其轻量级,xfce 等也是可以的。可以自行尝试。

共享主机 socket 方式

  • 先在 FreeBSD 系统上执行

$ xhost +
  • 关闭访问控制:

然后在 jail 的 fstab 中加入下面内容,这里以 ubuntu jail 的 fstab 为例,其它 jail 参照修改即可。

/tmp/.X11-unix   /usr/jails/ubuntu/tmp/.X11-unix    nullfs   ro   0  0

必要时先 mkdir -p /usr/jails/ubuntu/tmp/.X11-unix,确保有挂载点。

重启 jail 后,在 jail 中执行:

$ export DISPLAY=:0.0
$ xclock &

上文提到 fstab 文件中有下面这样一行

#/tmp   /usr/jails/ubuntu/tmp   nullfs  rw    0  0

虽然很多教程中有这样写,但我认为是不安全的,所以注释掉不用。如果这么写,那么 FreeBSD 的 /tmp 目录都将暴露在 jail 中,且因为是可读写的:在 jail 中就可以对 FreeBSD 的 /tmp 目录进行写入。这样就破坏了 jail 与 FreeBSD 的隔离性,是不安全的。而仅读挂载 /tmp/.X11-unix,则大大提高了安全性。

X Server tcp 侦听加 xhost 连接管理

这里我使用的是 sddm 桌面管理器,使用其它桌面管理器的,请参考相应桌面管理器的文档进行,原理一样。

在 FreeBSD 内新建 /usr/local/etc/sddm.conf(如果没有的话),修改 ServerArguments 内容如下:

[X11]
ServerArguments=-listen tcp

重启后,FreeBSD 上用下面方式加入 jail IP 以允许访问 (无需 root 权限):

$ xhost + 192.168.5.1  # 这里不建议用上面的提到 `xhost +` 方式关闭访问控制,以避免意料外的连接

然后在 jail 中,执行:

$ export DISPLAY=:0.0
$ xclock &
  • 这里把 DISPLAY 设为 :0.0,127.0.0.1:0.0,10.0.2.15:0.0 都成功了,上面几种方法也可以一一尝试。

VNC

在 jail 中安装 vnc server,可以用 tightvnc-server,也可以用 tigervnc-server,这里以 debian jail 为例,在 jail 中执行

# apt install tightvncserver
$ vncpasswd           # 这里不要求 root 用户
Password:
Verify:
Would you like to enter a view-only password (y/n)? n
A view-only password is not used
$ vncserver :0        # 同样不要求 root 用户,vncserver 的端口号为 5900 加上冒号后的数字,现在为 5900,`:1` 端口号 5901,以此类推。

使用 vnc 客户端登录

备注

宿主机 X Server tcp 侦听加 xhost 连接管理的方式是安全性最差的一种,是 tcp 侦听默认关闭原因之一。

共享宿主机 socket 的方式注意上面提到的两点安全性还是有保障的。

前 4 种方法算是“回字的 4 种写法”,都算是 X Server 连接的变体。带 X Server 的终端和共享 socket 的方式之外,其它三种方式最好在 jail 内再搭配个桌面。

带 X Server 的终端、共享主机 socket、vnc 这三种方式比较推荐。无论哪个方式,linux jail 中不要要求每个 X 应用都能运行,那真的很难做到,毕竟兼容层不是百分百兼容,freebsd jail 的话就好很多。

除去共享宿主机 socket 的方法,其它方法都是可以应用的非 jail 环境的。

参考资料

网站:

上一页第 21.11 节 Linux 兼容层——基于 Deepin下一页第 21.13 节 Linux 兼容层故障排除与未竟事宜

最后更新于22天前

其他更多可以运行的软件及方法见 。

https://wiki.freebsd.org/LinuxApps
12.2.配置 Linux 二进制兼容层
linux -- Linux ABI support
wiki/Linuxulator
wiki/LinuxJails
12.3.Linux 用户空间