diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 1927be497..5662c1e71 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -3,7 +3,7 @@ version: 2 sphinx: configuration: docs/conf.py -python: - version: 3.7 - install: - - requirements: docs/requirements.txt +build: + os: "ubuntu-22.04" + tools: + python: "3.11" diff --git a/LICENSE b/LICENSE index d5981bde2..c8c6e406f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2018-2022, Christer Edwards +Copyright (c) 2018-2023, Christer Edwards All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index b4ef92752..36eb47e1e 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ Bastille [Bastille](https://bastillebsd.org/) is an open-source system for automating deployment and management of containerized applications on FreeBSD. -Looking for [Bastille Templates](https://gitlab.com/BastilleBSD-Templates/)? +[Bastille Documentation](https://bastille.readthedocs.io/en/latest/) Installation ============ -Bastille is available in the official FreeBSD ports tree. +Bastille is available for installation from the official FreeBSD ports tree. **pkg** ```shell @@ -22,7 +22,7 @@ make -C /usr/ports/sysutils/bastille install clean **Git** (bleeding edge / unstable -- primarily for developers) ```shell -git clone https://github.com/BastilleBSD/bastille.git +git clone https://github.com/bastillebsd/bastille.git cd bastille make install ``` @@ -30,8 +30,22 @@ make install **enable at boot** ```shell sysrc bastille_enable=YES +sysrc bastille_rcorder=YES ``` +Upgrading from a previous version +--------------------------------- +When upgrading from a previous version of bastille (e.g. 0.10.20230714 to +0.10.20231013) you will need to update your bastille.conf + +```shell +cd /usr/local/etc/bastille +diff -u bastille.conf bastille.conf.sample +``` + +Merge the lines that are present in the new bastille.conf.sample into +your bastille.conf + Basic Usage ----------- ```shell @@ -39,7 +53,7 @@ Bastille is an open-source system for automating deployment and management of containerized applications on FreeBSD. Usage: - bastille command TARGET args + bastille command TARGET [args] Available Commands: bootstrap Bootstrap a FreeBSD release for container base. @@ -47,31 +61,35 @@ Available Commands: 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. + convert Convert a Thin container into a Thick container. cp cp(1) files from host to targeted container(s). - create Create a new thin or thick container. - destroy Destroy a stopped container or a bootstrapped release. + 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 container archive or image. - help Help about any command + export Exports a specified container. + help Help about any command. htop Interactive process viewer (requires htop). - import Import a container archive or image. + import Import a specified container. limits Apply resources limits to targeted container(s). See rctl(8). - list List containers, releases, templates, logs, limits or backups. + list List containers (running and stopped). mount Mount a volume inside the targeted container(s). pkg Manipulate binary packages within targeted container(s). See pkg(8). rdr Redirect host port to container port. + rcp reverse cp(1) files from a single container to the host. + rename Rename a container. restart Restart a running container. service Manage services within targeted container(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). - template Apply automation templates to targeted container(s). + tags Add or remove tags to targeted container(s). + template Apply file templates to targeted container(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. - verify Verify bootstrapped release or automation template. + 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. @@ -79,1003 +97,42 @@ Use "bastille command -h|--help" for more information about a command. ``` -## 0.9-beta +## 0.10-beta This document outlines the basic usage of the Bastille container management framework. This release is still considered beta. -Network Requirements -==================== -Several networking options can be performed regarding the user needs. Basic -containers can support IP alias networking, where the IP address is assigned to -the host interface and used by the container, generally known as "shared IP" -based containers. - -If you administer your own network and can assign and remove unallocated IP -addresses, then "shared IP" is a simple method to get started. If this is the -case, skip ahead to ZFS Support. +Setup Requirements +================== +Bastille can now (attempt) to configure the networking, firewall and storage +automatically. This feature is new since version 0.10.20231013. -If you are not the administator of the network, or perhaps you're in "the -cloud" someplace and are only provided a single IP4 address. In this situation -Bastille can create and attach containers to a private loopback interface. The -host system then acts as the firewall, permitting and denying traffic as -needed. (This method has been my primary method for years.) - -**bastille0** - -First, create the loopback interface: +**bastille setup** ```shell -ishmael ~ # sysrc cloned_interfaces+=lo1 -ishmael ~ # sysrc ifconfig_lo1_name="bastille0" -ishmael ~ # service netif cloneup -``` - -Create the firewall config, or merge as necessary. - -/etc/pf.conf ------------- -``` -ext_if="vtnet0" - -set block-policy return -scrub in on $ext_if all fragment reassemble -set skip on lo - -table persist -nat on $ext_if from to any -> ($ext_if:0) - -## static rdr example -# rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45 - -## Enable dynamic rdr (see below) -rdr-anchor "rdr/*" - -block in all -pass out quick keep state -antispoof for $ext_if inet -pass in inet proto tcp from any to any port ssh flags S/SA keep state - -## make sure you also open up ports that you are going to use for dynamic rdr -# pass in inet proto tcp from any to any port : flags S/SA keep state -# pass in inet proto udp from any to any port : flags S/SA keep state -## for IPv6 networks please uncomment the following rule -# pass inet6 proto icmp6 icmp6-type { echoreq, routersol, routeradv, neighbradv, neighbrsol } - -``` - -* Make sure to change the `ext_if` variable to match your host system interface. -* Note that if multiple interface aliases are in place, the index `($ext_if:0)` -can be changed accordingly; so if you want to send traffic out the second IP alias -of the interface, change the value to `($ext_if:1)` and so on. -* Make sure to include the last line (`port ssh`) or you'll end up locked -out of a remote system. - -Note: if you have an existing firewall, the key lines for in/out traffic to -containers are: - -``` -table persist -nat on $ext_if from to any -> ($ext_if:0) - -## rdr example -## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45 -``` - -The `nat` routes traffic from the loopback interface to the external interface -for outbound access. - -The `rdr pass ...` will redirect traffic from the host firewall on port X to -the ip of container Y. The example shown redirects web traffic (80 & 443) to the -container at `10.17.89.45`. - -Finally, enable and (re)start the firewall: - -## dynamic rdr - -The `rdr-anchor "rdr/*"` enables dynamic rdr rules to be setup using the -`bastille rdr` command at runtime - eg. - -``` - bastille rdr tcp 2001 22 # Redirects tcp port 2001 on host to 22 on jail - bastille rdr udp 2053 53 # Same for udp - bastille rdr list # List dynamic rdr rules - bastille rdr clear # Clear dynamic rdr rules +ishmael ~ # bastille setup -h +ishmael ~ # Usage: bastille setup [pf|bastille0|zfs|vnet] ``` - Note that if you are redirecting ports where the host is also listening - (eg. ssh) you should make sure that the host service is not listening on - the cloned interface - eg. for ssh set sshd_flags in rc.conf +On fresh installations it is likely safe to run `bastille setup` with no +arguments. This will configure the firewall, the loopback interface and attempt +to determine ZFS vs UFS storage. -## Enable pf rules +If you have an existing firewall, or customized network design, you may want to +run individual options; eg `bastille setup zfs` or `bastille setup vnet`. -```shell -ishmael ~ # sysrc pf_enable="YES" -ishmael ~ # service pf restart -``` - -At this point you'll likely be disconnected from the host. Reconnect the ssh -session and continue. +Note: The `bastille setup` command can configure and enable PF but it does not +automatically reload the firewall. You will still need to manually `service pf +start`. At that point you'll likely be disconnected if configuring a remote +host. Simply reconnect the ssh session and continue. This step only needs to be done once in order to prepare the host. - -ZFS support -=========== - -![BastilleBSD Twitter Poll](/docs/images/bastillebsd-twitter-poll.png) - -Bastille 0.4 added initial support for ZFS. `bastille bootstrap` and `bastille -create` will generate ZFS volumes based on settings found in the -`bastille.conf`. This section outlines how to enable and configure Bastille for -ZFS. - -Two values are required for Bastille to use ZFS. The default values in the -`bastille.conf` are empty. Populate these two to enable ZFS. - -```shell -## ZFS options -bastille_zfs_enable="" ## default: "" -bastille_zfs_zpool="" ## default: "" -bastille_zfs_prefix="bastille" ## default: "${bastille_zfs_zpool}/bastille" -bastille_prefix="/bastille" ## default: "/usr/local/bastille". ${bastille_zfs_prefix} gets mounted here -bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off" -``` - -**Example** - -```shell -ishmael ~ # sysrc -f /usr/local/etc/bastille/bastille.conf bastille_zfs_enable=YES -ishmael ~ # sysrc -f /usr/local/etc/bastille/bastille.conf bastille_zfs_zpool=ZPOOL_NAME -``` - -Replace `ZPOOL_NAME` with the zpool you want Bastille to use. Tip: `zpool list` -and `zpool status` will help. If you get 'no pools available' you are likely -not using ZFS and can safely ignore these settings. - - -bastille bootstrap ------------------- -Before you can begin creating containers, Bastille needs to "bootstrap" a -release. Current supported releases are 11.4-RELEASE, 12.2-RELEASE and -13.0-RELEASE. - -**Important: If you need ZFS support see the above section BEFORE -bootstrapping.** - -To `bootstrap` a release, run the bootstrap sub-command with the -release version as the argument. - -**FreeBSD 11.4-RELEASE** -```shell -ishmael ~ # bastille bootstrap 11.4-RELEASE -``` - -**FreeBSD 12.2-RELEASE** -```shell -ishmael ~ # bastille bootstrap 12.2-RELEASE -``` - -**HardenedBSD 11-STABLE-BUILD-XX** -```shell -ishmael ~ # bastille bootstrap 11-STABLE-BUILD-XX -``` - -**HardenedBSD 12-STABLE-BUILD-XX** -```shell -ishmael ~ # bastille bootstrap 12-STABLE-BUILD-XX -``` - -> `bastille bootstrap RELEASE update` to apply updates automatically at bootstrap. - -This command will ensure the required directory structures are in place and -download the requested release. For each requested release, `bootstrap` will -download the base.txz. If you need more than base (eg; ports, lib32, src) you -can configure the `bastille_bootstrap_archives` in the configuration file. By -default this value is set to "base". Additional components are added, space -separated, without file extension. - -Bastille will attempt to fetch the required archives if they are not found in -the `cache/$RELEASE` directory. - -Downloaded artifacts are stored in the `cache/RELEASE` directory. "bootstrapped" -releases are stored in `releases/RELEASE`. - -Advanced: If you want to create your own custom base.txz, or use an unsupported -variant of FreeBSD, drop your own base.txz in `cache/RELEASE/base.txz` and -`bastille bootstrap` will attempt to extract and use it. - -The bootstrap subcommand is generally only used once to prepare the system. The -other use cases for the bootstrap command are when a new FreeBSD version is -released and you want to start building containers on that version, or -bootstrapping templates from GitHub or GitLab. - -See `bastille update` to ensure your bootstrapped releases include the latest -patches. - -**Ubuntu Linux [new since 0.9]** - -The bootstrap process for Linux containers is very different from the BSD process. -You will need the package debootstrap and some kernel modules for that. -But don't worry, Bastille will do that for you. - -```shell -ishmael ~ # bastille bootstrap focal -sysrc: unknown variable 'linprocfs_load' -sysrc: unknown variable 'linsysfs_load' -sysrc: unknown variable 'tmpfs_load' -linprocfs_load, linsysfs_load, tmpfs_load not enabled in /boot/loader.conf or linux_enable not active. Should I do that for you? (N|y) -#y -Loading modules -Persisting modules -linux_enable: -> YES -linprocfs_load: -> YES -linsysfs_load: -> YES -tmpfs_load: -> YES -Debootstrap not found. Should it be installed? (N|y) -#y -FreeBSD repository is up to date. -All repositories are up to date. -Checking integrity... done (0 conflicting) -The following 1 package(s) will be affected (of 0 checked): - -New packages to be INSTALLED: - debootstrap: 1.0.123_4 -[...] -``` -As of 0.9.20210714 Bastille supports Ubuntu 18.04 (bionic) and Ubuntu 20.04 (focal). - -bastille create ---------------- -`bastille create` uses a bootstrapped release to create a lightweight container -system. To create a container simply provide a name, release and a private -(rfc1918) IP address. Optionally provide a network interface name to attach the -IP at container creation. - -- name -- release (bootstrapped) -- ip (ip4 or ip6) -- interface (optional) - - -**ip4** -```shell -ishmael ~ # bastille create folsom 12.2-RELEASE 10.17.89.10 -Valid: (10.17.89.10). - -NAME: folsom. -IP: 10.17.89.10. -RELEASE: 12.2-RELEASE. - -syslogd_flags: -s -> -ss -sendmail_enable: NO -> NONE -cron_flags: -> -J 60 -``` - -This command will create a 12.2-RELEASE container assigning the 10.17.89.10 ip -address to the new system. - -**ip6** -```shell -ishmael ~ # bastille create folsom 12.2-RELEASE fd35:f1fd:2cb6:6c5c::13 -Valid: (fd35:f1fd:2cb6:6c5c::13). - -NAME: folsom. -IP: fd35:f1fd:2cb6:6c5c::13 -RELEASE: 12.1-RELEASE. - -syslogd_flags: -s -> -ss -sendmail_enable: NO -> NONE -cron_flags: -> -J 60 -``` - -This command will create a 12.2-RELEASE container assigning the -fd35:f1fd:2cb6:6c5c::13 ip address to the new system. - -**VNET** -```shell -ishmael ~ # bastille create -V vnetjail 12.2-RELEASE 192.168.87.55/24 em0 -Valid: (192.168.87.55/24). -Valid: (em0). - -NAME: vnettest0. -IP: 192.168.87.55/24. -INTERFACE: em0. -RELEASE: 12.1-RELEASE. - -syslogd_flags: -s -> -ss -sendmail_enable: NO -> NONE -cron_flags: -> -J 60 -ifconfig_e0b_bastille0_name: -> vnet0 -ifconfig_vnet0: -> inet 192.168.87.55/24 -``` - -This command will create a 12.2-RELEASE container assigning the -192.168.87.55/24 ip address to the new system. - -VNET-enabled containers are attached to a virtual bridge interface for -connectivity. This bridge interface is defined by the interface argument in the -create command (in this case, em0). - -VNET also requires a custom `devfs` ruleset. Create the file as needed on the host system: - -**/etc/devfs.rules** -``` -[bastille_vnet=13] -add path 'bpf*' unhide -``` - -Optionally `bastille create [ -T | --thick ]` will create a container with a -private base. This is sometimes referred to as a "thick" container (whereas the -shared base container is a "thin"). - -```shell -ishmael ~ # bastille create -T folsom 12.2-RELEASE 10.17.89.10 -``` - -**Linux** -```shell -ishmael ~ # bastille create folsom focal 10.17.89.10 -``` - -Systemd is not supported due to the missing boot process. - - - -I recommend using private (rfc1918) ip address ranges for your containers. -These ranges include: - -- 10.0.0.0/8 -- 172.16.0.0/12 -- 192.168.0.0/16 - -If your Bastille host also uses private (rfc1918) addresses, use a different -range for your containers. ie; Host uses 192.168.0.0/16, containers use 10.0.0.0/8. - -Bastille does its best to validate the submitted ip is valid. I generally use -the 10.0.0.0/8 range for containers. - - -bastille start --------------- -To start a containers you can use the `bastille start` command. - -```shell -ishmael ~ # bastille start folsom -[folsom]: -folsom: created - -``` - - -bastille stop -------------- -To stop a containers you can use the `bastille stop` command. - -```shell -ishmael ~ # bastille stop folsom -[folsom]: -folsom: removed - -``` - - -bastille restart ----------------- -To restart a container you can use the `bastille restart` command. - -```shell -ishmael ~ # bastille restart folsom -[folsom]: -folsom: removed - -[folsom]: -folsom: created - -``` - -bastille list -------------- -This sub-command will show you the running containers on your system. - -```shell -ishmael ~ # bastille list - JID IP Address Hostname Path - bastion 10.17.89.65 bastion /usr/local/bastille/jails/bastion/root - unbound0 10.17.89.60 unbound0 /usr/local/bastille/jails/unbound0/root - unbound1 10.17.89.61 unbound1 /usr/local/bastille/jails/unbound1/root - squid 10.17.89.30 squid /usr/local/bastille/jails/squid/root - nginx 10.17.89.45 nginx /usr/local/bastille/jails/nginx/root - folsom 10.17.89.10 folsom /usr/local/bastille/jails/folsom/root -``` - -You can also list non-running containers with `bastille list containers`. In -the same manner you can list archived `logs`, downloaded `templates`, and -`releases` and `backups`. Providing the `-j` flag to list alone will result in -JSON output. - - -bastille service ----------------- -To restart services inside a containers you can use the `bastille service` -command. - -```shell -ishmael ~ # bastille service folsom postfix restart -[folsom] -postfix/postfix-script: stopping the Postfix mail system -postfix/postfix-script: starting the Postfix mail system - -``` - - -bastille cmd ------------- -To execute commands within the container you can use `bastille cmd`. - -```shell -ishmael ~ # bastille cmd folsom ps -auxw -[folsom]: -USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND -root 71464 0.0 0.0 14536 2000 - IsJ 4:52PM 0:00.00 /usr/sbin/syslogd -ss -root 77447 0.0 0.0 16632 2140 - SsJ 4:52PM 0:00.00 /usr/sbin/cron -s -root 80591 0.0 0.0 18784 2340 1 R+J 4:53PM 0:00.00 ps -auxw - -``` - - -bastille pkg ------------- -To manage binary packages within the container use `bastille pkg`. - -```shell -ishmael ~ # bastille pkg folsom install vim-console git-lite zsh -[folsom]: -Updating FreeBSD repository catalogue... -[folsom] Fetching meta.txz: 100% 944 B 0.9kB/s 00:01 -[folsom] Fetching packagesite.txz: 100% 6 MiB 6.6MB/s 00:01 -Processing entries: 100% -FreeBSD repository update completed. 32617 packages processed. -All repositories are up to date. -Updating database digests format: 100% -The following 10 package(s) will be affected (of 0 checked): - -New packages to be INSTALLED: - vim-console: 8.1.1954 - git-lite: 2.23.0 - zsh: 5.7.1_1 - expat: 2.2.8 - curl: 7.66.0 - libnghttp2: 1.39.2 - ca_root_nss: 3.47.1 - pcre: 8.43_2 - gettext-runtime: 0.20.1 - indexinfo: 0.3.1 - -Number of packages to be installed: 10 - -The process will require 87 MiB more space. -18 MiB to be downloaded. - -Proceed with this action? [y/N]: -...[snip]... -``` - -The PKG sub-command can, of course, do more than just `install`. The -expectation is that you can fully leverage the pkg manager. This means, -`install`, `update`, `upgrade`, `audit`, `clean`, `autoremove`, etc. - -```shell -ishmael ~ # bastille pkg ALL upgrade -[bastion]: -Updating pkg.bastillebsd.org repository catalogue... -[bastion] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01 -[bastion] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01 -Processing entries: 100% -pkg.bastillebsd.org repository update completed. 493 packages processed. -All repositories are up to date. -Checking for upgrades (1 candidates): 100% -Processing candidates (1 candidates): 100% -Checking integrity... done (0 conflicting) -Your packages are up to date. - -[unbound0]: -Updating pkg.bastillebsd.org repository catalogue... -[unbound0] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01 -[unbound0] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01 -Processing entries: 100% -pkg.bastillebsd.org repository update completed. 493 packages processed. -All repositories are up to date. -Checking for upgrades (0 candidates): 100% -Processing candidates (0 candidates): 100% -Checking integrity... done (0 conflicting) -Your packages are up to date. - -[unbound1]: -Updating pkg.bastillebsd.org repository catalogue... -[unbound1] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01 -[unbound1] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01 -Processing entries: 100% -pkg.bastillebsd.org repository update completed. 493 packages processed. -All repositories are up to date. -Checking for upgrades (0 candidates): 100% -Processing candidates (0 candidates): 100% -Checking integrity... done (0 conflicting) -Your packages are up to date. - -[squid]: -Updating pkg.bastillebsd.org repository catalogue... -[squid] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01 -[squid] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01 -Processing entries: 100% -pkg.bastillebsd.org repository update completed. 493 packages processed. -All repositories are up to date. -Checking for upgrades (0 candidates): 100% -Processing candidates (0 candidates): 100% -Checking integrity... done (0 conflicting) -Your packages are up to date. - -[nginx]: -Updating pkg.bastillebsd.org repository catalogue... -[nginx] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01 -[nginx] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01 -Processing entries: 100% -pkg.bastillebsd.org repository update completed. 493 packages processed. -All repositories are up to date. -Checking for upgrades (1 candidates): 100% -Processing candidates (1 candidates): 100% -The following 1 package(s) will be affected (of 0 checked): - -Installed packages to be UPGRADED: - nginx-lite: 1.14.0_14,2 -> 1.14.1,2 - -Number of packages to be upgraded: 1 - -315 KiB to be downloaded. - -Proceed with this action? [y/N]: y -[nginx] [1/1] Fetching nginx-lite-1.14.1,2.txz: 100% 315 KiB 322.8kB/s 00:01 -Checking integrity... done (0 conflicting) -[nginx] [1/1] Upgrading nginx-lite from 1.14.0_14,2 to 1.14.1,2... -===> Creating groups. -Using existing group 'www'. -===> Creating users -Using existing user 'www'. -[nginx] [1/1] Extracting nginx-lite-1.14.1,2: 100% -You may need to manually remove /usr/local/etc/nginx/nginx.conf if it is no longer needed. -``` - - -bastille destroy ----------------- -Containers can be destroyed and thrown away just as easily as they were -created. Note: containers must be stopped before destroyed. - -```shell -ishmael ~ # bastille stop folsom -[folsom]: -folsom: removed - -ishmael ~ # bastille destroy folsom -Deleting Container: folsom. -Note: container console logs not destroyed. -/usr/local/bastille/logs/folsom_console.log - -``` - -bastille template ------------------ -Looking for ready made CI/CD validated [Bastille -Templates](https://gitlab.com/BastilleBSD-Templates)? - -Bastille supports a templating system allowing you to apply files, pkgs and -execute commands inside the container automatically. - -Currently supported template hooks are: `ARG`, `LIMITS`, `INCLUDE`, - `MOUNT`, `PKG`, `CP`, `SYSRC`, `SERVICE`, `RDR`, `CMD`, `RENDER`. - -Templates are created in `${bastille_prefix}/templates` and can leverage any of -the template hooks. Simply create a new directory in the format project/repo, -ie; `username/base-template` - -```shell -mkdir -p /usr/local/bastille/templates/username/base-template -``` - -To leverage a template hook, create an UPPERCASE file in the root of the -template directory named after the hook you want to execute. eg; - -```shell -echo "PKG zsh vim-console git-lite htop" >> /usr/local/bastille/templates/username/base-template/Bastillefile -echo "CMD /usr/bin/chsh -s /usr/local/bin/zsh" >> /usr/local/bastille/templates/username/base-template/Bastillefile -echo "CP usr" > /usr/local/bastille/templates/username/base-template/Bastillefile -``` - -Template hooks are executed in specific order and require specific syntax to -work as expected. This table outlines that order and those requirements: - -| SUPPORTED | format | example | -|-----------|-----------------------|------------------------------------------------| -| ARG | name=value (one/line) | domain=example.com (omit value for no default) | -| LIMITS | resource value | memoryuse 1G | -| INCLUDE | template path/URL | http?://TEMPLATE_URL or username/base-template | -| PRE | /bin/sh command | mkdir -p /usr/local/path | -| FSTAB | fstab syntax | /host/path container/path nullfs ro 0 0 | -| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop | -| OVERLAY | paths (one/line) | etc usr | -| SYSRC | sysrc command(s) | nginx_enable=YES | -| SERVICE | service command(s) | nginx restart | -| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh | -| RENDER | paths (one/line) | /usr/local/etc/nginx | -| RDR | protocol port port | tcp 2200 22 | - -Note: SYSRC requires NO quotes or that quotes (`"`) be escaped. ie; `\"`) - -Any name provided in the ARG file can be used as a variable in the other hooks. -For example, `name=value` in the ARG file will cause instances of `${name}` -to be replaced with `value`. The `RENDER` hook can be used to specify existing files or -directories inside the jail whose contents should have the variables replaced. Values can be -specified either through the command line when applying the template or as a default in the ARG -file. - -In addition to supporting template hooks, Bastille supports overlaying files -into the container. This is done by placing the files in their full path, using the -template directory as "/". - -An example here may help. Think of -`/usr/local/bastille/templates/username/base`, our example template, as the -root of our filesystem overlay. If you create an `etc/hosts` or -`etc/resolv.conf` inside the base template directory, these can be overlayed -into your container. - -Note: due to the way FreeBSD segregates user-space, the majority of your -overlayed template files will be in `usr/local`. The few general -exceptions are the `etc/hosts`, `etc/resolv.conf`, and `etc/rc.conf.local`. - -After populating `usr/local/` with custom config files that your container will -use, be sure to include `usr` in the template OVERLAY definition. eg; - -```shell -echo "OVERLAY etc" >> /usr/local/bastille/templates/username/base/Bastillefile -echo "OVERLAY usr" >> /usr/local/bastille/templates/username/base/Bastillefile -``` - -The above example will include anything under "etc" and "usr" inside -the template. You do not need to list individual files. Just include the -top-level directory name. - -For more control over the order of operations when applying a template, -create a `Bastillefile` inside the base template directory. Each line in -the file should begin with an uppercase reference to a Bastille command -followed by its arguments (omitting the target, which is deduced from the -`template` arguments). Lines beginning with `#` are treated as comments. -Variables can also be defined using `ARG` with one `name=value` pair per -line. Subsequent references to `${name}` would be replaced by `value`. -Note that argument values are not available for use until after the point -at which they are defined in the file. Both `${JAIL_NAME}` and `${JAIL_IP}` -are made available in templates without having to define them as args. - -Bastillefile example: - -```shell -LIMITS memoryuse 1G - -# This value can be overridden when the template is applied. -ARG domain=example.com - -# Replace all argument variables inside the nginx config. -RENDER /usr/local/etc/nginx - -# Install and start nginx. -PKG nginx -SYSRC nginx_enable=YES -SERVICE nginx restart - -# Copy files to nginx. -CP www/ usr/local/www/nginx-dist/ - -# Use the "domain" arg to create a file on the server containing the domain. -CMD echo "${domain}" > /usr/local/www/nginx-dist/domain.txt - -# Create a file on the server containing the jail's hostname. -CMD hostname > /usr/local/www/nginx-dist/hostname.txt - -# Forward TCP port 80 on the host to port 80 in the container. -RDR tcp 80 80 -``` - -Use the following command to convert a hook-based template into the Bastillefile format: -```shell -bastille template --convert my-template -``` - -Applying Templates ------------------- - -Containers must be running to apply templates. - -Bastille includes a `template` sub-command. This sub-command requires a target -and a template name. As covered in the previous section, template names -correspond to directory names in the `bastille/templates` directory. - -To provide values for arguments defined by `ARG` in the template, pass the -optional `--arg` parameter as many times as needed. Alternatively, use -`--arg-file ` with one `name=value` pair per line. - -```shell -ishmael ~ # bastille template folsom username/base --arg domain=example.com -[folsom]: -Copying files... -Copy complete. -Installing packages. -...[snip]... -Executing final command(s). -chsh: user information updated -Template Complete. - -``` - - -bastille top ------------- -This one simply runs `top` in that container. This command is interactive, as -`top` is interactive. - - -bastille htop -------------- -This one simply runs `htop` inside the container. This one is a quick and dirty -addition. note: won't work if you don't have htop installed in the container. - - -bastille sysrc --------------- -The `sysrc` sub-command allows for safely editing system configuration files. -In container terms, this allows us to toggle on/off services and options at -startup. - -```shell -ishmael ~ # bastille sysrc nginx nginx_enable=YES -[nginx]: -nginx_enable: NO -> YES -``` - -See `man sysrc(8)` for more info. - - -bastille console ----------------- -This sub-command launches a login shell into the container. Default is -password-less root login. If you provide an additional argument of a username -you will be logged in as that user. (user must be created first) - -```shell -ishmael ~ # bastille console folsom -[folsom]: -FreeBSD 11.3-RELEASE-p4 (GENERIC) #0: Thu Sep 27 08:16:24 UTC 2018 - -Welcome to FreeBSD! - -Release Notes, Errata: https://www.FreeBSD.org/releases/ -Security Advisories: https://www.FreeBSD.org/security/ -FreeBSD Handbook: https://www.FreeBSD.org/handbook/ -FreeBSD FAQ: https://www.FreeBSD.org/faq/ -Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/ -FreeBSD Forums: https://forums.FreeBSD.org/ - -Documents installed with the system are in the /usr/local/share/doc/freebsd/ -directory, or can be installed later with: pkg install en-freebsd-doc -For other languages, replace "en" with a language code like de or fr. - -Show the version of FreeBSD installed: freebsd-version ; uname -a -Please include that output and any error messages when posting questions. -Introduction to manual pages: man man -FreeBSD directory layout: man hier - -Edit /etc/motd to change this login announcement. -root@folsom:~ # -``` - -At this point you are logged in to the container and have full shell access. -The system is yours to use and/or abuse as you like. Any changes made inside -the container are limited to the container. - - -bastille cp ------------ -This sub-command allows efficiently copying files from host to container(s). - -```shell -ishmael ~ # bastille cp ALL /tmp/resolv.conf-cf etc/resolv.conf -[folsom]: -/tmp/resolv.conf-cf -> /usr/local/bastille/jails/folsom/root/etc/resolv.conf - -[nginx]: -/tmp/resolv.conf-cf -> /usr/local/bastille/jails/nginx/root/etc/resolv.conf - -[squid]: -/tmp/resolv.conf-cf -> /usr/local/bastille/jails/squid/root/etc/resolv.conf - -[unbound0]: -/tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound0/root/etc/resolv.conf -``` - -bastille rdr ------------- - -`bastille rdr` allows you to configure dynamic rdr rules for your containers -without modifying pf.conf (assuming you are using the `bastille0` interface -for a private network and have enabled `rdr-anchor 'rdr/*'` in /etc/pf.conf -as described in the Networking section). - -```shell - # bastille rdr help - Usage: bastille rdr TARGET [clear] | [list] | [tcp ] | [udp ] - # bastille rdr dev1 tcp 2001 22 - # bastille rdr dev1 list - rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 - # bastille rdr dev1 udp 2053 53 - # bastille rdr dev1 list - rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 - rdr on em0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53 - # bastille rdr dev1 clear - nat cleared -``` - -bastille update ---------------- -The `update` command targets a release instead of a container. Because every -container is based on a release, when the release is updated all the containers -are automatically updated as well. - -To update all containers based on the 11.4-RELEASE `release`: - -Up to date 11.4-RELEASE: -```shell -ishmael ~ # bastille update 11.4-RELEASE -Targeting specified release. -11.4-RELEASE - -Looking up update.FreeBSD.org mirrors... 2 mirrors found. -Fetching metadata signature for 11.4-RELEASE from update4.freebsd.org... done. -Fetching metadata index... done. -Inspecting system... done. -Preparing to download files... done. - -No updates needed to update system to 11.4-RELEASE-p4. -No updates are available to install. -``` - -To be safe, you may want to restart any containers that have been updated live. - - -bastille upgrade ----------------- -This sub-command lets you upgrade a release to a new release. Depending on the -workflow this can be similar to a `bootstrap`. - -For standard containers you need to upgrade the shared base jail: -```shell -ishmael ~ # bastille upgrade 12.1-RELEASE 12.2-RELEASE -... -``` - -For thick jails you need to upgrade every single container (according the freebsd-update procedure): -```shell -ishmael ~ # bastille upgrade folsom 12.2-RELEASE -ishmael ~ # bastille upgrade folsom install -... -ishmael ~ # bastille restart folsom -ishmael ~ # bastille upgrade folsom install -``` - - -bastille verify ---------------- -This sub-command scans a bootstrapped release and validates that everything -looks in order. This is not a 100% comprehensive check, but it compares the -release against a "known good" index. - -If you see errors or issues here, consider deleting and re-bootstrapping the -release. - -It should be noted that releases bootstrapped through Bastille are validated -using `sha256` checksum against the release manifest. Archives that fail -validation are not used. - - -bastille zfs ------------- -This sub-command allows managing ZFS attributes for the targeted container(s). -Common usage includes setting container quotas. - -**set quota** -```shell -ishmael ~ # bastille zfs folsom set quota=1G -``` - -**built-in: df** -```shell -ishmael ~ # bastille zfs ALL df -``` - -**built-in: df** -```shell -ishmael ~ # bastille zfs folsom df -``` - -bastille export ----------------- -Containers can be exported for archiving purposes easily. -Note: On UFS systems containers must be stopped before export. - -```shell -ishmael ~ # bastille export folsom -Exporting 'folsom' to a compressed .xz archive. -Sending ZFS data stream... - 100 % 1057.2 KiB / 9231.5 KiB = 0.115 0:01 -Exported '/usr/local/bastille/jails/backups/folsom_2020-01-26-19:23:04.xz' successfully. - -``` - -bastille import ----------------- -Containers can be imported from supported archives easily. - -```shell -ishmael ~ # bastille import folsom_2020-01-26-19:22:23.xz -Validating file: folsom_2020-01-26-19:22:23.xz... -File validation successful! -Importing 'folsom' from compressed .xz archive. -Receiving ZFS data stream... -/usr/local/bastille/jails/backups/folsom_2020-01-26-19:22:23.xz (1/1) - 100 % 626.4 KiB / 9231.5 KiB = 0.068 0:02 -Container 'folsom' imported successfully. -``` - -bastille clone ---------------- -`bastille clone` will duplicate an existing container. -Please be aware that no host specific keys or hashes will be regenerated. -E. g. remove OpenSSH host keys to avoid duplicate host keys `rm /etc/ssh/ssh_host_*` - -Usage: `bastille clone [TARGET] [NEWJAIL] [NEW_IPADRRESS]` - -```shell -ishmael ~ # bastille clone sourcejail targetjail 10.17.89.11 -``` - -bastille mount ---------------- -`bastille mount` will nullfs mount a path from the host inside the container. -Uses the same format as an fstab entry. -Filesystem type, options, dump, and pass number are optional and default to: nullfs ro 0 0 - -Usage: `bastille mount [TARGET] [HOST_PATH] [CONTAINER_PATH] [FILESYSTEM_TYPE] [OPTIONS] [DUMP] [PASS_NUMBER]` - -```shell -ishmael ~ # bastille mount targetjail /host/path container/path -[targetjail]: -Added: /host/path container/path nullfs ro 0 0 -``` - -bastille umount ---------------- -`bastille umount` will unmount a volume from inside the container. - -Usage: `bastille umount [TARGET] [CONTAINER_PATH]` - -```shell -ishmael ~ # bastille umount targetjail container/path -[targetjail]: -Unmounted: container/path -``` - Example (create, start, console) ================================ This example creates, starts and consoles into the container. ```shell -ishmael ~ # bastille create alcatraz 11.4-RELEASE 10.17.89.7 +ishmael ~ # bastille create alcatraz 14.0-RELEASE 10.17.89.10/24 ``` ```shell @@ -1087,7 +144,7 @@ alcatraz: created ```shell ishmael ~ # bastille console alcatraz [alcatraz]: -FreeBSD 11.4-RELEASE-p4 (GENERIC) #0: Thu Sep 27 08:16:24 UTC 2018 +FreeBSD 14.0-RELEASE GENERIC Welcome to FreeBSD! @@ -1095,7 +152,7 @@ Release Notes, Errata: https://www.FreeBSD.org/releases/ Security Advisories: https://www.FreeBSD.org/security/ FreeBSD Handbook: https://www.FreeBSD.org/handbook/ FreeBSD FAQ: https://www.FreeBSD.org/faq/ -Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/ +Questions List: https://www.FreeBSD.org/lists/questions/ FreeBSD Forums: https://forums.FreeBSD.org/ Documents installed with the system are in the /usr/local/share/doc/freebsd/ @@ -1107,7 +164,7 @@ Please include that output and any error messages when posting questions. Introduction to manual pages: man man FreeBSD directory layout: man hier -Edit /etc/motd to change this login announcement. +To change this login announcement, see motd(5). root@alcatraz:~ # ``` @@ -1122,62 +179,6 @@ root 92565 0.0 0.0 7412 3756 3 SJ 02:21 0:00.01 -csh (csh) root@alcatraz:~ # ``` - -Project Goals -============= -These tools are created initially with the mindset of function over form. I -want to simply prove the concept is sound for real work. The real work is a -sort of meta-container-port system. Instead of installing the MySQL port -directly on a system, you would use Bastille to install the MySQL port within a -container template built for MySQL. The same goes for DNS servers, and -everything else in the ports tree. - -Eventually I would like to have Bastille templates created for popular -FreeBSD-based services. From Plex Media Servers to ad-blocking DNS resolvers. -From tiny SSH containers to dynamic web servers. [COMPLETE] - -I don't want to tell you what you can and can't run within this framework. -There are no arbitrary limitations based on what I think may or may not be the -best way to design systems. This is not my goal. - -My goal is to provide a secure framework where processes and services can run -isolated. I want to limit the scope and reach of bad actors. I want to severely -limit the target areas available to anyone that has (or has gained) access. - -Networking Tips -=============== - -Tip #1: -------- -Ports and destinations can be defined as lists. eg; -``` -rdr pass inet proto tcp from any to any port {80, 443} -> {10.17.89.45, 10.17.89.46, 10.17.89.47, 10.17.89.48} -``` - -This rule would redirect any traffic to the host on ports 80 or 443 and -round-robin between containers with ips 45, 46, 47, and 48 (on ports 80 or -443). - - -Tip #2: -------- -Ports can redirect to other ports. eg; -``` -rdr pass inet proto tcp from any to any port 8080 -> 10.17.89.5 port 80 -rdr pass inet proto tcp from any to any port 8081 -> 10.17.89.5 port 8080 -rdr pass inet proto tcp from any to any port 8181 -> 10.17.89.5 port 443 -``` - -Tip #3: -------- -Don't worry too much about IP assignments. - -Initially I spent time worrying about what IP addresses to assign. In the end -I've come to the conclusion that it _really_ doesn't matter. Pick *any* private -address and be done with it. These are all isolated networks. In the end, what -matters is you can map host:port to container:port reliably, and we can. - - Community Support ================= If you've found a bug in Bastille, please submit it to the [Bastille Issue diff --git a/docs/chapters/gcp.rst b/docs/chapters/gcp.rst index 0eac5565c..b049337b1 100644 --- a/docs/chapters/gcp.rst +++ b/docs/chapters/gcp.rst @@ -90,4 +90,4 @@ Set the default network gateway for new jails as described in the Networking cha echo "nameserver 8.8.8.8" > /usr/local/etc/bastille/resolv.conf sysrc -f /usr/local/etc/bastille/bastille.conf bastille_resolv_conf="/usr/local/etc/bastille/resolv.conf" -You can now create a VNET jail with ``bastille create -V myjail 13.1-RELEASE 192.168.1.50/24 vtnet0`` +You can now create a VNET jail with ``bastille create -V myjail 13.2-RELEASE 192.168.1.50/24 vtnet0`` diff --git a/docs/chapters/installation.rst b/docs/chapters/installation.rst index cd66cea5a..95e648b83 100644 --- a/docs/chapters/installation.rst +++ b/docs/chapters/installation.rst @@ -4,7 +4,7 @@ Bastille is available in the official FreeBSD ports tree at `sysutils/bastille`. Binary packages available in `quarterly` and `latest` repositories. -Current version is `0.9.20220714`. +Current version is `0.10.20231125`. To install from the FreeBSD package repository: @@ -18,6 +18,8 @@ PKG .. code-block:: shell pkg install bastille + sysrc bastille_enable=YES + sysrc bastille_rcorder=YES To install from source (don't worry, no compiling): @@ -28,6 +30,8 @@ ports .. code-block:: shell make -C /usr/ports/sysutils/bastille install clean + sysrc bastille_enable=YES + sysrc bastille_rcorder=YES GIT @@ -38,7 +42,14 @@ GIT git clone https://github.com/BastilleBSD/bastille.git cd bastille make install + sysrc bastille_enable=YES + sysrc bastille_rcorder=YES This method will install the latest files from GitHub directly onto your system. It is verbose about the files it installs (for later removal), and also -has a `make uninstall` target. +has a `make uninstall` target. You may need to manually copy the `.sample` +config into place before Bastille will run. (ie; +`/usr/local/etc/bastille/bastille.conf.sample`) + +Note: installing using this method overwrites the version variable to match +that of the source revision commit hash. diff --git a/docs/chapters/migration.rst b/docs/chapters/migration.rst new file mode 100644 index 000000000..f297558b9 --- /dev/null +++ b/docs/chapters/migration.rst @@ -0,0 +1,36 @@ +Stop the running jail and export it: + +.. code-block:: shell + + iocage stop jailname + iocage export jailname + +Move the backup files (.zip and .sha256) into Bastille backup dir (default: /usr/local/bastille/backups/): + +.. code-block:: shell + + mv /iocage/images/jailname_$(date +%F).* /usr/local/bastille/backups/ + +for remote systems you could use rsync: + +.. code-block:: shell + + rsync -avh /iocage/images/jailname_$(date +%F).* root@10.0.1.10:/usr/local/bastille/backups/ + + +Import the iocage backup file (use zip file name) + +.. code-block:: shell + + bastille import jailname_$(date +%F).zip + +Set your new ip address and interface: + +.. code-block:: shell + + vim /usr/local/bastille/jails/jailname/jail.conf + interface = bastille0; + ip4.addr = "192.168.0.1"; + + +You can use you primary network interface instead of the virtual bastille0 interface as well if you know what you’re doing. diff --git a/docs/chapters/networking.rst b/docs/chapters/networking.rst index 55d7cab4d..d94bf27d7 100644 --- a/docs/chapters/networking.rst +++ b/docs/chapters/networking.rst @@ -3,37 +3,40 @@ Network Requirements Here's the scenario. You've installed Bastille at home or in the cloud and want to get started putting applications in secure little containers, but how do you get these containers on the network? Bastille tries to be flexible about how to -network containerized applications. Four methods are described here. +network containerized applications. Four methods are described here. 1. Home or Small Office 2. Cloud with IPV4 and multiple IPV6 -3. Could with single IPV4 (internatl bridge) +3. Cloud with single IPV4 (internal bridge) -4. Cloud with a single IPV4 (external bridge) +4. Cloud with a single IPV4 (external bridge) +Please choose the option which is most appropriate for your environment. -Please choose the option which is most appropriate for your environment. - - -First a few notes. Bastille tries to verify that the interface name you provide is a valid -interface. In FreeBSD network interfaces have different names, but look something like -`em0`, `bge0`, `re0`, `vtnet0` etc. Running the ifconfig commend will tell you the name -of your existing interfaces. Bastille also checks for a valid syntax IP4 or IP6 address. -When you are testing calling out from your containers, please note that the ping command is disabled within the containers, because raw socket access are a security hole. Instead I install and test with wget instead. +First a few notes. Bastille tries to verify that the interface name you provide +is a valid interface. In FreeBSD network interfaces have different names, but +look something like `em0`, `bge0`, `re0`, `vtnet0` etc. Running the ifconfig +commend will tell you the name of your existing interfaces. Bastille also +checks for a valid syntax IP4 or IP6 address. When you are testing calling out +from your containers, please note that the ping command is disabled within the +containers, because raw socket access are a security hole. Instead, install and +test with `wget`/`curl`/`fetch` instead. Shared Interface on Home or Small Office Network ================================================ -If you have just one computer, or a home or small office network, -where you are separated from the rest of the internet by a router. So you are free to use -`private IP addresses `. +If you have just one computer, or a home or small office network, where you are +separated from the rest of the internet by a router. So you are free to use +`private IP addresses +`_. -In this environment, to use Bastille, just create the container, give it a unique private ip address, and attach its ip address to your primary interface. +In this environment, to use Bastille, just create the container, give it a +unique private ip address, and attach its ip address to your primary interface. .. code-block:: shell - bastille create alcatraz 13.1-RELEASE 192.168.1.50 em0 + bastille create alcatraz 13.2-RELEASE 192.168.1.50 em0 You may have to change em0 @@ -46,50 +49,54 @@ This method is the simplest. All you need to know is the name of your network interface and a free IP on your local network. Shared Interface on IPV6 network (vultr.com) -======================================= -Some ISP's, such as `vultr.com `, give you a single ipv4 address, and a large block of ipv6 addresses. You can then assign a unique ipv6 address to each Bastille Container. +============================================ +Some ISP's, such as `Vultr `_, give you a single ipv4 address, +and a large block of ipv6 addresses. You can then assign a unique ipv6 address +to each Bastille Container. -On a virtual machine such as vultr.com the virtual interface may be `vtnet0`. +On a virtual machine such as vultr.com the virtual interface may be `vtnet0`. So we issue the command: .. code-block:: shell - bastille create alcatraz 13.1-RELEASE 2001:19f0:6c01:114c::100 vtnet0 + bastille create alcatraz 13.2-RELEASE 2001:19f0:6c01:114c::100 vtnet0 -We could also write the ipv6 address as 2001:19f0:6c01:114c:0:100 +We could also write the ipv6 address as 2001:19f0:6c01:114c:0:100 -The tricky part are the ipv6 addresses. IPV6 is a string of 8 4 digit +The tricky part are the ipv6 addresses. IPV6 is a string of 8 4 digit hexadecimal characters. At vultr they said: Your server was assigned the following six section subnet: 2001:19f0:6c01:114c:: / 64 -The `vultr ipv6 subnet calculator ` is helpful in making sense of that ipv6 address. +The `vultr ipv6 subnet calculator +`_ +is helpful in making sense of that ipv6 address. We could have also written that IPV6 address as 2001:19f0:6c01:114c:0:0 -Where the /64 basicaly means that the first 64 bits of the address (4x4 character hexadecimal) values define the network, and the remaining characters, we can assign as we want to the Bastille Container. In the actual bastille create command given above, it was defined to be 100. But we also have to tell the host operating system that we are now using this address. This is done on freebsd with the following command +Where the /64 basicaly means that the first 64 bits of the address (4x4 +character hexadecimal) values define the network, and the remaining characters, +we can assign as we want to the Bastille Container. In the actual bastille +create command given above, it was defined to be 100. But we also have to tell +the host operating system that we are now using this address. This is done on +freebsd with the following command .. code-block:: shell - ifconfig_vtnet0_alias0="inet6 2001:19f0:6c01:114c::100 prefixlen 64" - -At that point your container can talk to the world, and the world can ping your container. Of course when you reboot the machine, that command will be forgotten To make it permanent, -you have to add it to the file /etc/rc.conf - -Just remember you cannot ping out from the container. Instead I installed and used wget to test the connectivity. + ifconfig_vtnet0_alias0="inet6 2001:19f0:6c01:114c::100 prefixlen 64" -Use the bastille pkg command to install wget. - -.. code-block:: shell - - bastille pkg alcatraz install wget +At that point your container can talk to the world, and the world can ping your +container. Of course when you reboot the machine, that command will be +forgotten. To make it permanent, prefix the same command with `sysrc` +Just remember you cannot ping out from the container. Instead, install and +use `wget`/`curl`/`fetch` to test the connectivity. Virtual Network (VNET) -======================== +====================== (Added in 0.6.x) VNET is supported on FreeBSD 12+ only. Virtual Network (VNET) creates a private network interface for a container. @@ -101,12 +108,12 @@ external interface. .. code-block:: shell - bastille create -V azkaban 13.1-RELEASE 192.168.1.50/24 em0 + bastille create -V azkaban 13.2-RELEASE 192.168.1.50/24 em0 Bastille will automagically create the bridge interface and connect / disconnect containers as they are started and stopped. A new interface will be created on the host matching the pattern `interface0bridge`. In the example -here, `em0bridge`. +here, `em0bridge`. The `em0` interface will be attached to the bridge along with the unique container interfaces as they are started and stopped. These interface names @@ -121,6 +128,11 @@ host system: ## /etc/devfs.rules (NOT .conf) [bastille_vnet=13] + add include $devfsrules_hide_all + add include $devfsrules_unhide_basic + add include $devfsrules_unhide_login + add include $devfsrules_jail + add include $devfsrules_jail_vnet add path 'bpf*' unhide Lastly, you may want to consider these three `sysctl` values: @@ -131,12 +143,29 @@ Lastly, you may want to consider these three `sysctl` values: net.link.bridge.pfil_onlyip=0 net.link.bridge.pfil_member=0 +Below is the definition of what these three parameters are used for and mean: + + + net.link.bridge.pfil_onlyip Controls the handling of non-IP packets + which are not passed to pfil(9). Set to 1 + to only allow IP packets to pass (subject + to firewall rules), set to 0 to uncondi- + tionally pass all non-IP Ethernet frames. + + net.link.bridge.pfil_member Set to 1 to enable filtering on the incom- + ing and outgoing member interfaces, set to + 0 to disable it. + + net.link.bridge.pfil_bridge Set to 1 to enable filtering on the bridge + interface, set to 0 to disable it. + + **Regarding Routes** Bastille will attempt to auto-detect the default route from the host system and assign it to the VNET container. This auto-detection may not always be accurate -for your needs for the particular container. In this case you'll need to add -a default route manually or define the preferred default route in the +for your needs for the particular container. In this case you'll need to add a +default route manually or define the preferred default route in the `bastille.conf`. .. code-block:: shell @@ -155,23 +184,23 @@ This config change will apply the defined gateway to any new containers. Existing containers will need to be manually updated. Virtual Network (VNET) on External Bridge -======================================= -To create a VNET based container and attach it to an external, already existing bridge, use the `-B` option, an IP/netmask and -external bridge. +========================================= +To create a VNET based container and attach it to an external, already existing +bridge, use the `-B` option, an IP/netmask and external bridge. .. code-block:: shell - bastille create -B azkaban 13.1-RELEASE 192.168.1.50/24 bridge0 + bastille create -B azkaban 13.2-RELEASE 192.168.1.50/24 bridge0 -Bastille will automagically create the interface, attach it to the specified bridge and connect / -disconnect containers as they are started and stopped. +Bastille will automagically create the interface, attach it to the specified +bridge and connect / disconnect containers as they are started and stopped. The bridge needs to be created/enabled before creating and starting the jail. Public Network ============== In this section we describe how to network containers in a public network such as a cloud hosting provider who only provides you with a single ip address. -(AWS, digital ocean, etc) (The exception is vultr.com, which does +(AWS, Digital Ocean, etc) (The exception is vultr.com, which does provide you with lots of IPV6 addresses and does a great job supporting FreeBSD!) So if you only have a single IP address and if you want to create multiple @@ -239,7 +268,7 @@ to containers are: .. code-block:: shell - nat on $ext_if from to any -> ($ext_if) + nat on $ext_if from to any -> ($ext_if:0) The `nat` routes traffic from the loopback interface to the external interface for outbound access. @@ -253,16 +282,18 @@ The `rdr-anchor "rdr/*"` enables dynamic rdr rules to be setup using the .. code-block:: shell - bastille rdr tcp 2001 22 # Redirects tcp port 2001 on host to 22 on jail - bastille rdr udp 2053 53 # Same for udp - bastille rdr list # List dynamic rdr rules - bastille rdr clear # Clear dynamic rdr rules + bastille rdr TARGET tcp 2001 22 # Redirects tcp port 2001 on host to 22 on jail + bastille rdr TARGET udp 2053 53 # Same for udp + bastille rdr TARGET list # List dynamic rdr rules + bastille rdr TARGET clear # Clear dynamic rdr rules Note that if you are redirecting ports where the host is also listening (eg. ssh) you should make sure that the host service is not listening on the cloned interface - eg. for ssh set sshd_flags in rc.conf - sshd_flags="-o ListenAddress=" +.. code-block:: shell + + sshd_flags="-o ListenAddress=" Finally, start up the firewall: diff --git a/docs/chapters/subcommands/bootstrap.rst b/docs/chapters/subcommands/bootstrap.rst index eaa02f5de..4af05dd6f 100644 --- a/docs/chapters/subcommands/bootstrap.rst +++ b/docs/chapters/subcommands/bootstrap.rst @@ -27,8 +27,8 @@ release version as the argument. .. code-block:: shell - ishmael ~ # bastille bootstrap 12.3-RELEASE [update] - ishmael ~ # bastille bootstrap 13.1-RELEASE + ishmael ~ # bastille bootstrap 14.0-RELEASE [update] + ishmael ~ # bastille bootstrap 13.2-RELEASE [update] To `bootstrap` a HardenedBSD release, run the bootstrap sub-command with the build version as the argument. @@ -43,6 +43,21 @@ download the requested release. For each requested release, `bootstrap` will download the base.txz. These files are verified (sha256 via MANIFEST file) before they are extracted for use. +EOL Releases +------------ + +It is sometimes necessary to run end-of-life releases for testing or legacy +application support. Dy default Bastille will only install supported releases +but you can bootstrap EOL / unsupported releases with a simple trick. + +.. code-block:: shell + + ishmael ~ # export BASTILLE_URL_FREEBSD=http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/ + ishmael ~ # bastille bootstrap 11.2-RELEASE + +By overriding the BASTILLE_URL_FREEBSD variable you can now bootstrap archived +releases from the FTP archive. + Tips ---- diff --git a/docs/chapters/subcommands/create.rst b/docs/chapters/subcommands/create.rst index eb9a96771..fd3b9c5de 100644 --- a/docs/chapters/subcommands/create.rst +++ b/docs/chapters/subcommands/create.rst @@ -22,6 +22,15 @@ bootstrapped release and a private (rfc1918) IP address. This command will create a 11.3-RELEASE container assigning the 10.17.89.10 ip address to the new system. +.. 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. + + I recommend using private (rfc1918) ip address ranges for your container. These ranges include: @@ -31,3 +40,13 @@ ranges include: Bastille does its best to validate the submitted ip is valid. This has not been 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 host +system. This caused confusion for some users, so we implemented the .hushlogin which +silences the MOTD at login. + +Also, uname does not work from within a jail. Much like MOTD, it gives you the 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. + diff --git a/docs/chapters/subcommands/index.rst b/docs/chapters/subcommands/index.rst index 09d233450..5f860768e 100644 --- a/docs/chapters/subcommands/index.rst +++ b/docs/chapters/subcommands/index.rst @@ -23,9 +23,11 @@ Bastille sub-commands rename restart service + setup start stop sysrc + tags top umount update diff --git a/docs/chapters/subcommands/pkg.rst b/docs/chapters/subcommands/pkg.rst index 3ab1e328e..7b4757d5a 100644 --- a/docs/chapters/subcommands/pkg.rst +++ b/docs/chapters/subcommands/pkg.rst @@ -10,31 +10,7 @@ To manage binary packages within the container use `bastille pkg`. [folsom]: The package management tool is not yet installed on your system. Do you want to fetch and install it now? [y/N]: y - Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:10:amd64/quarterly, please wait... - Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done - [folsom] Installing pkg-1.10.5_5... - [folsom] Extracting pkg-1.10.5_5: 100% - Updating FreeBSD repository catalogue... - pkg: Repository FreeBSD load error: access repo file(/var/db/pkg/repo-FreeBSD.sqlite) failed: No such file or directory - [folsom] Fetching meta.txz: 100% 944 B 0.9kB/s 00:01 - [folsom] Fetching packagesite.txz: 100% 6 MiB 3.4MB/s 00:02 - Processing entries: 100% - FreeBSD repository update completed. 32550 packages processed. - All repositories are up to date. - Updating database digests format: 100% - The following 10 package(s) will be affected (of 0 checked): - - New packages to be INSTALLED: - vim-console: 8.1.0342 - git-lite: 2.19.1 - zsh: 5.6.2 - expat: 2.2.6_1 - curl: 7.61.1 - libnghttp2: 1.33.0 - ca_root_nss: 3.40 - pcre: 8.42 - gettext-runtime: 0.19.8.1_1 - indexinfo: 0.3.1 + ...[snip]... Number of packages to be installed: 10 @@ -42,41 +18,7 @@ To manage binary packages within the container use `bastille pkg`. 17 MiB to be downloaded. Proceed with this action? [y/N]: y - [folsom] [1/10] Fetching vim-console-8.1.0342.txz: 100% 5 MiB 5.8MB/s 00:01 - [folsom] [2/10] Fetching git-lite-2.19.1.txz: 100% 4 MiB 2.1MB/s 00:02 - [folsom] [3/10] Fetching zsh-5.6.2.txz: 100% 4 MiB 4.4MB/s 00:01 - [folsom] [4/10] Fetching expat-2.2.6_1.txz: 100% 109 KiB 111.8kB/s 00:01 - [folsom] [5/10] Fetching curl-7.61.1.txz: 100% 1 MiB 1.2MB/s 00:01 - [folsom] [6/10] Fetching libnghttp2-1.33.0.txz: 100% 107 KiB 109.8kB/s 00:01 - [folsom] [7/10] Fetching ca_root_nss-3.40.txz: 100% 287 KiB 294.3kB/s 00:01 - [folsom] [8/10] Fetching pcre-8.42.txz: 100% 1 MiB 1.2MB/s 00:01 - [folsom] [9/10] Fetching gettext-runtime-0.19.8.1_1.txz: 100% 148 KiB 151.3kB/s 00:01 - [folsom] [10/10] Fetching indexinfo-0.3.1.txz: 100% 6 KiB 5.7kB/s 00:01 - Checking integrity... done (0 conflicting) - [folsom] [1/10] Installing libnghttp2-1.33.0... - [folsom] [1/10] Extracting libnghttp2-1.33.0: 100% - [folsom] [2/10] Installing ca_root_nss-3.40... - [folsom] [2/10] Extracting ca_root_nss-3.40: 100% - [folsom] [3/10] Installing indexinfo-0.3.1... - [folsom] [3/10] Extracting indexinfo-0.3.1: 100% - [folsom] [4/10] Installing expat-2.2.6_1... - [folsom] [4/10] Extracting expat-2.2.6_1: 100% - [folsom] [5/10] Installing curl-7.61.1... - [folsom] [5/10] Extracting curl-7.61.1: 100% - [folsom] [6/10] Installing pcre-8.42... - [folsom] [6/10] Extracting pcre-8.42: 100% - [folsom] [7/10] Installing gettext-runtime-0.19.8.1_1... - [folsom] [7/10] Extracting gettext-runtime-0.19.8.1_1: 100% - [folsom] [8/10] Installing vim-console-8.1.0342... - [folsom] [8/10] Extracting vim-console-8.1.0342: 100% - [folsom] [9/10] Installing git-lite-2.19.1... - ===> Creating groups. - Creating group 'git_daemon' with gid '964'. - ===> Creating users - Creating user 'git_daemon' with uid '964'. - [folsom] [9/10] Extracting git-lite-2.19.1: 100% - [folsom] [10/10] Installing zsh-5.6.2... - [folsom] [10/10] Extracting zsh-5.6.2: 100% + ...[snip]... The PKG sub-command can, of course, do more than just `install`. The @@ -146,7 +88,7 @@ expectation is that you can fully leverage the pkg manager. This means, The following 1 package(s) will be affected (of 0 checked): Installed packages to be UPGRADED: - nginx-lite: 1.14.0_14,2 -> 1.14.1,2 + nginx-lite: 1.23.0 -> 1.24.0_12,3 Number of packages to be upgraded: 1 @@ -155,10 +97,10 @@ expectation is that you can fully leverage the pkg manager. This means, Proceed with this action? [y/N]: y [nginx] [1/1] Fetching nginx-lite-1.14.1,2.txz: 100% 315 KiB 322.8kB/s 00:01 Checking integrity... done (0 conflicting) - [nginx] [1/1] Upgrading nginx-lite from 1.14.0_14,2 to 1.14.1,2... + [nginx] [1/1] Upgrading nginx-lite from 1.23.0 to 1.24.0_12,3... ===> Creating groups. Using existing group 'www'. ===> Creating users Using existing user 'www'. - [nginx] [1/1] Extracting nginx-lite-1.14.1,2: 100% + [nginx] [1/1] Extracting nginx-lite-1.24.0_12: 100% You may need to manually remove /usr/local/etc/nginx/nginx.conf if it is no longer needed. diff --git a/docs/chapters/subcommands/setup.rst b/docs/chapters/subcommands/setup.rst new file mode 100644 index 000000000..53d65e618 --- /dev/null +++ b/docs/chapters/subcommands/setup.rst @@ -0,0 +1,16 @@ +===== +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. + +.. code-block:: shell + + ishmael ~ # bastille setup -h ## display setup help + ishmael ~ # bastille setup bastille0 ## 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 diff --git a/docs/chapters/subcommands/tags.rst b/docs/chapters/subcommands/tags.rst new file mode 100644 index 000000000..b0ba10b3b --- /dev/null +++ b/docs/chapters/subcommands/tags.rst @@ -0,0 +1,13 @@ +==== +tags +==== + +The `tags` sub-command adds, removes or lists arbitrary tags on your containers. + +.. code-block:: shell + + ishmael ~ # bastille tags -h ## display tags help + ishmael ~ # bastille tags TARGET add tag1,tag2 ## add the tags "tag1" and "tag2" to TARGET + ishmael ~ # bastille tags TARGET delete tag2 ## delete tag "tag2" from TARGET + ishmael ~ # bastille tags TARGET list ## list tags assigned to TARGET + ishmael ~ # bastille tags ALL list ## list tags from ALL containers diff --git a/docs/chapters/subcommands/update.rst b/docs/chapters/subcommands/update.rst index c5a179cb5..4beef6557 100644 --- a/docs/chapters/subcommands/update.rst +++ b/docs/chapters/subcommands/update.rst @@ -10,14 +10,14 @@ If no updates are available, a message will be shown: .. code-block:: shell - ishmael ~ # bastille update 11.2-RELEASE + ishmael ~ # bastille update 11.4-RELEASE Looking up update.FreeBSD.org mirrors... 2 mirrors found. - Fetching metadata signature for 11.2-RELEASE from update4.freebsd.org... done. + Fetching metadata signature for 11.4-RELEASE from update4.freebsd.org... done. Fetching metadata index... done. Inspecting system... done. Preparing to download files... done. - No updates needed to update system to 11.2-RELEASE-p4. + No updates needed to update system to 11.4-RELEASE-p4. No updates are available to install. @@ -25,9 +25,9 @@ The older the release, however, the more updates will be available: .. code-block:: shell - ishmael ~ # bastille update 10.4-RELEASE + ishmael ~ # bastille update 13.2-RELEASE Looking up update.FreeBSD.org mirrors... 2 mirrors found. - Fetching metadata signature for 10.4-RELEASE from update1.freebsd.org... done. + Fetching metadata signature for 13.2-RELEASE from update1.freebsd.org... done. Fetching metadata index... done. Fetching 2 metadata patches.. done. Applying metadata patches... done. @@ -35,7 +35,7 @@ The older the release, however, the more updates will be available: Inspecting system... done. Preparing to download files... done. - The following files will be added as part of updating to 10.4-RELEASE-p13: + The following files will be added as part of updating to 13.2-RELEASE-p4: ...[snip]... To be safe, you may want to restart any containers that have been updated live. diff --git a/docs/chapters/subcommands/upgrade.rst b/docs/chapters/subcommands/upgrade.rst deleted file mode 100644 index f635a058d..000000000 --- a/docs/chapters/subcommands/upgrade.rst +++ /dev/null @@ -1,10 +0,0 @@ -======= -upgrade -======= - -This command lets you upgrade a release to a new release. Depending on the -workflow this can be similar to a `bootstrap`. - -.. code-block:: shell - - ishmael ~ # bastille upgrade 13.0-RELEASE 13.1-RELEASE diff --git a/docs/chapters/targeting.rst b/docs/chapters/targeting.rst index be04c38dd..a71331ce0 100644 --- a/docs/chapters/targeting.rst +++ b/docs/chapters/targeting.rst @@ -42,7 +42,7 @@ Examples: Containers +----+------+----+---+------------------+--------------+----------------------------------------------+ | cp | bastion03 | /tmp/resolv.conf-cf etc/resolv.conf | copy host-path to container-path in bastion03| +----+------+----+---+---------------------------------+----------------------------------------------+ -| create | folsom | 13.1-RELEASE 10.17.89.10 | create 13.1 container named `folsom` with IP | +| create | folsom | 13.2-RELEASE 10.17.89.10 | create 13.2 container named `folsom` with IP | +-----------+--------+---------------------------------+----------------------------------------------+ @@ -56,11 +56,9 @@ Examples: Releases +-----------+--------------+--------------+-------------------------------------------------------------+ | command | target | args | description | +===========+==============+==============+=============================================================+ -| bootstrap | 13.1-RELEASE | --- | bootstrap 13.1-RELEASE release | +| bootstrap | 13.2-RELEASE | --- | bootstrap 13.2-RELEASE release | +-----------+--------------+--------------+-------------------------------------------------------------+ -| update | 11.4-RELEASE | --- | update 11.4-RELEASE release | +| update | 12.4-RELEASE | --- | update 12.4-RELEASE release | +-----------+--------------+--------------+-------------------------------------------------------------+ -| upgrade | 11.3-RELEASE | 11.4-RELEASE | upgrade 11.3-RELEASE release to 11.4-RELEASE | -+-----------+--------------+--------------+-------------------------------------------------------------+ -| verify | 11.4-RELEASE | --- | verify 11.4-RELEASE release | +| verify | 12.4-RELEASE | --- | verify 12.4-RELEASE release | +-----------+--------------+--------------+-------------------------------------------------------------+ diff --git a/docs/chapters/template.rst b/docs/chapters/template.rst index 346920f69..463fccbf6 100644 --- a/docs/chapters/template.rst +++ b/docs/chapters/template.rst @@ -1,8 +1,7 @@ ======== Template ======== -Looking for ready made CI/CD validated [Bastille -Templates](https://gitlab.com/BastilleBSD-Templates)? +Looking for ready made CI/CD validated `Bastille Templates`_? Bastille supports a templating system allowing you to apply files, pkgs and execute commands inside the containers automatically. @@ -71,7 +70,7 @@ use, be sure to include `usr` in the template OVERLAY definition. eg; .. code-block:: shell - echo "CP usr" >> /usr/local/bastille/templates/username/template/Bastillefile + echo "CP usr /" >> /usr/local/bastille/templates/username/template/Bastillefile The above example "usr" will include anything under "usr" inside the template. You do not need to list individual files. Just include the top-level directory @@ -139,3 +138,38 @@ directory names in the `bastille/templates` directory. Executing final command(s). chsh: user information updated Template Complete. + +.. _Bastille Templates: https://gitlab.com/BastilleBSD-Templates + +Using Ports in Templates +------------------------ + +Sometimes when you make a template you need special options for a package, or you need a newer version than what is in the pkgs. The solution for these cases, or a case like minecraft server that has NO compiled option, is to use the ports. A working example of this is the minecraft server template in the template repo. The main lines needed to use this is first to mount the ports directory, then compile the port. Below is an example of the minecraft template where this was used. + +.. code-block:: shell + + ARG MINECRAFT_MEMX="1024M" + ARG MINECRAFT_MEMS="1024M" + ARG MINECRAFT_ARGS="" + CONFIG set enforce_statfs=1; + CONFIG set allow.mount.fdescfs; + CONFIG set allow.mount.procfs; + RESTART + PKG dialog4ports tmux openjdk17 + MOUNT /usr/ports usr/ports nullfs ro 0 0 + CP etc / + CP var / + CMD make -C /usr/ports/games/minecraft-server install clean + CP usr / + SYSRC minecraft_enable=YES + SYSRC minecraft_memx=${MINECRAFT_MEMX} + SYSRC minecraft_mems=${MINECRAFT_MEMS} + SYSRC minecraft_args=${MINECRAFT_ARGS} + SERVICE minecraft restart + RDR tcp 25565 25565 + +The MOUNT line mounts the ports directory, then the CMD make line makes the port. This can be modified to use any port in the port tree. + + + + diff --git a/docs/chapters/upgrading.rst b/docs/chapters/upgrading.rst new file mode 100644 index 000000000..719f6103d --- /dev/null +++ b/docs/chapters/upgrading.rst @@ -0,0 +1,41 @@ +========= +Upgrading +========= +This document outlines upgrading jails hosted using Bastille. + +Bastille can "bootstrap" multiple versions of FreeBSD to be used by jails. All jails do not NEED to be the same version (even if they often are), the only requirement here is that the "bootstrapped" versions are less than or equal to the host version of FreeBSD. + +To upgrade Bastille jails for a minor release (ie; 13.1→13.2) you can do the following: + +1. ensure the new release version is bootstrapped and updated to the latest patch release: `bastille bootstrap 13.2-RELEASE update` +2. stop the jail(s) that need to be updated. +3. use `bastille edit TARGET fstab` to manually update the jail mounts from 13.1 to 13.2 release path. +4. start the jail(s) that were edited +5. upgrade complete! + +To upgrade Bastille jails for a major release (ie; 12.4→13.2) you can do the following: + +1. ensure the new version is bootstrapped and update to the latest patch release: `bastille bootstrap 13.2-RELEASE update` +2. stop the jail(s) that need to be updated. +3. use `bastille edit TARGET fstab` to manually update the jail mounts from 12.4 to 13.2 release path. +4. start the jail(s) that were edited +5. Force the reinstallation or upgrade of all installed packages (ABI change): `pkg upgrade -f` within each jail (or `bastille pkg ALL upgrade -f`) +6. restart the affected jail(s) +7. upgrade complete! + +Revert Upgrade / Downgrade Process +---------------------------------- +The downgrade process (not usually needed) is similar to the upgrade process only in reverse. + +If you did a minor upgrade changing the release path from 13.1 to 13.2, stop the jail and revert that change. Downgrade complete. + +If you did a major upgrade changing the release path from 12.4 to 13.2, stop the jail and revert that change. The pkg reinstallation will also need to be repeated after the jail restarts on the previous release. + +Old Releases +---------------------------------- +After upgrading all jails from one release to the next you may find that you now have bootstrapped a release that is no longer used. Once you've decided that you no longer need the option to revert the change you can destroy the old release. + + +`bastille list releases` to list all bootstrapped releases. + +`bastille destroy X.Y-RELEASE` to fully delete the release. diff --git a/docs/conf.py b/docs/conf.py index d8f5a043e..b9eab6caf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,13 +8,13 @@ # -- Project information ----------------------------------------------------- project = 'Bastille' -copyright = '2018-2022, Christer Edwards' +copyright = '2018-2023, Christer Edwards' author = 'Christer Edwards' # The short X.Y version -version = '0.9.20220714' +version = '0.10.20231125' # The full version, including alpha/beta/rc tags -release = '0.9.20220714-beta' +release = '0.10.20231125-beta' # -- General configuration --------------------------------------------------- @@ -26,10 +26,10 @@ source_suffix = ['.rst', '.md'] -from recommonmark.parser import CommonMarkParser -source_parsers = { - '.md': CommonMarkParser, -} +#from recommonmark.parser import CommonMarkParser +#source_parsers = { +# '.md': CommonMarkParser, +#} master_doc = 'index' language = None diff --git a/docs/index.rst b/docs/index.rst index 37f8271dd..ca300cd0f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,14 +12,17 @@ https://docs.bastillebsd.org. :caption: Contents: chapters/installation + chapters/upgrading chapters/networking chapters/usage chapters/targeting + chapters/upgrading chapters/subcommands/index chapters/template chapters/jail-config chapters/zfs-support chapters/gcp + chapters/migration copyright diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 71b06abac..0354df8d6 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -73,7 +73,7 @@ bastille_perms_check() { bastille_perms_check ## version -BASTILLE_VERSION=2a6c8d4dc2f3a43b6821608a1dfad2042fb278f2 +BASTILLE_VERSION=9784ccd50c6472afd53c96714b965e0da7ed70ea usage() { cat << EOF diff --git a/usr/local/bin/bastille.orig b/usr/local/bin/bastille.orig index 71b06abac..0354df8d6 100755 --- a/usr/local/bin/bastille.orig +++ b/usr/local/bin/bastille.orig @@ -73,7 +73,7 @@ bastille_perms_check() { bastille_perms_check ## version -BASTILLE_VERSION=2a6c8d4dc2f3a43b6821608a1dfad2042fb278f2 +BASTILLE_VERSION=9784ccd50c6472afd53c96714b965e0da7ed70ea usage() { cat << EOF diff --git a/usr/local/etc/bastille/bastille.conf.sample b/usr/local/etc/bastille/bastille.conf.sample index 4e812e7fe..d7ccc755a 100644 --- a/usr/local/etc/bastille/bastille.conf.sample +++ b/usr/local/etc/bastille/bastille.conf.sample @@ -11,6 +11,9 @@ bastille_releasesdir="${bastille_prefix}/releases" ## default bastille_templatesdir="${bastille_prefix}/templates" ## default: "${bastille_prefix}/templates" bastille_logsdir="/var/log/bastille" ## default: "/var/log/bastille" +## pf configuration path +bastille_pf_conf="/etc/pf.conf" ## default: "/etc/pf.conf" + ## bastille scripts directory (assumed by bastille pkg) bastille_sharedir="/usr/local/share/bastille" ## default: "/usr/local/share/bastille" @@ -32,7 +35,7 @@ bastille_resolv_conf="/etc/resolv.conf" ## default ## bootstrap urls bastille_url_freebsd="http://ftp.freebsd.org/pub/FreeBSD/releases/" ## default: "http://ftp.freebsd.org/pub/FreeBSD/releases/" -bastille_url_hardenedbsd="http://installer.hardenedbsd.org/pub/hardenedbsd/" ## default: "https://installer.hardenedbsd.org/pub/HardenedBSD/releases/" +bastille_url_hardenedbsd="https://installers.hardenedbsd.org/pub/" ## default: "https://installer.hardenedbsd.org/pub/HardenedBSD/releases/" bastille_url_midnightbsd="https://www.midnightbsd.org/ftp/MidnightBSD/releases/" ## default: "https://www.midnightbsd.org/pub/MidnightBSD/releases/" ## ZFS options @@ -46,6 +49,7 @@ bastille_compress_xz_options="-0 -v" ## default bastille_decompress_xz_options="-c -d -v" ## default "-c -d -v" bastille_compress_gz_options="-1 -v" ## default "-1 -v" bastille_decompress_gz_options="-k -d -c -v" ## default "-k -d -c -v" +bastille_export_options="" ## default "" predefined export options, e.g. "--safe --gz" ## Networking bastille_network_loopback="bastille0" ## default: "bastille0" diff --git a/usr/local/etc/rc.d/bastille b/usr/local/etc/rc.d/bastille index 84edfb282..beaa5a719 100755 --- a/usr/local/etc/rc.d/bastille +++ b/usr/local/etc/rc.d/bastille @@ -8,10 +8,19 @@ # Add the following to /etc/rc.conf[.local] to enable this service # -# bastille_enable (bool): Set to NO by default. -# Set it to YES to enable bastille. -# bastille_list (string): Set to "ALL" by default. -# Space separated list of jails to start. +# bastille_enable (bool): Set to "NO" by default. +# Set it to "YES" to enable bastille. +# bastille_conf (bool): Set to "/usr/local/etc/bastille/bastille.conf" by default. +# Path to bastile.conf file. Used if bastille_rcorder="YES". +# bastille_list (string): Set to "ALL" by default. +# Space separated list of jails to start or "ALL" to start all +# jails. +# bastille_rcorder (bool): Set to "NO" by default. +# Set it to "YES" to start all jails in order, defined by +# rcorder(8). It starts all jails, except jails with "KEYWORD: +# nostart" in jail.conf. Value of bastille_list is ignored in this +# case, requires correct path to bastile.conf in bastille_conf +# var. # . /etc/rc.subr @@ -19,24 +28,36 @@ name=bastille rcvar=${name}_enable -: ${bastille_enable:=NO} +: ${bastille_enable:="NO"} +: ${bastille_conf:="/usr/local/etc/bastille/bastille.conf"} : ${bastille_list:="ALL"} +: ${bastille_rcorder:="NO"} command=/usr/local/bin/${name} start_cmd="bastille_start" stop_cmd="bastille_stop" restart_cmd="bastille_stop && bastille_start" +rcordered_list() { + local _jailsdir + _jailsdir=$(. $bastille_conf; echo $bastille_jailsdir) + bastille_ordered_list=$(rcorder -s nostart ${_jailsdir}/*/jail.conf | xargs dirname | xargs basename | tr "\n" " ") +} + bastille_start() { - if [ -z "${bastille_list}" ]; then + local _jail + + if checkyesno bastille_rcorder; then + rcordered_list + elif [ -z "${bastille_list}" ]; then echo "bastille_list is undefined" return 1 + else + bastille_ordered_list=${bastille_list} fi - local _jail - - for _jail in ${bastille_list}; do + for _jail in ${bastille_ordered_list}; do echo "Starting Bastille Container: ${_jail}" ${command} start ${_jail} done @@ -44,16 +65,20 @@ bastille_start() bastille_stop() { - if [ -z "${bastille_list}" ]; then + local _jail _revlist + + if checkyesno bastille_rcorder; then + rcordered_list + elif [ -z "${bastille_list}" ]; then echo "bastille_list is undefined" return 1 + else + bastille_ordered_list=${bastille_list} fi - local _jail - ## reverse order of list for shutdown ## fixes #389 - bastille_revlist=$(echo "${bastille_list}" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }') - for _jail in ${bastille_revlist}; do + _revlist=$(echo "${bastille_ordered_list}" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }') + for _jail in ${_revlist}; do echo "Stopping Bastille Container: ${_jail}" ${command} stop ${_jail} done diff --git a/usr/local/man/man8/bastille.8.gz b/usr/local/man/man8/bastille.8.gz index cfe7efffa..8f40bcbfd 100644 Binary files a/usr/local/man/man8/bastille.8.gz and b/usr/local/man/man8/bastille.8.gz differ diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index 4a14ceafb..4c0d0a47a 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -42,8 +42,10 @@ help|-h|--help) ;; esac +bastille_root_check + #Validate if ZFS is enabled in rc.conf and bastille.conf. -if [ "$(sysrc -n zfs_enable)" = "YES" ] && [ ! "${bastille_zfs_enable}" = "YES" ]; then +if [ "$(sysrc -n zfs_enable)" = "YES" ] && ! checkyesno bastille_zfs_enable; then warn "ZFS is enabled in rc.conf but not bastille.conf. Do you want to continue? (N|y)" read answer case $answer in @@ -55,7 +57,7 @@ if [ "$(sysrc -n zfs_enable)" = "YES" ] && [ ! "${bastille_zfs_enable}" = "YES" fi # Validate ZFS parameters. -if [ "${bastille_zfs_enable}" = "YES" ]; then +if checkyesno bastille_zfs_enable; then ## check for the ZFS pool and bastille prefix if [ -z "${bastille_zfs_zpool}" ]; then error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_zpool." @@ -100,7 +102,7 @@ bootstrap_directories() { ## ${bastille_prefix} if [ ! -d "${bastille_prefix}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ];then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_prefix}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}" fi @@ -112,7 +114,7 @@ bootstrap_directories() { ## ${bastille_backupsdir} if [ ! -d "${bastille_backupsdir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ];then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_backupsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/backups" fi @@ -124,7 +126,7 @@ bootstrap_directories() { ## ${bastille_cachedir} if [ ! -d "${bastille_cachedir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache" # Don't create unused/stale cache/RELEASE directory on Linux jails creation. @@ -143,7 +145,7 @@ bootstrap_directories() { elif [ ! -d "${bastille_cachedir}/${RELEASE}" ]; then # Don't create unused/stale cache/RELEASE directory on Linux jails creation. if [ -z "${NOCACHEDIR}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}" fi @@ -155,7 +157,7 @@ bootstrap_directories() { ## ${bastille_jailsdir} if [ ! -d "${bastille_jailsdir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_jailsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails" fi @@ -166,7 +168,7 @@ bootstrap_directories() { ## ${bastille_logsdir} if [ ! -d "${bastille_logsdir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_logsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/logs" fi @@ -177,7 +179,7 @@ bootstrap_directories() { ## ${bastille_templatesdir} if [ ! -d "${bastille_templatesdir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_templatesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates" fi @@ -188,7 +190,7 @@ bootstrap_directories() { ## ${bastille_releasesdir} if [ ! -d "${bastille_releasesdir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases" zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}" @@ -199,7 +201,7 @@ bootstrap_directories() { ## create subsequent releases/XX.X-RELEASE datasets elif [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}" fi @@ -247,7 +249,7 @@ bootstrap_release() { if [ "${FETCH_VALIDATION}" -ne "0" ]; then ## perform cleanup only for stale/empty directories on failure - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then if [ ! "$(ls -A "${bastille_cachedir}/${RELEASE}")" ]; then zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}" @@ -384,7 +386,7 @@ debootstrap_release() { info "bastille_releasesdir=${bastille_releasesdir}" info "DIR_BOOTSTRAP=${DIR_BOOTSTRAP}" ## perform cleanup only for stale/empty directories on failure - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then if [ ! "$(ls -A "${bastille_releasesdir}/${DIR_BOOTSTRAP}")" ]; then zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${DIR_BOOTSTRAP}" @@ -400,7 +402,7 @@ debootstrap_release() { fi case "${LINUX_FLAVOR}" in - stretch|buster|bullseye) + bionic|focal|jammy|buster|bullseye|bookworm) info "Increasing APT::Cache-Start" echo "APT::Cache-Start 251658240;" > "${bastille_releasesdir}"/${DIR_BOOTSTRAP}/etc/apt/apt.conf.d/00aptitude ;; @@ -415,7 +417,7 @@ bootstrap_template() { ## ${bastille_templatesdir} if [ ! -d "${bastille_templatesdir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then zfs create ${bastille_zfs_options} -o mountpoint="${bastille_templatesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates" fi @@ -428,7 +430,7 @@ bootstrap_template() { ## define basic variables _url=${BASTILLE_TEMPLATE_URL} _user=${BASTILLE_TEMPLATE_USER} - _repo=${BASTILLE_TEMPLATE_REPO} + _repo=${BASTILLE_TEMPLATE_REPO%.*} # Remove the trailing ".git" _template=${bastille_templatesdir}/${_user}/${_repo} ## support for non-git @@ -474,6 +476,11 @@ if [ -n "${OPTION}" ] && [ "${OPTION}" != "${HW_MACHINE}" ] && [ "${OPTION}" != fi fi +## allow override bootstrap URLs via environment variables +[ -n "${BASTILLE_URL_FREEBSD}" ] && bastille_url_freebsd="${BASTILLE_URL_FREEBSD}" +[ -n "${BASTILLE_URL_HARDENEDBSD}" ] && bastille_url_hardenedbsd="${BASTILLE_URL_HARDENEDBSD}" +[ -n "${BASTILLE_URL_MIDNIGHTBSD}" ] && bastille_url_midnightbsd="${BASTILLE_URL_MIDNIGHTBSD}" + ## Filter sane release names case "${1}" in 2.[0-9]*) @@ -490,9 +497,9 @@ case "${1}" in PLATFORM_OS="FreeBSD" validate_release_url ;; -*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2|*-RC3|*-rc3|*-RC4|*-rc4|*-RC5|*-rc5|*-BETA1|*-BETA2|*-BETA3|*-BETA4|*-BETA5) +*-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9]) ## check for FreeBSD releases name - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-5]|-BETA[1-5])$' | tr '[:lower:]' '[:upper:]') + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([0-9]{1,2})\.[0-9](-RELEASE|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]') UPSTREAM_URL="${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" PLATFORM_OS="FreeBSD" validate_release_url @@ -517,8 +524,8 @@ case "${1}" in ## check for HardenedBSD(latest stable build release) NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-BUILD-LATEST//g') - NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-//g') - UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}" + NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-BUILD-//g') + UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}" PLATFORM_OS="HardenedBSD" validate_release_url ;; @@ -535,8 +542,8 @@ current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST) ## check for HardenedBSD(latest current build release) NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g') - NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-//g') - UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}" + NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-BUILD-//g') + UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}" PLATFORM_OS="HardenedBSD" validate_release_url ;; @@ -546,6 +553,13 @@ http?://*/*/*) BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }') bootstrap_template ;; +git@*:*/*) + BASTILLE_TEMPLATE_URL=${1} + git_repository=$(echo "${1}" | awk -F : '{ print $2 }') + BASTILLE_TEMPLATE_USER=$(echo "${git_repository}" | awk -F / '{ print $1 }') + BASTILLE_TEMPLATE_REPO=$(echo "${git_repository}" | awk -F / '{ print $2 }') + bootstrap_template + ;; #adding Ubuntu Bionic as valid "RELEASE" for POC @hackacad ubuntu_trusty|trusty|ubuntu-trusty) PLATFORM_OS="Ubuntu/Linux" @@ -576,26 +590,23 @@ ubuntu_focal|focal|ubuntu-focal) debootstrap_release ;; ubuntu_hirsute|hirsute|ubuntu-hirsute) - PLATFORM_OS="Ubuntu/Linux" - LINUX_FLAVOR="hirsute" - DIR_BOOTSTRAP="Ubuntu_2104" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; - ubuntu_jammy|jammy|ubuntu-jammy) - PLATFORM_OS="Ubuntu/Linux" - LINUX_FLAVOR="jammy" - DIR_BOOTSTRAP="Ubuntu_2204" - ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} - debootstrap_release - ;; -debian_stretch|stretch|debian-stretch) - PLATFORM_OS="Debian/Linux" - LINUX_FLAVOR="stretch" - DIR_BOOTSTRAP="Debian9" + PLATFORM_OS="Ubuntu/Linux" + LINUX_FLAVOR="hirsute" + DIR_BOOTSTRAP="Ubuntu_2104" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; + ubuntu_jammy|jammy|ubuntu-jammy) + PLATFORM_OS="Ubuntu/Linux" + LINUX_FLAVOR="jammy" + DIR_BOOTSTRAP="Ubuntu_2204" ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} debootstrap_release ;; + debian_stretch|stretch|debian-stretch) + PLATFORM_OS="Debian/Linux" + LINUX_FLAVOR="stretch" + DIR_BOOTSTRAP="Debian9" debian_buster|buster|debian-buster) PLATFORM_OS="Debian/Linux" LINUX_FLAVOR="buster" @@ -610,6 +621,13 @@ debian_bullseye|bullseye|debian-bullseye) ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} debootstrap_release ;; +debian_bookworm|bookworm|debian-bookworm) + PLATFORM_OS="Debian/Linux" + LINUX_FLAVOR="bookworm" + DIR_BOOTSTRAP="Debian12" + ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX} + debootstrap_release + ;; *) usage ;; diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 5630b71d9..1ebea6c40 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -ne 2 ]; then usage fi +bastille_root_check + NEWNAME="${1}" IP="${2}" @@ -134,7 +136,7 @@ update_fstab() { # Update fstab to use the new name FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab" if [ -f "${FSTAB_CONFIG}" ]; then - FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-5]|-BETA[1-5]|-CURRENT)|([0-9]{1,2}(-stable-build-[0-9]{1,3}|-stable-LAST))|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)' "${FSTAB_CONFIG}" | uniq) + FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9]|-CURRENT)|([0-9]{1,2}(-stable-build-[0-9]{1,3}|-stable-LAST))|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)' "${FSTAB_CONFIG}" | uniq) FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}") FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0" if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then @@ -152,7 +154,7 @@ clone_jail() { # Attempt container clone info "Attempting to clone '${TARGET}' to ${NEWNAME}..." if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then # Replicate the existing container DATE=$(date +%F-%H%M%S) diff --git a/usr/local/share/bastille/cmd.sh b/usr/local/share/bastille/cmd.sh index 6bc696105..137ea058b 100644 --- a/usr/local/share/bastille/cmd.sh +++ b/usr/local/share/bastille/cmd.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -eq 0 ]; then usage fi +bastille_root_check + COUNT=0 RETURN=0 diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index adc1ac21d..1295799a5 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -33,6 +33,14 @@ COLOR_GREEN= COLOR_YELLOW= COLOR_RESET= +bastille_root_check() { + if [ "$(id -u)" -ne 0 ]; then + ## permission denied + error_notify "Bastille: Permission Denied" + error_exit "root / sudo / doas required" + fi +} + enable_color() { . /usr/local/share/bastille/colors.pre.sh } @@ -109,3 +117,24 @@ EOF EOF fi } + +checkyesno() { + ## copied from /etc/rc.subr -- cedwards (20231125) + ## issue #368 (lowercase values should be parsed) + ## now used for all bastille_zfs_enable=YES|NO tests + ## example: if checkyesno bastille_zfs_enable; then ... + ## returns 0 for enabled; returns 1 for disabled + eval _value=\$${1} + case $_value in + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + return 0 + ;; + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + return 1 + ;; + *) + warn "\$${1} is not set properly - see rc.conf(5)." + return 1 + ;; + esac +} diff --git a/usr/local/share/bastille/config.sh b/usr/local/share/bastille/config.sh index 8bfa996d4..2ad5379e4 100644 --- a/usr/local/share/bastille/config.sh +++ b/usr/local/share/bastille/config.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -55,6 +55,8 @@ if [ $# -eq 1 ] || [ $# -gt 3 ]; then usage fi +bastille_root_check + ACTION=$1 shift diff --git a/usr/local/share/bastille/console.sh b/usr/local/share/bastille/console.sh index 30c5f0f43..16f5c599c 100644 --- a/usr/local/share/bastille/console.sh +++ b/usr/local/share/bastille/console.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -gt 1 ]; then usage fi +bastille_root_check + USER="${1}" validate_user() { diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index feb7ce855..48fda1454 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -ne 0 ]; then usage fi +bastille_root_check + convert_symlinks() { # Work with the symlinks, revert on first cp error if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then diff --git a/usr/local/share/bastille/cp.sh b/usr/local/share/bastille/cp.sh index a7dabc35a..cf895fe4a 100644 --- a/usr/local/share/bastille/cp.sh +++ b/usr/local/share/bastille/cp.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -54,6 +54,8 @@ if [ $# -ne 2 ]; then usage fi +bastille_root_check + case "${OPTION}" in -q|--quiet) OPTION="-a" diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 8d1bb459c..1e5751a09 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -104,10 +104,10 @@ validate_ip() { if echo "${ip}" | grep -qvE '(SLAAC|DHCP|0[.]0[.]0[.]0)'; then if [ "${ipx_addr}" = "ip4.addr" ]; then IP4_ADDR="${ip}" - IP4_DEFINITION="${ipx_addr}=${ip};" + IP4_DEFINITION="${ipx_addr} = ${ip};" else IP6_ADDR="${ip}" - IP6_DEFINITION="${ipx_addr}=${ip};" + IP6_DEFINITION="${ipx_addr} = ${ip};" fi fi } @@ -178,6 +178,7 @@ ${NAME} { mount.fstab = ${bastille_jail_fstab}; path = ${bastille_jail_path}; securelevel = 2; + osrelease = ${RELEASE}; interface = ${bastille_jail_conf_interface}; ${IP4_DEFINITION} @@ -225,6 +226,7 @@ ${NAME} { mount.fstab = ${bastille_jail_fstab}; path = ${bastille_jail_path}; securelevel = 2; + osrelease = ${RELEASE}; ${NETBLOCK} } @@ -232,81 +234,81 @@ EOF } generate_linux_vnet_jail_conf() { - cat << EOF > "${bastille_jail_conf}" + cat << EOF > "${bastille_jail_conf}" ${NAME} { - host.hostname = ${NAME}; - devfs_ruleset = 0; - enforce_statfs = 1; - - exec.start = ''; - exec.stop = ''; - - mount.devfs; - mount.fstab = ${bastille_jail_fstab}; - path = ${bastille_jail_path}; - persist; + host.hostname = ${NAME}; + devfs_ruleset = 0; + enforce_statfs = 1; + + exec.start = ''; + exec.stop = ''; + + mount.devfs; + mount.fstab = ${bastille_jail_fstab}; + path = ${bastille_jail_path}; + persist; allow.mount; allow.mount.devfs; - vnet; + vnet; } EOF } vnet_setting() { - ## rename interface to generic vnet0 - uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//') - echo "find unique epair! ${uniq_epair}" - - _gateway='' - _gateway6='' - _ifconfig_inet='' - _ifconfig_inet6='' - if echo "${IP}" | grep -qE '(0[.]0[.]0[.]0|DHCP)'; then - # Enable DHCP if requested - _ifconfig_inet=SYNCDHCP - else - # Else apply the default gateway - if [ -n "${bastille_network_gateway}" ]; then - _gateway="${bastille_network_gateway}" - else - _gateway="$(netstat -rn | awk '/default/ {print $2}')" - fi - echo "_gateway = ${_gateway}" - fi - echo "${_gateway}" - # Add IPv4 address (this is empty if DHCP is used) - if [ -n "${IP4_ADDR}" ]; then - _ifconfig_inet="${_ifconfig_inet} inet ${IP4_ADDR}" - fi - # Enable IPv6 if used - if [ "${IP6_MODE}" != "disable" ]; then - _ifconfig_inet6='inet6 -ifdisabled' - if echo "${IP}" | grep -qE 'SLAAC'; then - # Enable SLAAC if requested - _ifconfig_inet6="${_ifconfig_inet6} accept_rtadv" - else - # Else apply the default gateway - if [ -n "${bastille_network_gateway6}" ]; then - _gateway6="${bastille_network_gateway6}" - else - _gateway6="$(netstat -6rn | awk '/default/ {print $2}')" - fi - fi - fi - # Add IPv6 address (this is empty if SLAAC is used) - if [ -n "${IP6_ADDR}" ]; then - _ifconfig_inet6="${_ifconfig_inet6} ${IP6_ADDR}" - fi - # Join together IPv4 and IPv6 parts of ifconfig - _ifconfig="${_ifconfig_inet} ${_ifconfig_inet6}" - bastille template "${NAME}" ${bastille_template_vnet} \ - --arg BASE_TEMPLATE="${bastille_template_base}" \ - --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" \ - --arg EPAIR="${uniq_epair}" \ - --arg GATEWAY="${_gateway}" \ - --arg GATEWAY6="${_gateway6}" \ - --arg IFCONFIG="${_ifconfig}" + ## rename interface to generic vnet0 + uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//') + echo "find unique epair! ${uniq_epair}" + + _gateway='' + _gateway6='' + _ifconfig_inet='' + _ifconfig_inet6='' + if echo "${IP}" | grep -qE '(0[.]0[.]0[.]0|DHCP)'; then + # Enable DHCP if requested + _ifconfig_inet=SYNCDHCP + else + # Else apply the default gateway + if [ -n "${bastille_network_gateway}" ]; then + _gateway="${bastille_network_gateway}" + else + _gateway="$(netstat -rn | awk '/default/ {print $2}')" + fi + echo "_gateway = ${_gateway}" + fi + echo "${_gateway}" + # Add IPv4 address (this is empty if DHCP is used) + if [ -n "${IP4_ADDR}" ]; then + _ifconfig_inet="${_ifconfig_inet} inet ${IP4_ADDR}" + fi + # Enable IPv6 if used + if [ "${IP6_MODE}" != "disable" ]; then + _ifconfig_inet6='inet6 -ifdisabled' + if echo "${IP}" | grep -qE 'SLAAC'; then + # Enable SLAAC if requested + _ifconfig_inet6="${_ifconfig_inet6} accept_rtadv" + else + # Else apply the default gateway + if [ -n "${bastille_network_gateway6}" ]; then + _gateway6="${bastille_network_gateway6}" + else + _gateway6="$(netstat -6rn | awk '/default/ {print $2}')" + fi + fi + fi + # Add IPv6 address (this is empty if SLAAC is used) + if [ -n "${IP6_ADDR}" ]; then + _ifconfig_inet6="${_ifconfig_inet6} ${IP6_ADDR}" + fi + # Join together IPv4 and IPv6 parts of ifconfig + _ifconfig="${_ifconfig_inet} ${_ifconfig_inet6}" + bastille template "${NAME}" ${bastille_template_vnet} \ + --arg BASE_TEMPLATE="${bastille_template_base}" \ + --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" \ + --arg EPAIR="${uniq_epair}" \ + --arg GATEWAY="${_gateway}" \ + --arg GATEWAY6="${_gateway6}" \ + --arg IFCONFIG="${_ifconfig}" } post_create_jail() { @@ -340,8 +342,8 @@ post_create_jail() { # Generate the jail configuration file. if [ -n "${VNET_JAIL}" ]; then if [ -z "${LINUX_JAIL}" ]; then - generate_vnet_jail_conf - fi + generate_vnet_jail_conf + fi else generate_jail_conf fi @@ -359,7 +361,7 @@ create_jail() { bastille_jail_resolv_conf="${bastille_jailsdir}/${NAME}/root/etc/resolv.conf" ## file if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then ## create required zfs datasets, mountpoint inherited from system if [ -z "${CLONE_JAIL}" ]; then @@ -405,27 +407,27 @@ create_jail() { echo -e "/tmp ${bastille_jail_path}/tmp nullfs rw 0 0" >> "${bastille_jail_fstab}" ## removed temporarely / only for X11 jails? @hackacad #echo -e "/home ${bastille_jail_path}/home nullfs rw 0 0" >> "${bastille_jail_fstab}" - # linux network settings - echo "${bastille_jail_conf}" + # linux network settings + echo "${bastille_jail_conf}" if [ ! -f "${bastille_jail_conf}" ]; then if [ -n "${VNET_JAIL}" ]; then - # linux jail vnet - echo "linux jail + vnet" - vnet_settings - else - if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then - local bastille_jail_conf_interface=${bastille_network_shared} - fi - if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then - local bastille_jail_conf_interface=${bastille_network_loopback} - fi - if [ -n "${INTERFACE}" ]; then - local bastille_jail_conf_interface=${INTERFACE} - fi - fi + # linux jail vnet + echo "linux jail + vnet" + vnet_settings + else + if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then + local bastille_jail_conf_interface=${bastille_network_shared} + fi + if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then + local bastille_jail_conf_interface=${bastille_network_loopback} + fi + if [ -n "${INTERFACE}" ]; then + local bastille_jail_conf_interface=${INTERFACE} + fi + fi fi fi - # mark not linux + # mark not linux if [ -z "${EMPTY_JAIL}" ] && [ -z "${LINUX_JAIL}" ]; then if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then if [ ! -d "${bastille_jail_base}" ]; then @@ -473,7 +475,7 @@ create_jail() { fi done else - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then if [ -n "${CLONE_JAIL}" ]; then info "Creating a clonejail...\n" @@ -555,21 +557,21 @@ create_jail() { ## VNET specific if [ -n "${VNET_JAIL}" ]; then - vnet_settings + vnet_settings ## VNET requires jib script - 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 + 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 fi elif [ -n "${LINUX_JAIL}" ]; then ## Generate configuration for Linux jail if [ -n "${VNET_JAIL}" ]; then - generate_linux_vnet_jail_conf - else - generate_linux_jail_conf - fi + generate_linux_vnet_jail_conf + else + generate_linux_jail_conf + fi elif [ -n "${EMPTY_JAIL}" ]; then ## Generate minimal configuration for empty jail generate_minimal_conf @@ -587,11 +589,56 @@ create_jail() { bastille start "${NAME}" fi fi - #vnet settings + #vnet settings if [ -n "${VNET_JAIL}" && -z "${LINUX_JAIL}" ]; then - if [ -n "${bastille_template_vnet}" ]; then - vnet_setting - fi + if [ -n "${bastille_template_vnet}" ]; then + vnet_setting + fi + + ## rename interface to generic vnet0 + uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//; s/-/_/g') + + _gateway='' + _gateway6='' + _ifconfig_inet='' + _ifconfig_inet6='' + if echo "${IP}" | grep -qE '(0[.]0[.]0[.]0|DHCP)'; then + # Enable DHCP if requested + _ifconfig_inet=SYNCDHCP + else + # Else apply the default gateway + if [ -n "${bastille_network_gateway}" ]; then + _gateway="${bastille_network_gateway}" + else + _gateway="$(netstat -rn | awk '/default/ {print $2}')" + fi + fi + # Add IPv4 address (this is empty if DHCP is used) + if [ -n "${IP4_ADDR}" ]; then + _ifconfig_inet="${_ifconfig_inet} inet ${IP4_ADDR}" + fi + # Enable IPv6 if used + if [ "${IP6_MODE}" != "disable" ]; then + _ifconfig_inet6='inet6 -ifdisabled' + if echo "${IP}" | grep -qE 'SLAAC'; then + # Enable SLAAC if requested + _ifconfig_inet6="${_ifconfig_inet6} accept_rtadv" + else + # Else apply the default gateway + if [ -n "${bastille_network_gateway6}" ]; then + _gateway6="${bastille_network_gateway6}" + else + _gateway6="$(netstat -6rn | awk '/default/ {print $2}')" + fi + fi + fi + # Add IPv6 address (this is empty if SLAAC is used) + if [ -n "${IP6_ADDR}" ]; then + _ifconfig_inet6="${_ifconfig_inet6} ${IP6_ADDR}" + fi + # Join together IPv4 and IPv6 parts of ifconfig + _ifconfig="${_ifconfig_inet} ${_ifconfig_inet6}" + bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" elif [ -n "${THICK_JAIL}" ]; then if [ -n "${bastille_template_thick}" ]; then bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" @@ -637,6 +684,8 @@ help|-h|--help) ;; esac +bastille_root_check + if echo "$3" | grep '@'; then BASTILLE_JAIL_IP=$(echo "$3" | awk -F@ '{print $2}') BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}') @@ -652,42 +701,86 @@ LINUX_JAIL="" # Handle and parse options while [ $# -gt 0 ]; do case "${1}" in - -E|--empty|empty) + -E|--empty) EMPTY_JAIL="1" - echo "EMPTY: ON" + echo "EMPTY: ON" shift ;; - -L|--linux|linux) + -L|--linux) LINUX_JAIL="1" - echo "LINUX: ON" + echo "LINUX: ON" shift ;; - -T|--thick|thick) + -T|--thick) THICK_JAIL="1" - echo "THICK: ON" + echo "THICK: ON" shift ;; - -V|--vnet|vnet) + -V|--vnet) VNET_JAIL="1" - echo "VNET: ON" + echo "VNET: ON" shift ;; - -B|--bridge|bridge) + -B|--bridge) VNET_JAIL="1" VNET_JAIL_BRIDGE="1" - echo "BRIDGE: ON" + echo "BRIDGE: ON" + shift + ;; + -C|--clone) + CLONE_JAIL="1" + echo "CLONE: ON" shift ;; - -C|--clone|clone) + -CV|-VC|--clone-vnet) CLONE_JAIL="1" - echo "CLONE: ON" + VNET_JAIL="1" + shift + ;; + -CB|-BC|--clone-bridge) + CLONE_JAIL="1" + VNET_JAIL="1" + VNET_JAIL_BRIDGE="1" + shift + ;; + -TV|-VT|--thick-vnet) + THICK_JAIL="1" + VNET_JAIL="1" + shift + ;; + -TB|-BT|--thick-bridge) + THICK_JAIL="1" + VNET_JAIL="1" + VNET_JAIL_BRIDGE="1" + shift + ;; + -EB|-BE|--empty-bridge) + EMPTY_JAIL="1" + VNET_JAIL="1" + VNET_JAIL_BRIDGE="1" + shift + ;; + -EV|-VE|--empty-vnet) + EMPTY_JAIL="1" + VNET_JAIL="1" + shift + ;; + -LV|-VL|--linux-vnet) + LINUX_JAIL="1" + VNET_JAIL="1" + shift + ;; + -LB|-BL|--linux-bridge) + LINUX_JAIL="1" + VNET_JAIL="1" + VNET_JAIL_BRIDGE="1" shift ;; -*|--*) error_notify "Unknown Option." usage ;; - *) + *) break ;; esac @@ -728,12 +821,12 @@ fi if [ -n "${LINUX_JAIL}" ]; then case "${RELEASE}" in - ubuntu_trusty|trusty|ubuntu-trusty) - NAME_VERIFY=ubuntu_trusty - ;; - ubuntu_xenial|xenial|ubuntu-xenial) - NAME_VERIFY=ubuntu_xenial - ;; + ubuntu_trusty|trusty|ubuntu-trusty) + NAME_VERIFY=ubuntu_trusty + ;; + ubuntu_xenial|xenial|ubuntu-xenial) + NAME_VERIFY=ubuntu_xenial + ;; bionic|ubuntu_bionic|ubuntu|ubuntu-bionic) ## check for FreeBSD releases name NAME_VERIFY=ubuntu_bionic @@ -742,14 +835,13 @@ if [ -n "${LINUX_JAIL}" ]; then ## check for FreeBSD releases name NAME_VERIFY=ubuntu_focal ;; - hirsute|ubuntu_hirsute|ubuntu-hirsute) - NAME_VERIFY=ubuntu_hirsute - ;; - jammy|ubuntu_jammy|ubuntu-jammy) - NAME_VERIFY=ubuntu_jammy - ;; + hirsute|ubuntu_hirsute|ubuntu-hirsute) + NAME_VERIFY=ubuntu_hirsute + ;; + jammy|ubuntu_jammy|ubuntu-jammy) + NAME_VERIFY=ubuntu_jammy + ;; debian_stretch|stretch|debian-stretch) - ## check for FreeBSD releases name NAME_VERIFY=stretch ;; debian_buster|buster|debian-buster) @@ -760,6 +852,13 @@ if [ -n "${LINUX_JAIL}" ]; then ## check for FreeBSD releases name NAME_VERIFY=bullseye ;; + debian_bookworm|bookworm|debian-bookworm) + ## check for FreeBSD releases name + NAME_VERIFY=bookworm + ;; + await_rootfs|await|await-rootfs) + NAME_VERIFY=await_rootfs + ;; *) error_notify "Unknown Linux." usage @@ -780,9 +879,9 @@ if [ -z "${EMPTY_JAIL}" ]; then NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') validate_release ;; - *-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2|*-BETA1|*-BETA2|*-BETA3|*-BETA4|*-BETA5) + *-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9]) ## check for FreeBSD releases name - NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2]|-BETA[1-5])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') + NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') validate_release ;; *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) @@ -810,16 +909,16 @@ if [ -z "${EMPTY_JAIL}" ]; then NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') validate_release ;; - ubuntu_trusty|trusty|ubuntu-trusty) - UBUNTU="1" - NAME_VERIFY=Ubuntu_1404 - validate_release - ;; - ubuntu_xenial|xenial|ubuntu-xenial) - UBUNTU="1" - NAME_VERIFY=Ubuntu_1604 - validate_release - ;; + ubuntu_trusty|trusty|ubuntu-trusty) + UBUNTU="1" + NAME_VERIFY=Ubuntu_1404 + validate_release + ;; + ubuntu_xenial|xenial|ubuntu-xenial) + UBUNTU="1" + NAME_VERIFY=Ubuntu_1604 + validate_release + ;; ubuntu_bionic|bionic|ubuntu-bionic) UBUNTU="1" NAME_VERIFY=Ubuntu_1804 @@ -830,16 +929,16 @@ if [ -z "${EMPTY_JAIL}" ]; then NAME_VERIFY=Ubuntu_2004 validate_release ;; - ubuntu_hirsute|hirsute|ubuntu-hirsute) - UBUNTU="1" - NAME_VERIFY=Ubuntu_2104 - validate_release - ;; - ubuntu_jammy|jammy|ubuntu-jammy) - UBUNTU="1" - NAME_VERIFY=Ubuntu_2204 - validate_release - ;; + ubuntu_hirsute|hirsute|ubuntu-hirsute) + UBUNTU="1" + NAME_VERIFY=Ubuntu_2104 + validate_release + ;; + ubuntu_jammy|jammy|ubuntu-jammy) + UBUNTU="1" + NAME_VERIFY=Ubuntu_2204 + validate_release + ;; debian_stretch|stretch|debian-stretch) NAME_VERIFY=Debian9 validate_release @@ -852,6 +951,15 @@ if [ -z "${EMPTY_JAIL}" ]; then NAME_VERIFY=Debian11 validate_release ;; + debian_bookworm|bookworm|debian-bookworm) + NAME_VERIFY=Debian12 + validate_release + ;; + await_rootfs|await|await-rootfs) + UBUNTU="1" + NAME_VERIFY=Await + validate_release + ;; *) error_notify "Unknown Release." usage @@ -865,6 +973,7 @@ if [ -z "${EMPTY_JAIL}" ]; then ## check for required release if [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then + echo ${RELEASE} error_exit "Release must be bootstrapped first; see 'bastille bootstrap'." fi @@ -929,7 +1038,7 @@ if [ -z ${bastille_template_vnet+x} ]; then bastille_template_vnet='default/vnet' fi if [ -z ${bastille_template_vnet_linux+x} ]; then - bastille_template_vnet_linux='default/vnet_linux' + bastille_template_vnet_linux='default/vnet_linux' fi create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}" diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 91602dac2..2a660439e 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -55,7 +55,7 @@ destroy_jail() { if [ -d "${bastille_jail_base}" ]; then info "Deleting Jail: ${TARGET}." - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then if [ -n "${TARGET}" ]; then OPTIONS="-r" @@ -118,7 +118,7 @@ destroy_rel() { if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then error_notify "Notice: (${_jail}) depends on ${TARGET} base." BASE_HASCHILD="1" - elif [ "${bastille_zfs_enable}" = "YES" ]; then + elif checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then ## check if this release have child clones if zfs list -H -t snapshot -r "${bastille_rel_base}" > /dev/null 2>&1; then @@ -144,7 +144,7 @@ destroy_rel() { else if [ "${BASE_HASCHILD}" -eq "0" ]; then info "Deleting base: ${TARGET}" - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then if [ -n "${TARGET}" ]; then OPTIONS="-r" @@ -210,6 +210,8 @@ if [ $# -gt 1 ] || [ $# -lt 1 ]; then usage fi +bastille_root_check + ## check what should we clean case "${TARGET}" in *-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current) @@ -217,9 +219,9 @@ case "${TARGET}" in NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') destroy_rel ;; -*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2|*-RC3|*-rc3|*-RC4|*-rc4|*-RC5|*-rc5|*-BETA1|*-BETA2|*-BETA3|*-BETA4|*-BETA5) +*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9]) ## check for FreeBSD releases name - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-5]|-BETA[1-5])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g') destroy_rel ;; *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) @@ -247,14 +249,14 @@ current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST) NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build-latest)$' | sed 's/CURRENT/current/;s/build/BUILD/g;s/latest/LATEST/g') destroy_rel ;; -Ubuntu_1804|Ubuntu_2004|UBUNTU_1804|UBUNTU_2004) +Ubuntu_1804|Ubuntu_2004|Ubuntu_2204|UBUNTU_1804|UBUNTU_2004|UBUNTU_2204) ## check for Linux releases - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Ubuntu_1804)$|(Ubuntu_2004)$' | sed 's/UBUNTU/Ubuntu/g;s/ubuntu/Ubuntu/g') + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Ubuntu_1804)$|(Ubuntu_2004)$|(Ubuntu_2204)$' | sed 's/UBUNTU/Ubuntu/g;s/ubuntu/Ubuntu/g') destroy_rel ;; -Debian9|Debian10|Debian11|DEBIAN9|DEBIAN10|DEBIAN11) +Debian10|Debian11|Debian12|DEBIAN10|DEBIAN11|DEBIAN12) ## check for Linux releases - NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Debian9)$|(Debian10)$|(Debian11)$' | sed 's/DEBIAN/Debian/g') + NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Debian10)$|(Debian11)$|(Debian12)$' | sed 's/DEBIAN/Debian/g') destroy_rel ;; *) diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index 6b5916677..08c08f145 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -48,6 +48,8 @@ elif [ $# -eq 1 ]; then TARGET_FILENAME="${1}" fi +bastille_root_check + if [ -z "${EDITOR}" ]; then EDITOR=vi fi diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 3bedb9fe6..fc180b9ab 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -71,9 +71,11 @@ if [ $# -gt 5 ] || [ $# -lt 1 ]; then usage fi +bastille_root_check + zfs_enable_check() { # Temporarily disable ZFS so we can create a standard backup archive - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then bastille_zfs_enable="NO" fi } @@ -210,7 +212,7 @@ if [ -n "${TXZ_EXPORT}" -o -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then error_exit "Error: Simple archive modes with safe ZFS export can't be used together." fi -if [ -z "${bastille_zfs_enable}" ]; then +if checkyesno bastille_zfs_enable; then if [ -n "${GZIP_EXPORT}" -o -n "${RAW_EXPORT}" -o -n "${SAFE_EXPORT}" -o "${OPT_ZSEND}" = "-Rv" ]; then error_exit "Options --gz, --raw, --safe, --verbose are valid for ZFS configured systems only." fi @@ -292,7 +294,7 @@ export_check() { create_zfs_snap fi - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -z "${USER_EXPORT}" ]; then info "Sending ZFS data stream..." fi @@ -302,7 +304,7 @@ export_check() { jail_export() { # Attempt to export the container DATE=$(date +%F-%H%M%S) - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then if [ -n "${RAW_EXPORT}" ]; then FILE_EXT="" @@ -382,7 +384,7 @@ if [ -n "${TARGET}" ]; then fi # Check if is a ZFS system - if [ "${bastille_zfs_enable}" != "YES" ]; then + if ! checkyesno bastille_zfs_enable; then # Check if container is running and ask for stop in non ZFS systems if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then error_exit "${TARGET} is running. See 'bastille stop'." diff --git a/usr/local/share/bastille/htop.sh b/usr/local/share/bastille/htop.sh index a9e50848c..d2e1c5579 100644 --- a/usr/local/share/bastille/htop.sh +++ b/usr/local/share/bastille/htop.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -ne 0 ]; then usage fi +bastille_root_check + for _jail in ${JAILS}; do bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path) if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 7044a3da5..7209548cb 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -59,6 +59,8 @@ if [ $# -gt 3 ] || [ $# -lt 1 ]; then usage fi +bastille_root_check + TARGET="${1}" OPT_FORCE= USER_IMPORT= @@ -150,6 +152,11 @@ update_jailconf() { sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${TARGET_TRIM}/root;|" "${JAIL_CONFIG}" sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;|" "${JAIL_CONFIG}" fi + + # Check for the jib script + if grep -qw "vnet" "${JAIL_CONFIG}"; then + vnet_requirements + fi fi } @@ -157,7 +164,7 @@ update_fstab() { # Update fstab .bastille mountpoint on thin containers only # Set some variables FSTAB_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/fstab" - FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}") + FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}") FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}") FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then @@ -207,6 +214,7 @@ generate_config() { # See if we need to generate a vnet network section if [ "${IS_VNET_JAIL:-0}" = "1" ]; then NETBLOCK=$(generate_vnet_jail_netblock "${TARGET_TRIM}" "" "${VNET_DEFAULT_INTERFACE}") + vnet_requirements else # If there are multiple IP/NIC let the user configure network if [ -n "${IPV4_CONFIG}" ]; then @@ -333,6 +341,17 @@ workout_components() { fi } +vnet_requirements() { + # VNET jib script requirement + 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 + else + warn "Warning: Unable to locate/install jib script required by VNET jails." + fi + fi +} + config_netif() { # Get interface from bastille configuration if [ -n "${bastille_network_loopback}" ]; then @@ -391,7 +410,7 @@ jail_import() { FILE_TRIM=$(echo "${TARGET}" | sed 's/\.xz//g;s/\.gz//g;s/\.tgz//g;s/\.txz//g;s/\.zip//g;s/\.tar\.gz//g;s/\.tar//g') FILE_EXT=$(echo "${TARGET}" | sed "s/${FILE_TRIM}//g") if [ -d "${bastille_jailsdir}" ]; then - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ]; then if [ "${FILE_EXT}" = ".xz" ]; then validate_archive diff --git a/usr/local/share/bastille/limits.sh b/usr/local/share/bastille/limits.sh index ce16e76b4..41fcd200d 100644 --- a/usr/local/share/bastille/limits.sh +++ b/usr/local/share/bastille/limits.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # Ressource limits added by Sven R github.com/hackacad # @@ -55,6 +55,8 @@ if [ $# -ne 2 ]; then usage fi +bastille_root_check + OPTION="${1}" VALUE="${2}" diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index a646b5439..c5c346a5a 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -35,106 +35,114 @@ usage() { error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" } +if [ "${1}" = help -o "${1}" = "-h" -o "${1}" = "--help" ]; then + usage +fi + +bastille_root_check + if [ $# -eq 0 ]; then - /usr/sbin/jls -N + /usr/sbin/jls fi -if [ "$1" == "-j" ]; then +if [ "${1}" == "-j" ]; then /usr/sbin/jls -N --libxo json exit 0 fi -if [ $# -gt 0 ]; then - # Handle special-case commands first. - case "$1" in - help|-h|--help) - usage - ;; - all|-a|--all) +TARGET= + +list_all(){ if [ -d "${bastille_jailsdir}" ]; then DEFAULT_VALUE="-" SPACER=2 MAX_LENGTH_JAIL_NAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_NAME=${MAX_LENGTH_JAIL_NAME:-3} - if [ ${MAX_LENGTH_JAIL_NAME} -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi + if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi MAX_LENGTH_JAIL_IP=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1 /p" | sed 's/\// /g' | awk '{ print length($1) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_IP:-10} MAX_LENGTH_JAIL_VNET_IP=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" $(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p") | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_VNET_IP=${MAX_LENGTH_JAIL_VNET_IP:-10} - if [ ${MAX_LENGTH_JAIL_VNET_IP} -gt ${MAX_LENGTH_JAIL_IP} ]; then MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_VNET_IP}; fi - if [ ${MAX_LENGTH_JAIL_IP} -lt 10 ]; then MAX_LENGTH_JAIL_IP=10; fi + if [ "${MAX_LENGTH_JAIL_VNET_IP}" -gt "${MAX_LENGTH_JAIL_IP}" ]; then MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_VNET_IP}; fi + if [ "${MAX_LENGTH_JAIL_IP}" -lt 10 ]; then MAX_LENGTH_JAIL_IP=10; fi MAX_LENGTH_JAIL_HOSTNAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^[ ]*host.hostname[ ]*=[ ]*\(.*\);" | awk '{ print length(substr($3, 1, length($3)-1)) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_HOSTNAME=${MAX_LENGTH_JAIL_HOSTNAME:-8} - if [ ${MAX_LENGTH_JAIL_HOSTNAME} -lt 8 ]; then MAX_LENGTH_JAIL_HOSTNAME=8; fi + if [ "${MAX_LENGTH_JAIL_HOSTNAME}" -lt 8 ]; then MAX_LENGTH_JAIL_HOSTNAME=8; fi MAX_LENGTH_JAIL_PORTS=$(find ""${bastille_jailsdir}/*/rdr.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 -n1 awk '{ lines++; chars += length($0)} END { chars += lines - 1; print chars }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_PORTS=${MAX_LENGTH_JAIL_PORTS:-15} - if [ ${MAX_LENGTH_JAIL_PORTS} -lt 15 ]; then MAX_LENGTH_JAIL_PORTS=15; fi - if [ ${MAX_LENGTH_JAIL_PORTS} -gt 30 ]; then MAX_LENGTH_JAIL_PORTS=30; fi + if [ "${MAX_LENGTH_JAIL_PORTS}" -lt 15 ]; then MAX_LENGTH_JAIL_PORTS=15; fi + if [ "${MAX_LENGTH_JAIL_PORTS}" -gt 30 ]; then MAX_LENGTH_JAIL_PORTS=30; fi MAX_LENGTH_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/fstab"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_JAIL_RELEASE:-7} MAX_LENGTH_THICK_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/root/bin/freebsd-version"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -hE "^USERLAND_VERSION=" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) MAX_LENGTH_THICK_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE:-7} MAX_LENGTH_LINUX_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/fstab"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" $(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p") 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1) MAX_LENGTH_LINUX_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE:-7} - if [ ${MAX_LENGTH_THICK_JAIL_RELEASE} -gt ${MAX_LENGTH_JAIL_RELEASE} ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE}; fi - if [ ${MAX_LENGTH_LINUX_JAIL_RELEASE} -gt ${MAX_LENGTH_JAIL_RELEASE} ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE}; fi - if [ ${MAX_LENGTH_JAIL_RELEASE} -lt 7 ]; then MAX_LENGTH_JAIL_RELEASE=7; fi + if [ "${MAX_LENGTH_THICK_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE}; fi + if [ "${MAX_LENGTH_LINUX_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE}; fi + if [ "${MAX_LENGTH_JAIL_RELEASE}" -lt 7 ]; then MAX_LENGTH_JAIL_RELEASE=7; fi printf " JID%*sState%*sIP Address%*sPublished Ports%*sHostname%*sRelease%*sPath\n" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 3))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} + ${SPACER} - 8))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" "" - JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + if [ -n "${TARGET}" ]; then + # Query all info for a specific jail. + JAIL_LIST="${TARGET}" + else + # Query all info for all jails(default). + JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + fi for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then - JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }') - IS_FREEBSD_JAIL=0 - if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" -o -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" -o "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi - IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0} - IS_LINUX_JAIL=0 - if [ "$(grep -c "^linprocfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_LINUX_JAIL=1; fi - IS_LINUX_JAIL=${IS_LINUX_JAIL:-0} - if [ "$(/usr/sbin/jls name | awk "/^${JAIL_NAME}$/")" ]; then - JAIL_STATE="Up" - if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then - JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet 2> /dev/null | sed -n "/.inet /{s///;s/ .*//;p;}") - if [ ! ${JAIL_IP} ]; then JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet6 2> /dev/null | awk '/inet6 / && (!/fe80::/ || !/%vnet0/)' | sed -n "/.inet6 /{s///;s/ .*//;p;}"); fi - else - JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip4.addr 2> /dev/null) - if [ ${JAIL_IP} = "-" ]; then JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip6.addr 2> /dev/null); fi - fi - JAIL_HOSTNAME=$(/usr/sbin/jls -j ${JAIL_NAME} host.hostname 2> /dev/null) - JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s/%s:%s"",",$7,$14,$18 }' | sed "s/,$//") - JAIL_PATH=$(/usr/sbin/jls -j ${JAIL_NAME} path 2> /dev/null) - if [ ${IS_FREEBSD_JAIL} -eq 1 ]; then - JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null) - fi - if [ ${IS_LINUX_JAIL} -eq 1 ]; then - JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') - fi + JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }') + IS_FREEBSD_JAIL=0 + if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" -o -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" -o "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi + IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0} + IS_LINUX_JAIL=0 + if [ "$(grep -c "^linprocfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_LINUX_JAIL=1; fi + IS_LINUX_JAIL=${IS_LINUX_JAIL:-0} + if [ "$(/usr/sbin/jls name | awk "/^${JAIL_NAME}$/")" ]; then + JAIL_STATE="Up" + if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then + JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet 2> /dev/null | sed -n "/.inet /{s///;s/ .*//;p;}") + if [ ! "${JAIL_IP}" ]; then JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet6 2> /dev/null | awk '/inet6 / && (!/fe80::/ || !/%vnet0/)' | sed -n "/.inet6 /{s///;s/ .*//;p;}"); fi + else + JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip4.addr 2> /dev/null) + if [ "${JAIL_IP}" = "-" ]; then JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip6.addr 2> /dev/null); fi + fi + JAIL_HOSTNAME=$(/usr/sbin/jls -j ${JAIL_NAME} host.hostname 2> /dev/null) + JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s/%s:%s"",",$7,$14,$18 }' | sed "s/,$//") + JAIL_PATH=$(/usr/sbin/jls -j ${JAIL_NAME} path 2> /dev/null) + if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then + JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null) + fi + if [ "${IS_LINUX_JAIL}" -eq 1 ]; then + JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') + fi + else + JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" == "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) + if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then + JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }') else - JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" == "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) - if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then - JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }') - else - JAIL_IP=$(sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | sed "s/\// /g" | awk '{ print $1 }') + JAIL_IP=$(sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | sed "s/\// /g" | awk '{ print $1 }') + fi + JAIL_HOSTNAME=$(sed -n "s/^[ ]*host.hostname[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null) + if [ -f "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" ]; then JAIL_PORTS=$(awk '$1 ~ /^[tcp|udp]/ { printf "%s/%s:%s,",$1,$2,$3 }' "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" 2> /dev/null | sed "s/,$//"); else JAIL_PORTS=""; fi + JAIL_PATH=$(sed -n "s/^[ ]*path[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null) + if [ "${JAIL_PATH}" ]; then + if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then + if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then + JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") + else + JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") + fi fi - JAIL_HOSTNAME=$(sed -n "s/^[ ]*host.hostname[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null) - if [ -f "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" ]; then JAIL_PORTS=$(awk '$1 ~ /^[tcp|udp]/ { printf "%s/%s:%s,",$1,$2,$3 }' "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" 2> /dev/null | sed "s/,$//"); else JAIL_PORTS=""; fi - JAIL_PATH=$(sed -n "s/^[ ]*path[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null) - if [ ${JAIL_PATH} ]; then - if [ ${IS_FREEBSD_JAIL} -eq 1 ]; then - if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then - JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") - else - JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") - fi - fi - if [ ${IS_LINUX_JAIL} -eq 1 ]; then - JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') - fi - else - JAIL_RELEASE="" + if [ "${IS_LINUX_JAIL}" -eq 1 ]; then + JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') fi + else + JAIL_RELEASE="" + fi fi - if [ ${#JAIL_PORTS} -gt ${MAX_LENGTH_JAIL_PORTS} ]; then JAIL_PORTS="$(echo ${JAIL_PORTS} | cut -c-$((${MAX_LENGTH_JAIL_PORTS} - 3)))..."; fi + if [ "${#JAIL_PORTS}" -gt "${MAX_LENGTH_JAIL_PORTS}" ]; then JAIL_PORTS="$(echo ${JAIL_PORTS} | cut -c-$((${MAX_LENGTH_JAIL_PORTS} - 3)))..."; fi JAIL_NAME=${JAIL_NAME:-${DEFAULT_VALUE}} JAIL_STATE=${JAIL_STATE:-${DEFAULT_VALUE}} JAIL_IP=${JAIL_IP:-${DEFAULT_VALUE}} @@ -148,48 +156,85 @@ if [ $# -gt 0 ]; then else error_exit "unfortunately there are no jails here (${bastille_jailsdir})" fi +} + +list_release(){ + if [ -d "${bastille_releasesdir}" ]; then + REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g") + for _REL in ${REL_LIST}; do + if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" -o -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then + if [ "${2}" == "-p" -a -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then + REL_PATCH_LEVEL=$(sed -n "s/^USERLAND_VERSION=\"\(.*\)\"$/\1/p" "${bastille_releasesdir}/${_REL}/bin/freebsd-version" 2> /dev/null) + REL_PATCH_LEVEL=${REL_PATCH_LEVEL:-${_REL}} + echo "${REL_PATCH_LEVEL}" + else + echo "${_REL}" + fi + fi + done + fi +} + +list_template(){ + find "${bastille_templatesdir}" -type d -maxdepth 2 +} + +list_jail(){ + if [ -d "${bastille_jailsdir}" ]; then + JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + for _JAIL in ${JAIL_LIST}; do + if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then + echo "${_JAIL}" + fi + done + fi +} + +list_log(){ + find "${bastille_logsdir}" -type f -maxdepth 1 +} + +list_limit(){ + rctl -h jail: +} + +list_import(){ + ls "${bastille_backupsdir}" | grep -v ".sha256$" +} + +if [ $# -gt 0 ]; then + # Handle special-case commands first. + case "${1}" in + all|-a|--all) + list_all ;; release|releases) - if [ -d "${bastille_releasesdir}" ]; then - REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g") - for _REL in ${REL_LIST}; do - if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" -o -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then - if [ "$2" == "-p" -a -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then - REL_PATCH_LEVEL=$(sed -n "s/^USERLAND_VERSION=\"\(.*\)\"$/\1/p" "${bastille_releasesdir}/${_REL}/bin/freebsd-version" 2> /dev/null) - REL_PATCH_LEVEL=${REL_PATCH_LEVEL:-${_REL}} - echo "${REL_PATCH_LEVEL}" - else - echo "${_REL}" - fi - fi - done - fi + list_release ;; template|templates) - find "${bastille_templatesdir}" -type d -maxdepth 2 + list_template ;; jail|jails|container|containers) - if [ -d "${bastille_jailsdir}" ]; then - JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") - for _JAIL in ${JAIL_LIST}; do - if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then - echo "${_JAIL}" - fi - done - fi + list_jail ;; log|logs) - find "${bastille_logsdir}" -type f -maxdepth 1 + list_log ;; limit|limits) - rctl -h jail: + list_limit ;; import|imports|export|exports|backup|backups) - ls "${bastille_backupsdir}" | grep -v ".sha256$" + list_import exit 0 ;; *) - usage + # Check if we want to query all info for a specific jail instead. + if [ -f "${bastille_jailsdir}/${1}/jail.conf" ]; then + TARGET="${1}" + list_all + else + usage + fi ;; esac fi diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 4e946c66e..673187f78 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -50,6 +50,8 @@ else _fstab="$@" fi +bastille_root_check + ## assign needed variables _hostpath=$(echo "${_fstab}" | awk '{print $1}') _jailpath=$(echo "${_fstab}" | awk '{print $2}') diff --git a/usr/local/share/bastille/pkg.sh b/usr/local/share/bastille/pkg.sh index 97cabfe23..0f0540129 100644 --- a/usr/local/share/bastille/pkg.sh +++ b/usr/local/share/bastille/pkg.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -45,6 +45,8 @@ if [ $# -lt 1 ]; then usage fi +bastille_root_check + errors=0 for _jail in ${JAILS}; do diff --git a/usr/local/share/bastille/rcp.sh b/usr/local/share/bastille/rcp.sh new file mode 100644 index 000000000..09d1d2f8f --- /dev/null +++ b/usr/local/share/bastille/rcp.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# +# Copyright (c) 2018-2022, Christer Edwards +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +. /usr/local/share/bastille/common.sh +. /usr/local/etc/bastille/bastille.conf + +usage() { + error_exit "Usage: bastille rcp [OPTION] TARGET CONTAINER_PATH HOST_PATH" +} + +CPSOURCE="${1}" +CPDEST="${2}" + +# Handle special-case commands first. +case "$1" in +help|-h|--help) + usage + ;; +-q|--quiet) + OPTION="${1}" + CPSOURCE="${2}" + CPDEST="${3}" + ;; +esac + +if [ $# -ne 2 ]; then + usage +fi + +if [ "${TARGET}" = "ALL" ]; then + usage +fi + +case "${OPTION}" in + -q|--quiet) + OPTION="-a" + ;; + *) + OPTION="-av" + ;; +esac + +for _jail in ${JAILS}; do + info "[${_jail}]:" + bastille_jail_path="${bastille_jailsdir}/${_jail}/root" + cp "${OPTION}" "${bastille_jail_path}/${CPSOURCE}" "${CPDEST}" + RETURN="$?" + echo + return "${RETURN}" +done diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index a7e59c2ed..887c1f1e5 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,9 +46,12 @@ if [ $# -lt 2 ]; then usage fi +bastille_root_check + TARGET="${1}" JAIL_NAME="" JAIL_IP="" +JAIL_IP6="" EXT_IF="" shift @@ -71,6 +74,13 @@ check_jail_validity() { error_exit "Jail IP not found: ${TARGET}" fi fi + # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) + if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then + if [ "$(bastille config $TARGET get ip6)" != 'disable' ] && [ "$(bastille config $TARGET get ip6)" != 'not set' ]; then + JAIL_IP6=$(/usr/sbin/jls -j "${TARGET}" ip6.addr 2>/dev/null) + fi + fi + # Check if rdr-anchor is defined in pf.conf if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then @@ -78,9 +88,11 @@ check_jail_validity() { fi # Check if ext_if is defined in pf.conf - EXT_IF=$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" /etc/pf.conf) - if [ -z "${EXT_IF}" ]; then - error_exit "bastille_network_pf_ext_if (${bastille_network_pf_ext_if}) not defined in pf.conf" + if [ -n "${bastille_pf_conf}" ]; then + EXT_IF=$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf}) + if [ -z "${EXT_IF}" ]; then + error_exit "bastille_network_pf_ext_if (${bastille_network_pf_ext_if}) not defined in pf.conf" + fi fi } @@ -106,6 +118,11 @@ load_rdr_rule() { ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP" "$3" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- +if [ -n "$JAIL_IP6" ]; then + ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP6" "$3" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f- +fi } # function: load rdr rule with log via pfctl @@ -116,6 +133,12 @@ log=$@ ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- +if [ -n "$JAIL_IP6" ]; then + ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f- +fi + } while [ $# -gt 0 ]; do diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 5fd645c1b..08ebe1083 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -56,6 +56,8 @@ if [ $# -ne 1 ]; then usage fi +bastille_root_check + NEWNAME="${1}" update_jailconf() { @@ -68,6 +70,9 @@ update_jailconf() { sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}" sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}" sed -i '' "s|${TARGET}.*{|${NEWNAME} {|" "${JAIL_CONFIG}" + # Rename vnet interface + sed -i '' "/vnet.interface/s|_${TARGET}\";|_${NEWNAME}\";|" "${JAIL_CONFIG}" + sed -i '' "/ifconfig/s|_${TARGET}|_${NEWNAME}|" "${JAIL_CONFIG}" fi fi } @@ -78,7 +83,7 @@ update_fstab() { if [ -f "${FSTAB_CONFIG}" ]; then # Skip if fstab is empty, e.g newly created thick or clone jails if [ -s "${FSTAB_CONFIG}" ]; then - FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}") + FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-9])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}") FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}") FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0" if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then @@ -100,7 +105,7 @@ update_fstab() { change_name() { # Attempt container name change info "Attempting to rename '${TARGET}' to ${NEWNAME}..." - if [ "${bastille_zfs_enable}" = "YES" ]; then + if checkyesno bastille_zfs_enable; then if [ -n "${bastille_zfs_zpool}" ] && [ -n "${bastille_zfs_prefix}" ]; then # Check and rename container ZFS dataset accordingly # Perform additional checks in case of non-ZFS existing containers diff --git a/usr/local/share/bastille/restart.sh b/usr/local/share/bastille/restart.sh index 0942d72a9..22faa3a15 100644 --- a/usr/local/share/bastille/restart.sh +++ b/usr/local/share/bastille/restart.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index 0217d3bf9..dfd5d6632 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -45,6 +45,8 @@ if [ $# -lt 1 -o $# -gt 2 ]; then usage fi +bastille_root_check + for _jail in ${JAILS}; do info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/service "$@" diff --git a/usr/local/share/bastille/setup.sh b/usr/local/share/bastille/setup.sh new file mode 100644 index 000000000..80ea7a959 --- /dev/null +++ b/usr/local/share/bastille/setup.sh @@ -0,0 +1,144 @@ +#!/bin/sh +# +# Copyright (c) 2018-2023, Christer Edwards +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +. /usr/local/share/bastille/common.sh +. /usr/local/etc/bastille/bastille.conf + +usage() { + error_exit "Usage: bastille setup [pf|bastille0|zfs|vnet]" +} + +# Check for too many args +if [ $# -gt 1 ]; then + usage +fi + +# Configure bastille0 network interface +configure_bastille0() { + info "Configuring bastille0 loopback interface" + sysrc cloned_interfaces+=lo1 + sysrc ifconfig_lo1_name="bastille0" + + info "Bringing up new interface: bastille0" + service netif cloneup +} + +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 + info "Creating bastille_vnet devfs.rules" + cat << EOF > /etc/devfs.rules +[bastille_vnet=13] +add include \$devfsrules_hide_all +add include \$devfsrules_unhide_basic +add include \$devfsrules_unhide_login +add include \$devfsrules_jail +add include \$devfsrules_jail_vnet +add path 'bpf*' unhide +EOF + fi +} + +# Configure pf firewall +configure_pf() { +if [ ! -f "${bastille_pf_conf}" ]; then + local ext_if + ext_if=$(netstat -rn | awk '/default/ {print $4}' | head -n1) + info "Determined default network interface: ($ext_if)" + info "${bastille_pf_conf} does not exist: creating..." + + ## creating pf.conf + cat << EOF > ${bastille_pf_conf} +## generated by bastille setup +ext_if="$ext_if" + +set block-policy return +scrub in on \$ext_if all fragment reassemble +set skip on lo + +table persist +nat on \$ext_if from to any -> (\$ext_if:0) +rdr-anchor "rdr/*" + +block in all +pass out quick keep state +antispoof for \$ext_if inet +pass in inet proto tcp from any to any port ssh flags S/SA keep state +EOF + sysrc pf_enable=YES +else + error_exit "${bastille_pf_conf} already exists. Exiting." +fi +} + +# Configure ZFS +configure_zfs() { + if [ ! "$(kldstat -m zfs)" ]; then + info "ZFS module not loaded; skipping..." + else + ## attempt to determine bastille_zroot from `zpool list` + bastille_zroot=$(zpool list | grep -v NAME | awk '{print $1}') + sysrc -f "${bastille_prefix}/bastille.conf" bastille_zfs_enable=YES + sysrc -f "${bastille_prefix}/bastille.conf" bastille_zfs_zpool="${bastille_zroot}" + fi +} + +# Run all base functions (w/o vnet) if no args +if [ $# -eq 0 ]; then + sysrc bastille_enable=YES + configure_bastille0 + configure_pf + configure_zfs +fi + +# Handle special-case commands first. +case "$1" in +help|-h|--help) + usage + ;; +pf|firewall) + configure_pf + ;; +bastille0|loopback) + configure_bastille0 + ;; +zfs|storage) + configure_zfs + ;; +bastille1|vnet|bridge) + configure_vnet + ;; +esac diff --git a/usr/local/share/bastille/start.sh b/usr/local/share/bastille/start.sh index c681e1648..83aaf1adf 100644 --- a/usr/local/share/bastille/start.sh +++ b/usr/local/share/bastille/start.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -gt 1 ] || [ $# -lt 1 ]; then usage fi +bastille_root_check + TARGET="${1}" shift diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index 5343d77dd..ab600956a 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -ne 0 ]; then usage fi +bastille_root_check + for _jail in ${JAILS}; do ## test if running if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then diff --git a/usr/local/share/bastille/sysrc.sh b/usr/local/share/bastille/sysrc.sh index 20445f838..6429d28fd 100644 --- a/usr/local/share/bastille/sysrc.sh +++ b/usr/local/share/bastille/sysrc.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -45,6 +45,8 @@ if [ $# -lt 1 ]; then usage fi +bastille_root_check + for _jail in ${JAILS}; do info "[${_jail}]:" jexec -l "${_jail}" /usr/sbin/sysrc "$@" diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh new file mode 100644 index 000000000..6c8cca62e --- /dev/null +++ b/usr/local/share/bastille/tags.sh @@ -0,0 +1,104 @@ +#!/bin/sh +# +# Copyright (c) 2018-2023, Christer Edwards +# All rights reserved. +# Ressource limits added by Lars Engels github.com/bsdlme +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +. /usr/local/share/bastille/common.sh +. /usr/local/etc/bastille/bastille.conf + +usage() { + error_notify "Usage: bastille tags TARGET add tag1[,tag2,...]" + error_notify " bastille tags TARGET delete tag1[,tag2,...]" + error_notify " bastille tags TARGET list [tag]" + echo -e "Example: bastille tags JAILNAME add database,mysql" + echo -e " bastille tags JAILNAME delete mysql" + echo -e " bastille tags ALL list" + echo -e " bastille tags ALL list mysql" + exit 1 +} + +# Handle special-case commands first. +case "$1" in +help|-h|--help) + usage + ;; +esac + +if [ $# -lt 1 -o $# -gt 2 ]; then + usage +fi + +bastille_root_check + +ACTION="${1}" +TAGS="${2}" + +for _jail in ${JAILS}; do + bastille_jail_tags="${bastille_jailsdir}/${_jail}/tags" + case ${ACTION} in + add) + for _tag in $(echo ${TAGS} | tr , ' '); do + echo ${_tag} >> "${bastille_jail_tags}" + tmpfile="$(mktemp)" + sort "${bastille_jail_tags}" | uniq > "${tmpfile}" + mv "${tmpfile}" "${bastille_jail_tags}" + done + ;; + del*) + for _tag in $(echo ${TAGS} | tr , ' '); do + [ ! -f "${bastille_jail_tags}" ] && break # skip if no tags file + tmpfile="$(mktemp)" + grep -Ev "^${_tag}\$" "${bastille_jail_tags}" > "${tmpfile}" + mv "${tmpfile}" "${bastille_jail_tags}" + # delete tags file if empty + [ ! -s "${bastille_jail_tags}" ] && rm "${bastille_jail_tags}" + done + ;; + list) + if [ -n "${TAGS}" ]; then + [ -n "$(echo ${TAGS} | grep ,)" ] && usage # Only one tag per query + [ ! -f "${bastille_jail_tags}" ] && continue # skip if there is no tags file + grep -qE "^${TAGS}\$" "${bastille_jail_tags}" + if [ $? -eq 0 ]; then + echo "${_jail}" + continue + fi + else + if [ -f "${bastille_jail_tags}" ]; then + echo -n "${_jail}: " + xargs < "${bastille_jail_tags}" + fi + fi + ;; + *) + usage + ;; + esac +done + diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 9cb94d09c..058431bd1 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -116,6 +116,8 @@ if [ $# -lt 1 ]; then bastille_usage fi +bastille_root_check + ## global variables TEMPLATE="${1}" bastille_template=${bastille_templatesdir}/${TEMPLATE} diff --git a/usr/local/share/bastille/top.sh b/usr/local/share/bastille/top.sh index 5f8d59929..59ade595e 100644 --- a/usr/local/share/bastille/top.sh +++ b/usr/local/share/bastille/top.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -45,6 +45,8 @@ if [ $# -ne 0 ]; then usage fi +bastille_root_check + for _jail in ${JAILS}; do info "[${_jail}]:" jexec -l "${_jail}" /usr/bin/top diff --git a/usr/local/share/bastille/umount.sh b/usr/local/share/bastille/umount.sh index b9513c424..315656c3a 100644 --- a/usr/local/share/bastille/umount.sh +++ b/usr/local/share/bastille/umount.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -ne 1 ]; then usage fi +bastille_root_check + MOUNT_PATH=$1 for _jail in ${JAILS}; do diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index eeb8325b2..582b22a32 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -gt 2 ] || [ $# -lt 1 ]; then usage fi +bastille_root_check + TARGET="${1}" OPTION="${2}" @@ -116,7 +118,9 @@ release_update() { fi env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \ - fetch install --currently-running "${TARGET_TRIM}" + fetch --currently-running "${TARGET_TRIM}" + env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \ + install --currently-running "${TARGET_TRIM}" else error_exit "${TARGET} not found. See 'bastille bootstrap'." fi diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index eb2a16724..225ff170c 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,6 +46,8 @@ if [ $# -gt 3 ] || [ $# -lt 2 ]; then usage fi +bastille_root_check + TARGET="$1" NEWRELEASE="$2" OPTION="$3" @@ -87,7 +89,7 @@ jail_check() { release_check() { # Validate the release - if ! echo "${NEWRELEASE}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then + if ! echo "${NEWRELEASE}" | grep -q "[0-9]\{2\}.[0-9]-[RELEASE,BETA,RC]"; then error_exit "${NEWRELEASE} is not a valid release." fi } diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index be513dad2..177f02946 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -154,8 +154,10 @@ if [ $# -gt 1 ] || [ $# -lt 1 ]; then bastille_usage fi +bastille_root_check + case "$1" in -*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2) +*-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]) RELEASE=$1 verify_release ;; diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 62ddd92be..02ea7053c 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2022, Christer Edwards +# Copyright (c) 2018-2023, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -43,6 +43,14 @@ for _jail in ${JAILS}; do done } +zfs_destroy_snapshot() { +for _jail in ${JAILS}; do + info "[${_jail}]:" + zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" + echo +done +} + zfs_set_value() { for _jail in ${JAILS}; do info "[${_jail}]:" @@ -74,8 +82,10 @@ help|-h|--help) ;; esac +bastille_root_check + ## check ZFS enabled -if [ ! "${bastille_zfs_enable}" = "YES" ]; then +if ! checkyesno bastille_zfs_enable; then error_exit "ZFS not enabled." fi @@ -101,6 +111,10 @@ snap|snapshot) TAG=$2 zfs_snapshot ;; +destroy_snap|destroy_snapshot) + TAG=$2 + zfs_destroy_snapshot + ;; df|usage) zfs_disk_usage ;;