Compare commits
306 Commits
0.8.202101
...
0.9.202207
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da377f4735 | ||
|
|
f5b47d8f9e | ||
|
|
6de6e7bc6f | ||
|
|
533d108d91 | ||
|
|
a5bf6eca16 | ||
|
|
10468cd08f | ||
|
|
e8a72bcd75 | ||
|
|
b69eedc066 | ||
|
|
62d038049d | ||
|
|
3ba1024704 | ||
|
|
dbb720fef4 | ||
|
|
d0903347a6 | ||
|
|
b9d38a5d01 | ||
|
|
f14eddc958 | ||
|
|
e64c81d18a | ||
|
|
674a34d69c | ||
|
|
a97ac27a46 | ||
|
|
4302445eb5 | ||
|
|
d9f1dfdc2f | ||
|
|
ebb93c795e | ||
|
|
dbd4b5edc5 | ||
|
|
abc8a6b280 | ||
|
|
6e5a566d7f | ||
|
|
24eb03c2e6 | ||
|
|
ff7de9167a | ||
|
|
aafc2b3323 | ||
|
|
efed673e76 | ||
|
|
6aa6e40db1 | ||
|
|
4726c48813 | ||
|
|
920ca1fba0 | ||
|
|
6ca0369072 | ||
|
|
66d830a55f | ||
|
|
e4e1fadf35 | ||
|
|
6b43067d86 | ||
|
|
9052271232 | ||
|
|
4be7795f0a | ||
|
|
ab43a7569f | ||
|
|
d7d0d864c3 | ||
|
|
5d9ea33889 | ||
|
|
dc9b5fb9bd | ||
|
|
a62f36333d | ||
|
|
29e72cd34d | ||
|
|
03b9817f5a | ||
|
|
38bb7faabf | ||
|
|
cc8e9f24a1 | ||
|
|
268d00be1f | ||
|
|
91bb955dd5 | ||
|
|
c98d03a8e5 | ||
|
|
e11ed392f6 | ||
|
|
548ab2e250 | ||
|
|
9fa07ae24e | ||
|
|
523c3f0bde | ||
|
|
af0e9a95a4 | ||
|
|
26e8f382e4 | ||
|
|
788e4c283b | ||
|
|
a56cb2d433 | ||
|
|
17e4fa78f9 | ||
|
|
c8545e8598 | ||
|
|
9a47a6c573 | ||
|
|
00d9e03520 | ||
|
|
9010b58eb8 | ||
|
|
aaea27dcb3 | ||
|
|
c825f0ca75 | ||
|
|
7558fd42ca | ||
|
|
570c80ba85 | ||
|
|
b7914ba67a | ||
|
|
e21d31518a | ||
|
|
d3d5bf2df4 | ||
|
|
2f59bdecec | ||
|
|
a115ba5b87 | ||
|
|
ef070c9aed | ||
|
|
e2f051f899 | ||
|
|
5dabc75257 | ||
|
|
8683ad15d2 | ||
|
|
faf3b2b691 | ||
|
|
8a4b0a1f5c | ||
|
|
68951de687 | ||
|
|
35d3038bea | ||
|
|
947ed27f90 | ||
|
|
c09a5b05bf | ||
|
|
bbe44f79c6 | ||
|
|
4c4edc07c5 | ||
|
|
da2f9bce8e | ||
|
|
3af8d7384c | ||
|
|
7c255d26b3 | ||
|
|
2327c6a662 | ||
|
|
d6b12f93e7 | ||
|
|
1c5d343171 | ||
|
|
d951a70b30 | ||
|
|
ec1356df08 | ||
|
|
5aba3df6ae | ||
|
|
0a232dd140 | ||
|
|
e49662bab4 | ||
|
|
f4c60291c0 | ||
|
|
d1043bded2 | ||
|
|
6f8f025baf | ||
|
|
a73173e828 | ||
|
|
97d15d1a2f | ||
|
|
22b8f2f041 | ||
|
|
686fbc8572 | ||
|
|
85f138cd5a | ||
|
|
5c947d46d6 | ||
|
|
45b4005237 | ||
|
|
ce52faad9d | ||
|
|
db2e7e3062 | ||
|
|
4aa6b35e20 | ||
|
|
1e32811ea6 | ||
|
|
c0e2499dfc | ||
|
|
35938461d4 | ||
|
|
b0c5a61d4a | ||
|
|
2446f5c70e | ||
|
|
cd054f2a32 | ||
|
|
27ea04712f | ||
|
|
77afbd189f | ||
|
|
125b829872 | ||
|
|
e92451b37c | ||
|
|
9967a56e64 | ||
|
|
9d3cb5f5e3 | ||
|
|
fdc688bafe | ||
|
|
03c830bea4 | ||
|
|
cd93e139a2 | ||
|
|
cc38fabd31 | ||
|
|
c77ffb9617 | ||
|
|
3a7e720e82 | ||
|
|
30ba4bbb69 | ||
|
|
7f1dbc17c9 | ||
|
|
5c89ac5a27 | ||
|
|
c02a8735d8 | ||
|
|
5fcc56367d | ||
|
|
a21be862d8 | ||
|
|
4be0143de5 | ||
|
|
2581218f82 | ||
|
|
47fed3a76d | ||
|
|
f6b2e57051 | ||
|
|
7c8c324a17 | ||
|
|
e99fc5de6c | ||
|
|
403d6739bc | ||
|
|
295e57ac04 | ||
|
|
85b5c204c4 | ||
|
|
f9018047ea | ||
|
|
116014d191 | ||
|
|
261fdd7dc9 | ||
|
|
c90fea3066 | ||
|
|
494d811c32 | ||
|
|
d8f925b1c8 | ||
|
|
93bb9a5048 | ||
|
|
387fe3cf91 | ||
|
|
857414f410 | ||
|
|
b294a45bb9 | ||
|
|
cc60df5cec | ||
|
|
8ecded5cdb | ||
|
|
6d5da561bd | ||
|
|
2caf01b722 | ||
|
|
c6491710fc | ||
|
|
f39168b9c2 | ||
|
|
e564d50b2c | ||
|
|
fb74bcb047 | ||
|
|
43a33739a3 | ||
|
|
4d75ee6b2b | ||
|
|
c80b9da9ef | ||
|
|
64cc7747c8 | ||
|
|
50c09d0359 | ||
|
|
eeecffa93a | ||
|
|
4eb95f18ee | ||
|
|
b1258378ab | ||
|
|
4999f0968f | ||
|
|
92e9579e04 | ||
|
|
a932abe0e3 | ||
|
|
8005dd2081 | ||
|
|
9ff87f2904 | ||
|
|
9bb11c5d54 | ||
|
|
d20f5829c3 | ||
|
|
6977a42432 | ||
|
|
f8b50561ec | ||
|
|
b997be51ae | ||
|
|
f4738cb65d | ||
|
|
1b319c9bb9 | ||
|
|
ee2c25697c | ||
|
|
0a7db32490 | ||
|
|
f0c3620fac | ||
|
|
778b82949a | ||
|
|
140f02e140 | ||
|
|
a1d6e7b50d | ||
|
|
d73645facb | ||
|
|
17ea19bf65 | ||
|
|
5c4d69775f | ||
|
|
b0f947ca00 | ||
|
|
b768daf616 | ||
|
|
9e3ad27ecf | ||
|
|
8938d03f47 | ||
|
|
961731b063 | ||
|
|
2f63bf3bbc | ||
|
|
b517d3aece | ||
|
|
9f8b2514b3 | ||
|
|
ada9352e1f | ||
|
|
091a0f336c | ||
|
|
ad4c92055f | ||
|
|
1a522cb3a8 | ||
|
|
9347fd0eae | ||
|
|
f8f508f6f6 | ||
|
|
b85d6347de | ||
|
|
91aee11b54 | ||
|
|
e48ef60cd6 | ||
|
|
b2a4dcdd49 | ||
|
|
5241f9b03f | ||
|
|
585fd76ae2 | ||
|
|
df5cd02472 | ||
|
|
a3544343a8 | ||
|
|
89c6ce9e78 | ||
|
|
bfaa2681e0 | ||
|
|
b0167028e8 | ||
|
|
814201fa9f | ||
|
|
ac01384810 | ||
|
|
9a0d01da74 | ||
|
|
a311379afa | ||
|
|
c37006ec69 | ||
|
|
9c4b39bb40 | ||
|
|
7bf605cf9f | ||
|
|
e5d2bc00a5 | ||
|
|
2c87c58a5b | ||
|
|
0c699ea68d | ||
|
|
70f567ec43 | ||
|
|
4690805dbc | ||
|
|
32f861e67a | ||
|
|
71fd2a7ce7 | ||
|
|
e0f8848bd5 | ||
|
|
0fe341add8 | ||
|
|
2bfa5abedb | ||
|
|
0b16acd939 | ||
|
|
8d488b78c6 | ||
|
|
e7c6149d5a | ||
|
|
2278b3b4d5 | ||
|
|
f0d41580b8 | ||
|
|
d6d9d14820 | ||
|
|
f8489beea5 | ||
|
|
f02743fbd8 | ||
|
|
d9283b44b2 | ||
|
|
53ae7fe744 | ||
|
|
9984101e1b | ||
|
|
b5044a2ddb | ||
|
|
15ef005337 | ||
|
|
296236f793 | ||
|
|
dd3b2e8e62 | ||
|
|
8cb20e4457 | ||
|
|
2e5d5b4be1 | ||
|
|
f5e93e4b1a | ||
|
|
54697cf77a | ||
|
|
1710a09f6a | ||
|
|
3fe03807ef | ||
|
|
c7a84a4a4e | ||
|
|
2aa92042fd | ||
|
|
39990b584b | ||
|
|
214a3e9894 | ||
|
|
674e8ff087 | ||
|
|
f7ef58cc19 | ||
|
|
e35024508e | ||
|
|
baa362c69b | ||
|
|
440db5f82a | ||
|
|
4373b8b8d9 | ||
|
|
056b0237ad | ||
|
|
0b80c59744 | ||
|
|
373eafa4d6 | ||
|
|
e7959a3f67 | ||
|
|
519fe77fbb | ||
|
|
211a268c36 | ||
|
|
75ed5b3ce4 | ||
|
|
80639062d7 | ||
|
|
b31c8d514b | ||
|
|
5583ab1d78 | ||
|
|
af8d766b0e | ||
|
|
9a5a1f960e | ||
|
|
ec24d7a897 | ||
|
|
a450dd1de8 | ||
|
|
4b27614ad7 | ||
|
|
c3130f0eec | ||
|
|
b5f1f15c45 | ||
|
|
c141f31dbd | ||
|
|
584839fd78 | ||
|
|
627d1af284 | ||
|
|
8311a66b94 | ||
|
|
113beb54e7 | ||
|
|
2c5fff7ec7 | ||
|
|
ae5feaa3df | ||
|
|
6fa744bbda | ||
|
|
5b8fcf5a4d | ||
|
|
15c1505187 | ||
|
|
49e24c9ec9 | ||
|
|
2474382756 | ||
|
|
87944a0fd0 | ||
|
|
6aa84cb3f5 | ||
|
|
ed8ff8bd80 | ||
|
|
74fdcbdcb5 | ||
|
|
996e7e2b40 | ||
|
|
665cc19ce6 | ||
|
|
d2fcc011be | ||
|
|
b528289815 | ||
|
|
110346f9f7 | ||
|
|
099f09c8b0 | ||
|
|
083e019081 | ||
|
|
bc143f8fe2 | ||
|
|
4824d95d68 | ||
|
|
cc870b2667 | ||
|
|
67362ff309 | ||
|
|
6f043d62e5 | ||
|
|
03ab9fd203 | ||
|
|
b2134145a2 |
9
.readthedocs.yaml
Normal file
9
.readthedocs.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
version: 2
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
python:
|
||||
version: 3.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
14
AUTHORS.md
14
AUTHORS.md
@@ -7,13 +7,27 @@ Christer Edwards [christer.edwards@gmail.com]
|
||||
## Contributors (code)
|
||||
- Barry McCormick
|
||||
- Brian Downs
|
||||
- Carsten Bäcker
|
||||
- Chris Wells
|
||||
- Dave Cottlehuber
|
||||
- Giacomo Olgeni
|
||||
- Gleb Popov
|
||||
- JP Mens
|
||||
- Jose Rivera
|
||||
- Juan David Hurtado G.
|
||||
- Lars E.
|
||||
- Marius van Witzenburg
|
||||
- Matt Audesse
|
||||
- Paul C.
|
||||
- Petru T. Garstea
|
||||
- Sven R.
|
||||
- Tobias Tom
|
||||
- Stefano Marinelli
|
||||
- Logan Ellis
|
||||
- Chuck Tuffli
|
||||
- Niketh Murali
|
||||
- Eric Borisch
|
||||
- Kevet Duncombe
|
||||
|
||||
### Special thanks
|
||||
Software doesn't happen in a vacuum. Thank you to the following people who may
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
129
README.md
129
README.md
@@ -79,7 +79,7 @@ Use "bastille command -h|--help" for more information about a command.
|
||||
|
||||
```
|
||||
|
||||
## 0.8-beta
|
||||
## 0.9-beta
|
||||
This document outlines the basic usage of the Bastille container management
|
||||
framework. This release is still considered beta.
|
||||
|
||||
@@ -131,13 +131,15 @@ nat on $ext_if from <jails> to any -> ($ext_if:0)
|
||||
rdr-anchor "rdr/*"
|
||||
|
||||
block in all
|
||||
pass out quick modulate state
|
||||
pass out quick keep state
|
||||
antispoof for $ext_if inet
|
||||
pass in inet proto tcp from any to any port ssh flags S/SA keep state
|
||||
|
||||
## make sure you also open up ports that you are going to use for dynamic rdr
|
||||
# pass in inet proto tcp from any to any port <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
|
||||
## for IPv6 networks please uncomment the following rule
|
||||
# pass inet6 proto icmp6 icmp6-type { echoreq, routersol, routeradv, neighbradv, neighbrsol }
|
||||
|
||||
```
|
||||
|
||||
@@ -215,7 +217,7 @@ Two values are required for Bastille to use ZFS. The default values in the
|
||||
bastille_zfs_enable="" ## default: ""
|
||||
bastille_zfs_zpool="" ## default: ""
|
||||
bastille_zfs_prefix="bastille" ## default: "${bastille_zfs_zpool}/bastille"
|
||||
bastille_zfs_mountpoint=${bastille_prefix} ## default: "${bastille_prefix}"
|
||||
bastille_prefix="/bastille" ## default: "/usr/local/bastille". ${bastille_zfs_prefix} gets mounted here
|
||||
bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off"
|
||||
```
|
||||
|
||||
@@ -234,8 +236,8 @@ not using ZFS and can safely ignore these settings.
|
||||
bastille bootstrap
|
||||
------------------
|
||||
Before you can begin creating containers, Bastille needs to "bootstrap" a
|
||||
release. Current supported releases are 11.3-RELEASE, 12.0-RELEASE and
|
||||
12.1-RELEASE.
|
||||
release. Current supported releases are 11.4-RELEASE, 12.2-RELEASE and
|
||||
13.0-RELEASE.
|
||||
|
||||
**Important: If you need ZFS support see the above section BEFORE
|
||||
bootstrapping.**
|
||||
@@ -243,14 +245,14 @@ bootstrapping.**
|
||||
To `bootstrap` a release, run the bootstrap sub-command with the
|
||||
release version as the argument.
|
||||
|
||||
**FreeBSD 11.3-RELEASE**
|
||||
**FreeBSD 11.4-RELEASE**
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap 11.3-RELEASE
|
||||
ishmael ~ # bastille bootstrap 11.4-RELEASE
|
||||
```
|
||||
|
||||
**FreeBSD 12.1-RELEASE**
|
||||
**FreeBSD 12.2-RELEASE**
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap 12.1-RELEASE
|
||||
ishmael ~ # bastille bootstrap 12.2-RELEASE
|
||||
```
|
||||
|
||||
**HardenedBSD 11-STABLE-BUILD-XX**
|
||||
@@ -290,6 +292,37 @@ bootstrapping templates from GitHub or GitLab.
|
||||
See `bastille update` to ensure your bootstrapped releases include the latest
|
||||
patches.
|
||||
|
||||
**Ubuntu Linux [new since 0.9]**
|
||||
|
||||
The bootstrap process for Linux containers is very different from the BSD process.
|
||||
You will need the package debootstrap and some kernel modules for that.
|
||||
But don't worry, Bastille will do that for you.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap focal
|
||||
sysrc: unknown variable 'linprocfs_load'
|
||||
sysrc: unknown variable 'linsysfs_load'
|
||||
sysrc: unknown variable 'tmpfs_load'
|
||||
linprocfs_load, linsysfs_load, tmpfs_load not enabled in /boot/loader.conf or linux_enable not active. Should I do that for you? (N|y)
|
||||
#y
|
||||
Loading modules
|
||||
Persisting modules
|
||||
linux_enable: -> YES
|
||||
linprocfs_load: -> YES
|
||||
linsysfs_load: -> YES
|
||||
tmpfs_load: -> YES
|
||||
Debootstrap not found. Should it be installed? (N|y)
|
||||
#y
|
||||
FreeBSD repository is up to date.
|
||||
All repositories are up to date.
|
||||
Checking integrity... done (0 conflicting)
|
||||
The following 1 package(s) will be affected (of 0 checked):
|
||||
|
||||
New packages to be INSTALLED:
|
||||
debootstrap: 1.0.123_4
|
||||
[...]
|
||||
```
|
||||
As of 0.9.20210714 Bastille supports Ubuntu 18.04 (bionic) and Ubuntu 20.04 (focal).
|
||||
|
||||
bastille create
|
||||
---------------
|
||||
@@ -306,24 +339,24 @@ IP at container creation.
|
||||
|
||||
**ip4**
|
||||
```shell
|
||||
ishmael ~ # bastille create folsom 12.1-RELEASE 10.17.89.10
|
||||
ishmael ~ # bastille create folsom 12.2-RELEASE 10.17.89.10
|
||||
Valid: (10.17.89.10).
|
||||
|
||||
NAME: folsom.
|
||||
IP: 10.17.89.10.
|
||||
RELEASE: 12.1-RELEASE.
|
||||
RELEASE: 12.2-RELEASE.
|
||||
|
||||
syslogd_flags: -s -> -ss
|
||||
sendmail_enable: NO -> NONE
|
||||
cron_flags: -> -J 60
|
||||
```
|
||||
|
||||
This command will create a 12.1-RELEASE container assigning the 10.17.89.10 ip
|
||||
This command will create a 12.2-RELEASE container assigning the 10.17.89.10 ip
|
||||
address to the new system.
|
||||
|
||||
**ip6**
|
||||
```shell
|
||||
ishmael ~ # bastille create folsom 12.1-RELEASE fd35:f1fd:2cb6:6c5c::13
|
||||
ishmael ~ # bastille create folsom 12.2-RELEASE fd35:f1fd:2cb6:6c5c::13
|
||||
Valid: (fd35:f1fd:2cb6:6c5c::13).
|
||||
|
||||
NAME: folsom.
|
||||
@@ -335,12 +368,12 @@ sendmail_enable: NO -> NONE
|
||||
cron_flags: -> -J 60
|
||||
```
|
||||
|
||||
This command will create a 12.1-RELEASE container assigning the
|
||||
This command will create a 12.2-RELEASE container assigning the
|
||||
fd35:f1fd:2cb6:6c5c::13 ip address to the new system.
|
||||
|
||||
**VNET**
|
||||
```shell
|
||||
ishmael ~ # bastille create -V vnetjail 12.1-RELEASE 192.168.87.55/24 em0
|
||||
ishmael ~ # bastille create -V vnetjail 12.2-RELEASE 192.168.87.55/24 em0
|
||||
Valid: (192.168.87.55/24).
|
||||
Valid: (em0).
|
||||
|
||||
@@ -356,7 +389,7 @@ ifconfig_e0b_bastille0_name: -> vnet0
|
||||
ifconfig_vnet0: -> inet 192.168.87.55/24
|
||||
```
|
||||
|
||||
This command will create a 12.1-RELEASE container assigning the
|
||||
This command will create a 12.2-RELEASE container assigning the
|
||||
192.168.87.55/24 ip address to the new system.
|
||||
|
||||
VNET-enabled containers are attached to a virtual bridge interface for
|
||||
@@ -376,9 +409,18 @@ private base. This is sometimes referred to as a "thick" container (whereas the
|
||||
shared base container is a "thin").
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille create -T folsom 12.0-RELEASE 10.17.89.10
|
||||
ishmael ~ # bastille create -T folsom 12.2-RELEASE 10.17.89.10
|
||||
```
|
||||
|
||||
**Linux**
|
||||
```shell
|
||||
ishmael ~ # bastille create folsom focal 10.17.89.10
|
||||
```
|
||||
|
||||
Systemd is not supported due to the missing boot process.
|
||||
|
||||
|
||||
|
||||
I recommend using private (rfc1918) ip address ranges for your containers.
|
||||
These ranges include:
|
||||
|
||||
@@ -628,9 +670,8 @@ Templates](https://gitlab.com/BastilleBSD-Templates)?
|
||||
Bastille supports a templating system allowing you to apply files, pkgs and
|
||||
execute commands inside the container automatically.
|
||||
|
||||
Currently supported template hooks are: `ARG`, `LIMITS`, `INCLUDE`, `PRE`,
|
||||
`FSTAB`, `PKG`, `OVERLAY`, `SYSRC`, `SERVICE`, `CMD`, `RENDER`.
|
||||
Planned template hooks include: `PF`, `LOG`
|
||||
Currently supported template hooks are: `ARG`, `LIMITS`, `INCLUDE`,
|
||||
`MOUNT`, `PKG`, `CP`, `SYSRC`, `SERVICE`, `RDR`, `CMD`, `RENDER`.
|
||||
|
||||
Templates are created in `${bastille_prefix}/templates` and can leverage any of
|
||||
the template hooks. Simply create a new directory in the format project/repo,
|
||||
@@ -644,9 +685,9 @@ To leverage a template hook, create an UPPERCASE file in the root of the
|
||||
template directory named after the hook you want to execute. eg;
|
||||
|
||||
```shell
|
||||
echo "zsh vim-console git-lite htop" > /usr/local/bastille/templates/username/base-template/PKG
|
||||
echo "/usr/bin/chsh -s /usr/local/bin/zsh" > /usr/local/bastille/templates/username/base-template/CMD
|
||||
echo "usr" > /usr/local/bastille/templates/username/base-template/OVERLAY
|
||||
echo "PKG zsh vim-console git-lite htop" >> /usr/local/bastille/templates/username/base-template/Bastillefile
|
||||
echo "CMD /usr/bin/chsh -s /usr/local/bin/zsh" >> /usr/local/bastille/templates/username/base-template/Bastillefile
|
||||
echo "CP usr" > /usr/local/bastille/templates/username/base-template/Bastillefile
|
||||
```
|
||||
|
||||
Template hooks are executed in specific order and require specific syntax to
|
||||
@@ -665,11 +706,7 @@ work as expected. This table outlines that order and those requirements:
|
||||
| SERVICE | service command(s) | nginx restart |
|
||||
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
|
||||
| RENDER | paths (one/line) | /usr/local/etc/nginx |
|
||||
|
||||
| PLANNED | format | example |
|
||||
|---------|------------------|----------------------------------------------------------------|
|
||||
| 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 |
|
||||
| RDR | protocol port port | tcp 2200 22 |
|
||||
|
||||
Note: SYSRC requires NO quotes or that quotes (`"`) be escaped. ie; `\"`)
|
||||
|
||||
@@ -698,8 +735,8 @@ After populating `usr/local/` with custom config files that your container will
|
||||
use, be sure to include `usr` in the template OVERLAY definition. eg;
|
||||
|
||||
```shell
|
||||
echo "etc" > /usr/local/bastille/templates/username/base/OVERLAY
|
||||
echo "usr" >> /usr/local/bastille/templates/username/base/OVERLAY
|
||||
echo "OVERLAY etc" >> /usr/local/bastille/templates/username/base/Bastillefile
|
||||
echo "OVERLAY usr" >> /usr/local/bastille/templates/username/base/Bastillefile
|
||||
```
|
||||
|
||||
The above example will include anything under "etc" and "usr" inside
|
||||
@@ -890,21 +927,21 @@ The `update` command targets a release instead of a container. Because every
|
||||
container is based on a release, when the release is updated all the containers
|
||||
are automatically updated as well.
|
||||
|
||||
To update all containers based on the 11.2-RELEASE `release`:
|
||||
To update all containers based on the 11.4-RELEASE `release`:
|
||||
|
||||
Up to date 11.2-RELEASE:
|
||||
Up to date 11.4-RELEASE:
|
||||
```shell
|
||||
ishmael ~ # bastille update 11.2-RELEASE
|
||||
ishmael ~ # bastille update 11.4-RELEASE
|
||||
Targeting specified release.
|
||||
11.2-RELEASE
|
||||
11.4-RELEASE
|
||||
|
||||
Looking up update.FreeBSD.org mirrors... 2 mirrors found.
|
||||
Fetching metadata signature for 11.2-RELEASE from update4.freebsd.org... done.
|
||||
Fetching metadata signature for 11.4-RELEASE from update4.freebsd.org... done.
|
||||
Fetching metadata index... done.
|
||||
Inspecting system... done.
|
||||
Preparing to download files... done.
|
||||
|
||||
No updates needed to update system to 11.2-RELEASE-p4.
|
||||
No updates needed to update system to 11.4-RELEASE-p4.
|
||||
No updates are available to install.
|
||||
```
|
||||
|
||||
@@ -916,11 +953,21 @@ bastille upgrade
|
||||
This sub-command lets you upgrade a release to a new release. Depending on the
|
||||
workflow this can be similar to a `bootstrap`.
|
||||
|
||||
For standard containers you need to upgrade the shared base jail:
|
||||
```shell
|
||||
ishmael ~ # bastille upgrade 11.3-RELEASE 12.0-RELEASE
|
||||
ishmael ~ # bastille upgrade 12.1-RELEASE 12.2-RELEASE
|
||||
...
|
||||
```
|
||||
|
||||
For thick jails you need to upgrade every single container (according the freebsd-update procedure):
|
||||
```shell
|
||||
ishmael ~ # bastille upgrade folsom 12.2-RELEASE
|
||||
ishmael ~ # bastille upgrade folsom install
|
||||
...
|
||||
ishmael ~ # bastille restart folsom
|
||||
ishmael ~ # bastille upgrade folsom install
|
||||
```
|
||||
|
||||
|
||||
bastille verify
|
||||
---------------
|
||||
@@ -1028,11 +1075,7 @@ Example (create, start, console)
|
||||
This example creates, starts and consoles into the container.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille create alcatraz 11.2-RELEASE 10.17.89.7
|
||||
|
||||
RELEASE: 11.2-RELEASE.
|
||||
NAME: alcatraz.
|
||||
IP: 10.17.89.7.
|
||||
ishmael ~ # bastille create alcatraz 11.4-RELEASE 10.17.89.7
|
||||
```
|
||||
|
||||
```shell
|
||||
@@ -1044,7 +1087,7 @@ alcatraz: created
|
||||
```shell
|
||||
ishmael ~ # bastille console alcatraz
|
||||
[alcatraz]:
|
||||
FreeBSD 11.2-RELEASE-p4 (GENERIC) #0: Thu Sep 27 08:16:24 UTC 2018
|
||||
FreeBSD 11.4-RELEASE-p4 (GENERIC) #0: Thu Sep 27 08:16:24 UTC 2018
|
||||
|
||||
Welcome to FreeBSD!
|
||||
|
||||
|
||||
5
Vagrantfile
vendored
5
Vagrantfile
vendored
@@ -9,8 +9,8 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
|
||||
vm_config.ssh.shell = "sh"
|
||||
|
||||
vm_config.vm.box = "freebsd/FreeBSD-12.1-RELEASE"
|
||||
vm_config.vm.box_version = "2019.11.01"
|
||||
vm_config.vm.box = "freebsd/FreeBSD-13.0-RELEASE"
|
||||
vm_config.vm.box_version = "2021.04.09"
|
||||
|
||||
vm_config.vm.provider "virtualbox" do |vb|
|
||||
vb.name = "bastille"
|
||||
@@ -19,6 +19,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
end
|
||||
|
||||
vm_config.vm.provision "shell", inline: "cd /vagrant; make install"
|
||||
vm_config.vm.provision "shell", inline: "pkg install -y git-lite"
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
BIN
docs/chapters/bastilletweet.png
Normal file
BIN
docs/chapters/bastilletweet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -4,7 +4,7 @@ Bastille is available in the official FreeBSD ports tree at
|
||||
`sysutils/bastille`. Binary packages available in `quarterly` and `latest`
|
||||
repositories.
|
||||
|
||||
Current version is `0.8.20210101`.
|
||||
Current version is `0.9.20220714`.
|
||||
|
||||
To install from the FreeBSD package repository:
|
||||
|
||||
|
||||
@@ -109,6 +109,18 @@ To define a default route / gateway for all VNET containers define the value in
|
||||
This config change will apply the defined gateway to any new containers.
|
||||
Existing containers will need to be manually updated.
|
||||
|
||||
Virtual Network (VNET) on External Bridge
|
||||
--------------------------------------
|
||||
To create a VNET based container and attach it to an external, already existing bridge, use the `-B` option, an IP/netmask and
|
||||
external bridge.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille create -B azkaban 12.1-RELEASE 192.168.1.50/24 bridge0
|
||||
|
||||
Bastille will automagically create the interface, attach it to the specified bridge and connect /
|
||||
disconnect containers as they are started and stopped.
|
||||
The bridge needs to be created/enabled before creating and starting the jail.
|
||||
|
||||
Public Network
|
||||
==============
|
||||
@@ -165,23 +177,14 @@ Create the firewall rules:
|
||||
set skip on lo
|
||||
|
||||
table <jails> persist
|
||||
nat on $ext_if from <jails> to any -> ($ext_if)
|
||||
|
||||
## static rdr example
|
||||
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
|
||||
## dynamic rdr anchor (see below)
|
||||
nat on $ext_if from <jails> to any -> ($ext_if:0)
|
||||
rdr-anchor "rdr/*"
|
||||
|
||||
block in all
|
||||
pass out quick modulate state
|
||||
pass out quick keep state
|
||||
antispoof for $ext_if inet
|
||||
pass in inet proto tcp from any to any port ssh flags S/SA modulate state
|
||||
|
||||
# If you are using dynamic rdr also need to ensure that the external port
|
||||
# range you are using is open
|
||||
# pass in inet proto tcp from any to any port <rdr-start>:<rdr-end>
|
||||
|
||||
- Make sure to change the `ext_if` variable to match your host system interface.
|
||||
- Make sure to include the last line (`port ssh`) or you'll end up locked out.
|
||||
|
||||
@@ -192,30 +195,26 @@ to containers are:
|
||||
|
||||
nat on $ext_if from <jails> to any -> ($ext_if)
|
||||
|
||||
## static rdr example
|
||||
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
|
||||
The `nat` routes traffic from the loopback interface to the external
|
||||
interface for outbound access.
|
||||
|
||||
The `rdr pass ...` will redirect traffic from the host firewall on port X to
|
||||
the ip of Container Y. The example shown redirects web traffic (80 & 443) to the
|
||||
containers at `10.17.89.45`.
|
||||
.. code-block:: shell
|
||||
|
||||
## dynamic rdr anchor (see below)
|
||||
rdr-anchor "rdr/*"
|
||||
|
||||
The `rdr-anchor "rdr/*"` enables dynamic rdr rules to be setup using the
|
||||
`bastille rdr` command at runtime - eg.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille rdr <jail> tcp 2001 22 # Redirects tcp port 2001 on host to 22 on jail
|
||||
bastille rdr <jail> udp 2053 53 # Same for udp
|
||||
bastille rdr <jail> list # List dynamic rdr rules
|
||||
bastille rdr <jail> clear # Clear dynamic rdr rules
|
||||
|
||||
Note that if you are redirecting ports where the host is also listening
|
||||
(eg. ssh) you should make sure that the host service is not listening on
|
||||
the cloned interface - eg. for ssh set sshd_flags in rc.conf
|
||||
Note that if you are redirecting ports where the host is also listening (eg.
|
||||
ssh) you should make sure that the host service is not listening on the cloned
|
||||
interface - eg. for ssh set sshd_flags in rc.conf
|
||||
|
||||
sshd_flags="-o ListenAddress=<hostname>"
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Releases
|
||||
Example
|
||||
-------
|
||||
|
||||
To `bootstrap` a release, run the bootstrap sub-command with the
|
||||
To `bootstrap` a FreeBSD release, run the bootstrap sub-command with the
|
||||
release version as the argument.
|
||||
|
||||
.. code-block:: shell
|
||||
@@ -30,6 +30,14 @@ release version as the argument.
|
||||
ishmael ~ # bastille bootstrap 11.4-RELEASE [update]
|
||||
ishmael ~ # bastille bootstrap 12.1-RELEASE
|
||||
|
||||
To `bootstrap` a HardenedBSD release, run the bootstrap sub-command with the
|
||||
build version as the argument.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille bootstrap 13-stable-build-latest
|
||||
|
||||
|
||||
This command will ensure the required directory structures are in place and
|
||||
download the requested release. For each requested release, `bootstrap` will
|
||||
download the base.txz. These files are verified (sha256 via MANIFEST file)
|
||||
|
||||
@@ -11,7 +11,8 @@ container backups.
|
||||
ishmael ~ # bastille export azkaban
|
||||
|
||||
The export sub-command supports both UFS and ZFS storage. ZFS based containers
|
||||
will use ZFS snapshots. UFS based containers will use `txz` archives.
|
||||
will use ZFS snapshots. UFS based containers will use `txz` archives and they
|
||||
can be exported only when the jail is not running.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ To manage binary packages within the container use `bastille pkg`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille pkg folsom 'install vim-console git-lite zsh'
|
||||
ishmael ~ # bastille pkg folsom install vim-console git-lite zsh
|
||||
[folsom]:
|
||||
The package management tool is not yet installed on your system.
|
||||
Do you want to fetch and install it now? [y/N]: y
|
||||
|
||||
@@ -27,7 +27,7 @@ Examples: Containers
|
||||
| cmd | ALL | 'sockstat -4' | execute `sockstat -4` in ALL containers (ip4 sockets) |
|
||||
+-----------+--------+-----+------------+-------------------------------------------------------------+
|
||||
| console | mariadb02 | --- | console (shell) access to mariadb02 |
|
||||
+----+------+----+---------+------------+--------------+----------------------------------------------+
|
||||
+----+------+--------+-----+------------+-------------------------------------------------------------+
|
||||
| pkg | web01 | 'install nginx' | install nginx package in web01 container |
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
| pkg | ALL | upgrade | upgrade packages in ALL containers |
|
||||
@@ -39,11 +39,11 @@ Examples: Containers
|
||||
| template | ALL | username/base | apply `username/base` template to ALL containers |
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
| start | web02 | --- | start web02 container |
|
||||
+-----------+--------+-----+------------+-------------------------------------------------------------+
|
||||
| cp | bastion03 | /tmp/resolv.conf-cf etc/resolv.conf | copy host-path to container-path in bastion03|
|
||||
+----+------+----+---+------------------+--------------+----------------------------------------------+
|
||||
| cp | bastion03 | /tmp/resolv.conf-cf etc/resolv.conf | copy host-path to container-path in bastion03|
|
||||
+----+------+----+---+---------------------------------+----------------------------------------------+
|
||||
| create | folsom | 12.1-RELEASE 10.17.89.10 | create 12.1 container named `folsom` with IP |
|
||||
+-----------+--------+------------------+--------------+----------------------------------------------+
|
||||
+-----------+--------+---------------------------------+----------------------------------------------+
|
||||
|
||||
|
||||
Examples: Releases
|
||||
@@ -60,7 +60,7 @@ Examples: Releases
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| update | 11.4-RELEASE | --- | update 11.4-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| upgrade | 11.3-RELEASE | 11.4-RELEASE | update 11.4-RELEASE release |
|
||||
| upgrade | 11.3-RELEASE | 11.4-RELEASE | upgrade 11.3-RELEASE release to 11.4-RELEASE |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| verify | 11.4-RELEASE | --- | update 11.4-RELEASE release |
|
||||
| verify | 11.4-RELEASE | --- | verify 11.4-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
|
||||
@@ -7,14 +7,14 @@ Templates](https://gitlab.com/BastilleBSD-Templates)?
|
||||
Bastille supports a templating system allowing you to apply files, pkgs and
|
||||
execute commands inside the containers automatically.
|
||||
|
||||
Currently supported template hooks are: `LIMITS`, `INCLUDE`, `PRE`, `FSTAB`,
|
||||
`PKG`, `OVERLAY`, `SYSRC`, `SERVICE`, `CMD`.
|
||||
Currently supported template hooks are: `CMD`, `CP`, `INCLUDE`, `LIMITS`, `MOUNT`,
|
||||
`PKG`, `RDR`, `SERVICE`, `SYSRC`.
|
||||
|
||||
Templates are created in `${bastille_prefix}/templates` and can leverage any of
|
||||
the template hooks.
|
||||
|
||||
Bastille 0.7.x
|
||||
--------------
|
||||
Bastille 0.7.x+
|
||||
---------------
|
||||
Bastille 0.7.x introduces a template syntax that is more flexible and allows
|
||||
any-order scripting. Previous versions had a hard template execution order and
|
||||
instructions were spread across multiple files. The new syntax is done in a
|
||||
@@ -27,23 +27,23 @@ Template Automation Hooks
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| HOOK | format | example |
|
||||
+=========+===================+=========================================+
|
||||
| LIMITS | resource value | memoryuse 1G |
|
||||
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| CP | path(s) | etc root usr (one per line) |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| INCLUDE | template path/URL | http?://TEMPLATE_URL or project/path |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| PRE | /bin/sh command | mkdir -p /usr/local/my_app/html |
|
||||
| LIMITS | resource value | memoryuse 1G |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| FSTAB | fstab syntax | /host/path container/path nullfs ro 0 0 |
|
||||
| MOUNT | fstab syntax | /host/path container/path nullfs ro 0 0 |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| OVERLAY | path(s) | etc root usr (one per line) |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| SYSRC | sysrc command(s) | nginx_enable=YES |
|
||||
| RDR | tcp port port | tcp 2200 22 (hostport jailport) |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| SERVICE | service command | 'nginx start' OR 'postfix reload' |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
|
||||
| SYSRC | sysrc command(s) | nginx_enable=YES |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
|
||||
Note: SYSRC requires that NO quotes be used or that quotes (`"`) be escaped
|
||||
@@ -71,7 +71,7 @@ use, be sure to include `usr` in the template OVERLAY definition. eg;
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
echo "usr" > /usr/local/bastille/templates/username/template/OVERLAY
|
||||
echo "CP usr" >> /usr/local/bastille/templates/username/template/Bastillefile
|
||||
|
||||
The above example "usr" will include anything under "usr" inside the template.
|
||||
You do not need to list individual files. Just include the top-level directory
|
||||
|
||||
28
docs/chapters/zfs-support.rst
Normal file
28
docs/chapters/zfs-support.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
ZFS Support
|
||||
====================
|
||||
.. image:: /images/bastillebsd-twitter-poll.png
|
||||
:width: 400
|
||||
:alt: Alternative text
|
||||
|
||||
Bastille 0.4 added initial support for ZFS. ``bastille bootstrap`` and ``bastille create`` will generate ZFS volumes based on settings found in the ``bastille.conf``. This section outlines how to enable and configure Bastille for ZFS.
|
||||
|
||||
Two values are required for Bastille to use ZFS. The default values in the ``bastille.conf`` are empty. Populate these two to enable ZFS.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
## ZFS options
|
||||
bastille_zfs_enable="" ## default: ""
|
||||
bastille_zfs_zpool="" ## default: ""
|
||||
bastille_zfs_prefix="bastille" ## default: "${bastille_zfs_zpool}/bastille"
|
||||
bastille_prefix="/bastille" ## default: "/usr/local/bastille". ${bastille_zfs_prefix} gets mounted here
|
||||
bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off"
|
||||
|
||||
Example
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # sysrc -f /usr/local/etc/bastille/bastille.conf bastille_zfs_enable=YES
|
||||
ishmael ~ # sysrc -f /usr/local/etc/bastille/bastille.conf bastille_zfs_zpool=ZPOOL_NAME
|
||||
|
||||
Replace ``ZPOOL_NAME`` with the zpool you want Bastille to use. Tip: ``zpool list`` and ``zpool status`` will help.
|
||||
If you get 'no pools available' you are likely not using ZFS and can safely ignore these settings.
|
||||
@@ -8,13 +8,13 @@ else:
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'Bastille'
|
||||
copyright = '2018-2020, Christer Edwards'
|
||||
copyright = '2018-2022, Christer Edwards'
|
||||
author = 'Christer Edwards'
|
||||
|
||||
# The short X.Y version
|
||||
version = '0.8.20210101'
|
||||
version = '0.9.20220714'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '0.8.20210101-beta'
|
||||
release = '0.9.20220714-beta'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
@@ -18,6 +18,7 @@ https://docs.bastillebsd.org.
|
||||
chapters/subcommands/index
|
||||
chapters/template
|
||||
chapters/jail-config
|
||||
chapters/zfs-support
|
||||
|
||||
copyright
|
||||
|
||||
|
||||
1
docs/requirements.txt
Normal file
1
docs/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
docutils < 0.18
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -70,7 +70,7 @@ bastille_perms_check() {
|
||||
bastille_perms_check
|
||||
|
||||
## version
|
||||
BASTILLE_VERSION="0.8.20210101"
|
||||
BASTILLE_VERSION="0.9.20220714"
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
@@ -135,10 +135,10 @@ version|-v|--version)
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
bootstrap|create|destroy|import|list|rdr|restart|start|update|upgrade|verify)
|
||||
bootstrap|create|destroy|export|import|list|rdr|restart|start|update|upgrade|verify)
|
||||
# Nothing "extra" to do for these commands. -- cwells
|
||||
;;
|
||||
clone|config|cmd|console|convert|cp|edit|export|htop|limits|mount|pkg|rename|service|stop|sysrc|template|top|umount|zfs)
|
||||
clone|config|cmd|console|convert|cp|edit|htop|limits|mount|pkg|rename|service|stop|sysrc|template|top|umount|zfs)
|
||||
# Parse the target and ensure it exists. -- cwells
|
||||
if [ $# -eq 0 ]; then # No target was given, so show the command's help. -- cwells
|
||||
PARAMS='help'
|
||||
@@ -147,14 +147,24 @@ clone|config|cmd|console|convert|cp|edit|export|htop|limits|mount|pkg|rename|ser
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
_JAILS=$(jls name)
|
||||
_JAILS=$(/usr/sbin/jls name)
|
||||
JAILS=""
|
||||
for _jail in ${_JAILS}; do
|
||||
_JAILPATH=$(jls -j "${_jail}" path)
|
||||
_JAILPATH=$(/usr/sbin/jls -j "${_jail}" path)
|
||||
if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then
|
||||
JAILS="${JAILS} ${_jail}"
|
||||
fi
|
||||
done
|
||||
elif [ "${CMD}" = "pkg" ] && [ "${TARGET}" = '-H' ] || [ "${TARGET}" = '--host' ]; then
|
||||
TARGET="${1}"
|
||||
USE_HOST_PKG=1
|
||||
JAILS="${TARGET}"
|
||||
shift
|
||||
|
||||
# Require the target to be running
|
||||
if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
fi
|
||||
elif [ "${CMD}" = 'template' ] && [ "${TARGET}" = '--convert' ]; then
|
||||
# This command does not act on a jail, so we are temporarily bypassing the presence/started
|
||||
# checks. The command will simply convert a template from hooks to a Bastillefile. -- cwells
|
||||
@@ -169,18 +179,19 @@ clone|config|cmd|console|convert|cp|edit|export|htop|limits|mount|pkg|rename|ser
|
||||
case "${CMD}" in
|
||||
cmd|console|htop|pkg|service|stop|sysrc|template|top)
|
||||
# Require the target to be running. -- cwells
|
||||
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
fi
|
||||
;;
|
||||
convert|rename)
|
||||
# Require the target to be stopped. -- cwells
|
||||
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
export USE_HOST_PKG
|
||||
export TARGET
|
||||
export JAILS
|
||||
fi
|
||||
|
||||
@@ -25,7 +25,7 @@ bastille_sharedir="/usr/local/share/bastille" ## default
|
||||
bastille_bootstrap_archives="base" ## default: "base"
|
||||
|
||||
## default timezone
|
||||
bastille_tzdata="Etc/UTC" ## default: "Etc/UTC"
|
||||
bastille_tzdata="" ## default: empty to use host's time zone
|
||||
|
||||
## default jail resolv.conf
|
||||
bastille_resolv_conf="/etc/resolv.conf" ## default: "/etc/resolv.conf"
|
||||
@@ -33,6 +33,7 @@ bastille_resolv_conf="/etc/resolv.conf" ## default
|
||||
## bootstrap urls
|
||||
bastille_url_freebsd="http://ftp.freebsd.org/pub/FreeBSD/releases/" ## default: "http://ftp.freebsd.org/pub/FreeBSD/releases/"
|
||||
bastille_url_hardenedbsd="http://installer.hardenedbsd.org/pub/hardenedbsd/" ## default: "https://installer.hardenedbsd.org/pub/HardenedBSD/releases/"
|
||||
bastille_url_midnightbsd="https://www.midnightbsd.org/ftp/MidnightBSD/releases/" ## default: "https://www.midnightbsd.org/pub/MidnightBSD/releases/"
|
||||
|
||||
## ZFS options
|
||||
bastille_zfs_enable="" ## default: ""
|
||||
@@ -43,15 +44,19 @@ bastille_zfs_options="-o compress=lz4 -o atime=off" ## default
|
||||
## Export/Import options
|
||||
bastille_compress_xz_options="-0 -v" ## default "-0 -v"
|
||||
bastille_decompress_xz_options="-c -d -v" ## default "-c -d -v"
|
||||
bastille_compress_gz_options="-1 -v" ## default "-1 -v"
|
||||
bastille_decompress_gz_options="-k -d -c -v" ## default "-k -d -c -v"
|
||||
|
||||
## Networking
|
||||
bastille_network_loopback="bastille0" ## default: "bastille0"
|
||||
bastille_network_shared="" ## default: ""
|
||||
bastille_network_gateway="" ## default: ""
|
||||
bastille_network_gateway6="" ## default: ""
|
||||
|
||||
## Default Templates
|
||||
bastille_template_base="default/base" ## default: "default/base"
|
||||
bastille_template_empty="default/empty" ## default: "default/empty"
|
||||
bastille_template_empty="" ## default: "default/empty"
|
||||
bastille_template_thick="default/thick" ## default: "default/thick"
|
||||
bastille_template_clone="default/clone" ## default: "default/clone"
|
||||
bastille_template_thin="default/thin" ## default: "default/thin"
|
||||
bastille_template_vnet="default/vnet" ## default: "default/vnet"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Bastille jail startup script
|
||||
#
|
||||
# PROVIDE: bastille
|
||||
# REQUIRE: LOGIN
|
||||
# REQUIRE: NETWORKING
|
||||
# KEYWORD: shutdown
|
||||
|
||||
# Add the following to /etc/rc.conf[.local] to enable this service
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -45,14 +45,12 @@ esac
|
||||
#Validate if ZFS is enabled in rc.conf and bastille.conf.
|
||||
if [ "$(sysrc -n zfs_enable)" = "YES" ] && [ ! "${bastille_zfs_enable}" = "YES" ]; then
|
||||
warn "ZFS is enabled in rc.conf but not bastille.conf. Do you want to continue? (N|y)"
|
||||
read answer
|
||||
read answer
|
||||
case $answer in
|
||||
no|No|n|N|"")
|
||||
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_enable."
|
||||
;;
|
||||
yes|Yes|y|Y)
|
||||
continue
|
||||
;;
|
||||
yes|Yes|y|Y) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -85,7 +83,7 @@ validate_release_url() {
|
||||
info "Bootstrapping ${PLATFORM_OS} distfiles..."
|
||||
|
||||
# Alternate RELEASE/ARCH fetch support
|
||||
if [ "${OPTION}" = "--i386" -o "${OPTION}" = "--32bit" ]; then
|
||||
if [ "${OPTION}" = "--i386" ] || [ "${OPTION}" = "--32bit" ]; then
|
||||
ARCH="i386"
|
||||
RELEASE="${RELEASE}-${ARCH}"
|
||||
fi
|
||||
@@ -105,12 +103,11 @@ bootstrap_directories() {
|
||||
if [ "${bastille_zfs_enable}" = "YES" ];then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_prefix}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}"
|
||||
chmod 0750 "${bastille_prefix}"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_prefix}"
|
||||
chmod 0750 "${bastille_prefix}"
|
||||
fi
|
||||
chmod 0750 "${bastille_prefix}"
|
||||
fi
|
||||
|
||||
## ${bastille_backupsdir}
|
||||
@@ -118,12 +115,11 @@ bootstrap_directories() {
|
||||
if [ "${bastille_zfs_enable}" = "YES" ];then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_backupsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/backups"
|
||||
chmod 0750 "${bastille_backupsdir}"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_backupsdir}"
|
||||
chmod 0750 "${bastille_backupsdir}"
|
||||
fi
|
||||
chmod 0750 "${bastille_backupsdir}"
|
||||
fi
|
||||
|
||||
## ${bastille_cachedir}
|
||||
@@ -131,19 +127,29 @@ bootstrap_directories() {
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; 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}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}"
|
||||
# Don't create unused/stale cache/RELEASE directory on Linux jails creation.
|
||||
if [ -z "${NOCACHEDIR}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_cachedir}/${RELEASE}"
|
||||
mkdir -p "${bastille_cachedir}"
|
||||
# Don't create unused/stale cache/RELEASE directory on Linux jails creation.
|
||||
if [ -z "${NOCACHEDIR}" ]; then
|
||||
mkdir -p "${bastille_cachedir}/${RELEASE}"
|
||||
fi
|
||||
fi
|
||||
## create subsequent cache/XX.X-RELEASE datasets
|
||||
elif [ ! -d "${bastille_cachedir}/${RELEASE}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; 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}"
|
||||
# Don't create unused/stale cache/RELEASE directory on Linux jails creation.
|
||||
if [ -z "${NOCACHEDIR}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_cachedir}/${RELEASE}"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_cachedir}/${RELEASE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -178,7 +184,6 @@ bootstrap_directories() {
|
||||
else
|
||||
mkdir -p "${bastille_templatesdir}"
|
||||
fi
|
||||
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
|
||||
fi
|
||||
|
||||
## ${bastille_releasesdir}
|
||||
@@ -216,7 +221,7 @@ bootstrap_release() {
|
||||
|
||||
## check if release already bootstrapped, else continue bootstrapping
|
||||
if [ -z "${bastille_bootstrap_archives}" ]; then
|
||||
error_exit "Bootstrap appears complete."
|
||||
error_notify "Bootstrap appears complete."
|
||||
else
|
||||
info "Bootstrapping additional distfiles..."
|
||||
fi
|
||||
@@ -254,12 +259,12 @@ bootstrap_release() {
|
||||
fi
|
||||
if [ -d "${bastille_cachedir}/${RELEASE}" ]; then
|
||||
if [ ! "$(ls -A "${bastille_cachedir}/${RELEASE}")" ]; then
|
||||
rm -rf "${bastille_cachedir}/${RELEASE}"
|
||||
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}"
|
||||
rm -rf "${bastille_releasesdir:?}/${RELEASE}"
|
||||
fi
|
||||
fi
|
||||
error_exit "Bootstrap failed."
|
||||
@@ -267,8 +272,7 @@ bootstrap_release() {
|
||||
|
||||
## fetch for missing dist files
|
||||
if [ ! -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
|
||||
fetch "${UPSTREAM_URL}/${_archive}.txz" -o "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
if ! fetch "${UPSTREAM_URL}/${_archive}.txz" -o "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
|
||||
## alert only if unable to fetch additional dist files
|
||||
error_notify "Failed to fetch ${_archive}.txz."
|
||||
fi
|
||||
@@ -308,6 +312,102 @@ bootstrap_release() {
|
||||
echo
|
||||
}
|
||||
|
||||
debootstrap_release() {
|
||||
|
||||
# Make sure to check/bootstrap directories first.
|
||||
NOCACHEDIR=1
|
||||
RELEASE="${DIR_BOOTSTRAP}"
|
||||
bootstrap_directories
|
||||
|
||||
#check and install OS dependencies @hackacad
|
||||
#ToDo: add function 'linux_pre' for sysrc etc.
|
||||
|
||||
required_mods="fdescfs linprocfs linsysfs tmpfs"
|
||||
linuxarc_mods="linux linux64"
|
||||
for _req_kmod in ${required_mods}; do
|
||||
if [ ! "$(sysrc -f /boot/loader.conf -qn ${_req_kmod}_load)" = "YES" ] && \
|
||||
[ ! "$(sysrc -f /boot/loader.conf.local -qn ${_req_kmod}_load)" = "YES" ]; then
|
||||
warn "${_req_kmod} not enabled in /boot/loader.conf, Should I do that for you? (N|y)"
|
||||
read answer
|
||||
case "${answer}" in
|
||||
[Nn][Oo]|[Nn]|"")
|
||||
error_exit "Exiting."
|
||||
;;
|
||||
[Yy][Ee][Ss]|[Yy])
|
||||
# Skip already loaded known modules.
|
||||
if ! kldstat -m ${_req_kmod} >/dev/null 2>&1; then
|
||||
info "Loading kernel module: ${_req_kmod}"
|
||||
kldload -v ${_req_kmod}
|
||||
fi
|
||||
info "Persisting module: ${_req_kmod}"
|
||||
sysrc -f /boot/loader.conf ${_req_kmod}_load=YES
|
||||
;;
|
||||
esac
|
||||
else
|
||||
# If already set in /boot/loader.conf, check and try to load the module.
|
||||
if ! kldstat -m ${_req_kmod} >/dev/null 2>&1; then
|
||||
info "Loading kernel module: ${_req_kmod}"
|
||||
kldload -v ${_req_kmod}
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Mandatory Linux modules/rc.
|
||||
for _lin_kmod in ${linuxarc_mods}; do
|
||||
if ! kldstat -n ${_lin_kmod} >/dev/null 2>&1; then
|
||||
info "Loading kernel module: ${_lin_kmod}"
|
||||
kldload -v ${_lin_kmod}
|
||||
fi
|
||||
done
|
||||
if [ ! "$(sysrc -qn linux_enable)" = "YES" ] && \
|
||||
[ ! "$(sysrc -f /etc/rc.conf.local -qn linux_enable)" = "YES" ]; then
|
||||
sysrc linux_enable=YES
|
||||
fi
|
||||
|
||||
if ! which -s debootstrap; then
|
||||
warn "Debootstrap not found. Should it be installed? (N|y)"
|
||||
read answer
|
||||
case $answer in
|
||||
[Nn][Oo]|[Nn]|"")
|
||||
error_exit "Exiting. You need to install debootstap before boostrapping a Linux jail."
|
||||
;;
|
||||
[Yy][Ee][Ss]|[Yy])
|
||||
pkg install -y debootstrap
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Fetch the Linux flavor
|
||||
info "Bootstrapping ${PLATFORM_OS} distfiles..."
|
||||
if ! debootstrap --foreign --arch=${ARCH_BOOTSTRAP} --no-check-gpg ${LINUX_FLAVOR} "${bastille_releasesdir}"/${DIR_BOOTSTRAP}; then
|
||||
## perform cleanup only for stale/empty directories on failure
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
if [ ! "$(ls -A "${bastille_releasesdir}/${DIR_BOOTSTRAP}")" ]; then
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${DIR_BOOTSTRAP}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ -d "${bastille_releasesdir}/${DIR_BOOTSTRAP}" ]; then
|
||||
if [ ! "$(ls -A "${bastille_releasesdir}/${DIR_BOOTSTRAP}")" ]; then
|
||||
rm -rf "${bastille_releasesdir:?}/${DIR_BOOTSTRAP}"
|
||||
fi
|
||||
fi
|
||||
error_exit "Bootstrap failed."
|
||||
fi
|
||||
|
||||
case "${LINUX_FLAVOR}" in
|
||||
bionic|stretch|buster|bullseye)
|
||||
info "Increasing APT::Cache-Start"
|
||||
echo "APT::Cache-Start 251658240;" > "${bastille_releasesdir}"/${DIR_BOOTSTRAP}/etc/apt/apt.conf.d/00aptitude
|
||||
;;
|
||||
esac
|
||||
|
||||
info "Bootstrap successful."
|
||||
info "See 'bastille --help' for available commands."
|
||||
echo
|
||||
}
|
||||
|
||||
bootstrap_template() {
|
||||
|
||||
## ${bastille_templatesdir}
|
||||
@@ -329,15 +429,15 @@ bootstrap_template() {
|
||||
_template=${bastille_templatesdir}/${_user}/${_repo}
|
||||
|
||||
## support for non-git
|
||||
if [ ! -x "$(which git)" ]; then
|
||||
if ! which -s git; then
|
||||
error_notify "Git not found."
|
||||
error_exit "Not yet implemented."
|
||||
elif [ -x "$(which git)" ]; then
|
||||
else
|
||||
if [ ! -d "${_template}/.git" ]; then
|
||||
$(which git) clone "${_url}" "${_template}" ||\
|
||||
git clone "${_url}" "${_template}" ||\
|
||||
error_notify "Clone unsuccessful."
|
||||
elif [ -d "${_template}/.git" ]; then
|
||||
cd "${_template}" && $(which git) pull ||\
|
||||
git -C "${_template}" pull ||\
|
||||
error_notify "Template update unsuccessful."
|
||||
fi
|
||||
fi
|
||||
@@ -347,13 +447,23 @@ bootstrap_template() {
|
||||
|
||||
HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }')
|
||||
HW_MACHINE_ARCH=$(sysctl hw.machine_arch | awk '{ print $2 }')
|
||||
|
||||
# bootstrapping from aarch64/arm64 Debian or Ubuntu require a different value for ARCH
|
||||
# create a new variable
|
||||
if [ "${HW_MACHINE_ARCH}" == "aarch64" ]; then
|
||||
HW_MACHINE_ARCH_LINUX="arm64"
|
||||
else
|
||||
HW_MACHINE_ARCH_LINUX=${HW_MACHINE_ARCH}
|
||||
fi
|
||||
|
||||
NOCACHEDIR=
|
||||
RELEASE="${1}"
|
||||
OPTION="${2}"
|
||||
|
||||
# Alternate RELEASE/ARCH fetch support(experimental)
|
||||
if [ -n "${OPTION}" ] && [ "${OPTION}" != "${HW_MACHINE}" ] && [ "${OPTION}" != "update" ]; then
|
||||
# Supported architectures
|
||||
if [ "${OPTION}" = "--i386" -o "${OPTION}" = "--32bit" ]; then
|
||||
if [ "${OPTION}" = "--i386" ] || [ "${OPTION}" = "--32bit" ]; then
|
||||
HW_MACHINE="i386"
|
||||
HW_MACHINE_ARCH="i386"
|
||||
else
|
||||
@@ -363,6 +473,13 @@ fi
|
||||
|
||||
## Filter sane release names
|
||||
case "${1}" in
|
||||
2.[0-9]*)
|
||||
## check for MidnightBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}")
|
||||
UPSTREAM_URL="${bastille_url_midnightbsd}${HW_MACHINE_ARCH}/${NAME_VERIFY}"
|
||||
PLATFORM_OS="MidnightBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
*-CURRENT|*-current)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT)$' | tr '[:lower:]' '[:upper:]')
|
||||
@@ -370,9 +487,9 @@ case "${1}" in
|
||||
PLATFORM_OS="FreeBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2|*-RC3|*-rc3|*-RC4|*-rc4|*-RC5|*-rc5|*-BETA1|*-BETA2|*-BETA3|*-BETA4|*-BETA5)
|
||||
## 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-5]|-BETA[1-5])$' | tr '[:lower:]' '[:upper:]')
|
||||
UPSTREAM_URL="${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}"
|
||||
PLATFORM_OS="FreeBSD"
|
||||
validate_release_url
|
||||
@@ -420,12 +537,48 @@ current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST)
|
||||
PLATFORM_OS="HardenedBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
http?://github.com/*/*|http?://gitlab.com/*/*)
|
||||
http?://*/*/*)
|
||||
BASTILLE_TEMPLATE_URL=${1}
|
||||
BASTILLE_TEMPLATE_USER=$(echo "${1}" | awk -F / '{ print $4 }')
|
||||
BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }')
|
||||
bootstrap_template
|
||||
;;
|
||||
#adding Ubuntu Bionic as valid "RELEASE" for POC @hackacad
|
||||
ubuntu_bionic|bionic|ubuntu-bionic)
|
||||
PLATFORM_OS="Ubuntu/Linux"
|
||||
LINUX_FLAVOR="bionic"
|
||||
DIR_BOOTSTRAP="Ubuntu_1804"
|
||||
ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX}
|
||||
debootstrap_release
|
||||
;;
|
||||
ubuntu_focal|focal|ubuntu-focal)
|
||||
PLATFORM_OS="Ubuntu/Linux"
|
||||
LINUX_FLAVOR="focal"
|
||||
DIR_BOOTSTRAP="Ubuntu_2004"
|
||||
ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX}
|
||||
debootstrap_release
|
||||
;;
|
||||
debian_stretch|stretch|debian-stretch)
|
||||
PLATFORM_OS="Debian/Linux"
|
||||
LINUX_FLAVOR="stretch"
|
||||
DIR_BOOTSTRAP="Debian9"
|
||||
ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX}
|
||||
debootstrap_release
|
||||
;;
|
||||
debian_buster|buster|debian-buster)
|
||||
PLATFORM_OS="Debian/Linux"
|
||||
LINUX_FLAVOR="buster"
|
||||
DIR_BOOTSTRAP="Debian10"
|
||||
ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX}
|
||||
debootstrap_release
|
||||
;;
|
||||
debian_bullseye|bullseye|debian-bullseye)
|
||||
PLATFORM_OS="Debian/Linux"
|
||||
LINUX_FLAVOR="bullseye"
|
||||
DIR_BOOTSTRAP="Debian11"
|
||||
ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX}
|
||||
debootstrap_release
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -130,7 +130,7 @@ update_fstab() {
|
||||
# Update fstab to use the new name
|
||||
FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab"
|
||||
if [ -f "${FSTAB_CONFIG}" ]; then
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-5]|-BETA[1-5]|-CURRENT)|([0-9]{1,2}(-stable-build-[0-9]{1,3}|-stable-LAST))|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)' "${FSTAB_CONFIG}" | uniq)
|
||||
FSTAB_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
|
||||
@@ -139,6 +139,8 @@ update_fstab() {
|
||||
sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}"
|
||||
fi
|
||||
fi
|
||||
# Update additional fstab paths with new jail path
|
||||
sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|" "${FSTAB_CONFIG}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -164,7 +166,7 @@ clone_jail() {
|
||||
else
|
||||
# Just clone the jail directory
|
||||
# Check if container is running
|
||||
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'."
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -29,6 +29,7 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille cmd TARGET command"
|
||||
@@ -45,8 +46,35 @@ if [ $# -eq 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
COUNT=0
|
||||
RETURN=0
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
COUNT=$(($COUNT+1))
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" "$@"
|
||||
|
||||
if grep -qw "linsysfs" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
# Allow executing commands on Linux jails.
|
||||
jexec -l -u root "${_jail}" "$@"
|
||||
else
|
||||
jexec -l -U root "${_jail}" "$@"
|
||||
fi
|
||||
|
||||
ERROR_CODE=$?
|
||||
info "[${_jail}]: ${ERROR_CODE}"
|
||||
|
||||
if [ "$COUNT" -eq 1 ]; then
|
||||
RETURN=${ERROR_CODE}
|
||||
else
|
||||
RETURN=$(($RETURN+$ERROR_CODE))
|
||||
fi
|
||||
|
||||
echo
|
||||
done
|
||||
|
||||
# Check when a command is executed in all running jails. (bastille cmd ALL ...)
|
||||
if [ "${COUNT}" -gt 1 ] && [ "${RETURN}" -gt 0 ]; then
|
||||
RETURN=1
|
||||
fi
|
||||
|
||||
return "${RETURN}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -28,7 +28,19 @@
|
||||
# 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
|
||||
COLOR_RED=
|
||||
COLOR_GREEN=
|
||||
COLOR_YELLOW=
|
||||
COLOR_RESET=
|
||||
|
||||
enable_color() {
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
}
|
||||
|
||||
# If "NO_COLOR" environment variable is present, disable output colors.
|
||||
if [ -z "${NO_COLOR}" ]; then
|
||||
enable_color
|
||||
fi
|
||||
|
||||
# Notify message on error, but do not exit
|
||||
error_notify() {
|
||||
@@ -48,3 +60,51 @@ info() {
|
||||
warn() {
|
||||
echo -e "${COLOR_YELLOW}$*${COLOR_RESET}"
|
||||
}
|
||||
|
||||
generate_vnet_jail_netblock() {
|
||||
local jail_name="$1"
|
||||
local use_unique_bridge="$2"
|
||||
local external_interface="$3"
|
||||
## 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=$((list_jails_num + 1))
|
||||
for _num in $(seq 0 "${num_range}"); do
|
||||
if ! grep -q "e[0-9]b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then
|
||||
if ! grep -q "epair${_num}" "${bastille_jailsdir}"/*/jail.conf; then
|
||||
local uniq_epair="bastille${_num}"
|
||||
local uniq_epair_bridge="${_num}"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
local uniq_epair="bastille0"
|
||||
local uniq_epair_bridge="0"
|
||||
fi
|
||||
if [ -n "${use_unique_bridge}" ]; then
|
||||
## generate bridge config
|
||||
cat <<-EOF
|
||||
vnet;
|
||||
vnet.interface = "e${uniq_epair_bridge}b_${jail_name}";
|
||||
exec.prestart += "ifconfig epair${uniq_epair_bridge} create";
|
||||
exec.prestart += "ifconfig ${external_interface} addm epair${uniq_epair_bridge}a";
|
||||
exec.prestart += "ifconfig epair${uniq_epair_bridge}a up name e${uniq_epair_bridge}a_${jail_name}";
|
||||
exec.prestart += "ifconfig epair${uniq_epair_bridge}b up name e${uniq_epair_bridge}b_${jail_name}";
|
||||
exec.poststop += "ifconfig ${external_interface} deletem e${uniq_epair_bridge}a_${jail_name}";
|
||||
exec.poststop += "ifconfig e${uniq_epair_bridge}a_${jail_name} destroy";
|
||||
EOF
|
||||
else
|
||||
## generate config
|
||||
cat <<-EOF
|
||||
vnet;
|
||||
vnet.interface = e0b_${uniq_epair};
|
||||
exec.prestart += "jib addm ${uniq_epair} ${external_interface}";
|
||||
exec.prestart += "ifconfig e0a_${uniq_epair} description \"vnet host interface for Bastille jail ${jail_name}\"";
|
||||
exec.poststop += "jib destroy ${uniq_epair}";
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -76,7 +76,7 @@ for _jail in ${JAILS}; do
|
||||
MATCH_FOUND=$?
|
||||
|
||||
if [ "${ACTION}" = 'get' ]; then
|
||||
if [ $MATCH_FOUND -ne 0 ]; then
|
||||
if [ "${MATCH_FOUND}" -ne 0 ]; then
|
||||
warn "not set"
|
||||
elif ! echo "${MATCH_LINE}" | grep '=' > /dev/null 2>&1; then
|
||||
echo "enabled"
|
||||
@@ -99,7 +99,7 @@ for _jail in ${JAILS}; do
|
||||
LINE=" ${PROPERTY};"
|
||||
fi
|
||||
|
||||
if [ $MATCH_FOUND -ne 0 ]; then # No match, so insert the property at the end. -- cwells
|
||||
if [ "${MATCH_FOUND}" -ne 0 ]; then # No match, so insert the property at the end. -- cwells
|
||||
echo "$(awk -v line="${LINE}" '$0 == "}" { print line; } 1 { print $0; }' "${FILE}")" > "${FILE}"
|
||||
else # Replace the existing value. -- cwells
|
||||
sed -i '' -E "s/ *${ESCAPED_PROPERTY}[ =;].*/${LINE}/" "${FILE}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,7 +32,7 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille console TARGET [user]'"
|
||||
error_exit "Usage: bastille console TARGET [user]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -53,7 +53,7 @@ validate_user() {
|
||||
USER_SHELL="$(jexec -l "${_jail}" getent passwd "${USER}" | cut -d: -f7)"
|
||||
if [ -n "${USER_SHELL}" ]; then
|
||||
if jexec -l "${_jail}" grep -qwF "${USER_SHELL}" /etc/shells; then
|
||||
jexec -l "${_jail}" /usr/bin/login -f "${USER}"
|
||||
jexec -l "${_jail}" $LOGIN -f "${USER}"
|
||||
else
|
||||
echo "Invalid shell for user ${USER}"
|
||||
fi
|
||||
@@ -76,11 +76,12 @@ check_fib() {
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
LOGIN="$(jexec -l "${_jail}" which login)"
|
||||
if [ -n "${USER}" ]; then
|
||||
validate_user
|
||||
else
|
||||
check_fib
|
||||
${_setfib} jexec -l "${_jail}" /usr/bin/login -f root
|
||||
LOGIN="$(jexec -l "${_jail}" which login)"
|
||||
${_setfib} jexec -l "${_jail}" $LOGIN -f root
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -57,6 +57,7 @@ convert_symlinks() {
|
||||
done
|
||||
|
||||
# Copy new files to destination jail
|
||||
info "Copying required base files to container..."
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ ! -d "${_link}" ]; then
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}/${_link}" ]; then
|
||||
@@ -100,13 +101,15 @@ revert_convert() {
|
||||
|
||||
start_convert() {
|
||||
# Attempt container conversion and handle some errors
|
||||
DATE=$(date)
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
info "Converting '${TARGET}' into a thickjail. This may take a while..."
|
||||
|
||||
# Set some variables
|
||||
RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${bastille_jailsdir}/${TARGET}/fstab")
|
||||
RELEASE=$(grep -w "${bastille_releasesdir}/.* ${bastille_jailsdir}/${TARGET}/root/.bastille" ${bastille_jailsdir}/${TARGET}/fstab | sed "s|${bastille_releasesdir}/||;s| .*||")
|
||||
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"
|
||||
HASPORTS=$(grep -w ${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jailsdir}/${TARGET}/fstab)
|
||||
|
||||
if [ -n "${RELEASE}" ]; then
|
||||
cd "${bastille_jailsdir}/${TARGET}/root"
|
||||
@@ -115,7 +118,12 @@ start_convert() {
|
||||
convert_symlinks
|
||||
|
||||
# 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"
|
||||
if [ -n "${HASPORTS}" ]; then
|
||||
sed -i '' -E "s|${HASPORTS}|# Ports copied from base to container on ${DATE}|g" "${bastille_jailsdir}/${TARGET}/fstab"
|
||||
info "Copying ports to container..."
|
||||
cp -a "${bastille_releasesdir}/${RELEASE}/usr/ports" "${bastille_jailsdir}/${TARGET}/root/usr"
|
||||
fi
|
||||
mv "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/root/.bastille.old"
|
||||
|
||||
info "Conversion of '${TARGET}' completed successfully!"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,27 +32,41 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille cp TARGET HOST_PATH CONTAINER_PATH"
|
||||
error_exit "Usage: bastille cp [OPTION] TARGET HOST_PATH CONTAINER_PATH"
|
||||
}
|
||||
|
||||
CPSOURCE="${1}"
|
||||
CPDEST="${2}"
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
-q|--quiet)
|
||||
OPTION="${1}"
|
||||
CPSOURCE="${2}"
|
||||
CPDEST="${3}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
CPSOURCE="${1}"
|
||||
CPDEST="${2}"
|
||||
case "${OPTION}" in
|
||||
-q|--quiet)
|
||||
OPTION="-a"
|
||||
;;
|
||||
*)
|
||||
OPTION="-av"
|
||||
;;
|
||||
esac
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
bastille_jail_path="${bastille_jailsdir}/${_jail}/root"
|
||||
cp -av "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}"
|
||||
cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}"
|
||||
RETURN="$?"
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
# Display the return status for reference
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,11 +32,26 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille create [option] name release ip [interface]"
|
||||
# Build an independent usage for the create command
|
||||
# If no option specified, will create a thin container by default
|
||||
error_notify "Usage: bastille create [option(s)] name release ip [interface]"
|
||||
|
||||
cat << EOF
|
||||
Options:
|
||||
|
||||
-E | --empty -- Creates an empty container, intended for custom jail builds (thin/thick/linux or unsupported).
|
||||
-L | --linux -- This option is intended for testing with Linux jails, this is considered experimental.
|
||||
-T | --thick -- Creates a thick container, they consume more space as they are self contained and independent.
|
||||
-V | --vnet -- Enables VNET, VNET containers are attached to a virtual bridge interface for connectivity.
|
||||
-C | --clone -- Creates a clone container, they are duplicates of the base release, consume low space and preserves changing data.
|
||||
-B | --bridge -- Enables VNET, VNET containers are attached to a specified, already existing external bridge.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
running_jail() {
|
||||
if [ -n "$(jls name | awk "/^${NAME}$/")" ]; then
|
||||
if [ -n "$(/usr/sbin/jls name | awk "/^${NAME}$/")" ]; then
|
||||
error_exit "A running jail matches name."
|
||||
elif [ -d "${bastille_jailsdir}/${NAME}" ]; then
|
||||
error_exit "Jail: ${NAME} already created."
|
||||
@@ -46,7 +61,9 @@ running_jail() {
|
||||
validate_name() {
|
||||
local NAME_VERIFY=${NAME}
|
||||
local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')
|
||||
if [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
|
||||
if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then
|
||||
error_exit "Container names may not begin with (-|_) characters!"
|
||||
elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
|
||||
error_exit "Container names may not contain special characters!"
|
||||
fi
|
||||
}
|
||||
@@ -98,6 +115,13 @@ validate_netconf() {
|
||||
}
|
||||
|
||||
validate_release() {
|
||||
## ensure the user set the Linux(experimental) option explicitly
|
||||
if [ -n "${UBUNTU}" ]; then
|
||||
if [ -z "${LINUX_JAIL}" ]; then
|
||||
usage
|
||||
fi
|
||||
fi
|
||||
|
||||
## check release name match, else show usage
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
RELEASE="${NAME_VERIFY}"
|
||||
@@ -139,25 +163,31 @@ ${NAME} {
|
||||
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_linux_jail_conf() {
|
||||
cat << EOF > "${bastille_jail_conf}"
|
||||
${NAME} {
|
||||
host.hostname = ${NAME};
|
||||
mount.fstab = ${bastille_jail_fstab};
|
||||
path = ${bastille_jail_path};
|
||||
devfs_ruleset = 4;
|
||||
enforce_statfs = 1;
|
||||
|
||||
## generate config
|
||||
exec.start = '/bin/true';
|
||||
exec.stop = '/bin/true';
|
||||
persist;
|
||||
|
||||
allow.mount;
|
||||
allow.mount.devfs;
|
||||
|
||||
interface = ${bastille_jail_conf_interface};
|
||||
${IPX_ADDR} = ${IP};
|
||||
ip6 = ${IP6_MODE};
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_vnet_jail_conf() {
|
||||
NETBLOCK=$(generate_vnet_jail_netblock "$NAME" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}")
|
||||
cat << EOF > "${bastille_jail_conf}"
|
||||
${NAME} {
|
||||
devfs_ruleset = 13;
|
||||
@@ -172,14 +202,48 @@ ${NAME} {
|
||||
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}";
|
||||
${NETBLOCK}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
post_create_jail() {
|
||||
# Common config checks and settings.
|
||||
|
||||
# Using relative paths here.
|
||||
# MAKE SURE WE'RE IN THE RIGHT PLACE.
|
||||
cd "${bastille_jail_path}"
|
||||
echo
|
||||
|
||||
if [ ! -f "${bastille_jail_conf}" ]; then
|
||||
if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
|
||||
local bastille_jail_conf_interface=${bastille_network_shared}
|
||||
fi
|
||||
if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then
|
||||
local bastille_jail_conf_interface=${bastille_network_loopback}
|
||||
fi
|
||||
if [ -n "${INTERFACE}" ]; then
|
||||
local bastille_jail_conf_interface=${INTERFACE}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "${bastille_jail_fstab}" ]; then
|
||||
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||
echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}"
|
||||
else
|
||||
touch "${bastille_jail_fstab}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Generate the jail configuration file.
|
||||
if [ -n "${VNET_JAIL}" ]; then
|
||||
generate_vnet_jail_conf
|
||||
else
|
||||
generate_jail_conf
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
create_jail() {
|
||||
bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir
|
||||
bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir
|
||||
@@ -194,8 +258,10 @@ create_jail() {
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
## create required zfs datasets, mountpoint inherited from system
|
||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}"
|
||||
if [ -z "${THICK_JAIL}" ]; then
|
||||
if [ -z "${CLONE_JAIL}" ]; then
|
||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}"
|
||||
fi
|
||||
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
|
||||
fi
|
||||
fi
|
||||
@@ -204,26 +270,37 @@ create_jail() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${EMPTY_JAIL}" ]; then
|
||||
## PoC for Linux jails @hackacad
|
||||
if [ -n "${LINUX_JAIL}" ]; then
|
||||
info "\nCreating a linuxjail. This may take a while...\n"
|
||||
if [ ! -d "${bastille_jail_base}" ]; then
|
||||
mkdir -p "${bastille_jail_base}"
|
||||
fi
|
||||
|
||||
if [ ! -d "${bastille_jail_path}/usr/local" ]; then
|
||||
mkdir -p "${bastille_jail_path}/usr/local"
|
||||
fi
|
||||
mkdir -p "${bastille_jail_path}/dev"
|
||||
mkdir -p "${bastille_jail_path}/proc"
|
||||
mkdir -p "${bastille_jail_path}/sys"
|
||||
mkdir -p "${bastille_jail_path}/home"
|
||||
mkdir -p "${bastille_jail_path}/tmp"
|
||||
touch "${bastille_jail_path}/dev/shm"
|
||||
touch "${bastille_jail_path}/dev/fd"
|
||||
cp -RPf ${bastille_releasesdir}/${RELEASE}/* ${bastille_jail_path}/
|
||||
echo "${NAME}" > ${bastille_jail_path}/etc/hostname
|
||||
|
||||
if [ ! -d "${bastille_jail_template}" ]; then
|
||||
mkdir -p "${bastille_jail_template}"
|
||||
fi
|
||||
|
||||
if [ ! -f "${bastille_jail_fstab}" ]; then
|
||||
if [ -z "${THICK_JAIL}" ]; then
|
||||
echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}"
|
||||
else
|
||||
touch "${bastille_jail_fstab}"
|
||||
fi
|
||||
touch "${bastille_jail_fstab}"
|
||||
fi
|
||||
echo -e "devfs ${bastille_jail_path}/dev devfs rw 0 0" >> "${bastille_jail_fstab}"
|
||||
echo -e "tmpfs ${bastille_jail_path}/dev/shm tmpfs rw,size=1g,mode=1777 0 0" >> "${bastille_jail_fstab}"
|
||||
echo -e "fdescfs ${bastille_jail_path}/dev/fd fdescfs rw,linrdlnk 0 0" >> "${bastille_jail_fstab}"
|
||||
echo -e "linprocfs ${bastille_jail_path}/proc linprocfs rw 0 0" >> "${bastille_jail_fstab}"
|
||||
echo -e "linsysfs ${bastille_jail_path}/sys linsysfs rw 0 0" >> "${bastille_jail_fstab}"
|
||||
echo -e "/tmp ${bastille_jail_path}/tmp nullfs rw 0 0" >> "${bastille_jail_fstab}"
|
||||
## removed temporarely / only for X11 jails? @hackacad
|
||||
#echo -e "/home ${bastille_jail_path}/home nullfs rw 0 0" >> "${bastille_jail_fstab}"
|
||||
|
||||
if [ ! -f "${bastille_jail_conf}" ]; then
|
||||
if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
|
||||
@@ -235,42 +312,49 @@ create_jail() {
|
||||
if [ -n "${INTERFACE}" ]; then
|
||||
local bastille_jail_conf_interface=${INTERFACE}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
## generate the jail configuration file
|
||||
if [ -n "${VNET_JAIL}" ]; then
|
||||
generate_vnet_jail_conf
|
||||
else
|
||||
generate_jail_conf
|
||||
if [ -z "${EMPTY_JAIL}" ] && [ -z "${LINUX_JAIL}" ]; then
|
||||
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||
if [ ! -d "${bastille_jail_base}" ]; then
|
||||
mkdir -p "${bastille_jail_base}"
|
||||
fi
|
||||
if [ ! -d "${bastille_jail_template}" ]; then
|
||||
mkdir -p "${bastille_jail_template}"
|
||||
fi
|
||||
fi
|
||||
|
||||
## using relative paths here
|
||||
## MAKE SURE WE'RE IN THE RIGHT PLACE
|
||||
cd "${bastille_jail_path}"
|
||||
echo
|
||||
info "NAME: ${NAME}."
|
||||
info "IP: ${IP}."
|
||||
if [ -n "${INTERFACE}" ]; then
|
||||
info "INTERFACE: ${INTERFACE}."
|
||||
if [ ! -d "${bastille_jail_path}/usr/local" ]; then
|
||||
mkdir -p "${bastille_jail_path}/usr/local"
|
||||
fi
|
||||
info "RELEASE: ${RELEASE}."
|
||||
echo
|
||||
|
||||
if [ -z "${THICK_JAIL}" ]; then
|
||||
# Check and apply required settings.
|
||||
post_create_jail
|
||||
|
||||
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||
LINK_LIST="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/sbin usr/share usr/src"
|
||||
info "Creating a thinjail...\n"
|
||||
for _link in ${LINK_LIST}; do
|
||||
ln -sf /.bastille/${_link} ${_link}
|
||||
done
|
||||
|
||||
# Properly link shared ports on thin jails in read-write.
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}/usr/ports" ]; then
|
||||
if [ ! -d "${bastille_jail_path}/usr/ports" ]; then
|
||||
mkdir ${bastille_jail_path}/usr/ports
|
||||
fi
|
||||
echo -e "${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jail_path}/usr/ports nullfs rw 0 0" >> "${bastille_jail_fstab}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${THICK_JAIL}" ]; then
|
||||
if [ -z "${THICK_JAIL}" ] && [ -z "${CLONE_JAIL}" ]; then
|
||||
## rw
|
||||
## copy only required files for thin jails
|
||||
FILE_LIST=".cshrc .profile COPYRIGHT dev etc media mnt net proc root tmp var usr/obj usr/tests"
|
||||
for files in ${FILE_LIST}; do
|
||||
if [ -f "${bastille_releasesdir}/${RELEASE}/${files}" ] || [ -d "${bastille_releasesdir}/${RELEASE}/${files}" ]; then
|
||||
cp -a "${bastille_releasesdir}/${RELEASE}/${files}" "${bastille_jail_path}/${files}"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
if ! cp -a "${bastille_releasesdir}/${RELEASE}/${files}" "${bastille_jail_path}/${files}"; then
|
||||
## notify and clean stale files/directories
|
||||
bastille destroy "${NAME}"
|
||||
error_exit "Failed to copy release files. Please retry create!"
|
||||
@@ -278,27 +362,40 @@ create_jail() {
|
||||
fi
|
||||
done
|
||||
else
|
||||
info "Creating a thickjail. This may take a while..."
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
## perform release base replication
|
||||
if [ -n "${CLONE_JAIL}" ]; then
|
||||
info "Creating a clonejail...\n"
|
||||
## clone the release base to the new basejail
|
||||
SNAP_NAME="bastille-clone-$(date +%Y-%m-%d-%H%M%S)"
|
||||
zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
|
||||
|
||||
## sane bastille zfs options
|
||||
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
|
||||
zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \
|
||||
"${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
|
||||
|
||||
## take a temp snapshot of the base release
|
||||
SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)"
|
||||
zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
|
||||
# Check and apply required settings.
|
||||
post_create_jail
|
||||
elif [ -n "${THICK_JAIL}" ]; then
|
||||
info "Creating a thickjail. This may take a while...\n"
|
||||
## perform release base replication
|
||||
|
||||
## 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 receive "${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"
|
||||
## sane bastille zfs options
|
||||
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
|
||||
|
||||
## cleanup temp snapshots initially
|
||||
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}"
|
||||
## take a temp snapshot of the base release
|
||||
SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)"
|
||||
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
|
||||
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 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
|
||||
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}"
|
||||
fi
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
## notify and clean stale files/directories
|
||||
@@ -317,23 +414,33 @@ create_jail() {
|
||||
fi
|
||||
fi
|
||||
|
||||
## create home directory if missing
|
||||
if [ ! -d "${bastille_jail_path}/usr/home" ]; then
|
||||
mkdir -p "${bastille_jail_path}/usr/home"
|
||||
fi
|
||||
## link home properly
|
||||
if [ ! -L "home" ]; then
|
||||
ln -s usr/home home
|
||||
fi
|
||||
if [ -z "${LINUX_JAIL}" ]; then
|
||||
## create home directory if missing
|
||||
if [ ! -d "${bastille_jail_path}/usr/home" ]; then
|
||||
mkdir -p "${bastille_jail_path}/usr/home"
|
||||
fi
|
||||
## link home properly
|
||||
if [ ! -L "home" ]; then
|
||||
ln -s usr/home home
|
||||
fi
|
||||
|
||||
## TZ: configurable (default: Etc/UTC)
|
||||
ln -s "/usr/share/zoneinfo/${bastille_tzdata}" etc/localtime
|
||||
## TZ: configurable (default: empty to use host's time zone)
|
||||
if [ -z "${bastille_tzdata}" ]; then
|
||||
# Note that if host has no time zone, FreeBSD assumes UTC anyway
|
||||
if [ -e /etc/localtime ]; then
|
||||
# uses cp as a way to prevent issues with symlinks if the host happens to use that for tz configuration
|
||||
cp /etc/localtime etc/localtime
|
||||
fi
|
||||
else
|
||||
ln -s "/usr/share/zoneinfo/${bastille_tzdata}" etc/localtime
|
||||
fi
|
||||
|
||||
# Post-creation jail misc configuration
|
||||
# Create a dummy fstab file
|
||||
touch "etc/fstab"
|
||||
# Disables adjkerntz, avoids spurious error messages
|
||||
sed -i '' 's|[0-9],[0-9]\{2\}.*[0-9]-[0-9].*root.*kerntz -a|#& # Disabled by bastille|' "etc/crontab"
|
||||
# Post-creation jail misc configuration
|
||||
# Create a dummy fstab file
|
||||
touch "etc/fstab"
|
||||
# Disables adjkerntz, avoids spurious error messages
|
||||
sed -i '' 's|[0-9],[0-9]\{2\}.*[0-9]-[0-9].*root.*kerntz -a|#& # Disabled by bastille|' "etc/crontab"
|
||||
fi
|
||||
|
||||
## VNET specific
|
||||
if [ -n "${VNET_JAIL}" ]; then
|
||||
@@ -344,7 +451,10 @@ create_jail() {
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
elif [ -n "${LINUX_JAIL}" ]; then
|
||||
## Generate configuration for Linux jail
|
||||
generate_linux_jail_conf
|
||||
elif [ -n "${EMPTY_JAIL}" ]; then
|
||||
## Generate minimal configuration for empty jail
|
||||
generate_minimal_conf
|
||||
fi
|
||||
@@ -353,41 +463,79 @@ create_jail() {
|
||||
chmod 0700 "${bastille_jailsdir}/${NAME}"
|
||||
|
||||
# Jail must be started before applying the default template. -- cwells
|
||||
bastille start "${NAME}"
|
||||
if [ -z "${EMPTY_JAIL}" ]; then
|
||||
bastille start "${NAME}"
|
||||
elif [ -n "${EMPTY_JAIL}" ]; then
|
||||
# Don't start empty jails unless a template defined.
|
||||
if [ -n "${bastille_template_empty}" ]; then
|
||||
bastille start "${NAME}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${VNET_JAIL}" ]; then
|
||||
if [ -n ${bastille_template_vnet} ]; then
|
||||
if [ -n "${bastille_template_vnet}" ]; then
|
||||
## rename interface to generic vnet0
|
||||
uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//')
|
||||
|
||||
_gateway=''
|
||||
_gateway6=''
|
||||
_ifconfig=SYNCDHCP
|
||||
if [ "${IP}" != "0.0.0.0" ]; then # not using DHCP, so set static address.
|
||||
_ifconfig="inet ${IP}"
|
||||
if [ -n "${ip6}" ]; then
|
||||
_ifconfig="inet6 ${IP}"
|
||||
else
|
||||
_ifconfig="inet ${IP}"
|
||||
fi
|
||||
if [ -n "${bastille_network_gateway}" ]; then
|
||||
_gateway="${bastille_network_gateway}"
|
||||
elif [ -n "${bastille_network_gateway6}" ]; then
|
||||
_gateway6="${bastille_network_gateway6}"
|
||||
else
|
||||
_gateway="$(netstat -rn | awk '/default/ {print $2}')"
|
||||
if [ -z ${ip6} ]; then
|
||||
_gateway="$(netstat -4rn | awk '/default/ {print $2}')"
|
||||
else
|
||||
_gateway="$(netstat -6rn | awk '/default/ {print $2}')"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg IFCONFIG="${_ifconfig}"
|
||||
bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}"
|
||||
fi
|
||||
elif [ -n "${THICK_JAIL}" ]; then
|
||||
if [ -n ${bastille_template_thick} ]; then
|
||||
if [ -n "${bastille_template_thick}" ]; then
|
||||
bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||
fi
|
||||
elif [ -n "${CLONE_JAIL}" ]; then
|
||||
if [ -n "${bastille_template_clone}" ]; then
|
||||
bastille template "${NAME}" ${bastille_template_clone} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||
fi
|
||||
elif [ -n "${EMPTY_JAIL}" ]; then
|
||||
if [ -n ${bastille_template_empty} ]; then
|
||||
if [ -n "${bastille_template_empty}" ]; then
|
||||
bastille template "${NAME}" ${bastille_template_empty} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||
fi
|
||||
else # Thin jail.
|
||||
if [ -n ${bastille_template_thin} ]; then
|
||||
## Using templating function to fetch necessary packges @hackacad
|
||||
elif [ -n "${LINUX_JAIL}" ]; then
|
||||
info "Fetching packages..."
|
||||
jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive rm /var/cache/apt/archives/rsyslog*.deb"
|
||||
jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg --force-depends --force-confdef --force-confold -i /var/cache/apt/archives/*.deb"
|
||||
jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg --force-depends --force-confdef --force-confold -i /var/cache/apt/archives/*.deb"
|
||||
jexec -l "${NAME}" /bin/bash -c "chmod 777 /tmp"
|
||||
jexec -l "${NAME}" /bin/bash -c "apt update"
|
||||
else
|
||||
# Thin jail.
|
||||
if [ -n "${bastille_template_thin}" ]; then
|
||||
bastille template "${NAME}" ${bastille_template_thin} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Apply values changed by the template. -- cwells
|
||||
bastille restart "${NAME}"
|
||||
if [ -z "${EMPTY_JAIL}" ] && [ -z "${LINUX_JAIL}" ]; then
|
||||
bastille restart "${NAME}"
|
||||
elif [ -n "${EMPTY_JAIL}" ]; then
|
||||
# Don't restart empty jails unless a template defined.
|
||||
if [ -n "${bastille_template_empty}" ]; then
|
||||
bastille restart "${NAME}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -405,34 +553,59 @@ fi
|
||||
## reset this options
|
||||
EMPTY_JAIL=""
|
||||
THICK_JAIL=""
|
||||
CLONE_JAIL=""
|
||||
VNET_JAIL=""
|
||||
LINUX_JAIL=""
|
||||
|
||||
## handle combined options then shift
|
||||
if [ "${1}" = "-T" -o "${1}" = "--thick" -o "${1}" = "thick" ] && \
|
||||
[ "${2}" = "-V" -o "${2}" = "--vnet" -o "${2}" = "vnet" ]; then
|
||||
THICK_JAIL="1"
|
||||
VNET_JAIL="1"
|
||||
shift 2
|
||||
else
|
||||
## handle single options
|
||||
# Handle and parse options
|
||||
while [ $# -gt 0 ]; do
|
||||
case "${1}" in
|
||||
-E|--empty|empty)
|
||||
shift
|
||||
EMPTY_JAIL="1"
|
||||
shift
|
||||
;;
|
||||
-L|--linux|linux)
|
||||
LINUX_JAIL="1"
|
||||
shift
|
||||
;;
|
||||
-T|--thick|thick)
|
||||
shift
|
||||
THICK_JAIL="1"
|
||||
shift
|
||||
;;
|
||||
-V|--vnet|vnet)
|
||||
shift
|
||||
VNET_JAIL="1"
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
-B|--bridge|bridge)
|
||||
VNET_JAIL="1"
|
||||
VNET_JAIL_BRIDGE="1"
|
||||
shift
|
||||
;;
|
||||
-C|--clone|clone)
|
||||
CLONE_JAIL="1"
|
||||
shift
|
||||
;;
|
||||
-*|--*)
|
||||
error_notify "Unknown Option."
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
## validate for combined options
|
||||
if [ -n "${EMPTY_JAIL}" ]; then
|
||||
if [ -n "${CLONE_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${LINUX_JAIL}" ]; then
|
||||
error_exit "Error: Empty jail option can't be used with other options."
|
||||
fi
|
||||
elif [ -n "${LINUX_JAIL}" ]; then
|
||||
if [ -n "${EMPTY_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${CLONE_JAIL}" ]; then
|
||||
error_exit "Error: Linux jail option can't be used with other options."
|
||||
fi
|
||||
elif [ -n "${CLONE_JAIL}" ] && [ -n "${THICK_JAIL}" ]; then
|
||||
error_exit "Error: Clonejail and Thickjail can't be used together."
|
||||
fi
|
||||
|
||||
NAME="$1"
|
||||
@@ -455,17 +628,51 @@ if [ -n "${NAME}" ]; then
|
||||
validate_name
|
||||
fi
|
||||
|
||||
if [ -n "${LINUX_JAIL}" ]; then
|
||||
case "${RELEASE}" in
|
||||
bionic|ubuntu_bionic|ubuntu|ubuntu-bionic)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=ubuntu_bionic
|
||||
;;
|
||||
focal|ubuntu_focal|ubuntu-focal)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=ubuntu_focal
|
||||
;;
|
||||
debian_stretch|stretch|debian-stretch)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=stretch
|
||||
;;
|
||||
debian_buster|buster|debian-buster)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=buster
|
||||
;;
|
||||
debian_bullseye|bullseye|debian-bullseye)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=bullseye
|
||||
;;
|
||||
*)
|
||||
error_notify "Unknown Linux."
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ -z "${EMPTY_JAIL}" ]; then
|
||||
## verify release
|
||||
case "${RELEASE}" in
|
||||
2.[0-9]*)
|
||||
## check for MidnightBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}")
|
||||
validate_release
|
||||
;;
|
||||
*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
validate_release
|
||||
;;
|
||||
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2|*-BETA1|*-BETA2|*-BETA3|*-BETA4|*-BETA5)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2]|-BETA[1-5])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
validate_release
|
||||
;;
|
||||
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
|
||||
@@ -493,6 +700,28 @@ if [ -z "${EMPTY_JAIL}" ]; then
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g')
|
||||
validate_release
|
||||
;;
|
||||
ubuntu_bionic|bionic|ubuntu-bionic)
|
||||
UBUNTU="1"
|
||||
NAME_VERIFY=Ubuntu_1804
|
||||
validate_release
|
||||
;;
|
||||
ubuntu_focal|focal|ubuntu-focal)
|
||||
UBUNTU="1"
|
||||
NAME_VERIFY=Ubuntu_2004
|
||||
validate_release
|
||||
;;
|
||||
debian_stretch|stretch|debian-stretch)
|
||||
NAME_VERIFY=Debian9
|
||||
validate_release
|
||||
;;
|
||||
debian_buster|buster|debian-buster)
|
||||
NAME_VERIFY=Debian10
|
||||
validate_release
|
||||
;;
|
||||
debian_bullseye|bullseye|debian-bullseye)
|
||||
NAME_VERIFY=Debian11
|
||||
validate_release
|
||||
;;
|
||||
*)
|
||||
error_notify "Unknown Release."
|
||||
usage
|
||||
@@ -520,6 +749,15 @@ if [ -z "${EMPTY_JAIL}" ]; then
|
||||
if [ -n "${INTERFACE}" ]; then
|
||||
validate_netif
|
||||
validate_netconf
|
||||
elif [ -n "${VNET_JAIL}" ]; then
|
||||
if [ -z "${INTERFACE}" ]; then
|
||||
if [ -z "${bastille_network_shared}" ]; then
|
||||
# User must specify interface on vnet jails.
|
||||
error_exit "Error: Network interface not defined."
|
||||
else
|
||||
validate_netconf
|
||||
fi
|
||||
fi
|
||||
else
|
||||
validate_netconf
|
||||
fi
|
||||
@@ -545,9 +783,15 @@ fi
|
||||
if [ -z ${bastille_template_empty+x} ]; then
|
||||
bastille_template_empty='default/empty'
|
||||
fi
|
||||
if [ -z ${bastille_template_linux+x} ]; then
|
||||
bastille_template_linux='default/linux'
|
||||
fi
|
||||
if [ -z ${bastille_template_thick+x} ]; then
|
||||
bastille_template_thick='default/thick'
|
||||
fi
|
||||
if [ -z ${bastille_template_clone+x} ]; then
|
||||
bastille_template_clone='default/clone'
|
||||
fi
|
||||
if [ -z ${bastille_template_thin+x} ]; then
|
||||
bastille_template_thin='default/thin'
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,7 +32,7 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille destroy [option] | [container|release]"
|
||||
error_exit "Usage: bastille destroy [force] | [container|release]"
|
||||
}
|
||||
|
||||
destroy_jail() {
|
||||
@@ -40,7 +40,7 @@ destroy_jail() {
|
||||
bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir
|
||||
bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file
|
||||
|
||||
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ "${FORCE}" = "1" ]; then
|
||||
bastille stop "${TARGET}"
|
||||
else
|
||||
@@ -76,6 +76,12 @@ destroy_jail() {
|
||||
rm -rf "${bastille_jail_base}"
|
||||
fi
|
||||
|
||||
# Remove target from bastille_list if exist
|
||||
# Mute sysrc output here as it may be undesirable on large startup list
|
||||
if [ -n "$(sysrc -qn bastille_list | tr -s " " "\n" | awk "/^${TARGET}$/")" ]; then
|
||||
sysrc bastille_list-="${TARGET}" > /dev/null
|
||||
fi
|
||||
|
||||
## archive jail log
|
||||
if [ -f "${bastille_jail_log}" ]; then
|
||||
mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)"
|
||||
@@ -112,6 +118,23 @@ destroy_rel() {
|
||||
if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then
|
||||
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
|
||||
BASE_HASCHILD="1"
|
||||
elif [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
## check if this release have child clones
|
||||
if zfs list -H -t snapshot -r "${bastille_rel_base}" > /dev/null 2>&1; then
|
||||
SNAP_CLONE=$(zfs list -H -t snapshot -r "${bastille_rel_base}" 2> /dev/null | awk '{print $1}')
|
||||
for _snap_clone in ${SNAP_CLONE}; do
|
||||
if zfs list -H -o clones "${_snap_clone}" > /dev/null 2>&1; then
|
||||
CLONE_JAIL=$(zfs list -H -o clones "${_snap_clone}" | tr ',' '\n')
|
||||
CLONE_CHECK="${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}/root"
|
||||
if echo "${CLONE_JAIL}" | grep -qw "${CLONE_CHECK}"; then
|
||||
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
|
||||
BASE_HASCHILD="1"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
@@ -194,34 +217,44 @@ case "${TARGET}" in
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2|*-RC3|*-rc3|*-RC4|*-rc4|*-RC5|*-rc5|*-BETA1|*-BETA2|*-BETA3|*-BETA4|*-BETA5)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-5]|-BETA[1-5])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
|
||||
## check for HardenedBSD releases name
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})(-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;s/last/LAST/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*)
|
||||
## check for HardenedBSD(specific stable build releases)
|
||||
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')
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g;s/STABLE/stable/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST)
|
||||
## check for HardenedBSD(latest stable build release)
|
||||
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')
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/;s/build/BUILD/g;s/latest/LATEST/g')
|
||||
destroy_rel
|
||||
;;
|
||||
current-build-[0-9]*|CURRENT-BUILD-[0-9]*)
|
||||
## check for HardenedBSD(specific current build releases)
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(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;s/CURRENT/current/g')
|
||||
destroy_rel
|
||||
;;
|
||||
current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST)
|
||||
## check for HardenedBSD(latest current build release)
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(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/;s/build/BUILD/g;s/latest/LATEST/g')
|
||||
destroy_rel
|
||||
;;
|
||||
Ubuntu_1804|Ubuntu_2004|UBUNTU_1804|UBUNTU_2004)
|
||||
## check for Linux releases
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Ubuntu_1804)$|(Ubuntu_2004)$' | sed 's/UBUNTU/Ubuntu/g;s/ubuntu/Ubuntu/g')
|
||||
destroy_rel
|
||||
;;
|
||||
Debian9|Debian10|Debian11|DEBIAN9|DEBIAN10|DEBIAN11)
|
||||
## check for Linux releases
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Debian9)$|(Debian10)$|(Debian11)$' | sed 's/DEBIAN/Debian/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,7 +32,27 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille export TARGET [option] | PATH"
|
||||
# Build an independent usage for the export command
|
||||
# Valid compress/options for ZFS systems are raw, .gz, .tgz, .txz and .xz
|
||||
# Valid compress/options for non ZFS configured systems are .tgz and .txz
|
||||
# If no compression option specified, user must redirect standard output
|
||||
error_notify "Usage: bastille export | option(s) | TARGET | PATH"
|
||||
|
||||
cat << EOF
|
||||
Options:
|
||||
|
||||
--gz -- Export a ZFS jail using GZIP(.gz) compressed image.
|
||||
-r | --raw -- Export a ZFS jail to an uncompressed RAW image.
|
||||
-s | --safe -- Safely stop and start a ZFS jail before the exporting process.
|
||||
--tgz -- Export a jail using simple .tgz compressed archive instead.
|
||||
--txz -- Export a jail using simple .txz compressed archive instead.
|
||||
-v | --verbose -- Be more verbose during the ZFS send operation.
|
||||
--xz -- Export a ZFS jail using XZ(.xz) compressed image.
|
||||
|
||||
Note: If no export option specified, the container should be redirected to standard output.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Handle special-case commands first
|
||||
@@ -47,74 +67,306 @@ if [ "${TARGET}" = "ALL" ]; then
|
||||
error_exit "Batch export is unsupported."
|
||||
fi
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 0 ]; then
|
||||
if [ $# -gt 5 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
OPTION="${1}"
|
||||
EXPATH="${2}"
|
||||
zfs_enable_check() {
|
||||
# Temporarily disable ZFS so we can create a standard backup archive
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
bastille_zfs_enable="NO"
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle some options
|
||||
if [ -n "${OPTION}" ]; then
|
||||
if [ "${OPTION}" = "-t" -o "${OPTION}" = "--txz" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
# Temporarily disable ZFS so we can create a standard backup archive
|
||||
bastille_zfs_enable="NO"
|
||||
fi
|
||||
elif echo "${OPTION}" | grep -q "\/"; then
|
||||
if [ -d "${OPTION}" ]; then
|
||||
EXPATH="${OPTION}"
|
||||
else
|
||||
error_exit "Error: Path not found."
|
||||
fi
|
||||
else
|
||||
error_notify "Invalid option!"
|
||||
usage
|
||||
TARGET="${1}"
|
||||
GZIP_EXPORT=
|
||||
XZ_EXPORT=
|
||||
SAFE_EXPORT=
|
||||
USER_EXPORT=
|
||||
RAW_EXPORT=
|
||||
DIR_EXPORT=
|
||||
TXZ_EXPORT=
|
||||
TGZ_EXPORT=
|
||||
OPT_ZSEND="-R"
|
||||
COMP_OPTION="0"
|
||||
|
||||
opt_count() {
|
||||
COMP_OPTION=$(expr ${COMP_OPTION} + 1)
|
||||
}
|
||||
|
||||
if [ -n "${bastille_export_options}" ]; then
|
||||
# Overrides the case options by the user defined option(s) automatically.
|
||||
# Add bastille_export_options="--optionA --optionB" to bastille.conf, or simply `export bastille_export_options="--optionA --optionB"` environment variable.
|
||||
# To restore the standard case options, empty bastille_export_options="" in bastille.conf, or `unset bastille_export_options` environment variable.
|
||||
# Reference "/bastille/issues/443"
|
||||
|
||||
DEFAULT_EXPORT_OPTS="${bastille_export_options}"
|
||||
info "Default export option(s): '${DEFAULT_EXPORT_OPTS}'"
|
||||
|
||||
for opt in ${DEFAULT_EXPORT_OPTS}; do
|
||||
case "${opt}" in
|
||||
--gz)
|
||||
GZIP_EXPORT="1"
|
||||
opt_count
|
||||
shift;;
|
||||
--xz)
|
||||
XZ_EXPORT="1"
|
||||
opt_count
|
||||
shift;;
|
||||
--tgz)
|
||||
TGZ_EXPORT="1"
|
||||
opt_count
|
||||
zfs_enable_check
|
||||
shift;;
|
||||
--txz)
|
||||
TXZ_EXPORT="1"
|
||||
opt_count
|
||||
zfs_enable_check
|
||||
shift;;
|
||||
--safe)
|
||||
SAFE_EXPORT="1"
|
||||
shift;;
|
||||
--raw)
|
||||
RAW_EXPORT="1"
|
||||
opt_count
|
||||
shift ;;
|
||||
--verbose)
|
||||
OPT_ZSEND="-Rv"
|
||||
shift;;
|
||||
-*|--*) error_notify "Unknown Option."
|
||||
usage;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
# Handle and parse option args
|
||||
while [ $# -gt 0 ]; do
|
||||
case "${1}" in
|
||||
--gz)
|
||||
GZIP_EXPORT="1"
|
||||
TARGET="${2}"
|
||||
opt_count
|
||||
shift
|
||||
;;
|
||||
--xz)
|
||||
XZ_EXPORT="1"
|
||||
TARGET="${2}"
|
||||
opt_count
|
||||
shift
|
||||
;;
|
||||
--tgz)
|
||||
TGZ_EXPORT="1"
|
||||
TARGET="${2}"
|
||||
opt_count
|
||||
zfs_enable_check
|
||||
shift
|
||||
;;
|
||||
--txz)
|
||||
TXZ_EXPORT="1"
|
||||
TARGET="${2}"
|
||||
opt_count
|
||||
zfs_enable_check
|
||||
shift
|
||||
;;
|
||||
-s|--safe)
|
||||
SAFE_EXPORT="1"
|
||||
TARGET="${2}"
|
||||
shift
|
||||
;;
|
||||
-r|--raw)
|
||||
RAW_EXPORT="1"
|
||||
TARGET="${2}"
|
||||
opt_count
|
||||
shift
|
||||
;;
|
||||
-v|--verbose)
|
||||
OPT_ZSEND="-Rv"
|
||||
TARGET="${2}"
|
||||
shift
|
||||
;;
|
||||
-*|--*)
|
||||
error_notify "Unknown Option."
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if echo "${1}" | grep -q "\/"; then
|
||||
DIR_EXPORT="${1}"
|
||||
else
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# Validate for combined options
|
||||
if [ "${COMP_OPTION}" -gt "1" ]; then
|
||||
error_exit "Error: Only one compression format can be used during export."
|
||||
fi
|
||||
|
||||
if [ -n "${TXZ_EXPORT}" -o -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then
|
||||
error_exit "Error: Simple archive modes with safe ZFS export can't be used together."
|
||||
fi
|
||||
|
||||
if [ -z "${bastille_zfs_enable}" ]; then
|
||||
if [ -n "${GZIP_EXPORT}" -o -n "${RAW_EXPORT}" -o -n "${SAFE_EXPORT}" -o "${OPT_ZSEND}" = "-Rv" ]; then
|
||||
error_exit "Options --gz, --raw, --safe, --verbose are valid for ZFS configured systems only."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${SAFE_EXPORT}" ]; then
|
||||
# Check if container is running, otherwise just ignore
|
||||
if [ -z "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
SAFE_EXPORT=
|
||||
fi
|
||||
fi
|
||||
|
||||
# Export directory check
|
||||
if [ -n "${EXPATH}" ]; then
|
||||
if [ -d "${EXPATH}" ]; then
|
||||
if [ -n "${DIR_EXPORT}" ]; then
|
||||
if [ -d "${DIR_EXPORT}" ]; then
|
||||
# Set the user defined export directory
|
||||
bastille_backupsdir="${EXPATH}"
|
||||
bastille_backupsdir="${DIR_EXPORT}"
|
||||
else
|
||||
error_exit "Error: Path not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
jail_export()
|
||||
{
|
||||
# Fallback to default if missing config parameters
|
||||
if [ -z "${bastille_compress_xz_options}" ]; then
|
||||
bastille_compress_xz_options="-0 -v"
|
||||
fi
|
||||
if [ -z "${bastille_compress_gz_options}" ]; then
|
||||
bastille_compress_gz_options="-1 -v"
|
||||
fi
|
||||
|
||||
create_zfs_snap() {
|
||||
# Take a recursive temporary snapshot
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
info "Creating temporary ZFS snapshot for export..."
|
||||
fi
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}"
|
||||
}
|
||||
|
||||
clean_zfs_snap() {
|
||||
# Cleanup the recursive temporary snapshot
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_${TARGET}_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}"
|
||||
}
|
||||
|
||||
export_check() {
|
||||
# Inform the user about the exporting method
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ -n "${SAFE_EXPORT}" ]; then
|
||||
EXPORT_AS="Safely exporting"
|
||||
else
|
||||
EXPORT_AS="Hot exporting"
|
||||
fi
|
||||
else
|
||||
EXPORT_AS="Exporting"
|
||||
fi
|
||||
|
||||
if [ "${FILE_EXT}" = ".xz" -o "${FILE_EXT}" = ".gz" -o "${FILE_EXT}" = "" ]; then
|
||||
EXPORT_TYPE="image"
|
||||
else
|
||||
EXPORT_TYPE="archive"
|
||||
fi
|
||||
|
||||
if [ -n "${RAW_EXPORT}" ]; then
|
||||
EXPORT_INFO="to a raw ${EXPORT_TYPE}"
|
||||
else
|
||||
EXPORT_INFO="to a compressed ${FILE_EXT} ${EXPORT_TYPE}"
|
||||
fi
|
||||
|
||||
info "${EXPORT_AS} '${TARGET}' ${EXPORT_INFO}..."
|
||||
fi
|
||||
|
||||
# Safely stop and snapshot the jail
|
||||
if [ -n "${SAFE_EXPORT}" ]; then
|
||||
bastille stop ${TARGET}
|
||||
create_zfs_snap
|
||||
bastille start ${TARGET}
|
||||
else
|
||||
create_zfs_snap
|
||||
fi
|
||||
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
info "Sending ZFS data stream..."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
jail_export() {
|
||||
# Attempt to export the container
|
||||
DATE=$(date +%F-%H%M%S)
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
FILE_EXT="xz"
|
||||
info "Exporting '${TARGET}' to a compressed .${FILE_EXT} archive."
|
||||
info "Sending ZFS data stream..."
|
||||
# Take a recursive temporary snapshot
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
|
||||
if [ -n "${RAW_EXPORT}" ]; then
|
||||
FILE_EXT=""
|
||||
export_check
|
||||
|
||||
# Export the container recursively and cleanup temporary snapshots
|
||||
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}"
|
||||
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}"
|
||||
# Export the raw container recursively and cleanup temporary snapshots
|
||||
zfs send ${OPT_ZSEND} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}" \
|
||||
> "${bastille_backupsdir}/${TARGET}_${DATE}"
|
||||
clean_zfs_snap
|
||||
elif [ -n "${GZIP_EXPORT}" ]; then
|
||||
FILE_EXT=".gz"
|
||||
export_check
|
||||
|
||||
# Export the raw container recursively and cleanup temporary snapshots
|
||||
zfs send ${OPT_ZSEND} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}" | \
|
||||
gzip ${bastille_compress_gz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"
|
||||
clean_zfs_snap
|
||||
elif [ -n "${XZ_EXPORT}" ]; then
|
||||
FILE_EXT=".xz"
|
||||
export_check
|
||||
|
||||
# Export the container recursively and cleanup temporary snapshots
|
||||
zfs send ${OPT_ZSEND} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}" | \
|
||||
xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"
|
||||
clean_zfs_snap
|
||||
else
|
||||
FILE_EXT=""
|
||||
USER_EXPORT="1"
|
||||
export_check
|
||||
|
||||
# Quietly export the container recursively, user must redirect standard output
|
||||
if ! zfs send ${OPT_ZSEND} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}"; then
|
||||
clean_zfs_snap
|
||||
error_notify "\nError: An export option is required, see 'bastille export, otherwise the user must redirect to standard output."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Create standard backup archive
|
||||
FILE_EXT="txz"
|
||||
info "Exporting '${TARGET}' to a compressed .${FILE_EXT} archive..."
|
||||
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
|
||||
if [ -n "${TGZ_EXPORT}" ]; then
|
||||
FILE_EXT=".tgz"
|
||||
|
||||
# Create standard tgz backup archive
|
||||
info "Exporting '${TARGET}' to a compressed ${FILE_EXT} archive..."
|
||||
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | gzip ${bastille_compress_gz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"
|
||||
elif [ -n "${TXZ_EXPORT}" ]; then
|
||||
FILE_EXT=".txz"
|
||||
|
||||
# Create standard txz backup archive
|
||||
info "Exporting '${TARGET}' to a compressed ${FILE_EXT} archive..."
|
||||
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"
|
||||
else
|
||||
error_exit "Error: export option required"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_exit "Failed to export '${TARGET}' container."
|
||||
else
|
||||
# Generate container checksum file
|
||||
cd "${bastille_backupsdir}"
|
||||
sha256 -q "${TARGET}_${DATE}.${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
|
||||
info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}' successfully."
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
# Generate container checksum file
|
||||
cd "${bastille_backupsdir}"
|
||||
sha256 -q "${TARGET}_${DATE}${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
|
||||
info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}' successfully."
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
@@ -124,12 +376,17 @@ if [ ! -d "${bastille_backupsdir}" ]; then
|
||||
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
# Check if is a ZFS system
|
||||
if [ "${bastille_zfs_enable}" != "YES" ]; then
|
||||
# Check if container is running and ask for stop in UFS systems
|
||||
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "${TARGET} is running. See 'bastille stop'."
|
||||
if [ -n "${TARGET}" ]; then
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
error_exit "[${TARGET}]: Not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
jail_export
|
||||
# Check if is a ZFS system
|
||||
if [ "${bastille_zfs_enable}" != "YES" ]; then
|
||||
# Check if container is running and ask for stop in non ZFS systems
|
||||
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "${TARGET} is running. See 'bastille stop'."
|
||||
fi
|
||||
fi
|
||||
jail_export
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -47,7 +47,7 @@ if [ $# -ne 0 ]; then
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
bastille_jail_path=$(jls -j "${_jail}" path)
|
||||
bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path)
|
||||
if [ ! -x "${bastille_jail_path}/usr/local/bin/htop" ]; then
|
||||
error_notify "htop not found on ${_jail}."
|
||||
elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,7 +32,20 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille import file [option]"
|
||||
# Build an independent usage for the import command
|
||||
# If no file/extension specified, will import from standard input
|
||||
error_notify "Usage: bastille import [option(s)] FILE"
|
||||
|
||||
cat << EOF
|
||||
Options:
|
||||
|
||||
-f | --force -- Force an archive import regardless if the checksum file does not match or missing.
|
||||
-v | --verbose -- Be more verbose during the ZFS receive operation.
|
||||
|
||||
Tip: If no option specified, container should be imported from standard input.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Handle special-case commands first
|
||||
@@ -42,39 +55,70 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -gt 3 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
OPTION="${2}"
|
||||
shift
|
||||
OPT_FORCE=
|
||||
USER_IMPORT=
|
||||
OPT_ZRECV="-u"
|
||||
|
||||
# Handle and parse option args
|
||||
while [ $# -gt 0 ]; do
|
||||
case "${1}" in
|
||||
-f|--force)
|
||||
OPT_FORCE="1"
|
||||
TARGET="${2}"
|
||||
shift
|
||||
;;
|
||||
-v|--verbose)
|
||||
OPT_ZRECV="-u -v"
|
||||
TARGET="${2}"
|
||||
shift
|
||||
;;
|
||||
-*|--*)
|
||||
error_notify "Unknown Option."
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Fallback to default if missing config parameters
|
||||
if [ -z "${bastille_decompress_xz_options}" ]; then
|
||||
bastille_decompress_xz_options="-c -d -v"
|
||||
fi
|
||||
if [ -z "${bastille_decompress_gz_options}" ]; then
|
||||
bastille_decompress_gz_options="-k -d -c -v"
|
||||
fi
|
||||
|
||||
validate_archive() {
|
||||
# Compare checksums on the target archive
|
||||
# Skip validation for unsupported archives
|
||||
if [ "${FILE_EXT}" != ".tar.gz" ] && [ "${FILE_EXT}" != ".tar" ]; then
|
||||
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
|
||||
if [ -f "${bastille_backupsdir}/${FILE_TRIM}.sha256" ]; then
|
||||
info "Validating file: ${TARGET}..."
|
||||
SHA256_DIST=$(cat "${bastille_backupsdir}/${FILE_TRIM}.sha256")
|
||||
SHA256_FILE=$(sha256 -q "${bastille_backupsdir}/${TARGET}")
|
||||
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
|
||||
error_exit "Failed validation for ${TARGET}."
|
||||
else
|
||||
info "File validation successful!"
|
||||
fi
|
||||
# Skip validation for unsupported archive
|
||||
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
|
||||
if [ -f "${bastille_backupsdir}/${FILE_TRIM}.sha256" ]; then
|
||||
info "Validating file: ${TARGET}..."
|
||||
SHA256_DIST=$(cat "${bastille_backupsdir}/${FILE_TRIM}.sha256")
|
||||
SHA256_FILE=$(sha256 -q "${bastille_backupsdir}/${TARGET}")
|
||||
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
|
||||
error_exit "Failed validation for ${TARGET}."
|
||||
else
|
||||
# Check if user opt to force import
|
||||
if [ "${OPTION}" = "-f" -o "${OPTION}" = "force" ]; then
|
||||
warn "Warning: Skipping archive validation!"
|
||||
else
|
||||
error_exit "Checksum file not found. See 'bastille import TARGET -f'."
|
||||
fi
|
||||
info "File validation successful!"
|
||||
fi
|
||||
else
|
||||
# Check if user opt to force import
|
||||
if [ -n "${OPT_FORCE}" ]; then
|
||||
warn "Warning: Skipping archive validation!"
|
||||
else
|
||||
error_exit "Checksum file not found. See 'bastille import [option(s)] FILE'."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
warn "Warning: Skipping archive validation!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -129,6 +173,7 @@ 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
|
||||
info "Generating jail.conf..."
|
||||
DEVFS_RULESET=4
|
||||
|
||||
if [ "${FILE_EXT}" = ".zip" ]; then
|
||||
# Gather some bits from foreign/iocage config files
|
||||
@@ -136,63 +181,88 @@ generate_config() {
|
||||
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://')
|
||||
DEVFS_RULESET=$(grep -wo '\"devfs_ruleset\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/devfs_ruleset://')
|
||||
DEVFS_RULESET=${DEVFS_RULESET:-4}
|
||||
IS_THIN_JAIL=$(grep -wo '\"basejail\": .*' "${JSON_CONFIG}" | tr -d '" ,' | sed 's/basejail://')
|
||||
CONFIG_RELEASE=$(grep -wo '\"release\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/release://' | sed 's/\-[pP].*//')
|
||||
IS_VNET_JAIL=$(grep -wo '\"vnet\": .*' "${JSON_CONFIG}" | tr -d '" ,' | sed 's/vnet://')
|
||||
VNET_DEFAULT_INTERFACE=$(grep -wo '\"vnet_default_interface\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/vnet_default_interface://')
|
||||
ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED=1
|
||||
if [ "${VNET_DEFAULT_INTERFACE}" = "auto" ]; then
|
||||
# Grab the default ipv4 route from netstat and pull out the interface
|
||||
VNET_DEFAULT_INTERFACE=$(netstat -nr4 | grep default | cut -w -f 4)
|
||||
fi
|
||||
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=//")
|
||||
CONFIG_RELEASE=$(echo ${PROP_CONFIG} | grep -o '[0-9]\{2\}\.[0-9]_RELEASE' | sed 's/_/-/g')
|
||||
fi
|
||||
# Always assume it's thin for ezjail
|
||||
IS_THIN_JAIL=1
|
||||
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
|
||||
# See if we need to generate a vnet network section
|
||||
if [ "${IS_VNET_JAIL:-0}" = "1" ]; then
|
||||
NETBLOCK=$(generate_vnet_jail_netblock "${TARGET_TRIM}" "" "${VNET_DEFAULT_INTERFACE}")
|
||||
else
|
||||
# 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
|
||||
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
|
||||
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"
|
||||
warn "Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration."
|
||||
fi
|
||||
|
||||
NETBLOCK=$(cat <<-EOF
|
||||
interface = ${NETIF_CONFIG};
|
||||
${IPX_ADDR} = ${IP_CONFIG};
|
||||
ip6 = ${IP6_MODE};
|
||||
EOF
|
||||
)
|
||||
fi
|
||||
|
||||
# Let the user configure network manually
|
||||
if [ -z "${NETIF_CONFIG}" ]; then
|
||||
NETIF_CONFIG="lo1"
|
||||
IPX_ADDR="ip4.addr"
|
||||
IP_CONFIG="-"
|
||||
IP6_MODE="disable"
|
||||
warn "Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration."
|
||||
fi
|
||||
|
||||
if [ "${FILE_EXT}" = ".tar.gz" ]; then
|
||||
CONFIG_RELEASE=$(echo ${PROP_CONFIG} | grep -o '[0-9]\{2\}\.[0-9]_RELEASE' | sed 's/_/-/g')
|
||||
if [ "${IS_THIN_JAIL:-0}" = "1" ]; then
|
||||
if [ -z "${CONFIG_RELEASE}" ]; then
|
||||
# Fallback to host version
|
||||
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
|
||||
@@ -213,7 +283,7 @@ generate_config() {
|
||||
# Generate a basic jail configuration file on foreign imports
|
||||
cat << EOF > "${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
|
||||
${TARGET_TRIM} {
|
||||
devfs_ruleset = 4;
|
||||
devfs_ruleset = ${DEVFS_RULESET};
|
||||
enforce_statfs = 2;
|
||||
exec.clean;
|
||||
exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;
|
||||
@@ -225,9 +295,7 @@ ${TARGET_TRIM} {
|
||||
path = ${bastille_jailsdir}/${TARGET_TRIM}/root;
|
||||
securelevel = 2;
|
||||
|
||||
interface = ${NETIF_CONFIG};
|
||||
${IPX_ADDR} = ${IP_CONFIG};
|
||||
ip6 = ${IP6_MODE};
|
||||
${NETBLOCK}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
@@ -290,6 +358,13 @@ update_symlinks() {
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ -L "${_link}" ]; then
|
||||
ln -sf /.bastille/${_link} ${_link}
|
||||
elif [ "${ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED:-0}" = "1" -a -d "${_link}" ]; then
|
||||
# -F will enforce that the directory is empty and replaced by the symlink
|
||||
ln -sfF /.bastille/${_link} ${_link} || EXIT_CODE=$?
|
||||
if [ "${EXIT_CODE:-0}" != "0" ]; then
|
||||
# Assume that the failure was due to the directory not being empty and explain the problem in friendlier terms
|
||||
warn "Warning: directory ${_link} on imported jail was not empty and will not be updated by Bastille"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -313,23 +388,34 @@ remove_zfs_datasets() {
|
||||
|
||||
jail_import() {
|
||||
# Attempt to import container from file
|
||||
FILE_TRIM=$(echo "${TARGET}" | sed 's/\.xz//g;s/\.txz//g;s/\.zip//g;s/\.tar\.gz//g;s/\.tar//g')
|
||||
FILE_TRIM=$(echo "${TARGET}" | sed 's/\.xz//g;s/\.gz//g;s/\.tgz//g;s/\.txz//g;s/\.zip//g;s/\.tar\.gz//g;s/\.tar//g')
|
||||
FILE_EXT=$(echo "${TARGET}" | sed "s/${FILE_TRIM}//g")
|
||||
validate_archive
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
if [ "${FILE_EXT}" = ".xz" ]; then
|
||||
validate_archive
|
||||
# Import from compressed xz on ZFS systems
|
||||
info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} archive."
|
||||
info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} image."
|
||||
info "Receiving ZFS data stream..."
|
||||
xz ${bastille_decompress_xz_options} "${bastille_backupsdir}/${TARGET}" | \
|
||||
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
elif [ "${FILE_EXT}" = ".gz" ]; then
|
||||
validate_archive
|
||||
# Import from compressed xz on ZFS systems
|
||||
info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} image."
|
||||
info "Receiving ZFS data stream..."
|
||||
gzip ${bastille_decompress_gz_options} "${bastille_backupsdir}/${TARGET}" | \
|
||||
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
|
||||
elif [ "${FILE_EXT}" = ".txz" ]; then
|
||||
validate_archive
|
||||
# Prepare the ZFS environment and restore from existing .txz file
|
||||
create_zfs_datasets
|
||||
|
||||
@@ -340,7 +426,20 @@ jail_import() {
|
||||
if [ "$?" -ne 0 ]; then
|
||||
remove_zfs_datasets
|
||||
fi
|
||||
elif [ "${FILE_EXT}" = ".tgz" ]; then
|
||||
validate_archive
|
||||
# Prepare the ZFS environment and restore from existing .tgz file
|
||||
create_zfs_datasets
|
||||
|
||||
# Extract required files to the new datasets
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar --exclude='root' -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components 2 -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${TARGET_TRIM}/root"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
remove_zfs_datasets
|
||||
fi
|
||||
elif [ "${FILE_EXT}" = ".zip" ]; then
|
||||
validate_archive
|
||||
# Attempt to import a foreign/iocage container
|
||||
info "Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
|
||||
# Sane bastille ZFS options
|
||||
@@ -353,9 +452,9 @@ jail_import() {
|
||||
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
|
||||
fi
|
||||
info "Receiving ZFS data stream..."
|
||||
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${FILE_TRIM}"
|
||||
zfs receive ${OPT_ZRECV} "${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"
|
||||
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root"
|
||||
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
@@ -403,6 +502,27 @@ jail_import() {
|
||||
else
|
||||
update_config
|
||||
fi
|
||||
elif [ -z "${FILE_EXT}" ]; then
|
||||
if echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$'; then
|
||||
validate_archive
|
||||
# Based on the file name, looks like we are importing a raw bastille image
|
||||
# Import from uncompressed image file
|
||||
info "Importing '${TARGET_TRIM}' from uncompressed image archive."
|
||||
info "Receiving ZFS data stream..."
|
||||
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${bastille_backupsdir}/${TARGET}"
|
||||
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
else
|
||||
# Based on the file name, looks like we are importing from previous redirected bastille image
|
||||
# Quietly import from previous redirected bastille image
|
||||
if ! zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"; then
|
||||
exit 1
|
||||
else
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
fi
|
||||
fi
|
||||
else
|
||||
error_exit "Unknown archive format."
|
||||
fi
|
||||
@@ -412,6 +532,9 @@ jail_import() {
|
||||
if [ "${FILE_EXT}" = ".txz" ]; then
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar -Jxf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
elif [ "${FILE_EXT}" = ".tgz" ]; then
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
|
||||
# Attempt to import/configure foreign/ezjail container
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
@@ -442,7 +565,9 @@ jail_import() {
|
||||
# This is required on foreign imports only
|
||||
update_jailconf
|
||||
update_fstab
|
||||
info "Container '${TARGET_TRIM}' imported successfully."
|
||||
if [ -z "${USER_IMPORT}" ]; then
|
||||
info "Container '${TARGET_TRIM}' imported successfully."
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
@@ -465,22 +590,32 @@ fi
|
||||
# Check if archive exist then trim archive name
|
||||
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
|
||||
# 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 echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[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\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.gz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.tgz$\|_[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//")
|
||||
TARGET_TRIM=$(echo "${TARGET}" | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.xz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.gz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.tgz//;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//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*//")
|
||||
fi
|
||||
else
|
||||
error_exit "Unrecognized archive name."
|
||||
fi
|
||||
else
|
||||
error_exit "Archive '${TARGET}' not found."
|
||||
if echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*$'; then
|
||||
error_exit "Archive '${TARGET}' not found."
|
||||
else
|
||||
# Assume user will import from standard input
|
||||
TARGET_TRIM=${TARGET}
|
||||
USER_IMPORT="1"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if a running jail matches name or already exist
|
||||
if [ -n "$(jls name | awk "/^${TARGET_TRIM}$/")" ]; then
|
||||
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET_TRIM}$/")" ]; then
|
||||
error_exit "A running jail matches name."
|
||||
elif [ -d "${bastille_jailsdir}/${TARGET_TRIM}" ]; then
|
||||
error_exit "Container: ${TARGET_TRIM} already exists."
|
||||
elif [ -n "${TARGET_TRIM}" ]; then
|
||||
if [ -d "${bastille_jailsdir}/${TARGET_TRIM}" ]; then
|
||||
error_exit "Container: ${TARGET_TRIM} already exists."
|
||||
fi
|
||||
fi
|
||||
|
||||
jail_import
|
||||
if [ -n "${TARGET}" ]; then
|
||||
jail_import
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
# Ressource limits added by Sven R github.com/hackacad
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,15 +32,15 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille list [-j] [release|template|(jail|container)|log|limit|(import|export|backup)]"
|
||||
error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]"
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
jls -N
|
||||
/usr/sbin/jls -N
|
||||
fi
|
||||
|
||||
if [ "$1" == "-j" ]; then
|
||||
jls -N --libxo json
|
||||
/usr/sbin/jls -N --libxo json
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -50,12 +50,117 @@ if [ $# -gt 0 ]; then
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
all|-a|--all)
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
DEFAULT_VALUE="-"
|
||||
SPACER=2
|
||||
MAX_LENGTH_JAIL_NAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_JAIL_NAME=${MAX_LENGTH_JAIL_NAME:-3}
|
||||
if [ ${MAX_LENGTH_JAIL_NAME} -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi
|
||||
MAX_LENGTH_JAIL_IP=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1 /p" | sed 's/\// /g' | awk '{ print length($1) }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_IP:-10}
|
||||
MAX_LENGTH_JAIL_VNET_IP=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" $(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p") | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_JAIL_VNET_IP=${MAX_LENGTH_JAIL_VNET_IP:-10}
|
||||
if [ ${MAX_LENGTH_JAIL_VNET_IP} -gt ${MAX_LENGTH_JAIL_IP} ]; then MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_VNET_IP}; fi
|
||||
if [ ${MAX_LENGTH_JAIL_IP} -lt 10 ]; then MAX_LENGTH_JAIL_IP=10; fi
|
||||
MAX_LENGTH_JAIL_HOSTNAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^[ ]*host.hostname[ ]*=[ ]*\(.*\);" | awk '{ print length(substr($3, 1, length($3)-1)) }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_JAIL_HOSTNAME=${MAX_LENGTH_JAIL_HOSTNAME:-8}
|
||||
if [ ${MAX_LENGTH_JAIL_HOSTNAME} -lt 8 ]; then MAX_LENGTH_JAIL_HOSTNAME=8; fi
|
||||
MAX_LENGTH_JAIL_PORTS=$(find ""${bastille_jailsdir}/*/rdr.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 -n1 awk '{ lines++; chars += length($0)} END { chars += lines - 1; print chars }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_JAIL_PORTS=${MAX_LENGTH_JAIL_PORTS:-15}
|
||||
if [ ${MAX_LENGTH_JAIL_PORTS} -lt 15 ]; then MAX_LENGTH_JAIL_PORTS=15; fi
|
||||
if [ ${MAX_LENGTH_JAIL_PORTS} -gt 30 ]; then MAX_LENGTH_JAIL_PORTS=30; fi
|
||||
MAX_LENGTH_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/fstab"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_JAIL_RELEASE:-7}
|
||||
MAX_LENGTH_THICK_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/root/bin/freebsd-version"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -hE "^USERLAND_VERSION=" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_THICK_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE:-7}
|
||||
MAX_LENGTH_LINUX_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/fstab"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" $(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p") 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_LINUX_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE:-7}
|
||||
if [ ${MAX_LENGTH_THICK_JAIL_RELEASE} -gt ${MAX_LENGTH_JAIL_RELEASE} ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE}; fi
|
||||
if [ ${MAX_LENGTH_LINUX_JAIL_RELEASE} -gt ${MAX_LENGTH_JAIL_RELEASE} ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE}; fi
|
||||
if [ ${MAX_LENGTH_JAIL_RELEASE} -lt 7 ]; then MAX_LENGTH_JAIL_RELEASE=7; fi
|
||||
printf " JID%*sState%*sIP Address%*sPublished Ports%*sHostname%*sRelease%*sPath\n" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 3))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} + ${SPACER} - 8))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" ""
|
||||
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
|
||||
for _JAIL in ${JAIL_LIST}; do
|
||||
if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then
|
||||
JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }')
|
||||
IS_FREEBSD_JAIL=0
|
||||
if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" -o -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" -o "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi
|
||||
IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0}
|
||||
IS_LINUX_JAIL=0
|
||||
if [ "$(grep -c "^linprocfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_LINUX_JAIL=1; fi
|
||||
IS_LINUX_JAIL=${IS_LINUX_JAIL:-0}
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${JAIL_NAME}$/")" ]; then
|
||||
JAIL_STATE="Up"
|
||||
if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then
|
||||
JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet 2> /dev/null | sed -n "/.inet /{s///;s/ .*//;p;}")
|
||||
if [ ! ${JAIL_IP} ]; then JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet6 2> /dev/null | awk '/inet6 / && (!/fe80::/ || !/%vnet0/)' | sed -n "/.inet6 /{s///;s/ .*//;p;}"); fi
|
||||
else
|
||||
JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip4.addr 2> /dev/null)
|
||||
if [ ${JAIL_IP} = "-" ]; then JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip6.addr 2> /dev/null); fi
|
||||
fi
|
||||
JAIL_HOSTNAME=$(/usr/sbin/jls -j ${JAIL_NAME} host.hostname 2> /dev/null)
|
||||
JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s/%s:%s"",",$7,$14,$18 }' | sed "s/,$//")
|
||||
JAIL_PATH=$(/usr/sbin/jls -j ${JAIL_NAME} path 2> /dev/null)
|
||||
if [ ${IS_FREEBSD_JAIL} -eq 1 ]; then
|
||||
JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null)
|
||||
fi
|
||||
if [ ${IS_LINUX_JAIL} -eq 1 ]; then
|
||||
JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }')
|
||||
fi
|
||||
else
|
||||
JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" == "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi)
|
||||
if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then
|
||||
JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }')
|
||||
else
|
||||
JAIL_IP=$(sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | sed "s/\// /g" | awk '{ print $1 }')
|
||||
fi
|
||||
JAIL_HOSTNAME=$(sed -n "s/^[ ]*host.hostname[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)
|
||||
if [ -f "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" ]; then JAIL_PORTS=$(awk '$1 ~ /^[tcp|udp]/ { printf "%s/%s:%s,",$1,$2,$3 }' "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" 2> /dev/null | sed "s/,$//"); else JAIL_PORTS=""; fi
|
||||
JAIL_PATH=$(sed -n "s/^[ ]*path[ ]*=[ ]*\(.*\);$/\1/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)
|
||||
if [ ${JAIL_PATH} ]; then
|
||||
if [ ${IS_FREEBSD_JAIL} -eq 1 ]; then
|
||||
if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then
|
||||
JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p")
|
||||
else
|
||||
JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p")
|
||||
fi
|
||||
fi
|
||||
if [ ${IS_LINUX_JAIL} -eq 1 ]; then
|
||||
JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }')
|
||||
fi
|
||||
else
|
||||
JAIL_RELEASE=""
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ${#JAIL_PORTS} -gt ${MAX_LENGTH_JAIL_PORTS} ]; then JAIL_PORTS="$(echo ${JAIL_PORTS} | cut -c-$((${MAX_LENGTH_JAIL_PORTS} - 3)))..."; fi
|
||||
JAIL_NAME=${JAIL_NAME:-${DEFAULT_VALUE}}
|
||||
JAIL_STATE=${JAIL_STATE:-${DEFAULT_VALUE}}
|
||||
JAIL_IP=${JAIL_IP:-${DEFAULT_VALUE}}
|
||||
JAIL_PORTS=${JAIL_PORTS:-${DEFAULT_VALUE}}
|
||||
JAIL_HOSTNAME=${JAIL_HOSTNAME:-${DEFAULT_VALUE}}
|
||||
JAIL_RELEASE=${JAIL_RELEASE:-${DEFAULT_VALUE}}
|
||||
JAIL_PATH=${JAIL_PATH:-${DEFAULT_VALUE}}
|
||||
printf " ${JAIL_NAME}%*s${JAIL_STATE}%*s${JAIL_IP}%*s${JAIL_PORTS}%*s${JAIL_HOSTNAME}%*s${JAIL_RELEASE}%*s${JAIL_PATH}\n" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" "$((5 - ${#JAIL_STATE} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} - ${#JAIL_IP} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_PORTS} - ${#JAIL_PORTS} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} - ${#JAIL_HOSTNAME} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_RELEASE} - ${#JAIL_RELEASE} + ${SPACER}))" ""
|
||||
fi
|
||||
done
|
||||
else
|
||||
error_exit "unfortunately there are no jails here (${bastille_jailsdir})"
|
||||
fi
|
||||
;;
|
||||
release|releases)
|
||||
if [ -d "${bastille_releasesdir}" ]; then
|
||||
REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g")
|
||||
for _REL in ${REL_LIST}; do
|
||||
if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" ]; then
|
||||
echo "${_REL}"
|
||||
if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" -o -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then
|
||||
if [ "$2" == "-p" -a -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then
|
||||
REL_PATCH_LEVEL=$(sed -n "s/^USERLAND_VERSION=\"\(.*\)\"$/\1/p" "${bastille_releasesdir}/${_REL}/bin/freebsd-version" 2> /dev/null)
|
||||
REL_PATCH_LEVEL=${REL_PATCH_LEVEL:-${_REL}}
|
||||
echo "${REL_PATCH_LEVEL}"
|
||||
else
|
||||
echo "${_REL}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
@@ -80,7 +185,7 @@ if [ $# -gt 0 ]; then
|
||||
rctl -h jail:
|
||||
;;
|
||||
import|imports|export|exports|backup|backups)
|
||||
ls "${bastille_backupsdir}" | grep -Ev "*.sha256"
|
||||
ls "${bastille_backupsdir}" | grep -v ".sha256$"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -93,24 +93,25 @@ for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
|
||||
## aggregate variables into FSTAB entry
|
||||
_jailpath="${bastille_jailsdir}/${_jail}/root/${_jailpath}"
|
||||
_fstab_entry="${_hostpath} ${_jailpath} ${_type} ${_perms} ${_checks}"
|
||||
_fullpath="${bastille_jailsdir}/${_jail}/root/${_jailpath}"
|
||||
_fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}"
|
||||
|
||||
## Create mount point if it does not exist. -- cwells
|
||||
if [ ! -d "${bastille_jailsdir}/${_jail}/root/${_jailpath}" ]; then
|
||||
if ! mkdir -p "${bastille_jailsdir}/${_jail}/root/${_jailpath}"; then
|
||||
if [ ! -d "${_fullpath}" ]; then
|
||||
if ! mkdir -p "${_fullpath}"; then
|
||||
error_exit "Failed to create mount point inside jail."
|
||||
fi
|
||||
fi
|
||||
|
||||
## if entry doesn't exist, add; else show existing entry
|
||||
if ! egrep -q "[[:blank:]]${_jailpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then
|
||||
if ! egrep -q "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then
|
||||
if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then
|
||||
error_exit "Failed to create fstab entry: ${_fstab_entry}"
|
||||
fi
|
||||
echo "Added: ${_fstab_entry}"
|
||||
else
|
||||
egrep "[[:blank:]]${_jailpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab"
|
||||
warn "Mountpoint already present in ${bastille_jailsdir}/${_jail}/fstab"
|
||||
egrep "[[:blank:]]${_fullpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab"
|
||||
fi
|
||||
mount -F "${bastille_jailsdir}/${_jail}/fstab" -a
|
||||
echo
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -31,7 +31,7 @@
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille pkg TARGET command [args]"
|
||||
error_exit "Usage: bastille pkg [-H|--host] TARGET command [args]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -47,6 +47,15 @@ fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/sbin/pkg "$@"
|
||||
bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path)
|
||||
if [ -f "/usr/sbin/mport" ]; then
|
||||
jexec -l -U root "${_jail}" /usr/sbin/mport "$@"
|
||||
elif [ -f "${bastille_jail_path}/usr/bin/apt" ]; then
|
||||
jexec -l "${_jail}" /usr/bin/apt "$@"
|
||||
elif [ "${USE_HOST_PKG}" = 1 ]; then
|
||||
/usr/sbin/pkg -j "${_jail}" "$@"
|
||||
else
|
||||
jexec -l -U root "${_jail}" /usr/sbin/pkg "$@"
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2022, 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:
|
||||
#
|
||||
@@ -29,7 +32,7 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille rdr TARGET [clear] | [list] | [tcp <host_port> <jail_port>] | [udp <host_port> <jail_port>]"
|
||||
error_exit "Usage: bastille rdr TARGET [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -44,65 +47,144 @@ if [ $# -lt 2 ]; then
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
JAIL_NAME=""
|
||||
JAIL_IP=""
|
||||
EXT_IF=""
|
||||
shift
|
||||
|
||||
# Can only redirect to single jail
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
error_exit "Can only redirect to a single jail."
|
||||
fi
|
||||
|
||||
# Check jail name valid
|
||||
JAIL_NAME=$(jls -j "${TARGET}" name 2>/dev/null)
|
||||
if [ -z "${JAIL_NAME}" ]; then
|
||||
error_exit "Jail not found: ${TARGET}"
|
||||
fi
|
||||
|
||||
# Check jail ip4 address valid
|
||||
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
|
||||
JAIL_IP=$(jls -j "${TARGET}" ip4.addr 2>/dev/null)
|
||||
if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
|
||||
error_exit "Jail IP not found: ${TARGET}"
|
||||
check_jail_validity() {
|
||||
# Can only redirect to single jail
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
error_exit "Can only redirect to a single jail."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check rdr-anchor is setup in pf.conf
|
||||
if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
|
||||
error_exit "rdr-anchor not found in pf.conf"
|
||||
fi
|
||||
# Check if jail name is valid
|
||||
JAIL_NAME=$(/usr/sbin/jls -j "${TARGET}" name 2>/dev/null)
|
||||
if [ -z "${JAIL_NAME}" ]; then
|
||||
error_exit "Jail not found: ${TARGET}"
|
||||
fi
|
||||
|
||||
# Check ext_if is setup in pf.conf
|
||||
EXT_IF=$(grep '^[[:space:]]*ext_if[[:space:]]*=' /etc/pf.conf)
|
||||
if [ -z "${JAIL_NAME}" ]; then
|
||||
error_exit "ext_if not defined in pf.conf"
|
||||
# Check if jail ip4 address (ip4.addr) is valid (non-VNET only)
|
||||
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
|
||||
JAIL_IP=$(/usr/sbin/jls -j "${TARGET}" ip4.addr 2>/dev/null)
|
||||
if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
|
||||
error_exit "Jail IP not found: ${TARGET}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if rdr-anchor is defined in pf.conf
|
||||
if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
|
||||
error_exit "rdr-anchor not found in pf.conf"
|
||||
fi
|
||||
|
||||
# Check if ext_if is defined in pf.conf
|
||||
EXT_IF=$(grep '^[[:space:]]*ext_if[[:space:]]*=' /etc/pf.conf)
|
||||
if [ -z "${EXT_IF}" ]; then
|
||||
error_exit "ext_if not defined in pf.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
# function: write rule to rdr.conf
|
||||
persist_rdr_rule() {
|
||||
if ! grep -qs "$1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then
|
||||
echo "$1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
persist_rdr_log_rule() {
|
||||
proto=$1;host_port=$2;jail_port=$3;
|
||||
shift 3;
|
||||
log=$@;
|
||||
if ! grep -qs "$proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then
|
||||
echo "$proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# function: load rdr rule via pfctl
|
||||
load_rdr_rule() {
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr pass on $ext_if inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$1" "$2" "$JAIL_IP" "$3" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
}
|
||||
|
||||
# function: load rdr rule with log via pfctl
|
||||
load_rdr_log_rule() {
|
||||
proto=$1;host_port=$2;jail_port=$3;
|
||||
shift 3;
|
||||
log=$@
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr pass %s on $ext_if inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "$proto" "$host_port" "$JAIL_IP" "$jail_port" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
list)
|
||||
pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do
|
||||
echo "${JAIL_NAME} redirects:"
|
||||
pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null
|
||||
done
|
||||
else
|
||||
check_jail_validity
|
||||
pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
clear)
|
||||
pfctl -a "rdr/${JAIL_NAME}" -Fn
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do
|
||||
echo "${JAIL_NAME} redirects:"
|
||||
pfctl -a "rdr/${JAIL_NAME}" -Fn
|
||||
done
|
||||
else
|
||||
check_jail_validity
|
||||
pfctl -a "rdr/${JAIL_NAME}" -Fn
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
tcp)
|
||||
tcp|udp)
|
||||
if [ $# -lt 3 ]; then
|
||||
usage
|
||||
elif [ $# -eq 3 ]; then
|
||||
check_jail_validity
|
||||
persist_rdr_rule $1 $2 $3
|
||||
load_rdr_rule $1 $2 $3
|
||||
shift 3
|
||||
else
|
||||
case "$4" in
|
||||
log)
|
||||
proto=$1
|
||||
host_port=$2
|
||||
jail_port=$3
|
||||
shift 3
|
||||
if [ $# -gt 3 ]; then
|
||||
for last in $@; do
|
||||
true
|
||||
done
|
||||
if [ $2 == "(" ] && [ $last == ")" ] ; then
|
||||
check_jail_validity
|
||||
persist_rdr_log_rule $proto $host_port $jail_port $@
|
||||
load_rdr_log_rule $proto $host_port $jail_port $@
|
||||
shift $#
|
||||
else
|
||||
usage
|
||||
fi
|
||||
elif [ $# -eq 1 ]; then
|
||||
check_jail_validity
|
||||
persist_rdr_log_rule $proto $host_port $jail_port $@
|
||||
load_rdr_log_rule $proto $host_port $jail_port $@
|
||||
shift 1
|
||||
else
|
||||
usage
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr on $ext_if inet proto tcp to port %s -> %s port %s\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
shift 3
|
||||
;;
|
||||
udp)
|
||||
if [ $# -lt 3 ]; then
|
||||
usage
|
||||
fi
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr on $ext_if inet proto udp to port %s -> %s port %s\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
shift 3
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -38,7 +38,9 @@ usage() {
|
||||
validate_name() {
|
||||
local NAME_VERIFY=${NEWNAME}
|
||||
local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')
|
||||
if [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
|
||||
if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then
|
||||
error_exit "Container names may not begin with (-|_) characters!"
|
||||
elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
|
||||
error_exit "Container names may not contain special characters!"
|
||||
fi
|
||||
}
|
||||
@@ -74,13 +76,22 @@ 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}"
|
||||
# Skip if fstab is empty, e.g newly created thick or clone jails
|
||||
if [ -s "${FSTAB_CONFIG}" ]; then
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_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
|
||||
|
||||
# Update linuxjail fstab name entries
|
||||
# Search for either linprocfs/linsysfs, if true assume is a linux jail
|
||||
if grep -qwE "linprocfs|linsysfs" "${FSTAB_CONFIG}"; then
|
||||
sed -i '' "s|.${bastille_jailsdir}/${TARGET}/|${bastille_jailsdir}/${NEWNAME}/|" "${FSTAB_CONFIG}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -41,7 +41,7 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
if [ $# -lt 1 -o $# -gt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -62,11 +62,11 @@ fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
## test if running
|
||||
if [ "$(jls name | awk "/^${_jail}$/")" ]; then
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then
|
||||
error_notify "[${_jail}]: Already started."
|
||||
|
||||
## test if not running
|
||||
elif [ ! "$(jls name | awk "/^${_jail}$/")" ]; then
|
||||
elif [ ! "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then
|
||||
# Verify that the configured interface exists. -- cwells
|
||||
if [ "$(bastille config $_jail get vnet)" != 'enabled' ]; then
|
||||
_interface=$(bastille config $_jail get interface)
|
||||
@@ -83,6 +83,8 @@ for _jail in ${JAILS}; do
|
||||
error_notify "Error: IP address (${ip}) already in use."
|
||||
continue
|
||||
fi
|
||||
## add ip4.addr to firewall table:jails
|
||||
pfctl -q -t jails -T add "${ip}"
|
||||
fi
|
||||
|
||||
## start the container
|
||||
@@ -102,13 +104,6 @@ for _jail in ${JAILS}; do
|
||||
bastille rdr "${_jail}" ${_rules}
|
||||
done < "${bastille_jailsdir}/${_jail}/rdr.conf"
|
||||
fi
|
||||
|
||||
## add ip4.addr to firewall table:jails
|
||||
if [ -n "${bastille_network_loopback}" ]; then
|
||||
if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
|
||||
pfctl -q -t jails -T add "$(jls -j ${_jail} ip4.addr)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -48,17 +48,16 @@ fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
## test if running
|
||||
if [ "$(jls name | awk "/^${_jail}$/")" ]; then
|
||||
## remove ip4.addr from firewall table:jails
|
||||
if [ -n "${bastille_network_loopback}" ]; then
|
||||
if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
|
||||
pfctl -q -t jails -T delete "$(jls -j ${_jail} ip4.addr)"
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then
|
||||
## Capture ip4.addr address while still running
|
||||
_ip="$(/usr/sbin/jls -j ${_jail} ip4.addr)"
|
||||
|
||||
# Check if pfctl is present
|
||||
if which -s pfctl; then
|
||||
if [ "$(bastille rdr ${_jail} list)" ]; then
|
||||
bastille rdr ${_jail} clear
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$(bastille rdr ${_jail} list)" ]; then
|
||||
bastille rdr ${_jail} clear
|
||||
fi
|
||||
|
||||
## remove rctl limits
|
||||
if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then
|
||||
@@ -70,6 +69,13 @@ for _jail in ${JAILS}; do
|
||||
## stop container
|
||||
info "[${_jail}]:"
|
||||
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}"
|
||||
|
||||
## remove (captured above) ip4.addr from firewall table:jails
|
||||
if [ -n "${bastille_network_loopback}" -a ! -z "${_ip}" ]; then
|
||||
if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
|
||||
pfctl -q -t jails -T delete "${_ip}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -42,9 +42,6 @@ post_command_hook() {
|
||||
|
||||
case $_cmd in
|
||||
rdr)
|
||||
if ! grep -qs "${_args}" "${bastille_jailsdir}/${_jail}/rdr.conf"; then
|
||||
echo "${_args}" >> "${bastille_jailsdir}/${_jail}/rdr.conf"
|
||||
fi
|
||||
echo -e ${_args}
|
||||
esac
|
||||
}
|
||||
@@ -176,7 +173,7 @@ if [ "${TARGET}" = '--convert' ]; then
|
||||
fi
|
||||
|
||||
case ${TEMPLATE} in
|
||||
http?://github.com/*/*|http?://gitlab.com/*/*)
|
||||
http?://*/*/*)
|
||||
TEMPLATE_DIR=$(echo "${TEMPLATE}" | awk -F / '{ print $4 "/" $5 }')
|
||||
if [ ! -d "${bastille_templatesdir}/${TEMPLATE_DIR}" ]; then
|
||||
info "Bootstrapping ${TEMPLATE}..."
|
||||
@@ -189,7 +186,11 @@ case ${TEMPLATE} in
|
||||
;;
|
||||
*/*)
|
||||
if [ ! -d "${bastille_templatesdir}/${TEMPLATE}" ]; then
|
||||
error_exit "${TEMPLATE} not found."
|
||||
if [ ! -d ${TEMPLATE} ]; then
|
||||
error_exit "${TEMPLATE} not found."
|
||||
else
|
||||
bastille_template=${TEMPLATE}
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
@@ -225,9 +226,10 @@ for _jail in ${JAILS}; do
|
||||
info "Applying template: ${TEMPLATE}..."
|
||||
|
||||
## jail-specific variables.
|
||||
bastille_jail_path=$(jls -j "${_jail}" path)
|
||||
bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path)
|
||||
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
|
||||
_jail_ip=$(jls -j "${_jail}" ip4.addr 2>/dev/null)
|
||||
_jail_ip=$(/usr/sbin/jls -j "${_jail}" ip4.addr 2>/dev/null)
|
||||
_jail_ip6=$(/usr/sbin/jls -j "${_jail}" ip6.addr 2>/dev/null)
|
||||
if [ -z "${_jail_ip}" -o "${_jail_ip}" = "-" ]; then
|
||||
error_notify "Jail IP not found: ${_jail}"
|
||||
_jail_ip='' # In case it was -. -- cwells
|
||||
@@ -250,7 +252,7 @@ for _jail in ${JAILS}; do
|
||||
|
||||
# Build a list of sed commands like this: -e 's/${username}/root/g' -e 's/${domain}/example.com/g'
|
||||
# Values provided by default (without being defined by the user) are listed here. -- cwells
|
||||
ARG_REPLACEMENTS="-e 's/\${JAIL_IP}/${_jail_ip}/g' -e 's/\${JAIL_NAME}/${_jail}/g'"
|
||||
ARG_REPLACEMENTS="-e 's/\${JAIL_IP}/${_jail_ip}/g' -e 's/\${JAIL_IP6}/${_jail_ip6}/g' -e 's/\${JAIL_NAME}/${_jail}/g'"
|
||||
# This is parsed outside the HOOKS loop so an ARG file can be used with a Bastillefile. -- cwells
|
||||
if [ -s "${bastille_template}/ARG" ]; then
|
||||
while read _line; do
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ARG BASE_TEMPLATE=default/base
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}"
|
||||
@@ -0,0 +1,14 @@
|
||||
PRE mkdir -p home
|
||||
PRE mkdir -p tmp
|
||||
|
||||
|
||||
FSTAB devfs root/dev devfs rw 0 0
|
||||
FSTAB tmpfs dev/shm tmpfs rw,size=1g,mode=1777 0 0
|
||||
FSTAB fdescfs dev/fd fdescfs rw,linrdlnk 0 0
|
||||
FSTAB linprocfs proc linprocfs rw 0 0
|
||||
FSTAB linsysfs sys linsysfs rw 0 0
|
||||
FSTAB /tmp tmp nullfs rw 0 0
|
||||
FSTAB /home home nullfs rw 0 0
|
||||
|
||||
CMD mkdir etc/apt/apt.conf.d/00aptitude
|
||||
CMD echo "APT::Cache-Start 251658240;" > etc/apt/apt.conf.d/00aptitude
|
||||
@@ -5,9 +5,11 @@ INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}"
|
||||
|
||||
ARG EPAIR
|
||||
ARG GATEWAY
|
||||
ARG GATEWAY6
|
||||
ARG IFCONFIG="SYNCDHCP"
|
||||
|
||||
SYSRC ifconfig_${EPAIR}_name=vnet0
|
||||
SYSRC ifconfig_vnet0="${IFCONFIG}"
|
||||
# GATEWAY will be empty for a DHCP config. -- cwells
|
||||
CMD if [ -n "${GATEWAY}" ]; then /usr/sbin/sysrc defaultrouter="${GATEWAY}"; fi
|
||||
CMD if [ -n "${GATEWAY6}" ]; then /usr/sbin/sysrc ipv6_defaultrouter="${GATEWAY6}"; fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,7 +32,7 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille update [release|container] | [option]"
|
||||
error_exit "Usage: bastille update [release|container|template] | [force]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -64,13 +64,25 @@ if [ "${TARGET}" = "ALL" ]; then
|
||||
error_exit "Batch upgrade is unsupported."
|
||||
fi
|
||||
|
||||
if [ -f "/bin/midnightbsd-version" ]; then
|
||||
echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if freebsd-version | grep -qi HBSD; then
|
||||
error_exit "Not yet supported on HardenedBSD."
|
||||
fi
|
||||
|
||||
# Check for alternate/unsupported archs
|
||||
arch_check() {
|
||||
if echo "${TARGET}" | grep -w "[0-9]\{1,2\}\.[0-9]\-RELEASE\-i386"; then
|
||||
ARCH_I386="1"
|
||||
fi
|
||||
}
|
||||
|
||||
jail_check() {
|
||||
# Check if the jail is thick and is running
|
||||
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
else
|
||||
if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
@@ -98,15 +110,61 @@ jail_update() {
|
||||
release_update() {
|
||||
# Update a release base(affects child containers)
|
||||
if [ -d "${bastille_releasesdir}/${TARGET}" ]; then
|
||||
TARGET_TRIM="${TARGET}"
|
||||
if [ -n "${ARCH_I386}" ]; then
|
||||
TARGET_TRIM=$(echo "${TARGET}" | sed 's/-i386//')
|
||||
fi
|
||||
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \
|
||||
fetch install --currently-running "${TARGET}"
|
||||
fetch install --currently-running "${TARGET_TRIM}"
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
template_update() {
|
||||
# Update a template
|
||||
_template_path=${bastille_templatesdir}/${BASTILLE_TEMPLATE}
|
||||
if [ -d $_template_path ]; then
|
||||
info "[${BASTILLE_TEMPLATE}]:"
|
||||
git -C $_template_path pull ||\
|
||||
error_notify "${BASTILLE_TEMPLATE} update unsuccessful."
|
||||
|
||||
bastille verify "${BASTILLE_TEMPLATE}"
|
||||
else
|
||||
error_exit "${BASTILLE_TEMPLATE} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
templates_update() {
|
||||
# Update all templates
|
||||
_updated_templates=0
|
||||
if [ -d ${bastille_templatesdir} ]; then
|
||||
for _template_path in $(ls -d ${bastille_templatesdir}/*/*); do
|
||||
if [ -d $_template_path/.git ]; then
|
||||
BASTILLE_TEMPLATE=$(echo "$_template_path" | awk -F / '{ print $(NF-1) "/" $NF }')
|
||||
template_update
|
||||
|
||||
_updated_templates=$((_updated_templates+1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$_updated_templates" -ne "0" ]; then
|
||||
info "$_updated_templates templates updated."
|
||||
else
|
||||
error_exit "no templates found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check what we should update
|
||||
if echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
|
||||
if [ "${TARGET}" = 'TEMPLATES' ]; then
|
||||
templates_update
|
||||
elif echo "${TARGET}" | grep -Eq '^[A-Za-z0-9_-]+/[A-Za-z0-9_-]+$'; then
|
||||
BASTILLE_TEMPLATE="${TARGET}"
|
||||
template_update
|
||||
elif echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
|
||||
arch_check
|
||||
release_update
|
||||
else
|
||||
jail_update
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,7 +32,7 @@
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille upgrade release newrelease | target newrelease | target install | [option]"
|
||||
error_exit "Usage: bastille upgrade release newrelease | target newrelease | target install | [force]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -55,6 +55,11 @@ if [ "${TARGET}" = "ALL" ]; then
|
||||
error_exit "Batch upgrade is unsupported."
|
||||
fi
|
||||
|
||||
if [ -f "/bin/midnightbsd-version" ]; then
|
||||
echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if freebsd-version | grep -qi HBSD; then
|
||||
error_exit "Not yet supported on HardenedBSD."
|
||||
fi
|
||||
@@ -71,7 +76,7 @@ esac
|
||||
|
||||
jail_check() {
|
||||
# Check if the jail is thick and is running
|
||||
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
else
|
||||
if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
@@ -91,7 +96,9 @@ release_upgrade() {
|
||||
# Upgrade a release
|
||||
if [ -d "${bastille_releasesdir}/${TARGET}" ]; then
|
||||
release_check
|
||||
freebsd-update ${OPTION} -b "${bastille_releasesdir}/${TARGET}" -r "${NEWRELEASE}" upgrade
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" --currently-running "${TARGET}" -r "${NEWRELEASE}" upgrade
|
||||
echo
|
||||
echo -e "${COLOR_YELLOW}Please run 'bastille upgrade ${TARGET} install' to finish installing updates.${COLOR_RESET}"
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
@@ -121,9 +128,22 @@ jail_updates_install() {
|
||||
fi
|
||||
}
|
||||
|
||||
release_updates_install() {
|
||||
# Finish installing upgrade on a release
|
||||
if [ -d "${bastille_releasesdir}/${TARGET}" ]; then
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" install
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check what we should upgrade
|
||||
if echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
|
||||
release_upgrade
|
||||
if [ "${NEWRELEASE}" = "install" ]; then
|
||||
release_updates_install
|
||||
else
|
||||
release_upgrade
|
||||
fi
|
||||
elif [ "${NEWRELEASE}" = "install" ]; then
|
||||
jail_updates_install
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -36,6 +36,10 @@ bastille_usage() {
|
||||
}
|
||||
|
||||
verify_release() {
|
||||
if [ -f "/bin/midnightbsd-version" ]; then
|
||||
echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
if freebsd-version | grep -qi HBSD; then
|
||||
error_exit "Not yet supported on HardenedBSD."
|
||||
fi
|
||||
@@ -47,6 +51,22 @@ verify_release() {
|
||||
fi
|
||||
}
|
||||
|
||||
handle_template_include() {
|
||||
case ${TEMPLATE_INCLUDE} in
|
||||
http?://*/*/*)
|
||||
bastille bootstrap "${TEMPLATE_INCLUDE}"
|
||||
;;
|
||||
*/*)
|
||||
BASTILLE_TEMPLATE_USER=$(echo "${TEMPLATE_INCLUDE}" | awk -F / '{ print $1 }')
|
||||
BASTILLE_TEMPLATE_REPO=$(echo "${TEMPLATE_INCLUDE}" | awk -F / '{ print $2 }')
|
||||
bastille verify "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
|
||||
;;
|
||||
*)
|
||||
error_exit "Template INCLUDE content not recognized."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
verify_template() {
|
||||
_template_path=${bastille_templatesdir}/${BASTILLE_TEMPLATE}
|
||||
_hook_validate=0
|
||||
@@ -65,42 +85,42 @@ verify_template() {
|
||||
echo
|
||||
error_exit "Template validation failed."
|
||||
## if INCLUDE; recursive verify
|
||||
elif [ ${_hook} = 'INCLUDE' ]; then
|
||||
elif [ "${_hook}" = 'INCLUDE' ]; then
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
echo
|
||||
while read _include; do
|
||||
info "[${_hook}]:[${_include}]:"
|
||||
|
||||
case ${_include} in
|
||||
http?://github.com/*/*|http?://gitlab.com/*/*)
|
||||
bastille bootstrap "${_include}"
|
||||
;;
|
||||
*/*)
|
||||
BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }')
|
||||
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }')
|
||||
bastille verify "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
|
||||
;;
|
||||
*)
|
||||
error_exit "Template INCLUDE content not recognized."
|
||||
;;
|
||||
esac
|
||||
TEMPLATE_INCLUDE="${_include}"
|
||||
handle_template_include
|
||||
done < "${_path}"
|
||||
|
||||
## if tree; tree -a bastille_template/_dir
|
||||
elif [ ${_hook} = 'OVERLAY' ]; then
|
||||
elif [ "${_hook}" = 'OVERLAY' ]; then
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
echo
|
||||
while read _dir; do
|
||||
info "[${_hook}]:[${_dir}]:"
|
||||
if [ -x /usr/local/bin/tree ]; then
|
||||
if [ -x "/usr/local/bin/tree" ]; then
|
||||
/usr/local/bin/tree -a "${_template_path}/${_dir}"
|
||||
else
|
||||
find "${_template_path}/${_dir}" -print | sed -e 's;[^/]*/;|___;g;s;___|; |;g'
|
||||
fi
|
||||
echo
|
||||
done < "${_path}"
|
||||
elif [ "${_hook}" = 'Bastillefile' ]; then
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
while read _line; do
|
||||
_cmd=$(echo "${_line}" | awk '{print tolower($1);}')
|
||||
## if include; recursive verify
|
||||
if [ "${_cmd}" = 'include' ]; then
|
||||
TEMPLATE_INCLUDE=$(echo "${_line}" | awk '{print $2;}')
|
||||
handle_template_include
|
||||
fi
|
||||
done < "${_path}"
|
||||
echo
|
||||
else
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
@@ -110,7 +130,7 @@ verify_template() {
|
||||
done
|
||||
|
||||
## remove bad templates
|
||||
if [ ${_hook_validate} -lt 1 ]; then
|
||||
if [ "${_hook_validate}" -lt 1 ]; then
|
||||
error_notify "No valid template hooks found."
|
||||
error_notify "Template discarded."
|
||||
rm -rf "${bastille_template}"
|
||||
@@ -118,7 +138,7 @@ verify_template() {
|
||||
fi
|
||||
|
||||
## if validated; ready to use
|
||||
if [ ${_hook_validate} -gt 0 ]; then
|
||||
if [ "${_hook_validate}" -gt 0 ]; then
|
||||
info "Template ready to use."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2022, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
||||
Reference in New Issue
Block a user