在 FreeBSD Jail 中使用 OpenRC 启动并运行 Devuan GNU+Linux 系统

两年前,我写了一篇名为 "VoidLinux in FreeBSD Jail; with init" 的博文,在文中我们在一个 FreeBSD Jail 环境里安装并“启动”了 VoidLinux 。我认为现在是时候对那篇博文进行修订了。

这次,我们将使用 Devuan GNU+Linux 以及用 OpenRC 来启动系统,并在 Linux Jail 中放置一些本地的 FreeBSD 二进制程序。

以下是我这次运行的操作系统版本:

root@srv0:~ # uname -v
FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC

为了引导启动 Devuan 系统,我们需要使用一个叫 debootstrap 的软件,确切地说,是 Devuan Chimaera 版本的 debootstrap 工具 。我们可以从 ports/packages 中安装 debootstrap,然后再进行其余的修改。

pkg install -y debootstrap

现在我们需要获取 Devuan 的 debootstrap 工具,并将其解压缩,将一些文件放入我们的 debootstrap 中,并设置一些符号链接。

# 路径可能会随着时间变化,请访问 https://pkginfo.devuan.org/ 获取确切的链接。

fetch http://deb.devuan.org/merged/pool/DEVUAN/main/d/debootstrap/debootstrap_1.0.123+devuan3_all.deb

# .deb 文件很凌乱,建议创建一个目录。

mkdir debootstrap_devuan
mv debootstrap_1.0.123+devuan3_all.deb debootstrap_devuan/
cd debootstrap_devuan/
tar xf debootstrap_1.0.123+devuan3_all.deb
tar xf data.tar.gz

# 我们需要 chimaera(最新版本,符号链接)和 ceres(源始版本)。

cp usr/share/debootstrap/scripts/ceres usr/share/debootstrap/scripts/chimaera /usr/local/share/debootstrap/scripts/

现在我们可以引导启动我们的系统了。我将使用 ZFS 文件系统,但这也可以在不使用 ZFS 文件系统的情况下完成。

请记住,我的 Jail 路径将是 /usr/local/jails/devuan0 ,请根据需要修改此路径。🙂

zfs create zroot/jails/devuan0
debootstrap --no-check-gpg --arch=amd64 chimaera /usr/local/jails/devuan0/ http://pkgmaster.devuan.org/merged/

现在安装过程应该开始了,但在某个阶段,我们会遇到以下错误:

I: Configuring libpam-runtime...
I: Configuring login...
I: Configuring util-linux...
I: Configuring mount...
I: Configuring sysvinit-core...
W: Failure while configuring required packages.
W: See /usr/local/jails/devuan0/debootstrap/debootstrap.log for details (possibly the package package is at fault)

不要慌张!这没事儿。🙂 我们只需要进入 chroot 环境,手动修复这个问题,并安装 OpenRC 程序。

chroot /usr/local/jails/devuan0 /bin/bash

# 修复基本包

dpkg --force-depends -i /var/cache/apt/archives/*.deb

# 设置 Cache-Start

echo "APT::Cache-Start 251658240;" > /etc/apt/apt.conf.d/00chroot

# 安装 OpenRC

apt update
apt install openrc

我们几乎已经准备好了所有东西。我们只需要创建一个 password 数据库文件,供 jail(8) 命令在内部使用。

cd /usr/local/jails/devuan0/etc/
echo "root::0:0::0:0:Charlie &:/root:/bin/bash" > master.passwd
pwd_mkdb -d ./ -p master.passwd

# 存储 Linux passwd 文件

cp passwd- passwd

我们还可以将静态链接的 FreeBSD 二进制程序移入 Linux Jail 中,这样我们在需要时就可以使用它们。

cp -a /rescue /usr/local/jails/devuan0/native

现在我们还需要一个 Jail 配置文件,我们可以将其放在 /etc/jail.conf.d/devuan0.conf 中。(假设你的网络配置类似于“VNET Jail HowTo Part 2: Networking”

# vim:设置 syntax=sh:

exec.clean;
allow.raw_sockets;
mount.devfs;

devuan0 {

# ID == epair index :)

  $id             = "0";
  $bridge         = "bridge0";

# 设置域名 :)

  $domain         = "bsd.am";
  vnet;
  vnet.interface = "epair${id}b";

  mount.fstab     = "/etc/jail.conf.d/${name}.fstab";

  exec.prestart   = "ifconfig epair${id} create up";
  exec.prestart  += "ifconfig epair${id}a up descr vnet-${name}";
  exec.prestart  += "ifconfig ${bridge} addm epair${id}a up";

  exec.start      = "/sbin/openrc default";

  exec.stop       = "/sbin/openrc shutdown";

  exec.poststop   = "ifconfig ${bridge} deletem epair${id}a";
  exec.poststop  += "ifconfig epair${id}a destroy";

  host.hostname   = "${name}.${domain}";
  path            = "/usr/local/jails/devuan0";

# 也许需要创建路径 :)

  exec.consolelog = "/var/log/jail/${name}.log";

  persist;
  allow.socket_af;
}

正如你所猜到的,我们还需要一个 fstab 文件,应该放在 /etc/jail.conf.d/devuan0.fstab 中。

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

最后,我们加载一些内核模块(以防它们尚未加载)。

service linux enable
service linux start
kldload netlink

让我们启动 Jail 吧!

jail -c -f /etc/jail.conf.d/devuan0.conf

它正在运行吗?

# jls -N

JID             IP Address      Hostname                      Path
devuan0                         devuan0.bsd.am                /usr/local/jails/devuan0

是的,它已经在运行了!

现在我们可以使用 jexec 进入其中并运行一些命令!

root@srv0:~ # jexec -l devuan0 /bin/bash
root@devuan0:~# uname -a
Linux devuan0.bsd.am 4.4.0 FreeBSD 13.2-RELEASE releng/13.2-n254617-525ecfdad597 GENERIC x86_64 GNU/Linux

进程树看起来也很整洁!

root@devuan0:~# ps f
  PID TTY      STAT   TIME COMMAND
74682 pts/1    S      0:00 /bin/bash
78212 pts/1    R+     0:00  \_ ps f
48412 ?        Ss     0:00 /usr/sbin/cron
41190 ?        Ss     0:00 /usr/sbin/rsyslogd

让我们进行一些网络设置吧!设置网络并安装 OpenSSH。(假设你的网络配置类似于“VNET Jail HowTo Part 2: Networking”

# 设置网卡

/native/ifconfig lo0 inet 127.0.0.1/8 up
/native/ifconfig epair0b inet 10.0.0.10/24 up
/native/route add default 10.0.0.1

# 安装并启动 OpenSSH 服务器

apt-get --no-install-recommends install openssh-server
rc-service ssh start

现在你应该能够 ping 通其他主机了。

~# ping -n -c 1 bsd.am
ping: WARNING: setsockopt(ICMP_FILTER): Protocol not available
PING  (37.252.73.34) 56(84) bytes of data.
64 bytes from 37.252.73.34: icmp_seq=1 ttl=55 time=2.60 ms

---  ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.603/2.603/2.603/0.000 ms

为了使网络配置持久化,我们可以使用 rc.local 文件,在 OpenRC 启动时该文件会被执行。

chmod +x /etc/rc.local
echo '/native/ifconfig lo0 inet 127.0.0.1/8 up' >> /etc/rc.local
echo '/native/ifconfig epair0b inet 10.0.0.10/24 up' >> /etc/rc.local
echo '/native/route add default 10.0.0.1' >> /etc/rc.local

你知道这意味着什么吗?这意味着你现在可以在 Linux 上使用正确的 ZFS、DTrace 和 pf 防火墙了。恭喜你,现在你拥有了一片净土。

就是这样了,朋友们……

PS:我想感谢我的导师 norayr ,是他向我展示了如何手动启动/停止 OpenRC,还要感谢 #devuan 社区里那些了不起的人们,感谢他们的帮助。


作者简介:Antranig Vartanian 在 Illuria 安全公司从事工作。涉及 Unix、BSD、信息安全、Elixir/Erlang、DNS、XMPP 领域。通常没有太大问题。

最后更新于

FreeBSD 中文社区