Compare commits

...

97 Commits

Author SHA1 Message Date
Christer Edwards
a95040ac62 Merge pull request #198 from cedwards/0_6_release_validation
updating release version
2020-04-12 19:41:44 -06:00
Christer Edwards
9173674256 updating release version 2020-04-12 19:39:46 -06:00
Christer Edwards
0ca7c467ec Merge pull request #197 from cedwards/0_6_release_validation
release validation fixes
2020-04-12 19:15:13 -06:00
Christer Edwards
6558fdc403 Merge pull request #196 from cedwards/network_cleanup
network cleanup; default route addition for vnet
2020-04-12 19:12:38 -06:00
Christer Edwards
945944feb4 release validation fixes 2020-04-12 19:06:27 -06:00
Christer Edwards
106c566c88 network cleanup; default route addition for vnet 2020-04-12 17:04:37 -06:00
Christer Edwards
84b091474d Merge pull request #191 from JRGTH/master
Support for 'qjail' imports, import cmd improvements and fixes
2020-04-11 11:02:31 -06:00
Jose
4d538da4f8 Support for 'qjail' imports, import cmd improvements and fixes 2020-04-11 11:12:03 -04:00
Christer Edwards
f211fd268c Merge pull request #187 from hackacad/fix_man7
updated man page
2020-04-11 07:25:07 -06:00
Bike Dude
2f8128b160 updated 0.6.20200412 2020-04-10 21:19:39 +02:00
Christer Edwards
4e3b972cf7 Merge pull request #190 from JRGTH/master
Code cleanup, don't delete snapshot recursively
2020-04-09 09:20:41 -06:00
Jose
00443ccdd1 Destroy related datasets on target, simplify snapshot naming 2020-04-09 06:32:00 -04:00
Jose
d4dc133e19 Revert to recursive, mandatory here 2020-04-08 23:33:43 -04:00
Jose
4788e78436 Code cleanup, don't delete snapshot recursively 2020-04-08 23:21:13 -04:00
Christer Edwards
7ab17c2355 Merge pull request #184 from JRGTH/master
Support for 'ezjail' archive import, improvements and fixes
2020-04-08 12:57:06 -06:00
Christer Edwards
e436b36168 Merge pull request #182 from hackacad/rdr_destroy
add_rdr_destroy
2020-04-08 12:50:04 -06:00
Christer Edwards
7933d02d47 Merge pull request #173 from hackacad/clone.sh
RFC [NEW FEATURE] clone.sh
2020-04-08 12:45:43 -06:00
Christer Edwards
537cd66fd4 Merge pull request #188 from hackacad/fix_zfs_snap
fix zfs snapshot recursive
2020-04-08 08:19:52 -06:00
Bike Dude
3f386056a9 fix zfs snapshot recursive 2020-04-08 14:10:38 +02:00
Jose
241ce01074 Let zfs mountpoints be inherited on standard archive imports 2020-04-08 06:47:33 -04:00
svru
4de6f59e63 updated man page
Signed-off-by: svru <svru@svrus-MacBook-Pro.local>
2020-04-08 11:24:36 +02:00
Jose
bfa500a183 Always check if user specified path exist 2020-04-04 10:23:43 -04:00
Jose
7db47f3dac Allow the user specify path for Export/Import on-the-fly 2020-04-04 09:46:56 -04:00
Jose
c2fefc5f16 Support for 'ezjail' archive import, improvements and fixes 2020-04-03 07:56:28 -04:00
Bike Dude
0f4597a2c6 add_rdr_destroy 2020-03-30 22:33:32 +02:00
Christer Edwards
67964a7fbb Merge pull request #181 from cynix/fix_first_vnet_jail
Fix empty interface name when creating the first VNET jail.
2020-03-30 13:51:06 -06:00
cynix
ced148bcc7 Clean up code 2020-03-30 08:48:04 +00:00
cynix
6e850785a2 Fix empty interface name when creating the first VNET jail.
Fixes #170.
2020-03-30 08:41:33 +00:00
Christer Edwards
384ba3b82e Merge pull request #177 from hackacad/chmod_issue
Chmod issue
2020-03-10 15:13:39 -06:00
Bike Dude
512f973950 chmod issue fixed 2020-03-10 20:47:33 +01:00
Bike Dude
2240211f6a fix merge conflict 2020-03-10 20:46:09 +01:00
Sven R
afc363d72d Merge branch 'master' into chmod_issue 2020-03-10 20:41:19 +01:00
Christer Edwards
e804afa2b5 Merge pull request #174 from hackacad/rename_fix
no dots allowed in rename.sh
2020-03-10 10:48:58 -06:00
Christer Edwards
148dba4b22 Merge pull request #176 from hackacad/issue_templates
Create issue templates
2020-03-10 10:48:29 -06:00
Sven R
102fbc7d51 bootstrap chmod 2020-03-10 17:15:46 +01:00
Sven R
ac96e8b6ec bootstrap chmod 2020-03-10 17:14:18 +01:00
Sven R
0cbc8ff8e7 Create issue templates 2020-03-10 15:31:18 +01:00
Bike Dude
af06250c1d no dots allowed in rename.sh 2020-03-06 23:34:18 +01:00
Bike Dude
ed90760f68 several fixes 2020-03-06 23:12:09 +01:00
hackacad
c03d43af09 fix 2020-03-04 12:22:24 +01:00
hackacad
bc82da9aaa [NEW FEATURE] clone.sh 2020-03-04 10:52:17 +01:00
Christer Edwards
a3c40b2727 Merge pull request #169 from hackacad/import_fix
fix renaming on bastille import
2020-03-02 10:57:17 -07:00
Sven R
4bd0a9d00d Merge branch 'master' into import_fix 2020-02-27 07:43:52 +01:00
hackacad
a3311c5aa9 Merge branch 'master' of github.com:/hackacad/bastille into import_fix 2020-02-27 07:39:16 +01:00
Sven R
659517b595 fix_import 2020-02-25 12:48:52 +01:00
Sven R
73e97ab18f fix_import 2020-02-25 12:43:16 +01:00
Sven R
c342b5cdc0 fix_import 2020-02-25 12:37:01 +01:00
Christer Edwards
644b5319a1 Merge pull request #168 from cedwards/hushlogin
quiet login message on container login
2020-02-24 19:39:27 -07:00
Christer Edwards
be6a0e1b5f quiet login message on container login 2020-02-24 19:27:51 -07:00
Christer Edwards
d0f5b31e42 Merge pull request #166 from cedwards/quoting_fixes
overzealous quoting
2020-02-21 20:05:10 -07:00
Christer Edwards
8350af9c4f overzealous quoting 2020-02-21 20:04:17 -07:00
Christer Edwards
3945e82213 Merge pull request #162 from JRGTH/master
code standardization/cleanup; import improvements
2020-02-21 19:45:12 -07:00
Jose
9b3fde59b8 Fix Thickjail mountpoint inheritance in the root dataset 2020-02-21 11:35:35 -04:00
Jose
8e30774235 Merge remote-tracking branch 'upstream/master' 2020-02-21 11:31:12 -04:00
Christer Edwards
a18927fb7a Merge pull request #164 from hackacad/bastille_export_fix
remove colon from filename
2020-02-21 07:30:22 -07:00
Sven R
a0b522c48e remove colon from filename 2020-02-21 13:58:45 +01:00
Jose
29016faf20 Just return 0 if bastille_jail_external is set 2020-02-20 21:08:04 -04:00
Jose
01eaccc1da Add double quotes to prevent globbing/word splitting, general code consistency improvements 2020-02-20 18:06:31 -04:00
Christer Edwards
9481b6a1e6 Merge pull request #161 from JRGTH/master
Workaround  to combine options first, code cleanup/maintenance
2020-02-20 09:29:24 -07:00
Jose
8c1f9cd57a Just grep globally if jail list not empty 2020-02-20 12:22:25 -04:00
Jose
6b7b506c83 Simplify destroy options, no need to shift 1 on single options 2020-02-20 10:41:41 -04:00
Jose
e26fe60fe4 Keep options simple yet support for long options 2020-02-19 19:53:25 -04:00
Sven R
2fa9f34be6 lint
remove EOL release (reduce size of README)
2020-02-19 08:34:23 +01:00
Jose
5b25dbcdc5 Initial support to import foreign containers, ignore fstab update if don't exist. 2020-02-18 19:58:59 -04:00
Jose
3b8c339dfa Workaround to combine options first, code cleanup/maintenance 2020-02-18 17:04:06 -04:00
Christer Edwards
c6357127ea Merge pull request #160 from cedwards/quoting_fixes
properly quoting variables
2020-02-17 09:42:37 -07:00
Christer Edwards
950342f54e properly quoting variables 2020-02-17 09:41:33 -07:00
Christer Edwards
f271547e23 Merge pull request #159 from cedwards/documentation
basic VNET example + devfs.rules
2020-02-16 15:44:20 -07:00
Christer Edwards
c4ede0a829 basic VNET example + devfs.rules 2020-02-16 15:43:13 -07:00
Christer Edwards
64a4dd5987 Merge pull request #158 from cedwards/vnet_initial
Ability to create VNET containers
2020-02-16 15:28:13 -07:00
Christer Edwards
814dc6d926 properly set ip6 mode 2020-02-16 15:22:32 -07:00
Christer Edwards
273acb6e50 initial support to create vnet container 2020-02-16 15:20:31 -07:00
Christer Edwards
099c45422d Merge pull request #156 from cedwards/ip6_README
update README with ip6 example
2020-02-16 14:24:10 -07:00
Christer Edwards
863c3cacc5 update README with ip6 example 2020-02-16 14:23:05 -07:00
Christer Edwards
b1380b30e5 Merge pull request #154 from JRGTH/master
Initial IPv6 support
2020-02-16 10:26:08 -07:00
Jose
75fc18fec9 Initial IPv6 support 2020-02-16 13:22:32 -04:00
Christer Edwards
32ddcd5439 Merge pull request #153 from cedwards/edit_fixes
fixes for new edit sub-command; supports stopped as it should
2020-02-16 09:57:49 -07:00
Christer Edwards
26846d510e fixes for new edit sub-command; supports stopped as it should 2020-02-16 09:56:04 -07:00
Christer Edwards
44989660d2 Merge pull request #152 from JRGTH/master
Ignore IPv4 check if there is no entry at all
2020-02-15 13:43:44 -07:00
Jose
015558c4bc Don't set jail ZFS dataset mountpoint, let be inherited from the system 2020-02-15 07:57:33 -04:00
Jose
53e7856d28 Ignore IPv4 check if there is no entry at all 2020-02-14 19:01:08 -04:00
Christer Edwards
0e39f7cabb Merge pull request #151 from JRGTH/master
Return proper warning messages, code cleanup
2020-02-14 08:46:18 -07:00
Jose
19cadec03e Add quoted variables to rctl 2020-02-14 11:43:26 -04:00
Jose
7ef65036c6 Return proper warning messages, code cleanup 2020-02-14 11:00:02 -04:00
Christer Edwards
ee81a73264 Merge pull request #148 from hackacad/Makefile_bastilleconf
make deinstall: avoid removing bastille.conf
2020-02-13 06:58:05 -07:00
Sven R
fd90a21777 make deinstall: avoid removing bastille.conf 2020-02-13 07:37:38 +01:00
Sven R
a3494c1007 make deinstall: avoid removing bastille.conf 2020-02-13 07:34:31 +01:00
Christer Edwards
d667f93bc5 Merge pull request #147 from cedwards/edit_jail_files
ability to edit TARGET files (jail.conf, fstab, etc)
2020-02-12 16:48:46 -07:00
Christer Edwards
1e2bbcd3b7 Merge pull request #146 from JRGTH/master
Cleanup unused code, display related platform OS while bootstrapping …
2020-02-12 16:47:51 -07:00
Jose
1d1ea761fe Display corresponding platform OS while extracting distfiles 2020-02-11 17:43:52 -04:00
Jose
bf0bffd30f Update HardenedBSD options in bootstrap command too 2020-02-11 17:27:02 -04:00
Jose
fe012c44f0 Update HardenedBSD options in destroy command too 2020-02-10 15:39:14 -04:00
Jose
d1709b7199 Add HardenedBSD support for convert, import and rename commands 2020-02-10 15:22:41 -04:00
Jose
0e93832a30 Minor change, update comment 2020-02-10 14:10:00 -04:00
Jose
206d6a59e9 Ability to rename containers in both ZFS and UFS platforms 2020-02-10 14:03:28 -04:00
Christer Edwards
e3492d4087 ability to edit TARGET files (jail.conf, fstab, etc) 2020-02-10 10:42:09 -07:00
Jose
84cc8cb103 Cleanup unused code, display related platform OS while bootstrapping for reference 2020-02-08 09:10:17 -04:00
32 changed files with 1345 additions and 503 deletions

26
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,26 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''
---
**[MANDATORY] Describe the bug [MANDATORY]**
A clear and concise description of what the bug is.
**[MANDATORY] Bastille and FreeBSD version (paste ``bastille -v && freebsd-version -kru`` output)**
**[MANDATORY] How did you install bastille? (port/pkg/git)**
**[optional] Steps to reproduce?**
**[optional] Expected behavior**
A clear and concise description of what you expected to happen.
**[optional] Screenshots**
If applicable, add screenshots to help explain your problem.
**[optional] Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Enhancement & Feature Request
title: "[ENHANCEMENT]"
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -21,7 +21,8 @@ uninstall:
@rm -rvf /usr/local/share/man/man1/bastille.1.gz @rm -rvf /usr/local/share/man/man1/bastille.1.gz
@echo @echo
@echo "removing configuration file" @echo "removing configuration file"
@rm -rvf /usr/local/etc/bastille @rm -rvf /usr/local/etc/bastille/bastille.conf.sample
@echo @echo
@echo "removing startup script" @echo "removing startup script"
@rm -vf /usr/local/etc/rc.d/bastille @rm -vf /usr/local/etc/rc.d/bastille
@echo "You may need to manually remove /usr/local/etc/bastille/bastille.conf if it is no longer needed."

102
README.md
View File

@@ -1,11 +1,10 @@
Bastille: Automate Container Security Bastille
===================================== ========
[Bastille](https://bastillebsd.org/) is an open-source system for automating [Bastille](https://bastillebsd.org/) is an open-source system for automating
deployment and management of containerized applications on FreeBSD. deployment and management of containerized applications on FreeBSD.
Looking for [Bastille Templates](https://gitlab.com/BastilleBSD-Templates/)? Looking for [Bastille Templates](https://gitlab.com/BastilleBSD-Templates/)?
Installation Installation
============ ============
Bastille is available in the official FreeBSD ports tree. Bastille is available in the official FreeBSD ports tree.
@@ -21,7 +20,7 @@ portsnap fetch auto
make -C /usr/ports/sysutils/bastille install clean make -C /usr/ports/sysutils/bastille install clean
``` ```
**Git** **Git** (bleeding edge / unstable -- primarily for developers)
```shell ```shell
git clone https://github.com/BastilleBSD/bastille.git git clone https://github.com/BastilleBSD/bastille.git
cd bastille cd bastille
@@ -44,12 +43,15 @@ Usage:
Available Commands: Available Commands:
bootstrap Bootstrap a FreeBSD release for container base. bootstrap Bootstrap a FreeBSD release for container base.
clone Clone an existing container.
cmd Execute arbitrary command on targeted container(s). cmd Execute arbitrary command on targeted container(s).
clone Clone an existing container.
console Console into a running container. 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). cp cp(1) files from host to targeted container(s).
create Create a new thin or thick container. create Create a new thin or thick container.
destroy Destroy a stopped container or a bootstrapped release. destroy Destroy a stopped container or a bootstrapped release.
edit Edit container configuration files (advanced).
export Exports a container archive or image. export Exports a container archive or image.
help Help about any command help Help about any command
htop Interactive process viewer (requires htop). htop Interactive process viewer (requires htop).
@@ -121,9 +123,9 @@ table <jails> persist
nat on $ext_if from <jails> to any -> ($ext_if) nat on $ext_if from <jails> to any -> ($ext_if)
## static rdr example ## static rdr example
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45 # rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
# Enable dynamic rdr (see below) ## Enable dynamic rdr (see below)
rdr-anchor "rdr/*" rdr-anchor "rdr/*"
block in all block in all
@@ -131,7 +133,7 @@ pass out quick modulate state
antispoof for $ext_if inet antispoof for $ext_if inet
pass in inet proto tcp from any to any port ssh flags S/SA keep state 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 ## 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 <rdr-start>:<rdr-end> flags S/SA keep state # pass in inet proto tcp from any to any port <rdr-start>:<rdr-end> flags S/SA keep state
# pass in inet proto udp from any to any port <rdr-start>:<rdr-end> flags S/SA keep state # pass in inet proto udp from any to any port <rdr-start>:<rdr-end> flags S/SA keep state
@@ -241,11 +243,6 @@ release version as the argument.
ishmael ~ # bastille bootstrap 11.3-RELEASE ishmael ~ # bastille bootstrap 11.3-RELEASE
``` ```
**FreeBSD 12.0-RELEASE**
```shell
ishmael ~ # bastille bootstrap 12.0-RELEASE
```
**FreeBSD 12.1-RELEASE** **FreeBSD 12.1-RELEASE**
```shell ```shell
ishmael ~ # bastille bootstrap 12.1-RELEASE ishmael ~ # bastille bootstrap 12.1-RELEASE
@@ -298,26 +295,81 @@ IP at container creation.
- name - name
- release (bootstrapped) - release (bootstrapped)
- ip - ip (ip4 or ip6)
- interface (optional) - interface (optional)
**ip4**
```shell ```shell
ishmael ~ # bastille create folsom 12.0-RELEASE 10.17.89.10 ishmael ~ # bastille create folsom 12.1-RELEASE 10.17.89.10
Valid: (10.17.89.10). Valid: (10.17.89.10).
NAME: folsom. NAME: folsom.
IP: 10.17.89.10. IP: 10.17.89.10.
RELEASE: 12.0-RELEASE. RELEASE: 12.1-RELEASE.
syslogd_flags: -s -> -ss syslogd_flags: -s -> -ss
sendmail_enable: NO -> NONE sendmail_enable: NO -> NONE
cron_flags: -> -J 60 cron_flags: -> -J 60
``` ```
This command will create a 12.0-RELEASE container assigning the 10.17.89.10 ip This command will create a 12.1-RELEASE container assigning the 10.17.89.10 ip
address to the new system. address to the new system.
**ip6**
```shell
ishmael ~ # bastille create folsom 12.1-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.1-RELEASE container assigning the
fd35:f1fd:2cb6:6c5c::13 ip address to the new system.
**VNET**
```shell
ishmael ~ # bastille create -V vnetjail 12.1-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.1-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 include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add include $devfsrules_jail
add path 'bpf*' unhide
```
Optionally `bastille create [ -T | --thick ]` will create a container with a Optionally `bastille create [ -T | --thick ]` will create a container with a
private base. This is sometimes referred to as a "thick" container (whereas the private base. This is sometimes referred to as a "thick" container (whereas the
shared base container is a "thin"). shared base container is a "thin").
@@ -613,7 +665,7 @@ work as expected. This table outlines that order and those requirements:
| PLANNED | format | example | | PLANNED | format | example |
|---------|------------------|----------------------------------------------------------------| |---------|------------------|----------------------------------------------------------------|
| PF | pf rdr entry | rdr pass inet proto tcp from any to any port 80 -> 10.17.89.80 | | RDR | pf rdr entry | rdr pass inet proto tcp from any to any port 80 -> 10.17.89.80 |
| LOG | path | /var/log/nginx/access.log | | LOG | path | /var/log/nginx/access.log |
Note: SYSRC requires NO quotes or that quotes (`"`) be escaped. ie; `\"`) Note: SYSRC requires NO quotes or that quotes (`"`) be escaped. ie; `\"`)
@@ -752,7 +804,7 @@ ishmael ~ # bastille cp ALL /tmp/resolv.conf-cf etc/resolv.conf
/tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound0/root/etc/resolv.conf /tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound0/root/etc/resolv.conf
``` ```
bastille-rdr bastille rdr
------------ ------------
`bastille rdr` allows you to configure dynamic rdr rules for your containers `bastille rdr` allows you to configure dynamic rdr rules for your containers
@@ -761,7 +813,7 @@ for a private network and have enabled `rdr-anchor 'rdr/*'` in /etc/pf.conf
as described in the Networking section). as described in the Networking section).
```shell ```shell
# bastille rdr --help # bastille rdr help
Usage: bastille rdr TARGET [clear] | [list] | [tcp <host_port> <jail_port>] | [udp <host_port> <jail_port>] Usage: bastille rdr TARGET [clear] | [list] | [tcp <host_port> <jail_port>] | [udp <host_port> <jail_port>]
# bastille rdr dev1 tcp 2001 22 # bastille rdr dev1 tcp 2001 22
# bastille rdr dev1 list # bastille rdr dev1 list
@@ -875,6 +927,18 @@ Receiving zfs data stream...
Container 'folsom' imported successfully. 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
```
Example (create, start, console) Example (create, start, console)
================================ ================================
This example creates, starts and consoles into the container. This example creates, starts and consoles into the container.

View File

@@ -69,7 +69,7 @@ bastille_perms_check
. /usr/local/etc/bastille/bastille.conf . /usr/local/etc/bastille/bastille.conf
## version ## version
BASTILLE_VERSION="0.6.20200202" BASTILLE_VERSION="0.6.20200412"
usage() { usage() {
cat << EOF cat << EOF
@@ -82,11 +82,13 @@ Usage:
Available Commands: Available Commands:
bootstrap Bootstrap a FreeBSD release for container base. bootstrap Bootstrap a FreeBSD release for container base.
cmd Execute arbitrary command on targeted container(s). cmd Execute arbitrary command on targeted container(s).
clone Clone an existing container.
console Console into a running container. 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). cp cp(1) files from host to targeted container(s).
create Create a new thin container or a thick container if -T|--thick option specified. create Create a new thin container or a thick container if -T|--thick option specified.
destroy Destroy a stopped container or a FreeBSD release. destroy Destroy a stopped container or a FreeBSD release.
edit Edit container configuration files (advanced).
export Exports a specified container. export Exports a specified container.
help Help about any command. help Help about any command.
htop Interactive process viewer (requires htop). htop Interactive process viewer (requires htop).
@@ -94,6 +96,7 @@ Available Commands:
list List containers (running and stopped). list List containers (running and stopped).
pkg Manipulate binary packages within targeted container(s). See pkg(8). pkg Manipulate binary packages within targeted container(s). See pkg(8).
rdr Redirect host port to container port. rdr Redirect host port to container port.
rename Rename a container.
restart Restart a running container. restart Restart a running container.
service Manage services within targeted container(s). service Manage services within targeted container(s).
start Start a stopped container. start Start a stopped container.
@@ -131,11 +134,11 @@ esac
# Filter out all non-commands # Filter out all non-commands
case "${CMD}" in case "${CMD}" in
bootstrap|cmd|console|convert|cp|create) bootstrap|clone|cmd|console|convert|cp|create)
;; ;;
destroy|export|htop|import|limits|list) destroy|edit|export|htop|import|limits|list)
;; ;;
pkg|rdr|restart|service|start|stop|sysrc) pkg|rdr|rename|restart|service|start|stop|sysrc)
;; ;;
template|top|update|upgrade|verify|zfs) template|top|update|upgrade|verify|zfs)
;; ;;

View File

@@ -38,8 +38,6 @@ bastille_compress_xz_options="-0 -v" ## default
bastille_decompress_xz_options="-c -d -v" ## default "-c -d -v" bastille_decompress_xz_options="-c -d -v" ## default "-c -d -v"
## Networking ## Networking
bastille_jail_loopback="lo1" ## default: "lo1" bastille_network_loopback="bastille0" ## default: "bastille0"
bastille_jail_interface="bastille0" ## default: "bastille0" bastille_network_shared="" ## default: ""
bastille_jail_external="" ## default: "" bastille_network_gateway="" ## default: ""
bastille_jail_addr="10.17.89.10" ## default: "10.17.89.10"
bastille_jail_gateway="" ## default: ""

Binary file not shown.

View File

@@ -74,6 +74,7 @@ validate_release_url() {
echo -e "${COLOR_RED}Unable to fetch MANIFEST, See 'bootstrap urls'.${COLOR_RESET}" echo -e "${COLOR_RED}Unable to fetch MANIFEST, See 'bootstrap urls'.${COLOR_RESET}"
exit 1 exit 1
fi fi
echo -e "${COLOR_GREEN}Bootstrapping ${PLATFORM_OS} distfiles...${COLOR_RESET}"
bootstrap_directories bootstrap_directories
bootstrap_release bootstrap_release
else else
@@ -81,106 +82,15 @@ validate_release_url() {
fi fi
} }
bootstrap_network_interfaces() {
## test for both options empty
if [ -z "${bastille_jail_loopback}" ] && [ -z "${bastille_jail_external}" ]; then
echo -e "${COLOR_RED}Please set preferred loopback or external interface.${COLOR_RESET}"
echo -e "${COLOR_RED}See bastille.conf.${COLOR_RESET}"
exit 1
fi
## test for required variables -- external
if [ -z "${bastille_jail_loopback}" ] && [ ! -z "${bastille_jail_external}" ]; then
## test for existing interface
ifconfig ${bastille_jail_external} 2>&1 >/dev/null
if [ $? = 0 ]; then
## create ifconfig alias
ifconfig ${bastille_jail_external} inet ${bastille_jail_addr} alias && \
echo -e "${COLOR_GREEN}IP alias added to ${bastille_jail_external} successfully.${COLOR_RESET}"
echo
## attempt to ping gateway
echo -e "${COLOR_YELLOW}Attempting to ping default gateway...${COLOR_RESET}"
ping -c3 -t3 -S ${bastille_jail_addr} ${bastille_jail_gateway}
if [ $? = 0 ]; then
echo
echo -e "${COLOR_GREEN}External networking appears functional.${COLOR_RESET}"
echo
else
echo -e "${COLOR_RED}Unable to ping default gateway.${COLOR_RESET}"
fi
fi
fi
## test for required variables -- loopback
if [ -z "${bastille_jail_external}" ] && [ ! -z "${bastille_jail_loopback}" ] && \
[ ! -z "${bastille_jail_addr}" ]; then
echo -e "${COLOR_GREEN}Detecting...${COLOR_RESET}"
## test for existing interface
ifconfig ${bastille_jail_interface} >&2 >/dev/null
## if above return code is 1; create interface
if [ $? = 1 ]; then
sysrc ifconfig_${bastille_jail_loopback}_name | grep ${bastille_jail_interface} >&2 >/dev/null
if [ $? = 1 ]; then
echo
echo -e "${COLOR_GREEN}Defining secure loopback interface.${COLOR_RESET}"
sysrc cloned_interfaces+="${bastille_jail_loopback}" &&
sysrc ifconfig_${bastille_jail_loopback}_name="${bastille_jail_interface}"
sysrc ifconfig_${bastille_jail_interface}_aliases+="inet ${bastille_jail_addr}/32"
## create and name interface; assign address
echo
echo -e "${COLOR_GREEN}Creating secure loopback interface.${COLOR_RESET}"
ifconfig ${bastille_jail_loopback} create name ${bastille_jail_interface}
ifconfig ${bastille_jail_interface} up
ifconfig ${bastille_jail_interface} inet ${bastille_jail_addr}/32
## reload firewall
pfctl -f /etc/pf.conf
## look for nat rule for bastille_jail_addr
echo -e "${COLOR_GREEN}Detecting NAT from bastille0 interface...${COLOR_RESET}"
pfctl -s nat | grep nat | grep ${bastille_jail_addr}
if [ $? = 0 ]; then
## test connectivity; ping from bastille_jail_addr
echo
echo -e "${COLOR_YELLOW}Attempting to ping default gateway...${COLOR_RESET}"
ping -c3 -t3 -S ${bastille_jail_addr} ${bastille_jail_gateway}
if [ $? = 0 ]; then
echo
echo -e "${COLOR_GREEN}Private networking appears functional.${COLOR_RESET}"
echo
else
echo -e "${COLOR_RED}Unable to ping default gateway.${COLOR_RESET}"
echo -e "${COLOR_YELLOW}See https://github.com/BastilleBSD/bastille/blob/master/README.md#etcpfconf.${COLOR_RESET}"
echo -e
fi
else
echo -e "${COLOR_RED}Unable to detect firewall 'nat' rule.${COLOR_RESET}"
echo -e "${COLOR_YELLOW}See https://github.com/BastilleBSD/bastille/blob/master/README.md#etcpfconf.${COLOR_RESET}"
fi
else
echo -e "${COLOR_RED}Interface ${bastille_jail_loopback} already configured; bailing out.${COLOR_RESET}"
fi
else
echo -e "${COLOR_RED}Interface ${bastille_jail_interface} already active; bailing out.${COLOR_RESET}"
fi
fi
}
bootstrap_directories() { bootstrap_directories() {
## ensure required directories are in place ## ensure required directories are in place
## ${bastille_prefix} ## ${bastille_prefix}
if [ ! -d "${bastille_prefix}" ]; then if [ ! -d "${bastille_prefix}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ];then if [ "${bastille_zfs_enable}" = "YES" ];then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_prefix} ${bastille_zfs_zpool}/${bastille_zfs_prefix} zfs create ${bastille_zfs_options} -o mountpoint="${bastille_prefix}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}"
chmod 0750 "${bastille_prefix}"
fi fi
else else
mkdir -p "${bastille_prefix}" mkdir -p "${bastille_prefix}"
@@ -191,8 +101,9 @@ bootstrap_directories() {
## ${bastille_backupsdir} ## ${bastille_backupsdir}
if [ ! -d "${bastille_backupsdir}" ]; then if [ ! -d "${bastille_backupsdir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ];then if [ "${bastille_zfs_enable}" = "YES" ];then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_backupsdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/backups zfs create ${bastille_zfs_options} -o mountpoint="${bastille_backupsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/backups"
chmod 0750 "${bastille_backupsdir}"
fi fi
else else
mkdir -p "${bastille_backupsdir}" mkdir -p "${bastille_backupsdir}"
@@ -203,9 +114,9 @@ bootstrap_directories() {
## ${bastille_cachedir} ## ${bastille_cachedir}
if [ ! -d "${bastille_cachedir}" ]; then if [ ! -d "${bastille_cachedir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_cachedir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache"
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_cachedir}/${RELEASE} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE} zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}"
fi fi
else else
mkdir -p "${bastille_cachedir}/${RELEASE}" mkdir -p "${bastille_cachedir}/${RELEASE}"
@@ -213,8 +124,8 @@ bootstrap_directories() {
## create subsequent cache/XX.X-RELEASE datasets ## create subsequent cache/XX.X-RELEASE datasets
elif [ ! -d "${bastille_cachedir}/${RELEASE}" ]; then elif [ ! -d "${bastille_cachedir}/${RELEASE}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; 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} zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}"
fi fi
else else
mkdir -p "${bastille_cachedir}/${RELEASE}" mkdir -p "${bastille_cachedir}/${RELEASE}"
@@ -224,8 +135,8 @@ bootstrap_directories() {
## ${bastille_jailsdir} ## ${bastille_jailsdir}
if [ ! -d "${bastille_jailsdir}" ]; then if [ ! -d "${bastille_jailsdir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_jailsdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails zfs create ${bastille_zfs_options} -o mountpoint="${bastille_jailsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails"
fi fi
else else
mkdir -p "${bastille_jailsdir}" mkdir -p "${bastille_jailsdir}"
@@ -235,8 +146,8 @@ bootstrap_directories() {
## ${bastille_logsdir} ## ${bastille_logsdir}
if [ ! -d "${bastille_logsdir}" ]; then if [ ! -d "${bastille_logsdir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_logsdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/logs zfs create ${bastille_zfs_options} -o mountpoint="${bastille_logsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/logs"
fi fi
else else
mkdir -p "${bastille_logsdir}" mkdir -p "${bastille_logsdir}"
@@ -246,8 +157,8 @@ bootstrap_directories() {
## ${bastille_templatesdir} ## ${bastille_templatesdir}
if [ ! -d "${bastille_templatesdir}" ]; then if [ ! -d "${bastille_templatesdir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_templatesdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates zfs create ${bastille_zfs_options} -o mountpoint="${bastille_templatesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates"
fi fi
else else
mkdir -p "${bastille_templatesdir}" mkdir -p "${bastille_templatesdir}"
@@ -257,18 +168,19 @@ bootstrap_directories() {
## ${bastille_releasesdir} ## ${bastille_releasesdir}
if [ ! -d "${bastille_releasesdir}" ]; then if [ ! -d "${bastille_releasesdir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; 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}" "${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} zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"
fi fi
else else
mkdir -p "${bastille_releasesdir}/${RELEASE}" mkdir -p "${bastille_releasesdir}/${RELEASE}"
fi fi
## create subsequent releases/XX.X-RELEASE datasets ## create subsequent releases/XX.X-RELEASE datasets
elif [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then elif [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; 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} zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"
fi fi
else else
mkdir -p "${bastille_releasesdir}/${RELEASE}" mkdir -p "${bastille_releasesdir}/${RELEASE}"
@@ -281,9 +193,9 @@ bootstrap_release() {
if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then
## check distfiles list and skip existing cached files ## check distfiles list and skip existing cached files
bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/base//") bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/base//")
bastille_cached_files=$(ls ${bastille_cachedir}/${RELEASE} | grep -v "MANIFEST" | tr -d ".txz") bastille_cached_files=$(ls "${bastille_cachedir}/${RELEASE}" | grep -v "MANIFEST" | tr -d ".txz")
for distfile in ${bastille_cached_files}; do for distfile in ${bastille_cached_files}; do
bastille_bootstrap_archives=$(echo ${bastille_bootstrap_archives} | sed "s/${distfile}//") bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/${distfile}//")
done done
## check if release already bootstrapped, else continue bootstrapping ## check if release already bootstrapped, else continue bootstrapping
@@ -299,48 +211,51 @@ bootstrap_release() {
## check if the dist files already exists then extract ## check if the dist files already exists then extract
FETCH_VALIDATION="0" FETCH_VALIDATION="0"
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
echo -e "${COLOR_GREEN}Extracting FreeBSD ${RELEASE} ${_archive}.txz.${COLOR_RESET}" echo -e "${COLOR_GREEN}Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
/usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz" if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
if [ $? -ne 0 ]; then ## silence motd at container login
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
else
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}" echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
exit 1 exit 1
fi fi
else else
## get the manifest for dist files checksum validation ## get the manifest for dist files checksum validation
if [ ! -f "${bastille_cachedir}/${RELEASE}/MANIFEST" ]; then if [ ! -f "${bastille_cachedir}/${RELEASE}/MANIFEST" ]; then
fetch ${UPSTREAM_URL}/MANIFEST -o ${bastille_cachedir}/${RELEASE}/MANIFEST || FETCH_VALIDATION="1" fetch "${UPSTREAM_URL}/MANIFEST" -o "${bastille_cachedir}/${RELEASE}/MANIFEST" || FETCH_VALIDATION="1"
fi fi
if [ "${FETCH_VALIDATION}" -ne "0" ]; then if [ "${FETCH_VALIDATION}" -ne "0" ]; then
## perform cleanup only for stale/empty directories on failure ## perform cleanup only for stale/empty directories on failure
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
if [ ! "$(ls -A ${bastille_cachedir}/${RELEASE})" ]; then if [ ! "$(ls -A "${bastille_cachedir}/${RELEASE}")" ]; then
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE} zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}"
fi
if [ ! "$(ls -A ${bastille_releasesdir}/${RELEASE})" ]; then
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}
fi
fi
fi fi
if [ -d "${bastille_cachedir}/${RELEASE}" ]; then if [ ! "$(ls -A "${bastille_releasesdir}/${RELEASE}")" ]; then
if [ ! "$(ls -A ${bastille_cachedir}/${RELEASE})" ]; then zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"
rm -rf ${bastille_cachedir}/${RELEASE}
fi
fi fi
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
if [ ! "$(ls -A ${bastille_releasesdir}/${RELEASE})" ]; then
rm -rf ${bastille_releasesdir}/${RELEASE}
fi
fi fi
echo -e "${COLOR_RED}Bootstrap failed.${COLOR_RESET}"
exit 1
fi fi
if [ -d "${bastille_cachedir}/${RELEASE}" ]; then
if [ ! "$(ls -A "${bastille_cachedir}/${RELEASE}")" ]; then
rm -rf "${bastille_cachedir}/${RELEASE}"
fi
fi
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
if [ ! "$(ls -A "${bastille_releasesdir}/${RELEASE}")" ]; then
rm -rf "${bastille_releasesdir}/${RELEASE}"
fi
fi
echo -e "${COLOR_RED}Bootstrap failed.${COLOR_RESET}"
exit 1
fi
## fetch for missing dist files ## fetch for missing dist files
if [ ! -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then if [ ! -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
fetch ${UPSTREAM_URL}/${_archive}.txz -o ${bastille_cachedir}/${RELEASE}/${_archive}.txz fetch "${UPSTREAM_URL}/${_archive}.txz" -o "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
## alert only if unable to fetch additional dist files ## alert only if unable to fetch additional dist files
echo -e "${COLOR_RED}Failed to fetch ${_archive}.txz.${COLOR_RESET}" echo -e "${COLOR_RED}Failed to fetch ${_archive}.txz.${COLOR_RESET}"
fi fi
@@ -348,11 +263,11 @@ bootstrap_release() {
## compare checksums on the fetched dist files ## compare checksums on the fetched dist files
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
SHA256_DIST=$(grep -w "${_archive}.txz" ${bastille_cachedir}/${RELEASE}/MANIFEST | awk '{print $2}') SHA256_DIST=$(grep -w "${_archive}.txz" "${bastille_cachedir}/${RELEASE}/MANIFEST" | awk '{print $2}')
SHA256_FILE=$(sha256 -q ${bastille_cachedir}/${RELEASE}/${_archive}.txz) SHA256_FILE=$(sha256 -q "${bastille_cachedir}/${RELEASE}/${_archive}.txz")
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
echo -e "${COLOR_RED}Failed validation for ${_archive}.txz, please retry bootstrap!${COLOR_RESET}" echo -e "${COLOR_RED}Failed validation for ${_archive}.txz, please retry bootstrap!${COLOR_RESET}"
rm ${bastille_cachedir}/${RELEASE}/${_archive}.txz rm "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
exit 1 exit 1
else else
echo -e "${COLOR_GREEN}Validated checksum for ${RELEASE}:${_archive}.txz.${COLOR_RESET}" echo -e "${COLOR_GREEN}Validated checksum for ${RELEASE}:${_archive}.txz.${COLOR_RESET}"
@@ -363,9 +278,12 @@ bootstrap_release() {
## extract the fetched dist files ## extract the fetched dist files
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
echo -e "${COLOR_GREEN}Extracting FreeBSD ${RELEASE} ${_archive}.txz.${COLOR_RESET}" echo -e "${COLOR_GREEN}Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
/usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz" if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
if [ $? -ne 0 ]; then ## silence motd at container login
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
else
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}" echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
exit 1 exit 1
fi fi
@@ -384,8 +302,8 @@ bootstrap_template() {
## ${bastille_templatesdir} ## ${bastille_templatesdir}
if [ ! -d "${bastille_templatesdir}" ]; then if [ ! -d "${bastille_templatesdir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_templatesdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates zfs create ${bastille_zfs_options} -o mountpoint="${bastille_templatesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates"
fi fi
else else
mkdir -p "${bastille_templatesdir}" mkdir -p "${bastille_templatesdir}"
@@ -408,12 +326,12 @@ bootstrap_template() {
$(which git) clone "${_url}" "${_template}" ||\ $(which git) clone "${_url}" "${_template}" ||\
echo -e "${COLOR_RED}Clone unsuccessful.${COLOR_RESET}" echo -e "${COLOR_RED}Clone unsuccessful.${COLOR_RESET}"
elif [ -d "${_template}/.git" ]; then elif [ -d "${_template}/.git" ]; then
cd ${_template} && $(which git) pull ||\ cd "${_template}" && $(which git) pull ||\
echo -e "${COLOR_RED}Template update unsuccessful.${COLOR_RESET}" echo -e "${COLOR_RED}Template update unsuccessful.${COLOR_RESET}"
fi fi
fi fi
bastille verify ${_user}/${_repo} bastille verify "${_user}/${_repo}"
} }
HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }') HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }')
@@ -426,44 +344,50 @@ case "${1}" in
## check for FreeBSD releases name ## check for FreeBSD releases name
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]') NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]')
UPSTREAM_URL="${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" UPSTREAM_URL="${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}"
PLATFORM_OS="FreeBSD"
validate_release_url validate_release_url
;; ;;
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
## check for HardenedBSD releases name(previous infrastructure, keep for reference) ## check for HardenedBSD releases name(previous infrastructure, keep for reference)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
UPSTREAM_URL="${bastille_url_hardenedbsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-${NAME_VERIFY}" UPSTREAM_URL="${bastille_url_hardenedbsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-${NAME_VERIFY}"
PLATFORM_OS="HardenedBSD"
validate_release_url validate_release_url
;; ;;
*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) *-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*)
## check for HardenedBSD(specific stable build releases) ## check for HardenedBSD(specific stable build releases)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build|-STABLE-BUILD)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g') NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g')
NAME_RELEASE=$(echo ${NAME_VERIFY} | sed 's/-build-[0-9]\{1,2\}//g') NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-build-[0-9]\{1,3\}//g')
NAME_BUILD=$(echo ${NAME_VERIFY} | sed 's/[0-9]\{1,2\}-stable-//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}" UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}"
PLATFORM_OS="HardenedBSD"
validate_release_url validate_release_url
;; ;;
*-stable-build-latest|*-STABLE-BUILD-LATEST) *-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST)
## check for HardenedBSD(latest stable build release) ## check for HardenedBSD(latest stable build release)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build-latest|-STABLE-BUILD-LATEST)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') 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_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-BUILD-LATEST//g')
NAME_BUILD=$(echo ${NAME_VERIFY} | sed 's/[0-9]\{1,2\}-stable-//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}" UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}"
PLATFORM_OS="HardenedBSD"
validate_release_url validate_release_url
;; ;;
current-build-[0-9]*|*-CURRENT-BUILD-[0-9]*) current-build-[0-9]*|CURRENT-BUILD-[0-9]*)
## check for HardenedBSD(specific current build releases) ## check for HardenedBSD(specific current build releases)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build|-CURRENT-BUILD)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g') NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g')
NAME_RELEASE=$(echo ${NAME_VERIFY} | sed 's/current-.*/current/g') NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g')
NAME_BUILD=$(echo ${NAME_VERIFY} | sed 's/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}" UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}"
PLATFORM_OS="HardenedBSD"
validate_release_url validate_release_url
;; ;;
current-build-latest|*-CURRENT-BUILD-LATEST) current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST)
## check for HardenedBSD(latest current build release) ## check for HardenedBSD(latest current build release)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest|-CURRENT-BUILD-LATEST)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') 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_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g')
NAME_BUILD=$(echo ${NAME_VERIFY} | sed 's/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}" UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}"
PLATFORM_OS="HardenedBSD"
validate_release_url validate_release_url
;; ;;
http?://github.com/*/*|http?://gitlab.com/*/*) http?://github.com/*/*|http?://gitlab.com/*/*)
@@ -472,9 +396,6 @@ http?://github.com/*/*|http?://gitlab.com/*/*)
BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }') BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }')
bootstrap_template bootstrap_template
;; ;;
network)
bootstrap_network_interfaces
;;
*) *)
usage usage
;; ;;

View File

@@ -0,0 +1,217 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# 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/colors.pre.sh
. /usr/local/etc/bastille/bastille.conf
usage() {
echo -e "${COLOR_RED}Usage: bastille clone [TARGET] [NEW_NAME] [IPADRESS].${COLOR_RESET}"
exit 1
}
error_notify() {
# Notify message on error and exit
echo -e "$*" >&2
exit 1
}
# Handle special-case commands first
case "$1" in
help|-h|--help)
usage
;;
esac
if [ $# -ne 3 ]; then
usage
fi
TARGET="${1}"
NEWNAME="${2}"
IP="${3}"
shift
validate_ip() {
IPX_ADDR="ip4.addr"
IP6_MODE="disable"
ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))')
if [ -n "${ip6}" ]; then
echo -e "${COLOR_GREEN}Valid: (${ip6}).${COLOR_RESET}"
IPX_ADDR="ip6.addr"
IP6_MODE="new"
else
local IFS
if echo "${IP}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then
TEST_IP=$(echo "${IP}" | cut -d / -f1)
IFS=.
set ${TEST_IP}
for quad in 1 2 3 4; do
if eval [ \$$quad -gt 255 ]; then
echo "Invalid: (${TEST_IP})"
exit 1
fi
done
if ifconfig | grep -qw "${TEST_IP}"; then
echo -e "${COLOR_YELLOW}Warning: ip address already in use (${TEST_IP}).${COLOR_RESET}"
else
echo -e "${COLOR_GREEN}Valid: (${IP}).${COLOR_RESET}"
fi
else
echo -e "${COLOR_RED}Invalid: (${IP}).${COLOR_RESET}"
exit 1
fi
fi
}
update_jailconf() {
# Update jail.conf
JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf"
if [ -f "${JAIL_CONFIG}" ]; then
if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then
sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}"
sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}"
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}"
sed -i '' "s|${IPX_ADDR} = .*;|${IPX_ADDR} = ${IP};|" "${JAIL_CONFIG}"
fi
fi
if grep -qw "vnet;" "${JAIL_CONFIG}"; then
update_jailconf_vnet
fi
}
update_jailconf_vnet() {
bastille_jail_rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf"
# Determine number of containers and define an uniq_epair
local list_jails_num=$(bastille list jails | wc -l | awk '{print $1}')
local num_range=$(expr "${list_jails_num}" + 1)
jail_list=$(bastille list jail)
for _num in $(seq 0 "${num_range}"); do
if [ -n "${jail_list}" ]; then
if ! grep -q "e0b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then
uniq_epair="bastille${_num}"
sed -i '' "s|vnet.interface = e0b_bastille.*;|vnet.interface = e0b_${uniq_epair};|" "${JAIL_CONFIG}"
break
fi
fi
done
# Rename interface to new uniq_epair
sed -i '' "s|ifconfig_e0b_bastille.*_name|ifconfig_e0b_${uniq_epair}_name|" "${bastille_jail_rc_conf}"
# If 0.0.0.0 set DHCP, else set static IP address
if [ "${IP}" == "0.0.0.0" ]; then
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="DHCP"
else
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
fi
}
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|-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_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
# If both variables are set, update as needed
if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${NEWNAME}/root/.bastille" "${FSTAB_CONFIG}"; then
sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}"
fi
fi
fi
}
clone_jail() {
# Attempt container clone
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_GREEN}Attempting to clone '${TARGET}' to ${NEWNAME}...${COLOR_RESET}"
if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
# Replicate the existing container
DATE=$(date +%F-%H%M%S)
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" | zfs recv "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"
# Cleanup source temporary snapshots
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_clone_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
# Cleanup target temporary snapshots
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}"
fi
else
# Just clone the jail directory
# Check if container is running
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop ${TARGET}'.${COLOR_RESET}"
fi
# Perform container file copy(archive mode)
cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
fi
else
error_notify "${COLOR_RED}${NEWNAME} already exists.${COLOR_RESET}"
fi
else
error_notify "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
fi
# Generate jail configuration files
update_jailconf
update_fstab
# Display the exist status
if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}An error has occurred while attempting to clone '${TARGET}'.${COLOR_RESET}"
else
echo -e "${COLOR_GREEN}Cloned '${TARGET}' to '${NEWNAME}' successfully.${COLOR_RESET}"
fi
}
## don't allow for dots(.) in container names
if echo "${NEWNAME}" | grep -q "[.]"; then
echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}"
exit 1
fi
## check if ip address is valid
if [ -n "${IP}" ]; then
validate_ip
else
usage
fi
clone_jail

View File

@@ -58,6 +58,6 @@ fi
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
jexec -l ${_jail} $@ jexec -l "${_jail}" "$@"
echo echo
done done

View File

@@ -58,11 +58,11 @@ if [ "${TARGET}" != 'ALL' ]; then
fi fi
validate_user() { validate_user() {
if jexec -l ${_jail} id "${USER}" >/dev/null 2>&1; then if jexec -l "${_jail}" id "${USER}" >/dev/null 2>&1; then
USER_SHELL="$(jexec -l ${_jail} getent passwd "${USER}" | cut -d: -f7)" USER_SHELL="$(jexec -l "${_jail}" getent passwd "${USER}" | cut -d: -f7)"
if [ -n "${USER_SHELL}" ]; then if [ -n "${USER_SHELL}" ]; then
if jexec -l ${_jail} grep -qwF "${USER_SHELL}" /etc/shells; then if jexec -l "${_jail}" grep -qwF "${USER_SHELL}" /etc/shells; then
jexec -l ${_jail} /usr/bin/login -f "${USER}" jexec -l "${_jail}" /usr/bin/login -f "${USER}"
else else
echo "Invalid shell for user ${USER}" echo "Invalid shell for user ${USER}"
fi fi
@@ -76,10 +76,10 @@ validate_user() {
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
if [ ! -z "${USER}" ]; then if [ -n "${USER}" ]; then
validate_user validate_user
else else
jexec -l ${_jail} /usr/bin/login -f root jexec -l "${_jail}" /usr/bin/login -f root
fi fi
echo echo
done done

View File

@@ -63,7 +63,7 @@ convert_symlinks() {
# Retrieve old symlinks temporarily # Retrieve old symlinks temporarily
for _link in ${SYMLINKS}; do for _link in ${SYMLINKS}; do
if [ -L "${_link}" ]; then if [ -L "${_link}" ]; then
mv ${_link} ${_link}.old mv "${_link}" "${_link}.old"
fi fi
done done
@@ -73,7 +73,7 @@ convert_symlinks() {
if [ -d "${bastille_releasesdir}/${RELEASE}/${_link}" ]; then if [ -d "${bastille_releasesdir}/${RELEASE}/${_link}" ]; then
cp -a "${bastille_releasesdir}/${RELEASE}/${_link}" "${bastille_jailsdir}/${TARGET}/root/${_link}" cp -a "${bastille_releasesdir}/${RELEASE}/${_link}" "${bastille_jailsdir}/${TARGET}/root/${_link}"
fi fi
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
revert_convert revert_convert
fi fi
fi fi
@@ -82,11 +82,11 @@ convert_symlinks() {
# Remove the old symlinks on success # Remove the old symlinks on success
for _link in ${SYMLINKS}; do for _link in ${SYMLINKS}; do
if [ -L "${_link}.old" ]; then if [ -L "${_link}.old" ]; then
rm -r ${_link}.old rm -r "${_link}.old"
fi fi
done done
else else
error_notify "${COLOR_RED}Release must be bootstrapped first, See `bastille bootstrap`.${COLOR_RESET}" error_notify "${COLOR_RED}Release must be bootstrapped first, See 'bastille bootstrap'.${COLOR_RESET}"
fi fi
} }
@@ -103,7 +103,7 @@ revert_convert() {
# Restore previous symlinks # Restore previous symlinks
for _link in ${SYMLINKS}; do for _link in ${SYMLINKS}; do
if [ -L "${_link}.old" ]; then if [ -L "${_link}.old" ]; then
mv ${_link}.old ${_link} mv "${_link}.old" "${_link}"
fi fi
done done
error_notify "${COLOR_GREEN}Changes for '${TARGET}' has been reverted.${COLOR_RESET}" error_notify "${COLOR_GREEN}Changes for '${TARGET}' has been reverted.${COLOR_RESET}"
@@ -115,8 +115,8 @@ start_convert() {
echo -e "${COLOR_GREEN}Converting '${TARGET}' into a thickjail, this may take a while...${COLOR_RESET}" echo -e "${COLOR_GREEN}Converting '${TARGET}' into a thickjail, this may take a while...${COLOR_RESET}"
# Set some variables # Set some variables
RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])' ${bastille_jailsdir}/${TARGET}/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)' "${bastille_jailsdir}/${TARGET}/fstab")
FSTABMOD=$(grep -w "${bastille_releasesdir}/${RELEASE} ${bastille_jailsdir}/${TARGET}/root/.bastille" ${bastille_jailsdir}/${TARGET}/fstab) FSTABMOD=$(grep -w "${bastille_releasesdir}/${RELEASE} ${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab")
SYMLINKS="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/ports usr/sbin usr/share usr/src" SYMLINKS="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/ports usr/sbin usr/share usr/src"
if [ -n "${RELEASE}" ]; then if [ -n "${RELEASE}" ]; then
@@ -127,26 +127,21 @@ start_convert() {
# Comment the line containing .bastille and rename mountpoint # Comment the line containing .bastille and rename mountpoint
sed -i '' -E "s|${FSTABMOD}|# Converted from thin to thick container on $(date)|g" "${bastille_jailsdir}/${TARGET}/fstab" sed -i '' -E "s|${FSTABMOD}|# Converted from thin to thick container on $(date)|g" "${bastille_jailsdir}/${TARGET}/fstab"
mv ${bastille_jailsdir}/${TARGET}/root/.bastille ${bastille_jailsdir}/${TARGET}/root/.bastille.old mv "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/root/.bastille.old"
echo -e "${COLOR_GREEN}Conversion of '${TARGET}' completed successfully!${COLOR_RESET}" echo -e "${COLOR_GREEN}Conversion of '${TARGET}' completed successfully!${COLOR_RESET}"
exit 0 exit 0
else else
error_notify "${COLOR_RED}Can't determine release version, See `bastille bootstrap`.${COLOR_RESET}" error_notify "${COLOR_RED}Can't determine release version, See 'bastille bootstrap'.${COLOR_RESET}"
fi fi
else else
error_notify "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}" error_notify "${COLOR_RED}${TARGET} not found. See 'bastille create'.${COLOR_RESET}"
fi fi
} }
# Check compatibility
if [ -n "$(freebsd-version | grep -i HBSD)" ]; then
error_notify "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
fi
# Check if container is running # Check if container is running
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
error_notify "${COLOR_RED}${TARGET} is running, See `bastille stop`.${COLOR_RESET}" error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop'.${COLOR_RESET}"
fi fi
# Check if is a thin container # Check if is a thin container

View File

@@ -47,25 +47,34 @@ running_jail() {
} }
validate_ip() { validate_ip() {
local IFS IPX_ADDR="ip4.addr"
ip=${IP} IP6_MODE="disable"
if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))')
IFS=. if [ -n "${ip6}" ]; then
set $ip echo -e "${COLOR_GREEN}Valid: (${ip6}).${COLOR_RESET}"
for quad in 1 2 3 4; do IPX_ADDR="ip6.addr"
if eval [ \$$quad -gt 255 ]; then IP6_MODE="new"
echo "fail ($ip)"
exit 1
fi
done
if ifconfig | grep -w "$ip" >/dev/null; then
echo -e "${COLOR_YELLOW}Warning: ip address already in use ($ip).${COLOR_RESET}"
else
echo -e "${COLOR_GREEN}Valid: ($ip).${COLOR_RESET}"
fi
else else
echo -e "${COLOR_RED}Invalid: ($ip).${COLOR_RESET}" local IFS
exit 1 if echo "${IP}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then
TEST_IP=$(echo "${IP}" | cut -d / -f1)
IFS=.
set ${TEST_IP}
for quad in 1 2 3 4; do
if eval [ \$$quad -gt 255 ]; then
echo "Invalid: (${TEST_IP})"
exit 1
fi
done
if ifconfig | grep -qw "${TEST_IP}"; then
echo -e "${COLOR_YELLOW}Warning: ip address already in use (${TEST_IP}).${COLOR_RESET}"
else
echo -e "${COLOR_GREEN}Valid: (${IP}).${COLOR_RESET}"
fi
else
echo -e "${COLOR_RED}Invalid: (${IP}).${COLOR_RESET}"
exit 1
fi
fi fi
} }
@@ -80,21 +89,7 @@ validate_netif() {
} }
validate_netconf() { validate_netconf() {
if [ -n "${bastille_jail_loopback}" ] && [ -n "${bastille_jail_interface}" ] && [ -n "${bastille_jail_external}" ]; then if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
echo -e "${COLOR_RED}Invalid network configuration.${COLOR_RESET}"
exit 1
fi
if [ ! -z "${bastille_jail_external}" ]; then
break
elif [ ! -z "${bastille_jail_loopback}" ] && [ -z "${bastille_jail_external}" ]; then
if [ -z "${bastille_jail_interface}" ]; then
echo -e "${COLOR_RED}Invalid network configuration.${COLOR_RESET}"
exit 1
fi
elif [ -z "${bastille_jail_loopback}" ] && [ ! -z "${bastille_jail_interface}" ]; then
echo -e "${COLOR_RED}Invalid network configuration.${COLOR_RESET}"
exit 1
elif [ -z "${bastille_jail_external}" ]; then
echo -e "${COLOR_RED}Invalid network configuration.${COLOR_RESET}" echo -e "${COLOR_RED}Invalid network configuration.${COLOR_RESET}"
exit 1 exit 1
fi fi
@@ -109,6 +104,69 @@ validate_release() {
fi fi
} }
generate_jail_conf() {
cat << EOF > "${bastille_jail_conf}"
${NAME} {
devfs_ruleset = 4;
enforce_statfs = 2;
exec.clean;
exec.consolelog = ${bastille_jail_log};
exec.start = '/bin/sh /etc/rc';
exec.stop = '/bin/sh /etc/rc.shutdown';
host.hostname = ${NAME};
mount.devfs;
mount.fstab = ${bastille_jail_fstab};
path = ${bastille_jail_path};
securelevel = 2;
interface = ${bastille_jail_conf_interface};
${IPX_ADDR} = ${IP};
ip6 = ${IP6_MODE};
}
EOF
}
generate_vnet_jail_conf() {
## determine number of containers + 1
## iterate num and grep all jail configs
## define uniq_epair
local jail_list=$(bastille list jails)
if [ -n "${jail_list}" ]; then
local list_jails_num=$(echo "${jail_list}" | wc -l | awk '{print $1}')
local num_range=$(expr "${list_jails_num}" + 1)
for _num in $(seq 0 "${num_range}"); do
if ! grep -q "e0b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then
uniq_epair="bastille${_num}"
break
fi
done
else
uniq_epair="bastille0"
fi
## generate config
cat << EOF > "${bastille_jail_conf}"
${NAME} {
devfs_ruleset = 13;
enforce_statfs = 2;
exec.clean;
exec.consolelog = ${bastille_jail_log};
exec.start = '/bin/sh /etc/rc';
exec.stop = '/bin/sh /etc/rc.shutdown';
host.hostname = ${NAME};
mount.devfs;
mount.fstab = ${bastille_jail_fstab};
path = ${bastille_jail_path};
securelevel = 2;
vnet;
vnet.interface = e0b_${uniq_epair};
exec.prestart += "jib addm ${uniq_epair} ${INTERFACE}";
exec.poststop += "jib destroy ${uniq_epair}";
}
EOF
}
create_jail() { create_jail() {
bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir
bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir
@@ -121,11 +179,11 @@ create_jail() {
if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
## create required zfs datasets ## create required zfs datasets, mountpoint inherited from system
zfs create ${bastille_zfs_options} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME} zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}"
if [ -z "${THICK_JAIL}" ]; then if [ -z "${THICK_JAIL}" ]; then
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_jailsdir}/${NAME}/root ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
fi fi
fi fi
else else
@@ -151,43 +209,29 @@ create_jail() {
if [ ! -f "${bastille_jail_fstab}" ]; then if [ ! -f "${bastille_jail_fstab}" ]; then
if [ -z "${THICK_JAIL}" ]; then if [ -z "${THICK_JAIL}" ]; then
echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > ${bastille_jail_fstab} echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}"
else else
touch ${bastille_jail_fstab} touch "${bastille_jail_fstab}"
fi fi
fi fi
if [ ! -f "${bastille_jail_conf}" ]; then if [ ! -f "${bastille_jail_conf}" ]; then
if [ -z "${bastille_jail_loopback}" ] && [ ! -z "${bastille_jail_external}" ]; then if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
local bastille_jail_conf_interface=${bastille_jail_external} local bastille_jail_conf_interface=${bastille_network_shared}
fi fi
if [ ! -z "${bastille_jail_loopback}" ] && [ -z "${bastille_jail_external}" ]; then if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then
local bastille_jail_conf_interface=${bastille_jail_interface} local bastille_jail_conf_interface=${bastille_network_loopback}
fi fi
if [ ! -z ${INTERFACE} ]; then if [ -n "${INTERFACE}" ]; then
local bastille_jail_conf_interface=${INTERFACE} local bastille_jail_conf_interface=${INTERFACE}
fi fi
## generate the jail configuration file ## generate the jail configuration file
cat << EOF > ${bastille_jail_conf} if [ -n "${VNET_JAIL}" ]; then
interface = ${bastille_jail_conf_interface}; generate_vnet_jail_conf
host.hostname = ${NAME}; else
exec.consolelog = ${bastille_jail_log}; generate_jail_conf
path = ${bastille_jail_path}; fi
ip6 = disable;
securelevel = 2;
devfs_ruleset = 4;
enforce_statfs = 2;
exec.start = '/bin/sh /etc/rc';
exec.stop = '/bin/sh /etc/rc.shutdown';
exec.clean;
mount.devfs;
mount.fstab = ${bastille_jail_fstab};
${NAME} {
ip4.addr = ${IP};
}
EOF
fi fi
## using relative paths here ## using relative paths here
@@ -196,7 +240,7 @@ EOF
echo echo
echo -e "${COLOR_GREEN}NAME: ${NAME}.${COLOR_RESET}" echo -e "${COLOR_GREEN}NAME: ${NAME}.${COLOR_RESET}"
echo -e "${COLOR_GREEN}IP: ${IP}.${COLOR_RESET}" echo -e "${COLOR_GREEN}IP: ${IP}.${COLOR_RESET}"
if [ ! -z ${INTERFACE} ]; then if [ -n "${INTERFACE}" ]; then
echo -e "${COLOR_GREEN}INTERFACE: ${INTERFACE}.${COLOR_RESET}" echo -e "${COLOR_GREEN}INTERFACE: ${INTERFACE}.${COLOR_RESET}"
fi fi
echo -e "${COLOR_GREEN}RELEASE: ${RELEASE}.${COLOR_RESET}" echo -e "${COLOR_GREEN}RELEASE: ${RELEASE}.${COLOR_RESET}"
@@ -218,10 +262,10 @@ EOF
for files in ${FILE_LIST}; do for files in ${FILE_LIST}; do
if [ -f "${bastille_releasesdir}/${RELEASE}/${files}" ] || [ -d "${bastille_releasesdir}/${RELEASE}/${files}" ]; then if [ -f "${bastille_releasesdir}/${RELEASE}/${files}" ] || [ -d "${bastille_releasesdir}/${RELEASE}/${files}" ]; then
cp -a "${bastille_releasesdir}/${RELEASE}/${files}" "${bastille_jail_path}/${files}" cp -a "${bastille_releasesdir}/${RELEASE}/${files}" "${bastille_jail_path}/${files}"
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories ## notify and clean stale files/directories
echo -e "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}" echo -e "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}"
bastille destroy ${NAME} bastille destroy "${NAME}"
exit 1 exit 1
fi fi
fi fi
@@ -229,7 +273,7 @@ EOF
else else
echo -e "${COLOR_GREEN}Creating a thickjail, this may take a while...${COLOR_RESET}" echo -e "${COLOR_GREEN}Creating a thickjail, this may take a while...${COLOR_RESET}"
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
## perform release base replication ## perform release base replication
## sane bastille zfs options ## sane bastille zfs options
@@ -237,31 +281,32 @@ EOF
## take a temp snapshot of the base release ## take a temp snapshot of the base release
SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)" SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)"
zfs snapshot ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME} zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
## replicate the release base to the new thickjail and set the default mountpoint ## replicate the release base to the new thickjail and set the default mountpoint
zfs send -R ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME} | \ zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" | \
zfs receive ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root zfs receive "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
zfs set ${ZFS_OPTIONS} mountpoint=${bastille_jailsdir}/${NAME}/root ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root zfs set ${ZFS_OPTIONS} mountpoint=none "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
zfs inherit mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
## cleanup temp snapshots initially ## cleanup temp snapshots initially
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME} zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root@${SNAP_NAME} zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}"
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories ## notify and clean stale files/directories
echo -e "${COLOR_RED}Failed release base replication, please retry create!${COLOR_RESET}" echo -e "${COLOR_RED}Failed release base replication, please retry create!${COLOR_RESET}"
bastille destroy ${NAME} bastille destroy "${NAME}"
exit 1 exit 1
fi fi
fi fi
else else
## copy all files for thick jails ## copy all files for thick jails
cp -a "${bastille_releasesdir}/${RELEASE}/" "${bastille_jail_path}" cp -a "${bastille_releasesdir}/${RELEASE}/" "${bastille_jail_path}"
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories ## notify and clean stale files/directories
echo -e "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}" echo -e "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}"
bastille destroy ${NAME} bastille destroy "${NAME}"
exit 1 exit 1
fi fi
fi fi
@@ -273,19 +318,45 @@ EOF
## + cron_flags="-J 60" ## cedwards 20181118 ## + cron_flags="-J 60" ## cedwards 20181118
if [ ! -f "${bastille_jail_rc_conf}" ]; then if [ ! -f "${bastille_jail_rc_conf}" ]; then
touch "${bastille_jail_rc_conf}" touch "${bastille_jail_rc_conf}"
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" syslogd_flags=-ss sysrc -f "${bastille_jail_rc_conf}" syslogd_flags=-ss
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" sendmail_enable=NONE sysrc -f "${bastille_jail_rc_conf}" sendmail_enable=NONE
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" cron_flags='-J 60' sysrc -f "${bastille_jail_rc_conf}" cron_flags='-J 60'
echo
## VNET specific
if [ -n "${VNET_JAIL}" ]; then
## rename interface to generic vnet0
uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//')
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" "ifconfig_${uniq_epair}_name"=vnet0
## if 0.0.0.0 set DHCP
## else set static address
if [ "${IP}" == "0.0.0.0" ]; then
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="DHCP"
else
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
if [ -n "${bastille_network_gateway}" ]; then
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" defaultrouter="${bastille_network_gateway}"
else
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" defaultrouter="$(route show default | awk '/gateway/ {print $2}')"
fi
fi
## 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
fi
fi fi
## resolv.conf (default: copy from host) ## resolv.conf (default: copy from host)
if [ ! -f "${bastille_jail_resolv_conf}" ]; then if [ ! -f "${bastille_jail_resolv_conf}" ]; then
cp -L ${bastille_resolv_conf} ${bastille_jail_resolv_conf} cp -L "${bastille_resolv_conf}" "${bastille_jail_resolv_conf}"
fi fi
## TZ: configurable (default: etc/UTC) ## TZ: configurable (default: etc/UTC)
ln -s /usr/share/zoneinfo/${bastille_tzdata} etc/localtime ln -s "/usr/share/zoneinfo/${bastille_tzdata}" etc/localtime
} }
# Handle special-case commands first. # Handle special-case commands first.
@@ -295,44 +366,50 @@ help|-h|--help)
;; ;;
esac esac
if [ $(echo $3 | grep '@' ) ]; then if echo "$3" | grep '@'; then
BASTILLE_JAIL_IP=$(echo $3 | awk -F@ '{print $2}') BASTILLE_JAIL_IP=$(echo "$3" | awk -F@ '{print $2}')
BASTILLE_JAIL_INTERFACES=$( echo $3 | awk -F@ '{print $1}') BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}')
fi fi
TYPE="$1" ## reset this options
NAME="$2" THICK_JAIL=""
RELEASE="$3" VNET_JAIL=""
IP="$4"
INTERFACE="$5"
## handle additional options ## handle combined options then shift
case "${TYPE}" in if [ "${1}" = "-T" -o "${1}" = "--thick" -o "${1}" = "thick" ] && \
-T|--thick|thick) [ "${2}" = "-V" -o "${2}" = "--vnet" -o "${2}" = "vnet" ]; then
if [ $# -gt 5 ] || [ $# -lt 4 ]; then THICK_JAIL="1"
usage VNET_JAIL="1"
fi shift 2
THICK_JAIL="0" else
break ## handle single options
;; case "${1}" in
-*) -T|--thick|thick)
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}" shift
THICK_JAIL="1"
;;
-V|--vnet|vnet)
shift
VNET_JAIL="1"
;;
-*)
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}"
usage
;;
esac
fi
NAME="$1"
RELEASE="$2"
IP="$3"
INTERFACE="$4"
if [ $# -gt 4 ] || [ $# -lt 3 ]; then
usage usage
;; fi
*)
if [ $# -gt 4 ] || [ $# -lt 3 ]; then
usage
fi
THICK_JAIL=""
NAME="$1"
RELEASE="$2"
IP="$3"
INTERFACE="$4"
;;
esac
## don't allow for dots(.) in container names ## don't allow for dots(.) in container names
if [ $(echo "${NAME}" | grep "[.]") ]; then if echo "${NAME}" | grep -q "[.]"; then
echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}" echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}"
exit 1 exit 1
fi fi
@@ -346,27 +423,27 @@ case "${RELEASE}" in
;; ;;
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
## check for HardenedBSD releases name(previous infrastructure) ## check for HardenedBSD releases name(previous infrastructure)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
validate_release validate_release
;; ;;
*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) *-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*)
## check for HardenedBSD(specific stable build releases) ## check for HardenedBSD(specific stable build releases)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build|-STABLE-BUILD)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g') NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g')
validate_release validate_release
;; ;;
*-stable-build-latest|*-STABLE-BUILD-LATEST) *-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST)
## check for HardenedBSD(latest stable build release) ## check for HardenedBSD(latest stable build release)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build-latest|-STABLE-BUILD-LATEST)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') 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')
validate_release validate_release
;; ;;
current-build-[0-9]*|CURRENT-BUILD-[0-9]*) current-build-[0-9]*|CURRENT-BUILD-[0-9]*)
## check for HardenedBSD(specific current build releases) ## check for HardenedBSD(specific current build releases)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build|-CURRENT-BUILD)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g') NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g')
validate_release validate_release
;; ;;
current-build-latest|CURRENT-BUILD-LATEST) current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST)
## check for HardenedBSD(latest current build release) ## check for HardenedBSD(latest current build release)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest|-CURRENT-BUILD-LATEST)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') 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 validate_release
;; ;;
*) *)
@@ -383,7 +460,7 @@ fi
## check for required release ## check for required release
if [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then if [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then
echo -e "${COLOR_RED}Release must be bootstrapped first; see `bastille bootstrap`.${COLOR_RESET}" echo -e "${COLOR_RED}Release must be bootstrapped first; see 'bastille bootstrap'.${COLOR_RESET}"
exit 1 exit 1
fi fi
@@ -393,17 +470,18 @@ if [ -n "${NAME}" ]; then
fi fi
## check if ip address is valid ## check if ip address is valid
if [ ! -z "${IP}" ]; then if [ -n "${IP}" ]; then
validate_ip validate_ip
else else
usage usage
fi fi
## check if interface is valid ## check if interface is valid
if [ ! -z ${INTERFACE} ]; then if [ -n "${INTERFACE}" ]; then
validate_netif validate_netif
validate_netconf
else else
validate_netconf validate_netconf
fi fi
create_jail ${NAME} ${RELEASE} ${IP} ${INTERFACE} create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}"

View File

@@ -42,7 +42,7 @@ destroy_jail() {
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
if [ "${FORCE}" = "1" ]; then if [ "${FORCE}" = "1" ]; then
bastille stop ${TARGET} bastille stop "${TARGET}"
else else
echo -e "${COLOR_RED}Jail running.${COLOR_RESET}" echo -e "${COLOR_RED}Jail running.${COLOR_RESET}"
echo -e "${COLOR_RED}See 'bastille stop ${TARGET}'.${COLOR_RESET}" echo -e "${COLOR_RED}See 'bastille stop ${TARGET}'.${COLOR_RESET}"
@@ -58,28 +58,34 @@ destroy_jail() {
if [ -d "${bastille_jail_base}" ]; then if [ -d "${bastille_jail_base}" ]; then
echo -e "${COLOR_GREEN}Deleting Jail: ${TARGET}.${COLOR_RESET}" echo -e "${COLOR_GREEN}Deleting Jail: ${TARGET}.${COLOR_RESET}"
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
if [ ! -z "${TARGET}" ]; then if [ -n "${TARGET}" ]; then
## remove jail zfs dataset recursively ## remove jail zfs dataset recursively
zfs destroy -r ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET} zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"
fi fi
fi fi
fi fi
if [ -d "${bastille_jail_base}" ]; then if [ -d "${bastille_jail_base}" ]; then
## removing all flags ## removing all flags
chflags -R noschg ${bastille_jail_base} chflags -R noschg "${bastille_jail_base}"
## remove jail base ## remove jail base
rm -rf ${bastille_jail_base} rm -rf "${bastille_jail_base}"
fi fi
## archive jail log ## archive jail log
if [ -f "${bastille_jail_log}" ]; then if [ -f "${bastille_jail_log}" ]; then
mv ${bastille_jail_log} ${bastille_jail_log}-$(date +%F) mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)"
echo -e "${COLOR_GREEN}Note: jail console logs archived.${COLOR_RESET}" echo -e "${COLOR_GREEN}Note: jail console logs archived.${COLOR_RESET}"
echo -e "${COLOR_GREEN}${bastille_jail_log}-$(date +%F)${COLOR_RESET}" echo -e "${COLOR_GREEN}${bastille_jail_log}-$(date +%F)${COLOR_RESET}"
fi fi
## clear any active rdr rules
if [ ! -z "$(pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null)" ]; then
echo -e "${COLOR_GREEN}Clearing RDR rules:${COLOR_RESET}"
pfctl -a "rdr/${TARGET}" -Fn
fi
echo echo
fi fi
} }
@@ -88,7 +94,6 @@ destroy_rel() {
## check release name match before destroy ## check release name match before destroy
if [ -n "${NAME_VERIFY}" ]; then if [ -n "${NAME_VERIFY}" ]; then
TARGET="${NAME_VERIFY}" TARGET="${NAME_VERIFY}"
break
else else
usage usage
fi fi
@@ -100,7 +105,7 @@ destroy_rel() {
if [ -d "${bastille_jailsdir}" ]; then if [ -d "${bastille_jailsdir}" ]; then
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
for _jail in ${JAIL_LIST}; do for _jail in ${JAIL_LIST}; do
if grep -qwo "${TARGET}" ${bastille_jailsdir}/${_jail}/fstab 2>/dev/null; then if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then
echo -e "${COLOR_RED}Notice: (${_jail}) depends on ${TARGET} base.${COLOR_RESET}" echo -e "${COLOR_RED}Notice: (${_jail}) depends on ${TARGET} base.${COLOR_RESET}"
BASE_HASCHILD="1" BASE_HASCHILD="1"
fi fi
@@ -114,11 +119,11 @@ destroy_rel() {
if [ "${BASE_HASCHILD}" -eq "0" ]; then if [ "${BASE_HASCHILD}" -eq "0" ]; then
echo -e "${COLOR_GREEN}Deleting base: ${TARGET}.${COLOR_RESET}" echo -e "${COLOR_GREEN}Deleting base: ${TARGET}.${COLOR_RESET}"
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${TARGET} zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${TARGET}"
if [ "${FORCE}" = "1" ]; then if [ "${FORCE}" = "1" ]; then
if [ -d "${bastille_cachedir}/${TARGET}" ]; then if [ -d "${bastille_cachedir}/${TARGET}" ]; then
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${TARGET} zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${TARGET}"
fi fi
fi fi
fi fi
@@ -126,10 +131,10 @@ destroy_rel() {
if [ -d "${bastille_rel_base}" ]; then if [ -d "${bastille_rel_base}" ]; then
## removing all flags ## removing all flags
chflags -R noschg ${bastille_rel_base} chflags -R noschg "${bastille_rel_base}"
## remove jail base ## remove jail base
rm -rf ${bastille_rel_base} rm -rf "${bastille_rel_base}"
fi fi
if [ "${FORCE}" = "1" ]; then if [ "${FORCE}" = "1" ]; then
@@ -152,29 +157,27 @@ help|-h|--help)
;; ;;
esac esac
OPTION="${1}" ## reset this options
TARGET="${2}" FORCE=""
## handle additional options ## handle additional options
case "${OPTION}" in case "${1}" in
-f|--force) -f|--force|force)
if [ $# -gt 2 ] || [ $# -lt 2 ]; then FORCE="1"
shift
;;
-*)
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}"
usage usage
fi ;;
FORCE="1"
;;
-*)
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}"
usage
;;
*)
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
usage
fi
TARGET="${1}"
;;
esac esac
TARGET="${1}"
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
usage
fi
## check what should we clean ## check what should we clean
case "${TARGET}" in case "${TARGET}" in
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2) *-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
@@ -184,27 +187,27 @@ case "${TARGET}" in
;; ;;
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST) *-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
## check for HardenedBSD releases name ## check for HardenedBSD releases name
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g') NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
destroy_rel destroy_rel
;; ;;
*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*) *-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*)
## check for HardenedBSD(specific stable build releases) ## check for HardenedBSD(specific stable build releases)
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build|-STABLE-BUILD)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g') NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g')
destroy_rel destroy_rel
;; ;;
*-stable-build-latest|*-STABLE-BUILD-LATEST) *-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST)
## check for HardenedBSD(latest stable build release) ## check for HardenedBSD(latest stable build release)
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build-latest|-STABLE-BUILD-LATEST)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g')
destroy_rel destroy_rel
;; ;;
current-build-[0-9]*|CURRENT-BUILD-[0-9]*) current-build-[0-9]*|CURRENT-BUILD-[0-9]*)
## check for HardenedBSD(specific current build releases) ## check for HardenedBSD(specific current build releases)
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build|-CURRENT-BUILD)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g') NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g')
destroy_rel destroy_rel
;; ;;
current-build-latest|CURRENT-BUILD-LATEST) current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST)
## check for HardenedBSD(latest current build release) ## check for HardenedBSD(latest current build release)
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build-latest|-CURRENT-BUILD-LATEST)$' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g') NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(current-build-latest)$' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g')
destroy_rel destroy_rel
;; ;;
*) *)

View File

@@ -0,0 +1,72 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# 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/colors.pre.sh
. /usr/local/etc/bastille/bastille.conf
usage() {
echo -e "${COLOR_RED}Usage: bastille edit TARGET [filename]${COLOR_RESET}"
exit 1
}
# Handle special-case commands first.
case "$1" in
help|-h|--help)
usage
;;
esac
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
usage
fi
TARGET="${1}"
if [ $# == 2 ]; then
TARGET_FILENAME="${2}"
fi
if [ -z "${EDITOR}" ]; then
EDITOR=vi
fi
if [ "${TARGET}" = 'ALL' ]; then
JAILS=$(bastille list jails)
fi
if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(bastille list jails | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
if [ -n "${TARGET_FILENAME}" ]; then
"${EDITOR}" "${bastille_jailsdir}/${_jail}/${TARGET_FILENAME}"
else
"${EDITOR}" "${bastille_jailsdir}/${_jail}/jail.conf"
fi
done

View File

@@ -60,35 +60,35 @@ error_notify()
jail_export() jail_export()
{ {
# Attempt to export the container # Attempt to export the container
DATE=$(date +%F-%H:%M:%S) DATE=$(date +%F-%H%M%S)
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
FILE_EXT="xz" FILE_EXT="xz"
echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive.${COLOR_RESET}" echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Sending zfs data stream...${COLOR_RESET}" echo -e "${COLOR_GREEN}Sending zfs data stream...${COLOR_RESET}"
# Take a recursive temporary snapshot # Take a recursive temporary snapshot
SNAP_NAME="bastille_export-${DATE}" zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
zfs snapshot -r ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@${SNAP_NAME}
# Export the container recursively and cleanup temporary snapshots # Export the container recursively and cleanup temporary snapshots
zfs send -R ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@${SNAP_NAME} | \ zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" | \
xz ${bastille_compress_xz_options} > ${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT} xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
zfs destroy -r ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@${SNAP_NAME} zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_export_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
fi fi
else else
# Create standard backup archive # Create standard backup archive
FILE_EXT="txz" FILE_EXT="txz"
echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive...${COLOR_RESET}" echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive...${COLOR_RESET}"
cd ${bastille_jailsdir} && tar -cf - ${TARGET} | xz ${bastille_compress_xz_options} > ${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT} cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
fi fi
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}Failed to export '${TARGET}' container.${COLOR_RESET}" error_notify "${COLOR_RED}Failed to export '${TARGET}' container.${COLOR_RESET}"
else else
# Generate container checksum file # Generate container checksum file
cd ${bastille_backupsdir} cd "${bastille_backupsdir}"
sha256 -q ${TARGET}_${DATE}.${FILE_EXT} > ${TARGET}_${DATE}.sha256 sha256 -q "${TARGET}_${DATE}.${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
echo -e "${COLOR_GREEN}Exported '${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}' successfully.${COLOR_RESET}" echo -e "${COLOR_GREEN}Exported '${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}' successfully.${COLOR_RESET}"
exit 0 exit 0
fi fi
@@ -97,6 +97,13 @@ jail_export()
fi fi
} }
# Check for user specified file location
if echo "${TARGET}" | grep -q '\/'; then
GETDIR="${TARGET}"
TARGET=$(echo ${TARGET} | awk -F '\/' '{print $NF}')
bastille_backupsdir=$(echo ${GETDIR} | sed "s/${TARGET}//")
fi
# Check if backups directory/dataset exist # Check if backups directory/dataset exist
if [ ! -d "${bastille_backupsdir}" ]; then if [ ! -d "${bastille_backupsdir}" ]; then
error_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}" error_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"

View File

@@ -32,7 +32,7 @@
. /usr/local/etc/bastille/bastille.conf . /usr/local/etc/bastille/bastille.conf
usage() { usage() {
echo -e "${COLOR_RED}Usage: bastille import backup_file.${COLOR_RESET}" echo -e "${COLOR_RED}Usage: bastille import file [option].${COLOR_RESET}"
exit 1 exit 1
} }
@@ -43,11 +43,12 @@ help|-h|--help)
;; ;;
esac esac
if [ $# -gt 1 ] || [ $# -lt 1 ]; then if [ $# -gt 2 ] || [ $# -lt 1 ]; then
usage usage
fi fi
TARGET="${1}" TARGET="${1}"
OPTION="${2}"
shift shift
error_notify() { error_notify() {
@@ -58,25 +59,47 @@ error_notify() {
validate_archive() { validate_archive() {
# Compare checksums on the target archive # Compare checksums on the target archive
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then # Skip validation for unsupported archives
echo -e "${COLOR_GREEN}Validating file: ${TARGET}...${COLOR_RESET}" if [ "${FILE_EXT}" != ".tar.gz" ] && [ "${FILE_EXT}" != ".tar" ]; then
SHA256_DIST=$(cat ${bastille_backupsdir}/${FILE_TRIM}.sha256) if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
SHA256_FILE=$(sha256 -q ${bastille_backupsdir}/${TARGET}) if [ -f "${bastille_backupsdir}/${FILE_TRIM}.sha256" ]; then
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then echo -e "${COLOR_GREEN}Validating file: ${TARGET}...${COLOR_RESET}"
error_notify "${COLOR_RED}Failed validation for ${TARGET}.${COLOR_RESET}" SHA256_DIST=$(cat "${bastille_backupsdir}/${FILE_TRIM}.sha256")
else SHA256_FILE=$(sha256 -q "${bastille_backupsdir}/${TARGET}")
echo -e "${COLOR_GREEN}File validation successful!${COLOR_RESET}" if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
error_notify "${COLOR_RED}Failed validation for ${TARGET}.${COLOR_RESET}"
else
echo -e "${COLOR_GREEN}File validation successful!${COLOR_RESET}"
fi
else
# Check if user opt to force import
if [ "${OPTION}" = "-f" -o "${OPTION}" = "force" ]; then
echo -e "${COLOR_YELLOW}Warning: Skipping archive validation!${COLOR_RESET}"
else
error_notify "${COLOR_RED}Checksum file not found, See 'bastille import TARGET -f'${COLOR_RESET}"
fi
fi
fi fi
else
echo -e "${COLOR_YELLOW}Warning: Skipping archive validation!${COLOR_RESET}"
fi fi
} }
update_zfsmount() { update_zfsmount() {
# Update the mountpoint property on the received zfs data stream # Update the mountpoint property on the received zfs data stream
OLD_ZFS_MOUNTPOINT=$(zfs get -H mountpoint ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root | awk '{print $3}') OLD_ZFS_MOUNTPOINT=$(zfs get -H mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" | awk '{print $3}')
NEW_ZFS_MOUNTPOINT="${bastille_jailsdir}/${TARGET_TRIM}/root" NEW_ZFS_MOUNTPOINT="${bastille_jailsdir}/${TARGET_TRIM}/root"
if [ "${NEW_ZFS_MOUNTPOINT}" != "${OLD_ZFS_MOUNTPOINT}" ]; then if [ "${NEW_ZFS_MOUNTPOINT}" != "${OLD_ZFS_MOUNTPOINT}" ]; then
echo -e "${COLOR_GREEN}Updating zfs mountpoint...${COLOR_RESET}" echo -e "${COLOR_GREEN}Updating zfs mountpoint...${COLOR_RESET}"
zfs set mountpoint=${bastille_jailsdir}/${TARGET_TRIM}/root ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root zfs set mountpoint="${bastille_jailsdir}/${TARGET_TRIM}/root" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
fi
# Mount new container ZFS datasets
if ! zfs mount | grep -qw "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}$"; then
zfs mount "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
fi
if ! zfs mount | grep -qw "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root$"; then
zfs mount "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
fi fi
} }
@@ -84,11 +107,11 @@ update_jailconf() {
# Update jail.conf paths # Update jail.conf paths
JAIL_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/jail.conf" JAIL_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
if [ -f "${JAIL_CONFIG}" ]; then if [ -f "${JAIL_CONFIG}" ]; then
if ! grep -qw "path = ${bastille_jailsdir}/${TARGET_TRIM}/root;" ${JAIL_CONFIG}; then if ! grep -qw "path = ${bastille_jailsdir}/${TARGET_TRIM}/root;" "${JAIL_CONFIG}"; then
echo -e "${COLOR_GREEN}Updating jail.conf...${COLOR_RESET}" echo -e "${COLOR_GREEN}Updating jail.conf...${COLOR_RESET}"
sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;|" ${JAIL_CONFIG} sed -i '' "s|exec.consolelog.*= .*;|exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;|" "${JAIL_CONFIG}"
sed -i '' "s|path = .*;|path = ${bastille_jailsdir}/${TARGET_TRIM}/root;|" ${JAIL_CONFIG} 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} sed -i '' "s|mount.fstab.*= .*;|mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;|" "${JAIL_CONFIG}"
fi fi
fi fi
} }
@@ -97,67 +120,329 @@ update_fstab() {
# Update fstab .bastille mountpoint on thin containers only # Update fstab .bastille mountpoint on thin containers only
# Set some variables # Set some variables
FSTAB_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/fstab" FSTAB_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/fstab"
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2]|-stable-build-[0-9]{1,3})' ${FSTAB_CONFIG}) 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_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET_TRIM}/root/.bastille" ${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" FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0"
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
# If both variables are set, compare and update as needed # If both variables are set, compare and update as needed
if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille" ${FSTAB_CONFIG}; then if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}"; then
echo -e "${COLOR_GREEN}Updating fstab...${COLOR_RESET}" echo -e "${COLOR_GREEN}Updating fstab...${COLOR_RESET}"
sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" ${FSTAB_CONFIG} sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}"
fi fi
fi fi
} }
generate_config() {
# Attempt to read previous config file and set required variables accordingly
# If we can't get a valid interface, fallback to lo1 and warn user
echo -e "${COLOR_GREEN}Generating jail.conf...${COLOR_RESET}"
if [ "${FILE_EXT}" = ".zip" ]; then
# Gather some bits from foreign/iocage config files
JSON_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/config.json"
if [ -n "${JSON_CONFIG}" ]; then
IPV4_CONFIG=$(grep -wo '\"ip4_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip4_addr://')
IPV6_CONFIG=$(grep -wo '\"ip6_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip6_addr://')
fi
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
# Gather some bits from foreign/ezjail config files
PROP_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/prop.ezjail-${FILE_TRIM}-*"
if [ -n "${PROP_CONFIG}" ]; then
IPVX_CONFIG=$(grep -wo "jail_${TARGET_TRIM}_ip=.*" ${PROP_CONFIG} | tr -d '" ' | sed "s/jail_${TARGET_TRIM}_ip=//")
fi
fi
# If there are multiple IP/NIC let the user configure network
if [ -n "${IPV4_CONFIG}" ]; then
if ! echo "${IPV4_CONFIG}" | grep -q '.*,.*'; then
NETIF_CONFIG=$(echo "${IPV4_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${NETIF_CONFIG}" ]; then
config_netif
fi
IPX_ADDR="ip4.addr"
IP_CONFIG="${IPV4_CONFIG}"
IP6_MODE="disable"
fi
elif [ -n "${IPV6_CONFIG}" ]; then
if ! echo "${IPV6_CONFIG}" | grep -q '.*,.*'; then
NETIF_CONFIG=$(echo "${IPV6_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${NETIF_CONFIG}" ]; then
config_netif
fi
IPX_ADDR="ip6.addr"
IP_CONFIG="${IPV6_CONFIG}"
IP6_MODE="new"
fi
elif [ -n "${IPVX_CONFIG}" ]; then
if ! echo "${IPVX_CONFIG}" | grep -q '.*,.*'; then
NETIF_CONFIG=$(echo "${IPVX_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${NETIF_CONFIG}" ]; then
config_netif
fi
IPX_ADDR="ip4.addr"
IP_CONFIG="${IPVX_CONFIG}"
IP6_MODE="disable"
if echo "${IPVX_CONFIG}" | sed 's/.*|//' | grep -Eq '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))'; then
IPX_ADDR="ip6.addr"
IP6_MODE="new"
fi
fi
fi
# Let the user configure network manually
if [ -z "${NETIF_CONFIG}" ]; then
NETIF_CONFIG="lo1"
IPX_ADDR="ip4.addr"
IP_CONFIG="-"
IP6_MODE="disable"
echo -e "${COLOR_YELLOW}Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration${COLOR_RESET}"
fi
if [ "${FILE_EXT}" = ".tar.gz" ]; then
CONFIG_RELEASE=$(echo ${PROP_CONFIG} | grep -o '[0-9]\{2\}\.[0-9]_RELEASE' | sed 's/_/-/g')
if [ -z "${CONFIG_RELEASE}" ]; then
# Fallback to host version
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} was set by default!${COLOR_RESET}"
fi
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
>> "${bastille_jailsdir}/${TARGET_TRIM}/fstab"
# Work with the symlinks
cd "${bastille_jailsdir}/${TARGET_TRIM}/root"
update_symlinks
else
# Generate new empty fstab file
touch "${bastille_jailsdir}/${TARGET_TRIM}/fstab"
fi
# Generate a basic jail configuration file on foreign imports
cat << EOF > "${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
${TARGET_TRIM} {
devfs_ruleset = 4;
enforce_statfs = 2;
exec.clean;
exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;
exec.start = '/bin/sh /etc/rc';
exec.stop = '/bin/sh /etc/rc.shutdown';
host.hostname = ${TARGET_TRIM};
mount.devfs;
mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;
path = ${bastille_jailsdir}/${TARGET_TRIM}/root;
securelevel = 2;
interface = ${NETIF_CONFIG};
${IPX_ADDR} = ${IP_CONFIG};
ip6 = ${IP6_MODE};
}
EOF
}
update_config() {
# Update an existing jail configuration
# The config on select archives does not provide a clear way to determine
# the base release, so lets try to get it from the base/COPYRIGHT file,
# otherwise warn user and fallback to host system release
CONFIG_RELEASE=$(grep -wo 'releng/[0-9]\{2\}.[0-9]/COPYRIGHT' "${bastille_jailsdir}/${TARGET_TRIM}/root/COPYRIGHT" | sed 's|releng/||;s|/COPYRIGHT|-RELEASE|')
if [ -z "${CONFIG_RELEASE}" ]; then
# Fallback to host version
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} was set by default!${COLOR_RESET}"
fi
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
>> "${bastille_jailsdir}/${TARGET_TRIM}/fstab"
# Work with the symlinks
cd "${bastille_jailsdir}/${TARGET_TRIM}/root"
update_symlinks
}
workout_components() {
if [ "${FILE_EXT}" = ".tar" ]; then
# Workaround to determine the tarball path/components before extract(assumes path/jails/target)
JAIL_PATH=$(tar -tvf ${bastille_backupsdir}/${TARGET} | grep -wo "/.*/jails/${TARGET_TRIM}" | tail -n1)
JAIL_DIRS=$(echo ${JAIL_PATH} | grep -o '/' | wc -l)
DIRS_PLUS=$(expr ${JAIL_DIRS} + 1)
# Workaround to determine the jail.conf path before extract(assumes path/qjail.config/target)
JAIL_CONF=$(tar -tvf ${bastille_backupsdir}/${TARGET} | grep -wo "/.*/qjail.config/${TARGET_TRIM}")
CONF_TRIM=$(echo ${JAIL_CONF} | grep -o '/' | wc -l)
fi
}
config_netif() {
# Get interface from bastille configuration
if [ -n "${bastille_network_loopback}" ]; then
NETIF_CONFIG="${bastille_network_loopback}"
elif [ -n "${bastille_network_shared}" ]; then
NETIF_CONFIG="${bastille_network_shared}"
else
NETIF_CONFIG=
fi
}
update_symlinks() {
# Work with the symlinks
SYMLINKS="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/ports usr/sbin usr/share usr/src"
# Just warn user to bootstrap the release if missing
if [ ! -d "${bastille_releasesdir}/${CONFIG_RELEASE}" ]; then
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} must be bootstrapped, See 'bastille bootstrap'.${COLOR_RESET}"
fi
# Update old symlinks
echo -e "${COLOR_GREEN}Updating symlinks...${COLOR_RESET}"
for _link in ${SYMLINKS}; do
if [ -L "${_link}" ]; then
ln -sf /.bastille/${_link} ${_link}
fi
done
}
create_zfs_datasets() {
# Prepare the ZFS environment and restore from file
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Preparing zfs environment...${COLOR_RESET}"
# Create required ZFS datasets, mountpoint inherited from system
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
}
remove_zfs_datasets() {
# Perform cleanup on failure
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
error_notify "${COLOR_RED}Failed to extract files from '${TARGET}' archive.${COLOR_RESET}"
}
jail_import() { jail_import() {
# Attempt to import container from file # Attempt to import container from file
FILE_TRIM=$(echo ${TARGET} | sed 's/.[txz]\{2,3\}//') FILE_TRIM=$(echo "${TARGET}" | sed 's/\.xz//g;s/\.txz//g;s/\.zip//g;s/\.tar\.gz//g;s/\.tar//g')
FILE_EXT=$(echo ${TARGET} | cut -d '.' -f2) FILE_EXT=$(echo "${TARGET}" | sed "s/${FILE_TRIM}//g")
validate_archive validate_archive
if [ -d "${bastille_jailsdir}" ]; then if [ -d "${bastille_jailsdir}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ ! -z "${bastille_zfs_zpool}" ]; then if [ -n "${bastille_zfs_zpool}" ]; then
if [ "${FILE_EXT}" = "xz" ]; then if [ "${FILE_EXT}" = ".xz" ]; then
# Import from compressed xz on ZFS systems # Import from compressed xz on ZFS systems
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from compressed .${FILE_EXT} archive.${COLOR_RESET}" echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} archive.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Receiving zfs data stream...${COLOR_RESET}" echo -e "${COLOR_GREEN}Receiving zfs data stream...${COLOR_RESET}"
xz ${bastille_decompress_xz_options} ${bastille_backupsdir}/${TARGET} | \ xz ${bastille_decompress_xz_options} "${bastille_backupsdir}/${TARGET}" | \
zfs receive -u ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM} zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
# Update ZFS mountpoint property if required # Update ZFS mountpoint property if required
# This is required on foreign imports only
update_zfsmount update_zfsmount
# Mount new container ZFS datasets elif [ "${FILE_EXT}" = ".txz" ]; then
zfs mount ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM} # Prepare the ZFS environment and restore from existing .txz file
zfs mount ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root create_zfs_datasets
elif [ "${FILE_EXT}" = "txz" ]; then
# Prepare the ZFS environment and restore from existing tar.xz file
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' form .${FILE_EXT} archive.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Preparing zfs environment...${COLOR_RESET}"
zfs create ${bastille_zfs_options} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_jailsdir}/${TARGET_TRIM}/root \
${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root
# Extract required files to the new datasets # Extract required files to the new datasets
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}" echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
tar --exclude='root' -Jxf ${bastille_backupsdir}/${TARGET} --strip-components 1 -C ${bastille_jailsdir}/${TARGET_TRIM} tar --exclude='root' -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
tar -Jxf ${bastille_backupsdir}/${TARGET} --strip-components 2 -C ${bastille_jailsdir}/${TARGET_TRIM}/root ${TARGET_TRIM}/root tar -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 2 -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${TARGET_TRIM}/root"
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
zfs destroy -r ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM} remove_zfs_datasets
fi
elif [ "${FILE_EXT}" = ".zip" ]; then
# Attempt to import a foreign/iocage container
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive.${COLOR_RESET}"
# Sane bastille zfs options
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
# Extract required files from the zip archive
cd "${bastille_backupsdir}" && unzip -j "${TARGET}"
if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}Failed to extract files from '${TARGET}' archive.${COLOR_RESET}" error_notify "${COLOR_RED}Failed to extract files from '${TARGET}' archive.${COLOR_RESET}"
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
fi
echo -e "${COLOR_GREEN}Receiving zfs data stream...${COLOR_RESET}"
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${FILE_TRIM}"
zfs set ${ZFS_OPTIONS} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root"
# Update ZFS mountpoint property if required
update_zfsmount
# Keep old configuration files for user reference
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/fstab" ]; then
mv "${bastille_jailsdir}/${TARGET_TRIM}/fstab" "${bastille_jailsdir}/${TARGET_TRIM}/fstab.old"
fi
# Cleanup unwanted files
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
# Generate fstab and jail.conf files
generate_config
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
# Attempt to import a foreign/ezjail container
# Prepare the ZFS environment and restore from existing .tar.gz file
create_zfs_datasets
# Extract required files to the new datasets
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
tar --exclude='ezjail/' -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}/root"
if [ "$?" -ne 0 ]; then
remove_zfs_datasets
else
generate_config
fi
elif [ "${FILE_EXT}" = ".tar" ]; then
# Attempt to import a foreign/qjail container
# Prepare the ZFS environment and restore from existing .tar file
create_zfs_datasets
workout_components
# Extract required files to the new datasets
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${DIRS_PLUS}" -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${JAIL_PATH}"
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" ]; then
mv "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" "${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
fi
if [ "$?" -ne 0 ]; then
remove_zfs_datasets
else
update_config
fi fi
else else
error_notify "${COLOR_RED}Unknown archive format.${COLOR_RESET}" error_notify "${COLOR_RED}Unknown archive format.${COLOR_RESET}"
fi fi
fi fi
else else
# Import from standard tar.xz archive on UFS systems # Import from standard supported archives on UFS systems
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}" if [ "${FILE_EXT}" = ".txz" ]; then
tar -Jxf ${bastille_backupsdir}/${TARGET} -C ${bastille_jailsdir} echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
tar -Jxf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
# Attempt to import/configure foreign/ezjail container
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
mkdir "${bastille_jailsdir}/${TARGET_TRIM}"
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
mv "${bastille_jailsdir}/${TARGET_TRIM}/ezjail" "${bastille_jailsdir}/${TARGET_TRIM}/root"
generate_config
elif [ "${FILE_EXT}" = ".tar" ]; then
# Attempt to import/configure foreign/qjail container
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
mkdir -p "${bastille_jailsdir}/${TARGET_TRIM}/root"
workout_components
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${DIRS_PLUS}" -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${JAIL_PATH}"
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" ]; then
mv "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" "${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
fi
update_config
else
error_notify "${COLOR_RED}Unsupported archive format.${COLOR_RESET}"
fi
fi fi
if [ $? -ne 0 ]; then if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}Failed to import from '${TARGET}' archive.${COLOR_RESET}" error_notify "${COLOR_RED}Failed to import from '${TARGET}' archive.${COLOR_RESET}"
else else
# Update the jail.conf and fstab if required # Update the jail.conf and fstab if required
@@ -172,14 +457,28 @@ jail_import() {
fi fi
} }
# Check for user specified file location
if echo "${TARGET}" | grep -q '\/'; then
GETDIR="${TARGET}"
TARGET=$(echo ${TARGET} | awk -F '\/' '{print $NF}')
bastille_backupsdir=$(echo ${GETDIR} | sed "s/${TARGET}//")
fi
# Check if backups directory/dataset exist # Check if backups directory/dataset exist
if [ ! -d "${bastille_backupsdir}" ]; then if [ ! -d "${bastille_backupsdir}" ]; then
error_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}" error_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"
fi fi
# Check if archive exist then trim archive name # Check if archive exist then trim archive name
if [ "$(ls "${bastille_backupsdir}" | awk "/^${TARGET}$/")" ]; then if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
TARGET_TRIM=$(echo ${TARGET} | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*:[0-9]*:[0-9]*.[txz]\{2,3\}//") # Filter unsupported/unknown archives
if echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.xz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.txz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}.zip$\|-[0-9]\{12\}.[0-9]\{2\}.tar.gz$\|@[0-9]\{12\}.[0-9]\{2\}.tar$'; then
if ls "${bastille_backupsdir}" | awk "/^${TARGET}$/" >/dev/null; then
TARGET_TRIM=$(echo "${TARGET}" | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.xz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.txz//;s/_[0-9]*-[0-9]*-[0-9]*.zip//;s/-[0-9]\{12\}.[0-9]\{2\}.tar.gz//;s/@[0-9]\{12\}.[0-9]\{2\}.tar//")
fi
else
error_notify "${COLOR_RED}Unrecognized archive name.${COLOR_RESET}"
fi
else else
error_notify "${COLOR_RED}Archive '${TARGET}' not found.${COLOR_RESET}" error_notify "${COLOR_RED}Archive '${TARGET}' not found.${COLOR_RESET}"
fi fi

View File

@@ -69,6 +69,6 @@ fi
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
echo -e "${TYPE} ${VALUE}" echo -e "${TYPE} ${VALUE}"
rctl -a jail:${_jail}:${OPTION}:deny=${VALUE}/jail rctl -a jail:"${_jail}":"${OPTION}":deny="${VALUE}/jail"
echo -e "${COLOR_RESET}" echo -e "${COLOR_RESET}"
done done

View File

@@ -58,6 +58,6 @@ fi
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
jexec -l ${_jail} /usr/sbin/pkg $@ jexec -l "${_jail}" /usr/sbin/pkg "$@"
echo echo
done done

View File

@@ -68,7 +68,7 @@ if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
fi fi
# Check rdr-anchor is setup in pf.conf # Check rdr-anchor is setup in pf.conf
if !(pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
echo -e "${COLOR_RED}rdr-anchor not found in pf.conf${COLOR_RESET}" echo -e "${COLOR_RED}rdr-anchor not found in pf.conf${COLOR_RESET}"
exit 1 exit 1
fi fi
@@ -113,6 +113,3 @@ while [ $# -gt 0 ]; do
;; ;;
esac esac
done done

View File

@@ -0,0 +1,133 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# 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/colors.pre.sh
. /usr/local/etc/bastille/bastille.conf
usage() {
echo -e "${COLOR_RED}Usage: bastille rename [TARGET] [NEW_NAME].${COLOR_RESET}"
exit 1
}
error_notify() {
# Notify message on error and exit
echo -e "$*" >&2
exit 1
}
# Handle special-case commands first
case "$1" in
help|-h|--help)
usage
;;
esac
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
usage
fi
TARGET="${1}"
NEWNAME="${2}"
shift
if echo "${NEWNAME}" | grep -q "[.]"; then
echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}"
exit 1
fi
update_jailconf() {
# Update jail.conf
JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf"
if [ -f "${JAIL_CONFIG}" ]; then
if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then
sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}"
sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}"
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}"
fi
fi
}
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|-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_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
# If both variables are set, update as needed
if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${NEWNAME}/root/.bastille" "${FSTAB_CONFIG}"; then
sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}"
fi
fi
fi
}
change_name() {
# Attempt container name change
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_GREEN}Attempting to rename '${TARGET}' to ${NEWNAME}...${COLOR_RESET}"
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
# Rename ZFS dataset and mount points accordingly
zfs rename "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"
zfs set mountpoint="${bastille_jailsdir}/${NEWNAME}/root" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root"
fi
else
# Just rename the jail directory
mv "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
fi
else
error_notify "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
fi
# Update jail configuration files accordingly
update_jailconf
update_fstab
# Remove the old jail directory if exist
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
rm -r "${bastille_jailsdir}/${TARGET}"
fi
if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}An error has occurred while attempting to rename '${TARGET}'.${COLOR_RESET}"
else
echo -e "${COLOR_GREEN}Renamed '${TARGET}' to '${NEWNAME}' successfully.${COLOR_RESET}"
fi
}
# Check if container is running
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop'.${COLOR_RESET}"
fi
change_name

View File

@@ -59,6 +59,6 @@ fi
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
jexec -l ${_jail} /usr/sbin/service $@ jexec -l "${_jail}" /usr/sbin/service "$@"
echo echo
done done

View File

@@ -55,6 +55,10 @@ if [ "${TARGET}" = 'ALL' ]; then
fi fi
if [ "${TARGET}" != 'ALL' ]; then if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(bastille list jails | awk "/^${TARGET}$/") JAILS=$(bastille list jails | awk "/^${TARGET}$/")
## check if exist
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_RED}[${TARGET}]: Not found.${COLOR_RESET}"
fi
fi fi
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
@@ -64,16 +68,18 @@ for _jail in ${JAILS}; do
## test if not running ## test if not running
elif [ ! "$(jls name | awk "/^${_jail}$/")" ]; then elif [ ! "$(jls name | awk "/^${_jail}$/")" ]; then
## warn if matching configured (but not online) ip4.addr ## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry
ip=$(grep 'ip4.addr' "${bastille_jailsdir}/${_jail}/jail.conf" | awk '{print $3}' | sed 's/\;//g') ip=$(grep 'ip4.addr' "${bastille_jailsdir}/${_jail}/jail.conf" | awk '{print $3}' | sed 's/\;//g')
if ifconfig | grep -w "$ip" >/dev/null; then if [ -n "${ip}" ]; then
echo -e "${COLOR_RED}Error: IP address ($ip) already in use.${COLOR_RESET}" if ifconfig | grep -w "${ip}" >/dev/null; then
exit 1 echo -e "${COLOR_RED}Error: IP address (${ip}) already in use.${COLOR_RESET}"
exit 1
fi
fi fi
## start the container ## start the container
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c ${_jail} jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}"
## add rctl limits ## add rctl limits
if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then
@@ -83,8 +89,8 @@ for _jail in ${JAILS}; do
fi fi
## add ip4.addr to firewall table:jails ## add ip4.addr to firewall table:jails
if [ ! -z "${bastille_jail_loopback}" ]; then if [ ! -z "${bastille_network_loopback}" ]; then
pfctl -q -t jails -T add $(jls -j ${_jail} ip4.addr) pfctl -q -t jails -T add "$(jls -j "${_jail}" ip4.addr)"
fi fi
fi fi
echo echo

View File

@@ -55,8 +55,10 @@ if [ "${TARGET}" = 'ALL' ]; then
fi fi
if [ "${TARGET}" != 'ALL' ]; then if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(jls name | awk "/^${TARGET}$/") JAILS=$(jls name | awk "/^${TARGET}$/")
## test if not running ## check if exist or not running
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_RED}[${TARGET}]: Not found.${COLOR_RESET}"
elif [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
echo -e "${COLOR_RED}[${TARGET}]: Not started.${COLOR_RESET}" echo -e "${COLOR_RED}[${TARGET}]: Not started.${COLOR_RESET}"
fi fi
fi fi
@@ -65,8 +67,8 @@ for _jail in ${JAILS}; do
## test if running ## test if running
if [ "$(jls name | awk "/^${_jail}$/")" ]; then if [ "$(jls name | awk "/^${_jail}$/")" ]; then
## remove ip4.addr from firewall table:jails ## remove ip4.addr from firewall table:jails
if [ ! -z "${bastille_jail_loopback}" ]; then if [ -n "${bastille_network_loopback}" ]; then
pfctl -q -t jails -T delete $(jls -j ${_jail} ip4.addr) pfctl -q -t jails -T delete "$(jls -j "${_jail}" ip4.addr)"
fi fi
## remove rctl limits ## remove rctl limits
@@ -78,7 +80,7 @@ for _jail in ${JAILS}; do
## stop container ## stop container
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r ${_jail} jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}"
fi fi
echo echo
done done

View File

@@ -59,6 +59,6 @@ fi
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
jexec -l ${_jail} /usr/sbin/sysrc $@ jexec -l "${_jail}" /usr/sbin/sysrc "$@"
echo -e "${COLOR_RESET}" echo -e "${COLOR_RESET}"
done done

View File

@@ -80,12 +80,12 @@ for _jail in ${JAILS}; do
## TARGET ## TARGET
if [ -s "${bastille_template}/TARGET" ]; then if [ -s "${bastille_template}/TARGET" ]; then
if [ $(grep -w "${_jail}" ${bastille_template}/TARGET) ]; then if grep -qw "${_jail}" "${bastille_template}/TARGET"; then
echo -e "${COLOR_GREEN}TARGET: !${_jail}.${COLOR_RESET}" echo -e "${COLOR_GREEN}TARGET: !${_jail}.${COLOR_RESET}"
echo echo
continue continue
fi fi
if [ ! $(grep -E "(^|\b)(${_jail}|ALL)($|\b)" ${bastille_template}/TARGET) ]; then if ! grep -Eq "(^|\b)(${_jail}|ALL)($|\b)" "${bastille_template}/TARGET"; then
echo -e "${COLOR_GREEN}TARGET: ?${_jail}.${COLOR_RESET}" echo -e "${COLOR_GREEN}TARGET: ?${_jail}.${COLOR_RESET}"
echo echo
continue continue
@@ -107,7 +107,7 @@ for _jail in ${JAILS}; do
_rctl_rule="jail:${_jail}:${_limit_key}:deny=${_limit_value}/jail" _rctl_rule="jail:${_jail}:${_limit_key}:deny=${_limit_value}/jail"
## if entry doesn't exist, add; else show existing entry ## if entry doesn't exist, add; else show existing entry
if [ ! "$(grep -qs "${_rctl_rule}" "${bastille_jailsdir}/${_jail}/rctl.conf")" ]; then if ! grep -qs "${_rctl_rule}" "${bastille_jailsdir}/${_jail}/rctl.conf"; then
echo "${_rctl_rule}" >> "${bastille_jailsdir}/${_jail}/rctl.conf" echo "${_rctl_rule}" >> "${bastille_jailsdir}/${_jail}/rctl.conf"
echo "${_limits}" echo "${_limits}"
else else
@@ -131,12 +131,12 @@ for _jail in ${JAILS}; do
case ${_include} in case ${_include} in
http?://github.com/*/*|http?://gitlab.com/*/*) http?://github.com/*/*|http?://gitlab.com/*/*)
bastille bootstrap ${_include} bastille bootstrap "${_include}"
;; ;;
*/*) */*)
BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }') BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }')
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }') BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }')
bastille template ${_jail} ${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO} bastille template "${_jail}" "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
;; ;;
*) *)
echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}" echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}"
@@ -148,7 +148,7 @@ for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}Applying ${_include}...${COLOR_RESET}" echo -e "${COLOR_GREEN}Applying ${_include}...${COLOR_RESET}"
BASTILLE_TEMPLATE_PROJECT=$(echo "${_include}" | awk -F / '{ print $4}') BASTILLE_TEMPLATE_PROJECT=$(echo "${_include}" | awk -F / '{ print $4}')
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $5}') BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $5}')
bastille template ${_jail} ${BASTILLE_TEMPLATE_PROJECT}/${BASTILLE_TEMPLATE_REPO} bastille template "${_jail}" "${BASTILLE_TEMPLATE_PROJECT}/${BASTILLE_TEMPLATE_REPO}"
done < "${bastille_template}/INCLUDE" done < "${bastille_template}/INCLUDE"
echo -e "${COLOR_GREEN}[${_jail}]:INCLUDE -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:INCLUDE -- END${COLOR_RESET}"
echo echo
@@ -157,7 +157,7 @@ for _jail in ${JAILS}; do
## PRE ## PRE
if [ -s "${bastille_template}/PRE" ]; then if [ -s "${bastille_template}/PRE" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:PRE -- START${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:PRE -- START${COLOR_RESET}"
jexec -l ${_jail} /bin/sh < "${bastille_template}/PRE" || exit 1 jexec -l "${_jail}" /bin/sh < "${bastille_template}/PRE" || exit 1
echo -e "${COLOR_GREEN}[${_jail}]:PRE -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:PRE -- END${COLOR_RESET}"
echo echo
fi fi
@@ -206,11 +206,11 @@ for _jail in ${JAILS}; do
_fstab_entry="${_hostpath} ${bastille_jailsdir}/${_jail}/root/${_jailpath} ${_type} ${_perms} ${_checks}" _fstab_entry="${_hostpath} ${bastille_jailsdir}/${_jail}/root/${_jailpath} ${_type} ${_perms} ${_checks}"
## if entry doesn't exist, add; else show existing entry ## if entry doesn't exist, add; else show existing entry
if [ ! "$(grep "${_jailpath}" "${bastille_jailsdir}/${_jail}/fstab")" ]; then if ! grep -q "${_jailpath}" "${bastille_jailsdir}/${_jail}/fstab"; then
echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab" echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"
echo "Added: ${_fstab_entry}" echo "Added: ${_fstab_entry}"
else else
echo "$(grep "${_jailpath}" "${bastille_jailsdir}/${_jail}/fstab")" grep "${_jailpath}" "${bastille_jailsdir}/${_jail}/fstab"
fi fi
done < "${bastille_template}/FSTAB" done < "${bastille_template}/FSTAB"
mount -F "${bastille_jailsdir}/${_jail}/fstab" -a mount -F "${bastille_jailsdir}/${_jail}/fstab" -a
@@ -227,7 +227,7 @@ for _jail in ${JAILS}; do
if [ -s "${bastille_template}/PKG" ]; then if [ -s "${bastille_template}/PKG" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- START${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:PKG -- START${COLOR_RESET}"
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg bootstrap || exit 1 jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg bootstrap || exit 1
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg install $(cat ${bastille_template}/PKG) || exit 1 jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg install $(cat "${bastille_template}/PKG") || exit 1
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg audit -F jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg audit -F
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:PKG -- END${COLOR_RESET}"
echo echo
@@ -238,7 +238,7 @@ for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- START${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- START${COLOR_RESET}"
while read _dir; do while read _dir; do
cp -av "${bastille_template}/${_dir}" "${bastille_jail_path}" || exit 1 cp -av "${bastille_template}/${_dir}" "${bastille_jail_path}" || exit 1
done < ${bastille_template}/OVERLAY done < "${bastille_template}/OVERLAY"
echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- END${COLOR_RESET}"
echo echo
fi fi
@@ -247,7 +247,7 @@ for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:CONFIG -- START${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:CONFIG -- START${COLOR_RESET}"
while read _dir; do while read _dir; do
cp -av "${bastille_template}/${_dir}" "${bastille_jail_path}" || exit 1 cp -av "${bastille_template}/${_dir}" "${bastille_jail_path}" || exit 1
done < ${bastille_template}/CONFIG done < "${bastille_template}/CONFIG"
echo -e "${COLOR_GREEN}[${_jail}]:CONFIG -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:CONFIG -- END${COLOR_RESET}"
echo echo
fi fi
@@ -256,7 +256,7 @@ for _jail in ${JAILS}; do
if [ -s "${bastille_template}/SYSRC" ]; then if [ -s "${bastille_template}/SYSRC" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- START${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- START${COLOR_RESET}"
while read _sysrc; do while read _sysrc; do
jexec -l ${_jail} /usr/sbin/sysrc "${_sysrc}" || exit 1 jexec -l "${_jail}" /usr/sbin/sysrc "${_sysrc}" || exit 1
done < "${bastille_template}/SYSRC" done < "${bastille_template}/SYSRC"
echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- END${COLOR_RESET}"
echo echo
@@ -266,7 +266,7 @@ for _jail in ${JAILS}; do
if [ -s "${bastille_template}/SERVICE" ]; then if [ -s "${bastille_template}/SERVICE" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- START${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- START${COLOR_RESET}"
while read _service; do while read _service; do
jexec -l ${_jail} /usr/sbin/service ${_service} || exit 1 jexec -l "${_jail}" /usr/sbin/service "${_service}" || exit 1
done < "${bastille_template}/SERVICE" done < "${bastille_template}/SERVICE"
echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- END${COLOR_RESET}"
echo echo
@@ -275,7 +275,7 @@ for _jail in ${JAILS}; do
## CMD ## CMD
if [ -s "${bastille_template}/CMD" ]; then if [ -s "${bastille_template}/CMD" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:CMD -- START${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:CMD -- START${COLOR_RESET}"
jexec -l ${_jail} /bin/sh < "${bastille_template}/CMD" || exit 1 jexec -l "${_jail}" /bin/sh < "${bastille_template}/CMD" || exit 1
echo -e "${COLOR_GREEN}[${_jail}]:CMD -- END${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:CMD -- END${COLOR_RESET}"
echo echo
fi fi

View File

@@ -59,6 +59,6 @@ fi
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
jexec -l ${_jail} /usr/bin/top jexec -l "${_jail}" /usr/bin/top
echo -e "${COLOR_RESET}" echo -e "${COLOR_RESET}"
done done

View File

@@ -50,7 +50,7 @@ fi
TARGET="${1}" TARGET="${1}"
shift shift
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then if freebsd-version | grep -qi HBSD; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}" echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1 exit 1
fi fi
@@ -59,7 +59,7 @@ if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
if ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then if ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
# Update a thick container. # Update a thick container.
CURRENT_VERSION=$(/usr/sbin/jexec -l ${TARGET} freebsd-version 2>/dev/null) CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null)
if [ -z "${CURRENT_VERSION}" ]; then if [ -z "${CURRENT_VERSION}" ]; then
echo -e "${COLOR_RED}Can't determine '${TARGET}' version.${COLOR_RESET}" echo -e "${COLOR_RED}Can't determine '${TARGET}' version.${COLOR_RESET}"
exit 1 exit 1

View File

@@ -51,7 +51,7 @@ RELEASE="$1"
shift shift
NEWRELEASE="$1" NEWRELEASE="$1"
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then if freebsd-version | grep -qi HBSD; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}" echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1 exit 1
fi fi

View File

@@ -37,13 +37,13 @@ bastille_usage() {
} }
verify_release() { verify_release() {
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then if freebsd-version | grep -qi HBSD; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}" echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1 exit 1
fi fi
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" --currently-running ${RELEASE} IDS freebsd-update -b "${bastille_releasesdir}/${RELEASE}" --currently-running "${RELEASE}" IDS
else else
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}" echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
exit 1 exit 1
@@ -61,7 +61,7 @@ verify_template() {
echo -e "${COLOR_GREEN}Detected ${_hook} hook.${COLOR_RESET}" echo -e "${COLOR_GREEN}Detected ${_hook} hook.${COLOR_RESET}"
## line count must match newline count ## line count must match newline count
if [ $(wc -l ${_path} | awk '{print $1}') -ne $(grep -c $'\n' ${_path}) ]; then if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
echo -e "${COLOR_RED}${BASTILLE_TEMPLATE}:${_hook} [failed].${COLOR_RESET}" echo -e "${COLOR_RED}${BASTILLE_TEMPLATE}:${_hook} [failed].${COLOR_RESET}"
echo -e "${COLOR_RED}Line numbers don't match line breaks.${COLOR_RESET}" echo -e "${COLOR_RED}Line numbers don't match line breaks.${COLOR_RESET}"
@@ -79,19 +79,19 @@ verify_template() {
case ${_include} in case ${_include} in
http?://github.com/*/*|http?://gitlab.com/*/*) http?://github.com/*/*|http?://gitlab.com/*/*)
bastille bootstrap ${_include} bastille bootstrap "${_include}"
;; ;;
*/*) */*)
BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }') BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }')
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }') BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }')
bastille verify ${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO} bastille verify "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
;; ;;
*) *)
echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}" echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}"
exit 1 exit 1
;; ;;
esac esac
done < ${_path} done < "${_path}"
## if tree; tree -a bastille_template/_dir ## if tree; tree -a bastille_template/_dir
elif [ ${_hook} = 'OVERLAY' ]; then elif [ ${_hook} = 'OVERLAY' ]; then
@@ -101,12 +101,12 @@ verify_template() {
while read _dir; do while read _dir; do
echo -e "${COLOR_GREEN}[${_hook}]:[${_dir}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_hook}]:[${_dir}]:${COLOR_RESET}"
if [ -x /usr/local/bin/tree ]; then if [ -x /usr/local/bin/tree ]; then
/usr/local/bin/tree -a ${_template_path}/${_dir} /usr/local/bin/tree -a "${_template_path}/${_dir}"
else else
find "${_template_path}/${_dir}" -print | sed -e 's;[^/]*/;|___;g;s;___|; |;g' find "${_template_path}/${_dir}" -print | sed -e 's;[^/]*/;|___;g;s;___|; |;g'
fi fi
echo echo
done < ${_path} done < "${_path}"
else else
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
cat "${_path}" cat "${_path}"
@@ -119,7 +119,7 @@ verify_template() {
if [ ${_hook_validate} -lt 1 ]; then if [ ${_hook_validate} -lt 1 ]; then
echo -e "${COLOR_RED}No valid template hooks found.${COLOR_RESET}" echo -e "${COLOR_RED}No valid template hooks found.${COLOR_RESET}"
echo -e "${COLOR_RED}Template discarded.${COLOR_RESET}" echo -e "${COLOR_RED}Template discarded.${COLOR_RESET}"
rm -rf ${bastille_template} rm -rf "${bastille_template}"
exit 1 exit 1
fi fi

View File

@@ -39,7 +39,7 @@ usage() {
zfs_snapshot() { zfs_snapshot() {
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
zfs snapshot ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG} zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
echo echo
done done
} }
@@ -47,7 +47,7 @@ done
zfs_set_value() { zfs_set_value() {
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
zfs $ATTRIBUTE ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail} zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
echo echo
done done
} }
@@ -55,7 +55,7 @@ done
zfs_get_value() { zfs_get_value() {
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
zfs get $ATTRIBUTE ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail} zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
echo echo
done done
} }
@@ -63,7 +63,7 @@ done
zfs_disk_usage() { zfs_disk_usage() {
for _jail in ${JAILS}; do for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}" echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail} zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
echo echo
done done
} }