Skip to content

Instantly share code, notes, and snippets.

@SchleimKeim
Last active November 16, 2023 16:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SchleimKeim/98193f22e34821df9be5dc763581d99a to your computer and use it in GitHub Desktop.
Save SchleimKeim/98193f22e34821df9be5dc763581d99a to your computer and use it in GitHub Desktop.
Emby VNET Jail Setup

Running emby-server in a Jail

This article assumes that you have read the FreeBSD Handbook. Specifically the chapter about jails.

VNET Jails

To run properly, emby needs to run in a VNET jail. VNET jails have their own full network stack. There are various ways to use and setup VNET. But if all we want is a jail that is connected to the jail-host and is able to use the host's external interface, if_bridge(4) and epair(4) interfaces is the way to go.

Here's how to set one up.

Preparations

1. Create Bridge Interface

ifconfig bridge create up

2. Give the Bridge an IP

Give your newly created bridge an IP. Were going to use it as default gateway for the jail.

ifconfig bridge0 inet 172.16.1.254/24

This IP can be anything really. FreeBSD knows how to route bridge0 to the vtnet0. vtnet0 is just the name of the network interface on my host system. Yours might be called otherwise (em0, fxb0 or whatnot).

Making this permanent

To make the bridge settings permanent, add it to your host's /etc/rc.conf:

cloned_interfaces="bridge0"
ifconfig_bridge0="inet 172.16.1.254 netmask 255.255.255.0"

By the way: To make sure you didn't make any bad mistakes in your /etc/rc.conf, you can use the following command to do a basic syntax check.

for _rc_variable in $(sysrc -f /etc/rc.conf -a | cut -d ':' -f 1); do
    sysrc -c -f /etc/rc.conf $_rc_variable || echo "$_rc_variable is incorrect"
done

4. Update your jail.conf

The key to creating a VNET jail are mainly two entries in the jail.conf:

  • vnet -> this tells jail(8) to use VNET.
  • vnet.interface -> this tells jail(8) the interface and the address we want to use inside the jail.

Other than that, we just need some additional prestart/start/poststop parameteres to make sure the connected epair interfaces are setup and teared down at appropriate times.

Example VNET Jail.conf

vnet-jail {
    # allow memory locking
    allow.mlock = "true";

    # some variables to make prevent us from making typos along the way.
    $id = "66";
    $ip = "172.16.1.${id}/24";
    $gateway = "172.16.1.254";
    $bridge = "bridge0";
    $epair = "epair${id}";

    # tell jail(8) to use VNET
    vnet;
    vnet.interface = "${epair}b";

    # start and tear down epair depending on weither the jail is running.
    exec.prestart += "ifconfig ${epair} create up";
    exec.prestart += "ifconfig ${epair}a up descr jail:${name}";
    exec.prestart += "ifconfig ${bridge} addm ${epair}a up";
    exec.start    += "ifconfig ${epair}b ${ip} up";
    exec.start    += "route add default ${gateway}";
    exec.poststop = "ifconfig ${bridge} deletem ${epair}a";
    exec.poststop += "ifconfig ${epair}a destroy";
    # ...
}

Full Example /etc/jail.conf for emby

Here's my full configuration for the emby jail.

$jailroot="/jails";
path="$jailroot/$name";
host.hostname="$name.local.domain";
mount.devfs;
exec.clean;
exec.start="sh /etc/rc";
exec.stop="sh /etc/rc.shutdown";
allow.raw_sockets;

vnet-emby {
  # STARTUP/LOGGING
  exec.start = "/bin/sh /etc/rc";
  exec.stop  = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  devfs_ruleset = 5;
  allow.mlock = true;
  allow.mount = true;
  allow.mount.nullfs = true;

  # VNET/VIMAGE
  vnet;
  vnet.interface = "${epair}b";

  # NETWORKS/INTERFACES
  $id = "66"; 
  $ip = "172.16.1.${id}/24";
  $gateway = "172.16.1.254";
  $bridge = "bridge0"; 
  $epair = "epair${id}";

  # ADD TO bridge INTERFACE
  exec.prestart += "ifconfig ${epair} create up";
  exec.prestart += "ifconfig ${epair}a up descr jail:${name}";
  exec.prestart += "ifconfig ${bridge} addm ${epair}a up";
  exec.start    += "ifconfig ${epair}b ${ip} up";
  exec.start    += "route add default ${gateway}";
  exec.poststop = "ifconfig ${bridge} deletem ${epair}a";
  exec.poststop += "ifconfig ${epair}a destroy";
}

# vim: set ts=4 sw=4 syntax=conf ai et: 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment