Merge pull request #962 from BastilleBSD/tschettervictor-patch-1

New setup command with checking enabled to prevent overwriting existing configurations.  And individual switches to configure specific items individually.
This commit is contained in:
Barry McCormick
2025-04-23 08:46:13 -07:00
committed by GitHub
5 changed files with 263 additions and 83 deletions

View File

@@ -52,50 +52,50 @@ Bastille is an open-source system for automating deployment and management of
containerized applications on FreeBSD.
Usage:
bastille command TARGET [args]
bastille [options(s)] command [option(s)] TARGET [args]
Available Commands:
bootstrap Bootstrap a FreeBSD release for container base.
clone Clone an existing container.
cmd Execute arbitrary command on targeted container(s).
config Get or set a config value for the targeted container(s).
console Console into a running container.
convert Convert a Thin container into a Thick container.
cp cp(1) files from host or container to host or targeted container(s).
create Create a new thin container or a thick container if -T|--thick option specified.
destroy Destroy a stopped container or a FreeBSD release.
edit Edit container configuration files (advanced).
export Exports a specified container.
bootstrap Bootstrap a release for jail base.
clone Clone an existing jail.
cmd Execute arbitrary command on targeted jail(s).
config Get, set or remove a config value for the targeted jail(s).
console Console into a running jail.
convert Convert thin jail to thick jail, or convert a jail to a custom release.
cp cp(1) files from host or jail to host or targeted jail(s).
create Create a jail.
destroy Destroy a jail or release.
edit Edit jail configuration files (advanced).
export Exports a jail.
help Help about any command.
htop Interactive process viewer (requires htop).
import Import a specified container.
import Import a jail.
jcp cp(1) files from a jail to jail(s).
limits Apply resources limits to targeted container(s). See rctl(8).
list List containers (running).
mount Mount a volume inside the targeted container(s).
limits Apply resources limits to targeted jail(s). See rctl(8).
list List jails, releases, templates etc...
mount Mount a volume inside targeted jail(s).
network Add or remove interfaces from targeted jail(s).
pkg Manipulate binary packages within targeted container(s). See pkg(8).
pkg Manipulate binary packages within targeted jail(s). See pkg(8).
rcp cp(1) files from a jail to host.
rdr Redirect host port to container port.
rename Rename a container.
restart Restart a running container.
service Manage services within targeted container(s).
rename Rename a jail.
restart Restart a running jail.
service Manage services within targeted jail(s).
setup Attempt to auto-configure network, firewall and storage on new installs.
start Start a stopped container.
stop Stop a running container.
sysrc Safely edit rc files within targeted container(s).
tags Add or remove tags to targeted container(s).
template Apply file templates to targeted container(s).
start Start a stopped jail.
stop Stop a running jail.
sysrc Safely edit rc files within targeted jail(s).
tags Add or remove tags to targeted jail(s).
template Apply file templates to targeted jail(s).
top Display and update information about the top(1) cpu processes.
umount Unmount a volume from within the targeted container(s).
update Update container base -pX release.
upgrade Upgrade container release to X.Y-RELEASE.
umount Unmount a volume from targeted jail(s).
update Update jail base -pX release.
upgrade Upgrade jail release to X.Y-RELEASE.
verify Compare release against a "known good" index.
zfs Manage (get|set) ZFS attributes on targeted container(s).
Use "bastille -v|--version" for version information.
Use "bastille command -h|--help" for more information about a command.
Use "bastille [-c|--config FILE] command" to specify a non-default config file.
Use "bastille [-c|--config config.conf] command" to specify a non-default config file.
```
@@ -112,7 +112,7 @@ automatically. This feature is new since version 0.10.20231013.
```shell
ishmael ~ # bastille setup -h
ishmael ~ # Usage: bastille setup [pf|network|zfs|vnet]
Usage: bastille setup [-p|pf|firewall] [-l|loopback] [-s|shared] [-z|zfs|storage] [-v|vnet] [-b|bridge]
```
On fresh installations it is likely safe to run `bastille setup` with no

View File

@@ -4,12 +4,27 @@ Getting Started
This guide is meant to get you up and running with bastille, and will show you
a number of different options to create and manage your jails.
The first step is running ``bastille setup`` to try to configure bastille
initially, if you didn't during setup. Setup should only be run once.
Setup
-----
The first command a new user should run is the ``bastille setup`` command. This
will attempt to configure the networking, storage, and firewall on your system
for use with Bastille.
By default the setup command will configure a loopback interface, storage (ZFS if
enabled, otherwise UFS) and the pf firewall if you run it as below without any options.
Alternatively, you can run the ``setup`` command with any of the supported options to
configure the selected option by itself.
To see a list of available options and switches, see the ``setup`` subcommand.
.. code-block:: shell
ishmael ~ # bastille setup
Bootstrapping a Release
-----------------------
Then we need to bootstrap a release for bastille to use. We will use
14.2-RELEASE.
@@ -17,6 +32,9 @@ Then we need to bootstrap a release for bastille to use. We will use
.. code-block:: shell
ishmael ~ # bastille bootstrap 14.2-RELEASE
Creating a Jail
---------------
Next we can create our first jail. Bastille can create a few different types of
jails.
@@ -41,7 +59,7 @@ Only clone, thin, and thick jails can be created with ``-V`` ``-B`` and ``-M``.
We will focus on thin jails for the guide.
Classic/Standard Jail
---------------------
^^^^^^^^^^^^^^^^^^^^^
.. code-block:: shell
@@ -62,7 +80,7 @@ necessary to redirect the traffic. It will pass in and out normally.
This will forward traffic from port 80 on the host to port 80 inside the jail.
VNET Jail
---------
^^^^^^^^^
VNET jails can use either a host interface with ``-V`` or a manually created
bridge interface with ``-B``. You can also optionally set a static MAC for the
@@ -82,7 +100,7 @@ The IP used for VNET jails should be an IP reachable inside your local network.
You can also specify 0.0.0.0 or DHCP to use DHCP.
Linux Jail
----------
^^^^^^^^^^
Linux jails are still considered experimental, but they seem to work. First we
must bootstrap a linux distro.

View File

@@ -5,24 +5,27 @@ Bastille create uses any available bootstrapped release to create a lightweight
container system. To create a container simply provide a name, bootstrapped
release and a private (rfc1918) IP address.
- name - release - ip - interface (optional)
The format is ``bastille create NAME RELEASE IP [INTERFACE]``
Note that the ``interface`` is optional. Bastille will use the default interface
that is configured when running the setup command. See ``bastille setup -l`` or
``bastille setup -s``.
.. code-block:: shell
ishmael ~ # bastille create folsom 11.3-RELEASE 10.17.89.10 [interface]
ishmael ~ # bastille create folsom 11.3-RELEASE 10.17.89.10 [INTERFACE]
RELEASE: 11.3-RELEASE.
NAME: folsom.
IP: 10.17.89.10.
This command will create a 11.3-RELEASE container assigning the 10.17.89.10 ip
address to the new system.
This command will create a 11.3-RELEASE jail, assigning the 10.17.89.10 ip
address to the new jail.
.. code-block:: shell
ishmael ~ # bastille create alcatraz 13.2-RELEASE 10.17.89.113/24
The above code will create a jail with a /24 mask. At the time of this
documentation you can only use CIDR notation, and not use a netmask
255.255.255.0 to accomplish this.
@@ -33,7 +36,7 @@ ranges include:
- 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16
Bastille does its best to validate the submitted ip is valid. This has not been
thouroughly tested--I generally use the 10/8 range.
thouroughly tested. I generally use the 10/8 range.
A couple of notes about the created jails. First, MOTD has been disabled inside
of the jails because it does not give information about the jail, but about the
@@ -45,7 +48,6 @@ version information about the host system instead of the jail. If you need to
check the version of freebsd running on the jail use the freebsd-version command
to get accurate information.
Bastille can create many different types of jails, along with many different
options. See the below help output.

View File

@@ -2,19 +2,59 @@ setup
=====
The ``setup`` sub-command attempts to automatically configure a host system for
Bastille containers. This allows you to configure networking, firewall, and
storage options for a Bastille host with one command.
Bastille jails. This allows you to configure networking, firewall, storage, vnet
and bridge options for a Bastille host with one command.
Options
-------
Below is a list of available options that can be used with the ``setup`` command.
.. code-block:: shell
ishmael ~ # bastille setup -h ## display setup help
ishmael ~ # bastille setup network ## only configure loopback interface
ishmael ~ # bastille setup pf ## only configure default firewall
ishmael ~ # bastille setup zfs ## only configure ZFS storage
ishmael ~ # bastille setup vnet ## only configure VNET bridge
ishmael ~ # bastille setup ## configure all of the above
ishmael ~ # bastille setup -l ## configure loopback interface
ishmael ~ # bastille setup -s ## configure shared interface
ishmael ~ # bastille setup -p ## configure default pf firewall
ishmael ~ # bastille setup -z ## configure ZFS storage
ishmael ~ # bastille setup -v ## configure VNET
ishmael ~ # bastille setup -b ## configure bridge interface
ishmael ~ # bastille setup ## configure -l -p and -z
The ``-l|loopback`` option will configure a loopback interface called ``bastille0`` that
will be used as a default when not specifying an interface with the ``create`` command.
The ``-s|shared`` option will configure the interface you choose to also be used as the default
when not specifying an interface with the ``create`` command.
Please note. You CANNOT run both a loopback and a shared interface with Bastille. Only one
should be configured. If you configure one, it will disable the other.
The ``-l|loopback`` option is the default, and is enough for most use cases. It is simply an ``lo`` interface
that jails will get linked to on creation. It is not attached to any specific interface. This is the simplest
networking option. The ``-l|loopback`` and ``-s|shared`` options are only for cases where the ``interface``
is not specified during the ``create`` command. If an interface is specified, these options have no effect.
Instead, the specified interface will be used.
The ``-s|shared`` option is for cases where you want an actual interface to use with bastille as
opposed to a loopback. Jails will be linked to the shared interface on creation.
The ``-p|pf|firewall`` option will configure the pf firewall by enabling the service and creating the
default ``pf.conf`` file. Once this is done, you can use the ``rdr`` command to forward traffic into
a jail.
The ``-z|zfs|storage`` option will attempt to configure a pool and dataset for Bastille, but only
if ZFS in enabled on your system.
The ``-v|vnet`` option will configure your system for use with VNET ``-V`` jails.
The ``-b|bridge`` options will attempt to configure a bridge interface for use with bridged VNET
``-B`` jails.
Running ``bastille setup`` without any options will attempt to auto-configure the ``-l``, ``-p`` and
``-z`` options.
.. code-block:: shell
ishmael ~ # bastille setup help
Usage: bastille setup [pf|network|zfs|vnet]
Usage: bastille setup [-p|pf|firewall] [-l|loopback] [-s|shared] [-z|zfs|storage] [-v|vnet] [-b|bridge]

View File

@@ -33,7 +33,7 @@
. /usr/local/share/bastille/common.sh
usage() {
error_exit "Usage: bastille setup [pf|network|zfs|vnet]"
error_exit "Usage: bastille setup [-p|pf|firewall] [-l|loopback] [-s|shared] [-z|zfs|storage] [-v|vnet] [-b|bridge]"
}
# Check for too many args
@@ -42,24 +42,103 @@ if [ $# -gt 1 ]; then
fi
# Configure bastille loopback network interface
configure_network() {
info "Configuring ${bastille_network_loopback} loopback interface"
sysrc cloned_interfaces+=lo1
sysrc ifconfig_lo1_name="${bastille_network_loopback}"
configure_loopback_interface() {
if [ -z "$(sysrc -f ${BASTILLE_CONFIG} -n bastille_network_loopback)" ] || ! sysrc -n cloned_interfaces | grep -oq "lo1"; then
info "Configuring bastille0 loopback interface"
sysrc cloned_interfaces+=lo1
sysrc ifconfig_lo1_name="bastille0"
info "Bringing up new interface: [bastille0]"
service netif cloneup
sysrc -f "${BASTILLE_CONFIG}" bastille_network_loopback="bastille0"
sysrc -f "${BASTILLE_CONFIG}" bastille_network_shared=""
info "Loopback interface successfully configured: [bastille0]"
else
info "Loopback interface has already been configured: [bastille0]"
fi
}
info "Bringing up new interface: ${bastille_network_loopback}"
service netif cloneup
configure_shared_interface() {
_interface_list="$(ifconfig -l)"
_interface_count=0
if [ -z "${_interface_list}" ]; then
error_exit "Unable to detect interfaces, exiting."
fi
if [ -z "$(sysrc -f ${BASTILLE_CONFIG} -n bastille_network_shared)" ]; then
info "Attempting to configure shared interface for bastille..."
info "Listing available interfaces..."
for _if in ${_interface_list}; do
echo "[${_interface_count}] ${_if}"
_if_num="${_if_num} [${_interface_count}]${_if}"
_interface_count=$(expr ${_interface_count} + 1)
done
# shellcheck disable=SC3045
read -p "Please select the interface you would like to use: " _interface_choice
if ! echo "${_interface_choice}" | grep -Eq "^[0-9]+$"; then
error_exit "Invalid input number, aborting!"
else
_interface_select=$(echo "${_if_num}" | grep -wo "\[${_interface_choice}\][^ ]*" | sed 's/\[.*\]//g')
fi
# Adjust bastille.conf to reflect above choices
sysrc -f "${BASTILLE_CONFIG}" bastille_network_loopback=""
sysrc cloned_interfaces-="lo1"
ifconfig bastille0 destroy 2>/dev/null
sysrc -f "${BASTILLE_CONFIG}" bastille_network_shared="${_interface_select}"
info "Shared interface successfully configured: [${_interface_select}]"
else
info "Shared interface has already been configured: [$(sysrc -f ${BASTILLE_CONFIG} -n bastille_network_shared)]"
fi
}
configure_bridge() {
_bridge_name="bastillebridge"
_interface_list="$(ifconfig -l)"
_interface_count=0
if [ -z "${_interface_list}" ]; then
error_exit "Unable to detect interfaces, exiting."
fi
if ! ifconfig -g bridge | grep -oqw "${_bridge_name}"; then
info "Configuring ${_bridge_name} bridge interface..."
info "Listing available interfaces..."
for _if in ${_interface_list}; do
if ifconfig -g bridge | grep -oqw "${_if}" || ifconfig -g lo | grep -oqw "${_if}"; then
continue
else
echo "[${_interface_count}] ${_if}"
_if_num="${_if_num} [${_interface_count}]${_if}"
_interface_count=$(expr ${_interface_count} + 1)
fi
done
# shellcheck disable=SC3045
read -p "Please select the interface to attach the bridge to: " _interface_choice
if ! echo "${_interface_choice}" | grep -Eq "^[0-9]+$"; then
error_exit "Invalid input number, aborting!"
else
_interface_select=$(echo "${_if_num}" | grep -wo "\[${_interface_choice}\][^ ]*" | sed 's/\[.*\]//g')
fi
# Create bridge and persist on reboot
ifconfig bridge0 create
ifconfig bridge0 name bastillebridge
ifconfig bastillebridge addm ${_interface_select} up
sysrc cloned_interfaces+="bridge0"
sysrc ifconfig_bridge0_name="bastillebridge"
sysrc ifconfig_bastillebridge="addm ${_interface_select} up"
info "Bridge interface successfully configured: [${_bridge_name}]"
else
info "Bridge has alread been configured: [${_bridge_name}]"
fi
}
configure_vnet() {
info "Configuring bridge interface"
sysrc cloned_interfaces+=bridge1
sysrc ifconfig_bridge1_name=bastille1
info "Bringing up new interface: bastille1"
service netif cloneup
if [ ! -f /etc/devfs.rules ]; then
# Ensure jib script is in place for VNET jails
if [ ! "$(command -v jib)" ]; then
if [ -f /usr/share/examples/jails/jib ] && [ ! -f /usr/local/bin/jib ]; then
install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib
fi
fi
# Create default VNET ruleset
if [ ! -f /etc/devfs.rules ] || ! grep -oq "bastille_vnet=13" /etc/devfs.rules; then
info "Creating bastille_vnet devfs.rules"
cat << EOF > /etc/devfs.rules
[bastille_vnet=13]
@@ -70,6 +149,8 @@ add include \$devfsrules_jail
add include \$devfsrules_jail_vnet
add path 'bpf*' unhide
EOF
else
info "VNET has already been configured!"
fi
}
@@ -104,7 +185,7 @@ EOF
sysrc pf_enable=YES
warn "pf ruleset created, please review ${bastille_pf_conf} and enable it using 'service pf start'."
else
error_exit "${bastille_pf_conf} already exists. Exiting."
info "Firewall (pf) has already been configured!"
fi
}
@@ -112,6 +193,8 @@ fi
configure_zfs() {
if [ ! "$(kldstat -m zfs)" ]; then
info "ZFS module not loaded; skipping..."
elif sysrc -f ${BASTILLE_CONFIG} -n bastille_zfs_enable | grep -Eoq "([Y|y][E|e][S|s])"; then
info "ZFS has already been configured!"
else
## attempt to determine bastille_zroot from `zpool list`
bastille_zroot=$(zpool list | grep -v NAME | awk '{print $1}')
@@ -128,26 +211,63 @@ configure_zfs() {
# Run all base functions (w/o vnet) if no args
if [ $# -eq 0 ]; then
sysrc bastille_enable=YES
configure_network
configure_loopback_interface
configure_pf
configure_zfs
fi
# Handle special-case commands first.
# Handle options.
case "$1" in
help|-h|--help)
usage
;;
pf|firewall)
configure_pf
;;
network|loopback)
configure_network
;;
zfs|storage)
configure_zfs
;;
bastille1|vnet|bridge)
configure_vnet
;;
-h|--help|help)
usage
;;
-p|pf|firewall)
configure_pf
;;
-l|loopback)
warn "[WARNING] Bastille only allows using either the 'loopback' or 'shared'"
warn "interface to be configured ant one time. If you continue, the 'shared'"
warn "interface will be disabled, and the 'loopback' interface will be used as default."
# shellcheck disable=SC3045
read -p "Do you really want to continue setting up the loopback interface? [y|n]:" _answer
case "${_answer}" in
[Yy]|[Yy][Ee][Ss])
configure_loopback_interface
;;
[Nn]|[Nn][Oo])
error_exit "Loopback interface setup cancelled."
;;
*)
error_exit "Invalid selection. Please answer 'y' or 'n'"
;;
esac
;;
-s|shared)
warn "[WARNING] Bastille only allows using either the 'loopback' or 'shared'"
warn "interface to be configured at one time. If you continue, the 'loopback'"
warn "interface will be disabled, and the shared interface will be used as default."
# shellcheck disable=SC3045
read -p "Do you really want to continue setting up the shared interface? [y|n]:" _answer
case "${_answer}" in
[Yy]|[Yy][Ee][Ss])
configure_shared_interface
;;
[Nn]|[Nn][Oo])
error_exit "Shared interface setup cancelled."
;;
*)
error_exit "Invalid selection. Please answer 'y' or 'n'"
;;
esac
;;
-z|zfs|storage)
configure_zfs
;;
-v|vnet)
configure_vnet
;;
-b|bridge)
configure_vnet
configure_bridge
;;
esac