Compare commits
843 Commits
0.5.201911
...
20231125_p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d44c85637e | ||
|
|
94656350a1 | ||
|
|
dc6e755c2b | ||
|
|
8906e491d0 | ||
|
|
ace7bdce2f | ||
|
|
9e71332876 | ||
|
|
2b6eb3c9f4 | ||
|
|
8c04f1d110 | ||
|
|
157125c4af | ||
|
|
b7d741b5cd | ||
|
|
1e849d41af | ||
|
|
df00a7939e | ||
|
|
49f6402a00 | ||
|
|
cf928f1237 | ||
|
|
11367238ec | ||
|
|
78c77b7e26 | ||
|
|
bf98acd330 | ||
|
|
01ee385384 | ||
|
|
22b3c3cd69 | ||
|
|
3ac2921559 | ||
|
|
0354baa6d5 | ||
|
|
445b42ed39 | ||
|
|
00d5c97f64 | ||
|
|
4ea6f00077 | ||
|
|
10fe9df412 | ||
|
|
440b24371b | ||
|
|
8b38497cb1 | ||
|
|
b0ba336d7e | ||
|
|
fe31dbdca8 | ||
|
|
4bebca9a69 | ||
|
|
864d8d03f5 | ||
|
|
ca2b75e8c0 | ||
|
|
0a93940442 | ||
|
|
b76df46cd1 | ||
|
|
2c932cf281 | ||
|
|
e7eb9b7717 | ||
|
|
27e88d45d5 | ||
|
|
721a5ca6a0 | ||
|
|
91f479e5d7 | ||
|
|
f35de69b28 | ||
|
|
e078aed54a | ||
|
|
848be8d8e3 | ||
|
|
a0d6d58a6b | ||
|
|
40e4b817d8 | ||
|
|
6be0f23256 | ||
|
|
3355c07dbf | ||
|
|
aa688f7072 | ||
|
|
9fc8804f97 | ||
|
|
d6b5733d48 | ||
|
|
72bd211f7b | ||
|
|
61e7084b33 | ||
|
|
3ea553086f | ||
|
|
2fd1f2c812 | ||
|
|
e15a481e46 | ||
|
|
15f2ea8574 | ||
|
|
4efcc5021c | ||
|
|
a2e1befa80 | ||
|
|
15c43ee214 | ||
|
|
a406654e18 | ||
|
|
7f41973f43 | ||
|
|
373ccd45d9 | ||
|
|
6e78be22f0 | ||
|
|
cf569eaeeb | ||
|
|
8d16399e50 | ||
|
|
bea80db898 | ||
|
|
a89f42242c | ||
|
|
16fae72518 | ||
|
|
4891ce69e7 | ||
|
|
e64a6af214 | ||
|
|
72b8000347 | ||
|
|
a0140e18bb | ||
|
|
bc9f4d7e90 | ||
|
|
0b7ed7850a | ||
|
|
e454f1c826 | ||
|
|
cb840684ab | ||
|
|
2e583cf9ab | ||
|
|
6ec7ae99f0 | ||
|
|
8f803d511e | ||
|
|
c760b817bd | ||
|
|
be50bd2359 | ||
|
|
228420049c | ||
|
|
d7609c2bc1 | ||
|
|
bf6fbed2b5 | ||
|
|
2e2032fee8 | ||
|
|
a9d8ae2cf1 | ||
|
|
f936afeae6 | ||
|
|
5aa98a8dae | ||
|
|
64c3b6045e | ||
|
|
6776427e5a | ||
|
|
10d94668fc | ||
|
|
91d1768740 | ||
|
|
c94f653e0b | ||
|
|
09a1d306dc | ||
|
|
b60bc10537 | ||
|
|
7b63059d03 | ||
|
|
34669ce2e6 | ||
|
|
5c94c283fb | ||
|
|
5c84731cd4 | ||
|
|
c016bc0667 | ||
|
|
3f665e4738 | ||
|
|
9588d52686 | ||
|
|
5adc75abed | ||
|
|
9a00ae5323 | ||
|
|
124902d6ba | ||
|
|
0629233f25 | ||
|
|
c00d8a4e05 | ||
|
|
bfce059225 | ||
|
|
ec7a6d8f6d | ||
|
|
0240d6532b | ||
|
|
ec18847f3e | ||
|
|
dd7f195c1e | ||
|
|
bdae170529 | ||
|
|
0ee17be875 | ||
|
|
778ef6e581 | ||
|
|
a73b9972e3 | ||
|
|
6a7ab04d9b | ||
|
|
937986f4b6 | ||
|
|
a4102c7f61 | ||
|
|
3702066864 | ||
|
|
79897e9af7 | ||
|
|
55c7c4c6be | ||
|
|
e5c71c794a | ||
|
|
e04aee2617 | ||
|
|
0dcefae18c | ||
|
|
37e607c055 | ||
|
|
f6f179b6c3 | ||
|
|
fdfbb8287f | ||
|
|
44cc3c0b91 | ||
|
|
2f35d07e58 | ||
|
|
d451573889 | ||
|
|
64fcda2533 | ||
|
|
ca3303fd4d | ||
|
|
f1d73a0c02 | ||
|
|
a0abac97ff | ||
|
|
6f739229cb | ||
|
|
427128b9f0 | ||
|
|
cf6e555ce9 | ||
|
|
c9d28ceed1 | ||
|
|
797f406a31 | ||
|
|
a352fd6507 | ||
|
|
a4ac5e961f | ||
|
|
c50e99b3e7 | ||
|
|
a0b7bc54e0 | ||
|
|
639334052f | ||
|
|
40c99ef979 | ||
|
|
260149c2a9 | ||
|
|
722adc44cb | ||
|
|
e35c59330d | ||
|
|
74b6eb76e7 | ||
|
|
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 | ||
|
|
7c271df2f5 | ||
|
|
c9b02fa1dd | ||
|
|
83a83e087e | ||
|
|
a0feac3f66 | ||
|
|
4136f8fff4 | ||
|
|
1120a0eebd | ||
|
|
c337994414 | ||
|
|
d9ee2e190d | ||
|
|
ca8819d7b6 | ||
|
|
32a1278326 | ||
|
|
cbd60032fc | ||
|
|
a56c37983c | ||
|
|
2e5811b1ee | ||
|
|
857b5d430b | ||
|
|
a3d2f69b71 | ||
|
|
7150b63391 | ||
|
|
31dfa2bfba | ||
|
|
7675286cd3 | ||
|
|
be6b1adfb9 | ||
|
|
4e843be9e3 | ||
|
|
62c8060b53 | ||
|
|
01494ad3fd | ||
|
|
574f655cc8 | ||
|
|
160040d2e9 | ||
|
|
73c500ce3e | ||
|
|
81ff4a3243 | ||
|
|
7c134184c6 | ||
|
|
54f6ef62cd | ||
|
|
02f9df6cc0 | ||
|
|
c6ad100d8a | ||
|
|
7d44a39a01 | ||
|
|
c2839f859e | ||
|
|
b90d8c60f7 | ||
|
|
5518273881 | ||
|
|
a47b0a43c9 | ||
|
|
30a8a93fe9 | ||
|
|
554f2293c1 | ||
|
|
b0c27329c9 | ||
|
|
351020d137 | ||
|
|
ce57d05081 | ||
|
|
0a9ae633e3 | ||
|
|
4c9f1aca25 | ||
|
|
5e9578ca5e | ||
|
|
a9ea02b743 | ||
|
|
1ffa999f08 | ||
|
|
e1cda4ba15 | ||
|
|
64b869e295 | ||
|
|
8d3b83bd44 | ||
|
|
8b4d18f8f3 | ||
|
|
cc513c3bed | ||
|
|
dd9e55bb9b | ||
|
|
52643c7e07 | ||
|
|
3dc2db84b0 | ||
|
|
3c79e1d82b | ||
|
|
67d2fdcbbb | ||
|
|
2483fdd0f0 | ||
|
|
2225f48f05 | ||
|
|
5b096e82ed | ||
|
|
8bef2bfe63 | ||
|
|
20b6f2ffe6 | ||
|
|
7d78358f9f | ||
|
|
855dcf3eae | ||
|
|
bc07ff2389 | ||
|
|
67a9c65912 | ||
|
|
917b4d8d0b | ||
|
|
ace6c9ab29 | ||
|
|
5e9e58dd92 | ||
|
|
2b9aa0ecd3 | ||
|
|
0c5225571f | ||
|
|
9fd83714c8 | ||
|
|
8725e9ccac | ||
|
|
bf5fd4ef2a | ||
|
|
5b36a9e762 | ||
|
|
5766d66078 | ||
|
|
935118fc99 | ||
|
|
976aa077b6 | ||
|
|
cbff4e326d | ||
|
|
3ca32fa1bc | ||
|
|
fddb762b45 | ||
|
|
a4fcf0100b | ||
|
|
c6aded8d0a | ||
|
|
aaffc882f9 | ||
|
|
94df833e6b | ||
|
|
3c070bf908 | ||
|
|
a369ed399d | ||
|
|
0ce53f4c4e | ||
|
|
abd80b151f | ||
|
|
8b196ffaeb | ||
|
|
5a9034ff18 | ||
|
|
7e27bcd36c | ||
|
|
3ebfb69305 | ||
|
|
d09644dc23 | ||
|
|
1dd2280e2c | ||
|
|
14dbc09b7c | ||
|
|
388cb39607 | ||
|
|
ad749e8a75 | ||
|
|
85176e35da | ||
|
|
a0b0eadc68 | ||
|
|
709f00a2ac | ||
|
|
dc1b1f838a | ||
|
|
24b4985371 | ||
|
|
3872f93063 | ||
|
|
3c19c5b183 | ||
|
|
5edf9cbe51 | ||
|
|
845bb9106f | ||
|
|
9150da4a5f | ||
|
|
d3d4a9c030 | ||
|
|
da15b4f59a | ||
|
|
93bc945e90 | ||
|
|
b9efa0ad04 | ||
|
|
579cf76a38 | ||
|
|
328112c74e | ||
|
|
428fd59925 | ||
|
|
0fd46b50e5 | ||
|
|
77274adb95 | ||
|
|
af6f0064d6 | ||
|
|
ed50e3fa04 | ||
|
|
d01ca09eaa | ||
|
|
7cdbe9ac3d | ||
|
|
012510e312 | ||
|
|
d7413d29ec | ||
|
|
8d98b8f6ec | ||
|
|
016523253a | ||
|
|
a0f4752287 | ||
|
|
7514e800f4 | ||
|
|
b98b841a1c | ||
|
|
26c41543c2 | ||
|
|
d92aeb3f70 | ||
|
|
99bd323897 | ||
|
|
3fccba30d6 | ||
|
|
547aa27816 | ||
|
|
e9c2a4d7b6 | ||
|
|
8b00e0adf4 | ||
|
|
457e95a08b | ||
|
|
0cbf8e93dd | ||
|
|
932f1afae1 | ||
|
|
6fb6e49c6c | ||
|
|
42bafe7619 | ||
|
|
61ee522f18 | ||
|
|
1d21ff58fe | ||
|
|
0658a343d3 | ||
|
|
147e7d5db3 | ||
|
|
b515565bde | ||
|
|
a28201f53e | ||
|
|
c98ea0a380 | ||
|
|
9344b2f647 | ||
|
|
33588397ad | ||
|
|
d47e2a7cfb | ||
|
|
8826f53d9a | ||
|
|
f84fd4ad85 | ||
|
|
e07f6cb0ed | ||
|
|
a607dc2719 | ||
|
|
b6b76fb7ae | ||
|
|
3035e86d55 | ||
|
|
702a0b8318 | ||
|
|
9617a2ab9a | ||
|
|
b80bbfe838 | ||
|
|
cdda90fa69 | ||
|
|
5c0e5dea35 | ||
|
|
4d9d4f61ef | ||
|
|
a98032e912 | ||
|
|
268008b967 | ||
|
|
f54151cf94 | ||
|
|
5249e2580a | ||
|
|
ef320ebcdc | ||
|
|
0378e3f5bd | ||
|
|
e989af8144 | ||
|
|
9e6028eba4 | ||
|
|
f28054b47e | ||
|
|
597175bafb | ||
|
|
0ed07b4ee2 | ||
|
|
21937ddbe8 | ||
|
|
72857be9d0 | ||
|
|
a95040ac62 | ||
|
|
9173674256 | ||
|
|
0ca7c467ec | ||
|
|
6558fdc403 | ||
|
|
945944feb4 | ||
|
|
106c566c88 | ||
|
|
84b091474d | ||
|
|
4d538da4f8 | ||
|
|
f211fd268c | ||
|
|
2f8128b160 | ||
|
|
4e3b972cf7 | ||
|
|
00443ccdd1 | ||
|
|
d4dc133e19 | ||
|
|
4788e78436 | ||
|
|
7ab17c2355 | ||
|
|
e436b36168 | ||
|
|
7933d02d47 | ||
|
|
537cd66fd4 | ||
|
|
3f386056a9 | ||
|
|
241ce01074 | ||
|
|
4de6f59e63 | ||
|
|
bfa500a183 | ||
|
|
7db47f3dac | ||
|
|
c2fefc5f16 | ||
|
|
0f4597a2c6 | ||
|
|
67964a7fbb | ||
|
|
ced148bcc7 | ||
|
|
6e850785a2 | ||
|
|
384ba3b82e | ||
|
|
512f973950 | ||
|
|
2240211f6a | ||
|
|
afc363d72d | ||
|
|
e804afa2b5 | ||
|
|
148dba4b22 | ||
|
|
102fbc7d51 | ||
|
|
ac96e8b6ec | ||
|
|
0cbc8ff8e7 | ||
|
|
af06250c1d | ||
|
|
ed90760f68 | ||
|
|
c03d43af09 | ||
|
|
bc82da9aaa | ||
|
|
a3c40b2727 | ||
|
|
4bd0a9d00d | ||
|
|
a3311c5aa9 | ||
|
|
659517b595 | ||
|
|
73e97ab18f | ||
|
|
c342b5cdc0 | ||
|
|
644b5319a1 | ||
|
|
be6a0e1b5f | ||
|
|
d0f5b31e42 | ||
|
|
8350af9c4f | ||
|
|
3945e82213 | ||
|
|
9b3fde59b8 | ||
|
|
8e30774235 | ||
|
|
a18927fb7a | ||
|
|
a0b522c48e | ||
|
|
29016faf20 | ||
|
|
01eaccc1da | ||
|
|
9481b6a1e6 | ||
|
|
8c1f9cd57a | ||
|
|
6b7b506c83 | ||
|
|
e26fe60fe4 | ||
|
|
2fa9f34be6 | ||
|
|
5b25dbcdc5 | ||
|
|
3b8c339dfa | ||
|
|
c6357127ea | ||
|
|
950342f54e | ||
|
|
f271547e23 | ||
|
|
c4ede0a829 | ||
|
|
64a4dd5987 | ||
|
|
814dc6d926 | ||
|
|
273acb6e50 | ||
|
|
099c45422d | ||
|
|
863c3cacc5 | ||
|
|
b1380b30e5 | ||
|
|
75fc18fec9 | ||
|
|
32ddcd5439 | ||
|
|
26846d510e | ||
|
|
44989660d2 | ||
|
|
015558c4bc | ||
|
|
53e7856d28 | ||
|
|
0e39f7cabb | ||
|
|
19cadec03e | ||
|
|
7ef65036c6 | ||
|
|
ee81a73264 | ||
|
|
fd90a21777 | ||
|
|
a3494c1007 | ||
|
|
d667f93bc5 | ||
|
|
1e2bbcd3b7 | ||
|
|
1d1ea761fe | ||
|
|
bf0bffd30f | ||
|
|
fe012c44f0 | ||
|
|
d1709b7199 | ||
|
|
0e93832a30 | ||
|
|
206d6a59e9 | ||
|
|
e3492d4087 | ||
|
|
84cc8cb103 | ||
|
|
7b706f83f4 | ||
|
|
62c77b4e71 | ||
|
|
488b6b614b | ||
|
|
e6fb8ba45f | ||
|
|
498029a13c | ||
|
|
c9db9b41d0 | ||
|
|
9a1b673721 | ||
|
|
11d7524446 | ||
|
|
b1e44e39ce | ||
|
|
70eb3e6aa2 | ||
|
|
96fcc6b591 | ||
|
|
b3f4064d08 | ||
|
|
7e43c10281 | ||
|
|
210a4f5018 | ||
|
|
3171015ea3 | ||
|
|
45f9247be9 | ||
|
|
f61c530265 | ||
|
|
b3a30a8951 | ||
|
|
031a23400e | ||
|
|
830de68bf9 | ||
|
|
9517d9608e | ||
|
|
874e3696e3 | ||
|
|
013987f7e1 | ||
|
|
9681254d76 | ||
|
|
5aba0d36f5 | ||
|
|
7620d61e49 | ||
|
|
503f787d69 | ||
|
|
d8914f9892 | ||
|
|
fe16a25cee | ||
|
|
f5ddc434a3 | ||
|
|
e408254448 | ||
|
|
56f2f9afb6 | ||
|
|
f65fe999cc | ||
|
|
eb38963752 | ||
|
|
97417b5b4f | ||
|
|
2cfcc4b8ad | ||
|
|
d9d52f09e3 | ||
|
|
08d9449f42 | ||
|
|
38ae0ed4a6 | ||
|
|
19e1cbf0fe | ||
|
|
eedcaf9abb | ||
|
|
0f20ae255f | ||
|
|
4a94dd53f8 | ||
|
|
095075b142 | ||
|
|
af15a39160 | ||
|
|
a60c678036 | ||
|
|
7c5436c740 | ||
|
|
27393f8db4 | ||
|
|
9917550093 | ||
|
|
02d0e94ef6 | ||
|
|
49c60f9896 | ||
|
|
8b9760b0a5 | ||
|
|
798d182e21 | ||
|
|
04303353f2 | ||
|
|
aa15b13594 | ||
|
|
9299670126 | ||
|
|
0940d86d62 | ||
|
|
b16d32e673 | ||
|
|
e0d722203a | ||
|
|
39b3c25bb5 | ||
|
|
39a12abe25 | ||
|
|
04b19ccc2b | ||
|
|
c588f54156 | ||
|
|
19a838921f | ||
|
|
35717ada4e | ||
|
|
a6b4ede0fa | ||
|
|
4ce6b41c7c | ||
|
|
6641baad51 | ||
|
|
65855ecd80 | ||
|
|
ab67cb82d0 | ||
|
|
edc6308001 | ||
|
|
9778a24870 | ||
|
|
2eb91e2f95 | ||
|
|
f3615a3380 | ||
|
|
9421cc59a0 | ||
|
|
0c78ebae88 | ||
|
|
de1590d709 | ||
|
|
ff9313a2ca | ||
|
|
bac677dc41 | ||
|
|
8770e5dd4c | ||
|
|
861953734f | ||
|
|
b16b393717 | ||
|
|
9b859f84ed | ||
|
|
ddff440b4f | ||
|
|
61f49e5d02 | ||
|
|
eb13d48eac | ||
|
|
1b522522af | ||
|
|
71873e9389 | ||
|
|
ffe6efd0e5 | ||
|
|
d95d815949 | ||
|
|
0fd6cd0fd9 | ||
|
|
4a1e769036 | ||
|
|
a57ae3ff46 | ||
|
|
5b11f81a1b | ||
|
|
ed60f9c409 | ||
|
|
23b96bd82a | ||
|
|
3f7573825d | ||
|
|
265b8480e1 | ||
|
|
abbec0652d | ||
|
|
1608d7f226 | ||
|
|
172baa8c32 | ||
|
|
cfcad20f4a | ||
|
|
6e8279ecd4 | ||
|
|
9a30610d1a | ||
|
|
f68ed2ecfd | ||
|
|
29565b22c8 | ||
|
|
8414865355 | ||
|
|
90c0c1d4c0 | ||
|
|
80412679a7 | ||
|
|
61eb7f5625 | ||
|
|
fbb99470ec | ||
|
|
f2a968a065 | ||
|
|
0a708c3dc7 | ||
|
|
f6653a6a48 | ||
|
|
03597e1489 | ||
|
|
f36744f2a0 | ||
|
|
43da7b25a1 | ||
|
|
b5c8330502 |
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**[MANDATORY] Describe the bug [MANDATORY]**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**[MANDATORY] Bastille and FreeBSD version (paste ``bastille -v && freebsd-version -kru`` output)**
|
||||
|
||||
**[MANDATORY] How did you install bastille? (port/pkg/git)**
|
||||
|
||||
**[optional] Steps to reproduce?**
|
||||
|
||||
**[optional] Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**[optional] Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**[optional] Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Enhancement & Feature Request
|
||||
title: "[ENHANCEMENT]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
9
.readthedocs.yaml
Normal file
9
.readthedocs.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
version: 2
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
build:
|
||||
os: "ubuntu-22.04"
|
||||
tools:
|
||||
python: "3.11"
|
||||
59
AUTHORS.md
59
AUTHORS.md
@@ -4,27 +4,46 @@
|
||||
|
||||
Christer Edwards [christer.edwards@gmail.com]
|
||||
|
||||
## Contributors
|
||||
|
||||
Barry McCormick
|
||||
Jose Rivera
|
||||
Giacomo Olgeni
|
||||
Jan-Piet Mens
|
||||
## 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
|
||||
not be found in the commit history.
|
||||
not be found in the commit history but have influenced Bastille's development
|
||||
in some way.
|
||||
|
||||
Barry McCormick
|
||||
Carlos Meza
|
||||
Casandra Woodcox
|
||||
Clint Savage
|
||||
G. Clifford Williams
|
||||
Jack Thomasson
|
||||
Jun C Park
|
||||
Justin Desilets
|
||||
Larry Raab
|
||||
Nate Taylor
|
||||
Ryan Simpkins
|
||||
Tim Gelter
|
||||
Trevor Sharpe
|
||||
- Carlos Meza
|
||||
- Casandra Woodcox
|
||||
- Clint Savage
|
||||
- G. Clifford Williams
|
||||
- Jack Thomasson
|
||||
- Jun C Park
|
||||
- Justin Desilets
|
||||
- Larry Raab
|
||||
- Nate Taylor
|
||||
- Peter Czanik
|
||||
- Ryan Simpkins
|
||||
- Tim Gelter
|
||||
- Trevor Sharpe
|
||||
|
||||
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at conduct@bastillebsd.org. All
|
||||
reported by contacting the project team lead at christer.edwards@gmail.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
@@ -71,4 +71,3 @@ This Code of Conduct is adapted from the [Contributor Covenant][homepage], versi
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
34
Makefile
Normal file
34
Makefile
Normal file
@@ -0,0 +1,34 @@
|
||||
BASTILLE_VERSION=$$(git rev-parse HEAD)
|
||||
|
||||
.PHONY: all
|
||||
all:
|
||||
@echo "Nothing to be done. Please use make install or make uninstall"
|
||||
.PHONY: install
|
||||
install:
|
||||
@echo "Installing Bastille"
|
||||
@echo
|
||||
@echo "Updating Bastille version to match git revision."
|
||||
@echo "BASTILLE_VERSION: ${BASTILLE_VERSION}"
|
||||
@sed -i.orig "s/BASTILLE_VERSION=.*/BASTILLE_VERSION=${BASTILLE_VERSION}/" usr/local/bin/bastille
|
||||
@cp -Rv usr /
|
||||
@echo
|
||||
@echo "This method is for testing & development."
|
||||
@echo "Please report any issues to https://github.com/BastilleBSD/bastille/issues"
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
@echo "Removing Bastille command"
|
||||
@rm -vf /usr/local/bin/bastille
|
||||
@echo
|
||||
@echo "Removing Bastille sub-commands"
|
||||
@rm -rvf /usr/local/share/bastille
|
||||
@echo
|
||||
@echo "removing man page"
|
||||
@rm -rvf /usr/local/share/man/man1/bastille.1.gz
|
||||
@echo
|
||||
@echo "removing configuration file"
|
||||
@rm -rvf /usr/local/etc/bastille/bastille.conf.sample
|
||||
@echo
|
||||
@echo "removing startup script"
|
||||
@rm -vf /usr/local/etc/rc.d/bastille
|
||||
@echo "You may need to manually remove /usr/local/etc/bastille/bastille.conf if it is no longer needed."
|
||||
849
README.md
849
README.md
@@ -1,14 +1,13 @@
|
||||
Bastille: Automated Container Security
|
||||
======================================
|
||||
Bastille is an open-source system for automating deployment and management of
|
||||
containerized applications on FreeBSD.
|
||||
|
||||
Looking for [Bastille Templates](https://gitlab.com/BastilleBSD-Templates)?
|
||||
Bastille
|
||||
========
|
||||
[Bastille](https://bastillebsd.org/) is an open-source system for automating
|
||||
deployment and management of containerized applications on FreeBSD.
|
||||
|
||||
[Bastille Documentation](https://bastille.readthedocs.io/en/latest/)
|
||||
|
||||
Installation
|
||||
============
|
||||
Bastille is available in the official FreeBSD ports tree.
|
||||
Bastille is available for installation from the official FreeBSD ports tree.
|
||||
|
||||
**pkg**
|
||||
```shell
|
||||
@@ -21,11 +20,31 @@ portsnap fetch auto
|
||||
make -C /usr/ports/sysutils/bastille install clean
|
||||
```
|
||||
|
||||
**Git** (bleeding edge / unstable -- primarily for developers)
|
||||
```shell
|
||||
git clone https://github.com/bastillebsd/bastille.git
|
||||
cd bastille
|
||||
make install
|
||||
```
|
||||
|
||||
**enable at boot**
|
||||
```shell
|
||||
sysrc bastille_enable=YES
|
||||
sysrc bastille_rcorder=YES
|
||||
```
|
||||
|
||||
Upgrading from a previous version
|
||||
---------------------------------
|
||||
When upgrading from a previous version of bastille (e.g. 0.10.20230714 to
|
||||
0.10.20231013) you will need to update your bastille.conf
|
||||
|
||||
```shell
|
||||
cd /usr/local/etc/bastille
|
||||
diff -u bastille.conf bastille.conf.sample
|
||||
```
|
||||
|
||||
Merge the lines that are present in the new bastille.conf.sample into
|
||||
your bastille.conf
|
||||
|
||||
Basic Usage
|
||||
-----------
|
||||
@@ -34,770 +53,86 @@ Bastille is an open-source system for automating deployment and management of
|
||||
containerized applications on FreeBSD.
|
||||
|
||||
Usage:
|
||||
bastille command TARGET args
|
||||
bastille command TARGET [args]
|
||||
|
||||
Available Commands:
|
||||
bootstrap Bootstrap a FreeBSD release for container base.
|
||||
clone Clone an existing container.
|
||||
cmd Execute arbitrary command on targeted container(s).
|
||||
config Get or set a config value for the targeted container(s).
|
||||
console Console into a running container.
|
||||
convert Convert a Thin container into a Thick container.
|
||||
cp cp(1) files from host to targeted container(s).
|
||||
create Create a new thin container or a thick container if -T|--thick option specified.
|
||||
destroy Destroy a stopped container or a FreeBSD release.
|
||||
help Help about any command
|
||||
edit Edit container configuration files (advanced).
|
||||
export Exports a specified container.
|
||||
help Help about any command.
|
||||
htop Interactive process viewer (requires htop).
|
||||
import Import a specified container.
|
||||
limits Apply resources limits to targeted container(s). See rctl(8).
|
||||
list List containers (running and stopped).
|
||||
mount Mount a volume inside the targeted container(s).
|
||||
pkg Manipulate binary packages within targeted container(s). See pkg(8).
|
||||
rdr Redirect host port to container port.
|
||||
rcp reverse cp(1) files from a single container to the host.
|
||||
rename Rename a container.
|
||||
restart Restart a running container.
|
||||
service Manage services within targeted container(s).
|
||||
setup Attempt to auto-configure network, firewall and storage on new installs.
|
||||
start Start a stopped container.
|
||||
stop Stop a running container.
|
||||
sysrc Safely edit rc files within targeted container(s).
|
||||
tags Add or remove tags to targeted container(s).
|
||||
template Apply file templates to targeted container(s).
|
||||
top Display and update information about the top(1) cpu processes.
|
||||
umount Unmount a volume from within the targeted container(s).
|
||||
update Update container base -pX release.
|
||||
upgrade Upgrade container release to X.Y-RELEASE.
|
||||
verify Compare release against a "known good" index.
|
||||
zfs Manage (get|set) zfs attributes on targeted container(s).
|
||||
zfs Manage (get|set) ZFS attributes on targeted container(s).
|
||||
|
||||
Use "bastille -v|--version" for version information.
|
||||
Use "bastille command -h|--help" for more information about a command.
|
||||
|
||||
```
|
||||
|
||||
|
||||
## 0.5-beta
|
||||
## 0.10-beta
|
||||
This document outlines the basic usage of the Bastille container management
|
||||
framework. This release is still considered beta.
|
||||
|
||||
Setup Requirements
|
||||
==================
|
||||
Bastille can now (attempt) to configure the networking, firewall and storage
|
||||
automatically. This feature is new since version 0.10.20231013.
|
||||
|
||||
Network Requirements
|
||||
====================
|
||||
Several networking options can be performed regarding the user needs. Basic
|
||||
containers can support IP alias networking, where the IP address is assigned to
|
||||
the host interface and used by the container, generally known as "shared IP"
|
||||
based containers.
|
||||
|
||||
If you administer your own network and can assign and remove unallocated IP
|
||||
addresses, then "shared IP" is a simple method to get started. If this is the
|
||||
case, skip ahead to ZFS Support.
|
||||
|
||||
If you are not the administator of the network, or perhaps you're in "the
|
||||
cloud" someplace and are only provided a single IP4 address. In this situation
|
||||
Bastille can create and attach containers to a private loopback interface. The
|
||||
host system then acts as the firewall, permitting and denying traffic as
|
||||
needed. (This method has been my primary method for years.)
|
||||
|
||||
**bastille0**
|
||||
|
||||
First, create the loopback interface:
|
||||
**bastille setup**
|
||||
|
||||
```shell
|
||||
ishmael ~ # sysrc cloned_interfaces+=lo1
|
||||
ishmael ~ # sysrc ifconfig_lo1_name="bastille0"
|
||||
ishmael ~ # sysrc ifconfig_bastille0_aliases="inet 10.17.89.1/32"
|
||||
ishmael ~ # service netif cloneup
|
||||
ishmael ~ # ifconfig bastille0 inet 10.17.89.1/32
|
||||
ishmael ~ # bastille setup -h
|
||||
ishmael ~ # Usage: bastille setup [pf|bastille0|zfs|vnet]
|
||||
```
|
||||
|
||||
Second, enable the firewall:
|
||||
On fresh installations it is likely safe to run `bastille setup` with no
|
||||
arguments. This will configure the firewall, the loopback interface and attempt
|
||||
to determine ZFS vs UFS storage.
|
||||
|
||||
```shell
|
||||
ishmael ~ # sysrc pf_enable="YES"
|
||||
```
|
||||
If you have an existing firewall, or customized network design, you may want to
|
||||
run individual options; eg `bastille setup zfs` or `bastille setup vnet`.
|
||||
|
||||
Create the firewall config, or merge as necessary.
|
||||
|
||||
/etc/pf.conf
|
||||
------------
|
||||
```
|
||||
ext_if="vtnet0"
|
||||
|
||||
set block-policy return
|
||||
scrub in on $ext_if all fragment reassemble
|
||||
|
||||
set skip on lo
|
||||
nat on $ext_if from bastille0:network to any -> ($ext_if)
|
||||
|
||||
## rdr example
|
||||
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
|
||||
block in all
|
||||
pass out quick modulate state
|
||||
antispoof for $ext_if inet
|
||||
pass in inet proto tcp from any to any port ssh flags S/SA keep state
|
||||
```
|
||||
|
||||
* 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 of a remote system.
|
||||
|
||||
Note: if you have an existing firewall, the key lines for in/out traffic to
|
||||
containers are:
|
||||
|
||||
```
|
||||
nat on $ext_if from bastille0:network to any -> ($ext_if)
|
||||
|
||||
## rdr example
|
||||
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
```
|
||||
|
||||
The `nat` routes traffic from the loopback interface to the external interface
|
||||
for outbound access.
|
||||
|
||||
The `rdr pass ...` will redirect traffic from the host firewall on port X to
|
||||
the ip of container Y. The example shown redirects web traffic (80 & 443) to the
|
||||
container at `10.17.89.45`.
|
||||
|
||||
Finally, start up the firewall:
|
||||
|
||||
```shell
|
||||
ishmael ~ # service pf restart
|
||||
```
|
||||
|
||||
At this point you'll likely be disconnected from the host. Reconnect the ssh
|
||||
session and continue.
|
||||
Note: The `bastille setup` command can configure and enable PF but it does not
|
||||
automatically reload the firewall. You will still need to manually `service pf
|
||||
start`. At that point you'll likely be disconnected if configuring a remote
|
||||
host. Simply reconnect the ssh session and continue.
|
||||
|
||||
This step only needs to be done once in order to prepare the host.
|
||||
|
||||
|
||||
ZFS support
|
||||
===========
|
||||
|
||||

|
||||
|
||||
Bastille 0.4 added initial support for ZFS. `bastille bootstrap` and `bastille
|
||||
create` will generate ZFS volumes based on settings found in the
|
||||
`bastille.conf`. This section outlines how to enable and configure Bastille for
|
||||
ZFS.
|
||||
|
||||
Two values are required for Bastille to use ZFS. The default values in the
|
||||
`bastille.conf` are empty. Populate these two to enable ZFS.
|
||||
|
||||
```shell
|
||||
## ZFS options
|
||||
bastille_zfs_enable="" ## default: ""
|
||||
bastille_zfs_zpool="" ## default: ""
|
||||
bastille_zfs_prefix="bastille" ## default: "${bastille_zfs_zpool}/bastille"
|
||||
bastille_zfs_mountpoint=${bastille_prefix} ## default: "${bastille_prefix}"
|
||||
bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off"
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```shell
|
||||
ishmael ~ # sysrc -f /usr/local/etc/bastille/bastille.conf bastille_zfs_enable=YES
|
||||
ishmael ~ # sysrc -f /usr/local/etc/bastille/bastille.conf bastille_zfs_zpool=ZPOOL_NAME
|
||||
```
|
||||
|
||||
Replace `ZPOOL_NAME` with the zpool you want Bastille to use. Tip: `zpool list`
|
||||
and `zpool status` will help. If you get 'no pools available' you are likely
|
||||
not using ZFS and can safely ignore these settings.
|
||||
|
||||
|
||||
bastille bootstrap
|
||||
------------------
|
||||
Before you can begin creating containers, Bastille needs to "bootstrap" a
|
||||
release. Current supported releases are 11.3-RELEASE, 12.0-RELEASE and
|
||||
12.1-RELEASE.
|
||||
|
||||
**Important: If you need ZFS support see the above section BEFORE
|
||||
bootstrapping.**
|
||||
|
||||
To `bootstrap` a release, run the bootstrap sub-command with the
|
||||
release version as the argument.
|
||||
|
||||
**FreeBSD 11.3-RELEASE**
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap 11.3-RELEASE
|
||||
```
|
||||
|
||||
**FreeBSD 12.0-RELEASE**
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap 12.0-RELEASE
|
||||
```
|
||||
|
||||
**FreeBSD 12.1-RELEASE**
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap 12.1-RELEASE
|
||||
```
|
||||
|
||||
**HardenedBSD 11-STABLE-LAST**
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap 11-STABLE-LAST
|
||||
```
|
||||
|
||||
**HardenedBSD 12-STABLE-LAST**
|
||||
```shell
|
||||
ishmael ~ # bastille bootstrap 12-STABLE-LAST
|
||||
```
|
||||
|
||||
> `bastille bootstrap RELEASE update` to apply updates automatically at bootstrap.
|
||||
|
||||
This command will ensure the required directory structures are in place and
|
||||
download the requested release. For each requested release, `bootstrap` will
|
||||
download the base.txz. If you need more than base (eg; ports, lib32, src) you
|
||||
can configure the `bastille_bootstrap_archives` in the configuration file. By
|
||||
default this value is set to "base". Additional components are added, space
|
||||
separated, without file extension.
|
||||
|
||||
Bastille will attempt to fetch the required archives if they are not found in
|
||||
the `cache/$RELEASE` directory.
|
||||
|
||||
Downloaded artifacts are stored in the `cache/RELEASE` directory. "bootstrapped"
|
||||
releases are stored in `releases/RELEASE`.
|
||||
|
||||
Advanced: If you want to create your own custom base.txz, or use an unsupported
|
||||
variant of FreeBSD, drop your own base.txz in `cache/RELEASE/base.txz` and
|
||||
`bastille bootstrap` will attempt to extract and use it.
|
||||
|
||||
The bootstrap subcommand is generally only used once to prepare the system. The
|
||||
other use cases for the bootstrap command are when a new FreeBSD version is
|
||||
released and you want to start building containers on that version, or
|
||||
bootstrapping templates from GitHub or GitLab.
|
||||
|
||||
See `bastille update` to ensure your bootstrapped releases include the latest
|
||||
patches.
|
||||
|
||||
|
||||
bastille create
|
||||
---------------
|
||||
`bastille create` uses a bootstrapped release to create a lightweight container
|
||||
system. To create a container simply provide a name, release and a private
|
||||
(rfc1918) IP address. Optionally provide a network interface name to attach the
|
||||
IP at container creation.
|
||||
|
||||
- name
|
||||
- release (bootstrapped)
|
||||
- ip
|
||||
- interface (optional)
|
||||
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille create folsom 12.0-RELEASE 10.17.89.10
|
||||
Valid: (10.17.89.10).
|
||||
|
||||
NAME: folsom.
|
||||
IP: 10.17.89.10.
|
||||
RELEASE: 12.0-RELEASE.
|
||||
|
||||
syslogd_flags: -s -> -ss
|
||||
sendmail_enable: NO -> NONE
|
||||
cron_flags: -> -J 60
|
||||
```
|
||||
|
||||
This command will create a 12.0-RELEASE container assigning the 10.17.89.10 ip
|
||||
address to the new system.
|
||||
|
||||
Optionally `bastille create [ -T | --thick ]` will create a container with a
|
||||
private base. This is sometimes referred to as a "thick" container (whereas the
|
||||
shared base container is a "thin").
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille create -T folsom 12.0-RELEASE 10.17.89.10
|
||||
```
|
||||
|
||||
I recommend using private (rfc1918) ip address ranges for your containers.
|
||||
These ranges include:
|
||||
|
||||
- 10.0.0.0/8
|
||||
- 172.16.0.0/12
|
||||
- 192.168.0.0/16
|
||||
|
||||
If your Bastille host also uses private (rfc1918) addresses, use a different
|
||||
range for your containers. ie; Host uses 192.168.0.0/16, containers use 10.0.0.0/8.
|
||||
|
||||
Bastille does its best to validate the submitted ip is valid. I generally use
|
||||
the 10.0.0.0/8 range for containers.
|
||||
|
||||
|
||||
bastille start
|
||||
--------------
|
||||
To start a containers you can use the `bastille start` command.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille start folsom
|
||||
[folsom]:
|
||||
folsom: created
|
||||
|
||||
```
|
||||
|
||||
|
||||
bastille stop
|
||||
-------------
|
||||
To stop a containers you can use the `bastille stop` command.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille stop folsom
|
||||
[folsom]:
|
||||
folsom: removed
|
||||
|
||||
```
|
||||
|
||||
|
||||
bastille restart
|
||||
----------------
|
||||
To restart a container you can use the `bastille restart` command.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille restart folsom
|
||||
[folsom]:
|
||||
folsom: removed
|
||||
|
||||
[folsom]:
|
||||
folsom: created
|
||||
|
||||
```
|
||||
|
||||
bastille list
|
||||
-------------
|
||||
This sub-command will show you the running containers on your system.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille list
|
||||
JID IP Address Hostname Path
|
||||
bastion 10.17.89.65 bastion /usr/local/bastille/jails/bastion/root
|
||||
unbound0 10.17.89.60 unbound0 /usr/local/bastille/jails/unbound0/root
|
||||
unbound1 10.17.89.61 unbound1 /usr/local/bastille/jails/unbound1/root
|
||||
squid 10.17.89.30 squid /usr/local/bastille/jails/squid/root
|
||||
nginx 10.17.89.45 nginx /usr/local/bastille/jails/nginx/root
|
||||
folsom 10.17.89.10 folsom /usr/local/bastille/jails/folsom/root
|
||||
```
|
||||
|
||||
You can also list non-running containers with `bastille list containers`. In
|
||||
the same manner you can list archived `logs`, downloaded `templates`, and
|
||||
`releases`.
|
||||
|
||||
|
||||
bastille service
|
||||
----------------
|
||||
To restart services inside a containers you can use the `bastille service`
|
||||
command.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille service folsom postfix restart
|
||||
[folsom]
|
||||
postfix/postfix-script: stopping the Postfix mail system
|
||||
postfix/postfix-script: starting the Postfix mail system
|
||||
|
||||
```
|
||||
|
||||
|
||||
bastille cmd
|
||||
------------
|
||||
To execute commands within the container you can use `bastille cmd`.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille cmd folsom ps -auxw
|
||||
[folsom]:
|
||||
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
|
||||
root 71464 0.0 0.0 14536 2000 - IsJ 4:52PM 0:00.00 /usr/sbin/syslogd -ss
|
||||
root 77447 0.0 0.0 16632 2140 - SsJ 4:52PM 0:00.00 /usr/sbin/cron -s
|
||||
root 80591 0.0 0.0 18784 2340 1 R+J 4:53PM 0:00.00 ps -auxw
|
||||
|
||||
```
|
||||
|
||||
|
||||
bastille pkg
|
||||
------------
|
||||
To manage binary packages within the container use `bastille pkg`.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille pkg folsom install vim-console git-lite zsh
|
||||
[folsom]:
|
||||
Updating FreeBSD repository catalogue...
|
||||
[folsom] Fetching meta.txz: 100% 944 B 0.9kB/s 00:01
|
||||
[folsom] Fetching packagesite.txz: 100% 6 MiB 6.6MB/s 00:01
|
||||
Processing entries: 100%
|
||||
FreeBSD repository update completed. 32617 packages processed.
|
||||
All repositories are up to date.
|
||||
Updating database digests format: 100%
|
||||
The following 10 package(s) will be affected (of 0 checked):
|
||||
|
||||
New packages to be INSTALLED:
|
||||
vim-console: 8.1.1954
|
||||
git-lite: 2.23.0
|
||||
zsh: 5.7.1_1
|
||||
expat: 2.2.8
|
||||
curl: 7.66.0
|
||||
libnghttp2: 1.39.2
|
||||
ca_root_nss: 3.47.1
|
||||
pcre: 8.43_2
|
||||
gettext-runtime: 0.20.1
|
||||
indexinfo: 0.3.1
|
||||
|
||||
Number of packages to be installed: 10
|
||||
|
||||
The process will require 87 MiB more space.
|
||||
18 MiB to be downloaded.
|
||||
|
||||
Proceed with this action? [y/N]:
|
||||
...[snip]...
|
||||
```
|
||||
|
||||
The PKG sub-command can, of course, do more than just `install`. The
|
||||
expectation is that you can fully leverage the pkg manager. This means,
|
||||
`install`, `update`, `upgrade`, `audit`, `clean`, `autoremove`, etc.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille pkg ALL upgrade
|
||||
[bastion]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[bastion] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
[bastion] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01
|
||||
Processing entries: 100%
|
||||
pkg.bastillebsd.org repository update completed. 493 packages processed.
|
||||
All repositories are up to date.
|
||||
Checking for upgrades (1 candidates): 100%
|
||||
Processing candidates (1 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
[unbound0]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[unbound0] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
[unbound0] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01
|
||||
Processing entries: 100%
|
||||
pkg.bastillebsd.org repository update completed. 493 packages processed.
|
||||
All repositories are up to date.
|
||||
Checking for upgrades (0 candidates): 100%
|
||||
Processing candidates (0 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
[unbound1]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[unbound1] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
[unbound1] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01
|
||||
Processing entries: 100%
|
||||
pkg.bastillebsd.org repository update completed. 493 packages processed.
|
||||
All repositories are up to date.
|
||||
Checking for upgrades (0 candidates): 100%
|
||||
Processing candidates (0 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
[squid]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[squid] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
[squid] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01
|
||||
Processing entries: 100%
|
||||
pkg.bastillebsd.org repository update completed. 493 packages processed.
|
||||
All repositories are up to date.
|
||||
Checking for upgrades (0 candidates): 100%
|
||||
Processing candidates (0 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
[nginx]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[nginx] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
[nginx] Fetching packagesite.txz: 100% 118 KiB 121.3kB/s 00:01
|
||||
Processing entries: 100%
|
||||
pkg.bastillebsd.org repository update completed. 493 packages processed.
|
||||
All repositories are up to date.
|
||||
Checking for upgrades (1 candidates): 100%
|
||||
Processing candidates (1 candidates): 100%
|
||||
The following 1 package(s) will be affected (of 0 checked):
|
||||
|
||||
Installed packages to be UPGRADED:
|
||||
nginx-lite: 1.14.0_14,2 -> 1.14.1,2
|
||||
|
||||
Number of packages to be upgraded: 1
|
||||
|
||||
315 KiB to be downloaded.
|
||||
|
||||
Proceed with this action? [y/N]: y
|
||||
[nginx] [1/1] Fetching nginx-lite-1.14.1,2.txz: 100% 315 KiB 322.8kB/s 00:01
|
||||
Checking integrity... done (0 conflicting)
|
||||
[nginx] [1/1] Upgrading nginx-lite from 1.14.0_14,2 to 1.14.1,2...
|
||||
===> Creating groups.
|
||||
Using existing group 'www'.
|
||||
===> Creating users
|
||||
Using existing user 'www'.
|
||||
[nginx] [1/1] Extracting nginx-lite-1.14.1,2: 100%
|
||||
You may need to manually remove /usr/local/etc/nginx/nginx.conf if it is no longer needed.
|
||||
```
|
||||
|
||||
|
||||
bastille destroy
|
||||
----------------
|
||||
Containers can be destroyed and thrown away just as easily as they were
|
||||
created. Note: containers must be stopped before destroyed.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille stop folsom
|
||||
[folsom]:
|
||||
folsom: removed
|
||||
|
||||
ishmael ~ # bastille destroy folsom
|
||||
Deleting Container: folsom.
|
||||
Note: container console logs not destroyed.
|
||||
/usr/local/bastille/logs/folsom_console.log
|
||||
|
||||
```
|
||||
|
||||
bastille template
|
||||
-----------------
|
||||
Looking for ready made CI/CD validated [Bastille
|
||||
Templates](https://gitlab.com/BastilleBSD-Templates)?
|
||||
|
||||
Bastille supports a templating system allowing you to apply files, pkgs and
|
||||
execute commands inside the container automatically.
|
||||
|
||||
Currently supported template hooks are: `PRE`, `CONFIG`, `PKG`, `SYSRC`, `CMD`.
|
||||
Planned template hooks include: `FSTAB`, `PF`, `LOG`
|
||||
|
||||
Templates are created in `${bastille_prefix}/templates` and can leverage any of
|
||||
the template hooks. Simply create a new directory named after the template. eg;
|
||||
|
||||
```shell
|
||||
mkdir -p /usr/local/bastille/templates/username/base
|
||||
```
|
||||
|
||||
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 "install zsh vim-console git-lite htop" > /usr/local/bastille/templates/base/PKG
|
||||
echo "/usr/bin/chsh -s /usr/local/bin/zsh" > /usr/local/bastille/templates/base/CMD
|
||||
echo "etc\nroot\nusr" > /usr/local/bastille/templates/base/OVERLAY
|
||||
```
|
||||
|
||||
Template hooks are executed in specific order and require specific syntax to
|
||||
work as expected. This table outlines those requirements:
|
||||
|
||||
| SUPPORTED | format | example |
|
||||
|-----------|------------------|----------------------------------------------------------------|
|
||||
| PRE/CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
|
||||
| OVERLAY | paths (one/line) | etc root usr |
|
||||
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
|
||||
| SYSRC | sysrc command(s) | nginx_enable=YES |
|
||||
|
||||
| PLANNED | format | example |
|
||||
|---------|------------------|----------------------------------------------------------------|
|
||||
| PF | 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 |
|
||||
| FSTAB | fstab syntax | /path/on/host /path/in/container nullfs ro 0 0 |
|
||||
|
||||
Note: SYSRC requires NO quotes or that quotes (`"`) be escaped. ie; `\"`)
|
||||
|
||||
In addition to supporting template hooks, Bastille supports overlaying files
|
||||
into the container. This is done by placing the files in their full path, using the
|
||||
template directory as "/".
|
||||
|
||||
An example here may help. Think of
|
||||
`/usr/local/bastille/templates/username/base`, our example template, as the
|
||||
root of our filesystem overlay. If you create an `etc/hosts` or
|
||||
`etc/resolv.conf` *inside* the base template directory, these can be overlayed
|
||||
into your container.
|
||||
|
||||
Note: due to the way FreeBSD segregates user-space, the majority of your
|
||||
overlayed template files will be in `usr/local`. The few general
|
||||
exceptions are the `etc/hosts`, `etc/resolv.conf`, and `etc/rc.conf.local`, etc.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
The above example will include anything under "etc" and "usr" inside
|
||||
the template. You do not need to list individual files. Just include the
|
||||
top-level directory name.
|
||||
|
||||
|
||||
Applying Templates
|
||||
------------------
|
||||
|
||||
Containers must be running to apply templates.
|
||||
|
||||
Bastille includes a `template` sub-command. This sub-command requires a target
|
||||
and a template name. As covered in the previous section, template names
|
||||
correspond to directory names in the `bastille/templates` directory.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille template folsom username/base
|
||||
[folsom]:
|
||||
Copying files...
|
||||
Copy complete.
|
||||
Installing packages.
|
||||
...[snip]...
|
||||
Executing final command(s).
|
||||
chsh: user information updated
|
||||
Template Complete.
|
||||
|
||||
```
|
||||
|
||||
|
||||
bastille top
|
||||
------------
|
||||
This one simply runs `top` in that container. This command is interactive, as
|
||||
`top` is interactive.
|
||||
|
||||
|
||||
bastille htop
|
||||
-------------
|
||||
This one simply runs `htop` inside the container. This one is a quick and dirty
|
||||
addition. note: won't work if you don't have htop installed in the container.
|
||||
|
||||
|
||||
bastille sysrc
|
||||
--------------
|
||||
The `sysrc` sub-command allows for safely editing system configuration files.
|
||||
In container terms, this allows us to toggle on/off services and options at
|
||||
startup.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille sysrc nginx nginx_enable=YES
|
||||
[nginx]:
|
||||
nginx_enable: NO -> YES
|
||||
```
|
||||
|
||||
See `man sysrc(8)` for more info.
|
||||
|
||||
|
||||
bastille console
|
||||
----------------
|
||||
This sub-command launches a login shell into the container. Default is
|
||||
password-less root login. If you provide an additional argument of a username
|
||||
you will be logged in as that user. (user must be created first)
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille console folsom
|
||||
[folsom]:
|
||||
FreeBSD 11.3-RELEASE-p4 (GENERIC) #0: Thu Sep 27 08:16:24 UTC 2018
|
||||
|
||||
Welcome to FreeBSD!
|
||||
|
||||
Release Notes, Errata: https://www.FreeBSD.org/releases/
|
||||
Security Advisories: https://www.FreeBSD.org/security/
|
||||
FreeBSD Handbook: https://www.FreeBSD.org/handbook/
|
||||
FreeBSD FAQ: https://www.FreeBSD.org/faq/
|
||||
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
|
||||
FreeBSD Forums: https://forums.FreeBSD.org/
|
||||
|
||||
Documents installed with the system are in the /usr/local/share/doc/freebsd/
|
||||
directory, or can be installed later with: pkg install en-freebsd-doc
|
||||
For other languages, replace "en" with a language code like de or fr.
|
||||
|
||||
Show the version of FreeBSD installed: freebsd-version ; uname -a
|
||||
Please include that output and any error messages when posting questions.
|
||||
Introduction to manual pages: man man
|
||||
FreeBSD directory layout: man hier
|
||||
|
||||
Edit /etc/motd to change this login announcement.
|
||||
root@folsom:~ #
|
||||
```
|
||||
|
||||
At this point you are logged in to the container and have full shell access.
|
||||
The system is yours to use and/or abuse as you like. Any changes made inside
|
||||
the container are limited to the container.
|
||||
|
||||
|
||||
bastille cp
|
||||
-----------
|
||||
This sub-command allows efficiently copying files from host to container(s).
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille cp ALL /tmp/resolv.conf-cf etc/resolv.conf
|
||||
[folsom]:
|
||||
/tmp/resolv.conf-cf -> /usr/local/bastille/jails/folsom/root/etc/resolv.conf
|
||||
|
||||
[nginx]:
|
||||
/tmp/resolv.conf-cf -> /usr/local/bastille/jails/nginx/root/etc/resolv.conf
|
||||
|
||||
[squid]:
|
||||
/tmp/resolv.conf-cf -> /usr/local/bastille/jails/squid/root/etc/resolv.conf
|
||||
|
||||
[unbound0]:
|
||||
/tmp/resolv.conf-cf -> /usr/local/bastille/jails/unbound0/root/etc/resolv.conf
|
||||
```
|
||||
|
||||
bastille update
|
||||
---------------
|
||||
The `update` command targets a release instead of a container. Because every
|
||||
container is based on a release, when the release is updated all the containers
|
||||
are automatically updated as well.
|
||||
|
||||
To update all containers based on the 11.2-RELEASE `release`:
|
||||
|
||||
Up to date 11.2-RELEASE:
|
||||
```shell
|
||||
ishmael ~ # bastille update 11.2-RELEASE
|
||||
Targeting specified release.
|
||||
11.2-RELEASE
|
||||
|
||||
Looking up update.FreeBSD.org mirrors... 2 mirrors found.
|
||||
Fetching metadata signature for 11.2-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 are available to install.
|
||||
```
|
||||
|
||||
To be safe, you may want to restart any containers that have been updated live.
|
||||
|
||||
|
||||
bastille upgrade
|
||||
----------------
|
||||
This sub-command lets you upgrade a release to a new release. Depending on the
|
||||
workflow this can be similar to a `bootstrap`.
|
||||
|
||||
```shell
|
||||
ishmael ~ # bastille upgrade 11.3-RELEASE 12.0-RELEASE
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
bastille verify
|
||||
---------------
|
||||
This sub-command scans a bootstrapped release and validates that everything
|
||||
looks in order. This is not a 100% comprehensive check, but it compares the
|
||||
release against a "known good" index.
|
||||
|
||||
If you see errors or issues here, consider deleting and re-bootstrapping the
|
||||
release.
|
||||
|
||||
It should be noted that releases bootstrapped through Bastille are validated
|
||||
using `sha256` checksum against the release manifest. Archives that fail
|
||||
validation are not used.
|
||||
|
||||
|
||||
bastille zfs
|
||||
------------
|
||||
This sub-command allows managing zfs attributes for the targeted container(s).
|
||||
Common usage includes setting container quotas.
|
||||
|
||||
**set quota**
|
||||
```shell
|
||||
ishmael ~ # bastille zfs folsom set quota=1G
|
||||
```
|
||||
|
||||
**built-in: df**
|
||||
```shell
|
||||
ishmael ~ # bastille zfs ALL df
|
||||
```
|
||||
|
||||
**built-in: df**
|
||||
```shell
|
||||
ishmael ~ # bastille zfs folsom df
|
||||
```
|
||||
|
||||
|
||||
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 14.0-RELEASE 10.17.89.10/24
|
||||
```
|
||||
|
||||
```shell
|
||||
@@ -809,7 +144,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 14.0-RELEASE GENERIC
|
||||
|
||||
Welcome to FreeBSD!
|
||||
|
||||
@@ -817,7 +152,7 @@ Release Notes, Errata: https://www.FreeBSD.org/releases/
|
||||
Security Advisories: https://www.FreeBSD.org/security/
|
||||
FreeBSD Handbook: https://www.FreeBSD.org/handbook/
|
||||
FreeBSD FAQ: https://www.FreeBSD.org/faq/
|
||||
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
|
||||
Questions List: https://www.FreeBSD.org/lists/questions/
|
||||
FreeBSD Forums: https://forums.FreeBSD.org/
|
||||
|
||||
Documents installed with the system are in the /usr/local/share/doc/freebsd/
|
||||
@@ -829,7 +164,7 @@ Please include that output and any error messages when posting questions.
|
||||
Introduction to manual pages: man man
|
||||
FreeBSD directory layout: man hier
|
||||
|
||||
Edit /etc/motd to change this login announcement.
|
||||
To change this login announcement, see motd(5).
|
||||
root@alcatraz:~ #
|
||||
```
|
||||
|
||||
@@ -844,62 +179,6 @@ root 92565 0.0 0.0 7412 3756 3 SJ 02:21 0:00.01 -csh (csh)
|
||||
root@alcatraz:~ #
|
||||
```
|
||||
|
||||
|
||||
Project Goals
|
||||
=============
|
||||
These tools are created initially with the mindset of function over form. I
|
||||
want to simply prove the concept is sound for real work. The real work is a
|
||||
sort of meta-container-port system. Instead of installing the MySQL port
|
||||
directly on a system, you would use Bastille to install the MySQL port within a
|
||||
container template built for MySQL. The same goes for DNS servers, and
|
||||
everything else in the ports tree.
|
||||
|
||||
Eventually I would like to have Bastille templates created for popular
|
||||
FreeBSD-based services. From Plex Media Servers to ad-blocking DNS resolvers.
|
||||
From tiny SSH containers to dynamic web servers. [COMPLETE]
|
||||
|
||||
I don't want to tell you what you can and can't run within this framework.
|
||||
There are no arbitrary limitations based on what I think may or may not be the
|
||||
best way to design systems. This is not my goal.
|
||||
|
||||
My goal is to provide a secure framework where processes and services can run
|
||||
isolated. I want to limit the scope and reach of bad actors. I want to severely
|
||||
limit the target areas available to anyone that has (or has gained) access.
|
||||
|
||||
Networking Tips
|
||||
===============
|
||||
|
||||
Tip #1:
|
||||
-------
|
||||
Ports and destinations can be defined as lists. eg;
|
||||
```
|
||||
rdr pass inet proto tcp from any to any port {80, 443} -> {10.17.89.45, 10.17.89.46, 10.17.89.47, 10.17.89.48}
|
||||
```
|
||||
|
||||
This rule would redirect any traffic to the host on ports 80 or 443 and
|
||||
round-robin between containers with ips 45, 46, 47, and 48 (on ports 80 or
|
||||
443).
|
||||
|
||||
|
||||
Tip #2:
|
||||
-------
|
||||
Ports can redirect to other ports. eg;
|
||||
```
|
||||
rdr pass inet proto tcp from any to any port 8080 -> 10.17.89.5 port 80
|
||||
rdr pass inet proto tcp from any to any port 8081 -> 10.17.89.5 port 8080
|
||||
rdr pass inet proto tcp from any to any port 8181 -> 10.17.89.5 port 443
|
||||
```
|
||||
|
||||
Tip #3:
|
||||
-------
|
||||
Don't worry too much about IP assignments.
|
||||
|
||||
Initially I spent time worrying about what IP addresses to assign. In the end
|
||||
I've come to the conclusion that it _really_ doesn't matter. Pick *any* private
|
||||
address and be done with it. These are all isolated networks. In the end, what
|
||||
matters is you can map host:port to container:port reliably, and we can.
|
||||
|
||||
|
||||
Community Support
|
||||
=================
|
||||
If you've found a bug in Bastille, please submit it to the [Bastille Issue
|
||||
|
||||
86
ROADMAP.md
86
ROADMAP.md
@@ -1,45 +1,55 @@
|
||||
Bastille Roadmap
|
||||
================
|
||||
This is the general roadmap for the next nine months. I would like the
|
||||
near-term done by the end of 2018. The mid-term should be done by March 2019.
|
||||
The long-term by summer 2019.
|
||||
2020 Bastille Roadmap
|
||||
=====================
|
||||
|
||||
At that point, if the templating is mature, and the top 50 is complete, the
|
||||
platform is ready for general purpose use.
|
||||
1. Virtual Networking
|
||||
1. Bastille CI/CD
|
||||
1. Template Maturity & Consolidation
|
||||
1. Container Monitoring
|
||||
1. Bastille API
|
||||
|
||||
Rough timeline and description below.
|
||||
|
||||
near-term
|
||||
---------
|
||||
1. zfs support (configurable)
|
||||
2. bastille-dev template (see below):
|
||||
```shell
|
||||
## jail -c name=foo host.hostname=foo allow.raw_sockets children.max=99
|
||||
## ip4.addr=10.20.12.68 persist
|
||||
## jexec foo /bin/csh
|
||||
## foo# jail -c name=bar host.hostname=bar allow.raw_sockets
|
||||
## ip4.addr=10.20.12.68 persist
|
||||
## foo# jexec bar /bin/csh
|
||||
## bar# ping gritton.org
|
||||
```
|
||||
3. branding
|
||||
Virtual Networking (Jan-Feb) ~ 0.6.x-beta
|
||||
-----------------------------------------
|
||||
VNET (Virtual Networking) will allow fully virtualized network stacks. This
|
||||
would bring the total network options to three (loopback, LAN, VNET). The
|
||||
anticipated design would use a bridge device connected to containers via epair
|
||||
interfaces.
|
||||
|
||||
Bastille CI/CD (March-May) ~ 0.7.x-beta
|
||||
---------------------------------------
|
||||
While we have many of the templates validated by automatic CI/CD, we are not
|
||||
validating updates to Bastille itself. This automated validation of Pull
|
||||
Requests should be a priority early in the year with a full test suite designed
|
||||
to validate all expected uses of Bastille sub-commands.
|
||||
|
||||
mid-term
|
||||
--------
|
||||
1. templating
|
||||
2. ssh-to-jail demo (ie; ldap + .authorized_keys + command)
|
||||
```shell
|
||||
## TODO: .ssh/authorized_keys auto-launch into user jail
|
||||
## jail_create_login_hook() {
|
||||
## echo "permit nopass ${user} cmd /usr/sbin/jexec args ${name} /usr/bin/login -f ${user}" >> /usr/local/etc/doas.conf
|
||||
## echo "command='/usr/local/bin/doas /usr/sbin/jexec ${name} /usr/bin/login -f ${user}' ${pubkey}" >> $HOME/.ssh/authorized_keys
|
||||
## }
|
||||
```
|
||||
3. additional modules: ps, sockstat, pf, fstab.
|
||||
Template Maturity & Consolidation (June-Aug) ~ 0.8.x-beta
|
||||
---------------------------------------------------------
|
||||
Put the 101 templates found in GitHub's BastilleBSD-Templates repository into
|
||||
GitLab CI/CD pipeline until fully covered. This is a great place for community
|
||||
contribution. Templates are easy to create and verify and we'd love to
|
||||
replicate as much of the FreeBSD ports tree as possible!
|
||||
|
||||
In addition, it would be nice to create a consolidated repository of curated
|
||||
templates similar in design to the FreeBSD ports tree. This would contain all
|
||||
templates in a single repository and mimick ports behavior where appropriate.
|
||||
|
||||
long-term
|
||||
---------
|
||||
1. top 50
|
||||
2. monitoring
|
||||
3. rctl
|
||||
Container Monitoring (Sept-Oct) ~ 0.9.x-beta
|
||||
--------------------------------------------
|
||||
The ability to monitor processes, services, mounts, sockets, etc from the host.
|
||||
Auto-remediation would be simple enough to define. Notifications would probably
|
||||
require a plugin system for methods/endpoints.
|
||||
|
||||
Possible monitoring modules: ps, sockstat, pf, fstab
|
||||
|
||||
Possible notification modules: pagerduty, slack, splunk, ELK, etc.
|
||||
|
||||
Bastille API (Nov-Dec) ~ 1.0.x-beta
|
||||
-----------------------------------
|
||||
I have thoughts about a lightweight API for Bastille that would accept (json?)
|
||||
payloads of Bastille commands. The API should be lightweight just as Bastille
|
||||
is.
|
||||
|
||||
The API is scheduled later in the roadmap because I want to have the other
|
||||
components stable before we implement an API on top of it. The addition of the
|
||||
API should match up with Bastille 1.0-stable.
|
||||
|
||||
25
Vagrantfile
vendored
Normal file
25
Vagrantfile
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
|
||||
config.vm.define "bastille" do |vm_config|
|
||||
|
||||
vm_config.ssh.shell = "sh"
|
||||
|
||||
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"
|
||||
vb.cpus = "1"
|
||||
vb.memory = "1024"
|
||||
end
|
||||
|
||||
vm_config.vm.provision "shell", inline: "cd /vagrant; make install"
|
||||
vm_config.vm.provision "shell", inline: "pkg install -y git-lite"
|
||||
|
||||
end
|
||||
end
|
||||
@@ -16,4 +16,4 @@ help:
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
BIN
docs/chapters/bastilletweet.png
Normal file
BIN
docs/chapters/bastilletweet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
93
docs/chapters/gcp.rst
Normal file
93
docs/chapters/gcp.rst
Normal file
@@ -0,0 +1,93 @@
|
||||
Bastille VNET on GCP
|
||||
====================
|
||||
|
||||
Bastille VNET runs on GCP with a few small tweaks. In summary, they are:
|
||||
|
||||
- change MTU setting in jib script
|
||||
- add an IP address to the bridge interface
|
||||
- configure host pf to NAT and allow bridge traffic
|
||||
- set defaultrouter and nameserver in the host
|
||||
|
||||
## Change MTU in the jib script
|
||||
|
||||
GCP uses ``vtnet`` with MTU 1460, which [jib fails on](https://github.com/BastilleBSD/bastille/issues/538).
|
||||
|
||||
Apply the below patch to set the correct MTU. You may need to ``cp /usr/share/examples/jails/jib /usr/local/bin/`` first.
|
||||
|
||||
``patch /usr/local/bin/jib jib.patch``
|
||||
|
||||
.. code-block:: text
|
||||
--- /usr/local/bin/jib 2022-07-31 03:27:04.163245000 +0000
|
||||
+++ jib.fixed 2022-07-31 03:41:16.710401000 +0000
|
||||
@@ -299,14 +299,14 @@
|
||||
|
||||
# Make sure the interface has been bridged
|
||||
if ! ifconfig "$iface$bridge" > /dev/null 2>&1; then
|
||||
- new=$( ifconfig bridge create ) || return
|
||||
+ new=$( ifconfig bridge create mtu 1460 ) || return
|
||||
ifconfig $new addm $iface || return
|
||||
ifconfig $new name "$iface$bridge" || return
|
||||
ifconfig "$iface$bridge" up || return
|
||||
fi
|
||||
|
||||
# Create a new interface to the bridge
|
||||
- new=$( ifconfig epair create ) || return
|
||||
+ new=$( ifconfig epair create mtu 1460 ) || return
|
||||
ifconfig "$iface$bridge" addm $new || return
|
||||
|
||||
# Rename the new interface
|
||||
|
||||
## Configure bridge interface
|
||||
|
||||
Configure the bridge interface in /etc/rc.conf so it is available in the firewall rules.
|
||||
|
||||
.. code-block:: shell
|
||||
sysrc cloned_interfaces="bridge0"
|
||||
sysrc ifconfig_bridge0="inet 192.168.1.1/24 mtu 1460 addm vtnet0 name vtnet0bridge up"
|
||||
sysrc gateway_enable="yes"
|
||||
sysrc pf_enable="yes"
|
||||
|
||||
## Configure host pf
|
||||
|
||||
This basic /etc/pf.conf allow incoming packets on the bridge interface, and NATs them through the external interface:
|
||||
|
||||
.. code-block:: text
|
||||
ext_if="vtnet0"
|
||||
bridge_if="vtnet0bridge"
|
||||
|
||||
set skip on lo
|
||||
scrub in
|
||||
|
||||
# permissive NAT allows jail bridge and wireguard tunnels
|
||||
nat on $ext_if inet from !($ext_if) -> ($ext_if:0)
|
||||
|
||||
block in
|
||||
pass out
|
||||
|
||||
pass in proto tcp to port {22}
|
||||
pass in inet proto icmp icmp-type { echoreq }
|
||||
pass in on $bridge_if
|
||||
|
||||
Restart the host and make sure everything comes up correctly. You should see the following ifconfig:
|
||||
|
||||
.. code-block:: text
|
||||
vtnet0bridge: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1460
|
||||
ether 58:9c:fc:10:ff:90
|
||||
inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
|
||||
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
|
||||
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
|
||||
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
|
||||
member: vtnet0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
|
||||
ifmaxaddr 0 port 1 priority 128 path cost 2000
|
||||
groups: bridge
|
||||
|
||||
## Configure router and resolver for new jails
|
||||
|
||||
Set the default network gateway for new jails as described in the Networking chapter, and configure a default resolver.
|
||||
|
||||
.. code-block:: shell
|
||||
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_network_gateway="192.168.1.1"
|
||||
echo "nameserver 8.8.8.8" > /usr/local/etc/bastille/resolv.conf
|
||||
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_resolv_conf="/usr/local/etc/bastille/resolv.conf"
|
||||
|
||||
You can now create a VNET jail with ``bastille create -V myjail 13.2-RELEASE 192.168.1.50/24 vtnet0``
|
||||
@@ -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.5.20191125`.
|
||||
Current version is `0.10.20231125`.
|
||||
|
||||
To install from the FreeBSD package repository:
|
||||
|
||||
@@ -18,6 +18,8 @@ PKG
|
||||
.. code-block:: shell
|
||||
|
||||
pkg install bastille
|
||||
sysrc bastille_enable=YES
|
||||
sysrc bastille_rcorder=YES
|
||||
|
||||
|
||||
To install from source (don't worry, no compiling):
|
||||
@@ -28,3 +30,26 @@ ports
|
||||
.. code-block:: shell
|
||||
|
||||
make -C /usr/ports/sysutils/bastille install clean
|
||||
sysrc bastille_enable=YES
|
||||
sysrc bastille_rcorder=YES
|
||||
|
||||
|
||||
GIT
|
||||
---
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone https://github.com/BastilleBSD/bastille.git
|
||||
cd bastille
|
||||
make install
|
||||
sysrc bastille_enable=YES
|
||||
sysrc bastille_rcorder=YES
|
||||
|
||||
This method will install the latest files from GitHub directly onto your
|
||||
system. It is verbose about the files it installs (for later removal), and also
|
||||
has a `make uninstall` target. You may need to manually copy the `.sample`
|
||||
config into place before Bastille will run. (ie;
|
||||
`/usr/local/etc/bastille/bastille.conf.sample`)
|
||||
|
||||
Note: installing using this method overwrites the version variable to match
|
||||
that of the source revision commit hash.
|
||||
|
||||
@@ -13,108 +13,25 @@ template looks like this:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
interface = {interface};
|
||||
host.hostname = {name};
|
||||
exec.consolelog = /usr/local/bastille/logs/{name}_console.log;
|
||||
path = /usr/local/bastille/jails/{name}/root;
|
||||
ip6 = disable;
|
||||
securelevel = 2;
|
||||
devfs_ruleset = 4;
|
||||
enforce_statfs = 2;
|
||||
exec.start = '/bin/sh /etc/rc';
|
||||
exec.stop = '/bin/sh /etc/rc.shutdown';
|
||||
exec.clean;
|
||||
mount.devfs;
|
||||
mount.fstab = /usr/local/bastille/jails/{name}/fstab;
|
||||
|
||||
{name} {
|
||||
devfs_ruleset = 4;
|
||||
enforce_statfs = 2;
|
||||
exec.clean;
|
||||
exec.consolelog = /var/log/bastille/{name}_console.log;
|
||||
exec.start = '/bin/sh /etc/rc';
|
||||
exec.stop = '/bin/sh /etc/rc.shutdown';
|
||||
host.hostname = {name};
|
||||
interface = {interface};
|
||||
mount.devfs;
|
||||
mount.fstab = /usr/local/bastille/jails/{name}/fstab;
|
||||
path = /usr/local/bastille/jails/{name}/root;
|
||||
securelevel = 2;
|
||||
|
||||
ip4.addr = x.x.x.x;
|
||||
ip6 = disable;
|
||||
}
|
||||
|
||||
|
||||
interface
|
||||
---------
|
||||
.. code-block:: shell
|
||||
|
||||
interface
|
||||
A network interface to add the jail's IP addresses (ip4.addr and
|
||||
ip6.addr) to. An alias for each address will be added to the
|
||||
interface before the jail is created, and will be removed from
|
||||
the interface after the jail is removed.
|
||||
|
||||
|
||||
host.hostname
|
||||
-------------
|
||||
.. code-block:: shell
|
||||
|
||||
host.hostname
|
||||
The hostname of the jail. Other similar parameters are
|
||||
host.domainname, host.hostuuid and host.hostid.
|
||||
|
||||
|
||||
exec.consolelog
|
||||
---------------
|
||||
.. code-block:: shell
|
||||
|
||||
exec.consolelog
|
||||
A file to direct command output (stdout and stderr) to.
|
||||
|
||||
|
||||
path
|
||||
----
|
||||
.. code-block:: shell
|
||||
|
||||
path
|
||||
The directory which is to be the root of the jail. Any commands
|
||||
run inside the jail, either by jail or from jexec(8), are run
|
||||
from this directory.
|
||||
|
||||
|
||||
securelevel
|
||||
-----------
|
||||
By default, Bastille containers run at `securelevel = 2;`. See below for the
|
||||
implications of kernel security levels and when they might be altered.
|
||||
|
||||
Note: Bastille does not currently have any mechanism to automagically change
|
||||
securelevel settings. My recommendation is this only be altered manually on a
|
||||
case-by-case basis and that "Highly secure mode" is a sane default for most use
|
||||
cases.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
The kernel runs with five different security levels. Any super-user
|
||||
process can raise the level, but no process can lower it. The security
|
||||
levels are:
|
||||
|
||||
-1 Permanently insecure mode - always run the system in insecure mode.
|
||||
This is the default initial value.
|
||||
|
||||
0 Insecure mode - immutable and append-only flags may be turned off.
|
||||
All devices may be read or written subject to their permissions.
|
||||
|
||||
1 Secure mode - the system immutable and system append-only flags may
|
||||
not be turned off; disks for mounted file systems, /dev/mem and
|
||||
/dev/kmem may not be opened for writing; /dev/io (if your platform
|
||||
has it) may not be opened at all; kernel modules (see kld(4)) may
|
||||
not be loaded or unloaded. The kernel debugger may not be entered
|
||||
using the debug.kdb.enter sysctl. A panic or trap cannot be forced
|
||||
using the debug.kdb.panic and other sysctl's.
|
||||
|
||||
2 Highly secure mode - same as secure mode, plus disks may not be
|
||||
opened for writing (except by mount(2)) whether mounted or not.
|
||||
This level precludes tampering with file systems by unmounting
|
||||
them, but also inhibits running newfs(8) while the system is multi-
|
||||
user.
|
||||
|
||||
In addition, kernel time changes are restricted to less than or
|
||||
equal to one second. Attempts to change the time by more than this
|
||||
will log the message "Time adjustment clamped to +1 second".
|
||||
|
||||
3 Network secure mode - same as highly secure mode, plus IP packet
|
||||
filter rules (see ipfw(8), ipfirewall(4) and pfctl(8)) cannot be
|
||||
changed and dummynet(4) or pf(4) configuration cannot be adjusted.
|
||||
|
||||
|
||||
devfs_ruleset
|
||||
-------------
|
||||
.. code-block:: shell
|
||||
@@ -128,7 +45,7 @@ devfs_ruleset
|
||||
effective and enforce_statfs is set to a value lower than 2.
|
||||
Devfs rules and rulesets cannot be viewed or modified from inside
|
||||
a jail.
|
||||
|
||||
|
||||
NOTE: It is important that only appropriate device nodes in devfs
|
||||
be exposed to a jail; access to disk devices in the jail may
|
||||
permit processes in the jail to bypass the jail sandboxing by
|
||||
@@ -156,6 +73,27 @@ enforce_statfs
|
||||
located.
|
||||
|
||||
|
||||
exec.clean
|
||||
----------
|
||||
.. code-block:: shell
|
||||
|
||||
exec.clean
|
||||
Run commands in a clean environment. The environment is
|
||||
discarded except for HOME, SHELL, TERM and USER. HOME and SHELL
|
||||
are set to the target login's default values. USER is set to the
|
||||
target login. TERM is imported from the current environment.
|
||||
The environment variables from the login class capability
|
||||
database for the target login are also set.
|
||||
|
||||
|
||||
exec.consolelog
|
||||
---------------
|
||||
.. code-block:: shell
|
||||
|
||||
exec.consolelog
|
||||
A file to direct command output (stdout and stderr) to.
|
||||
|
||||
|
||||
exec.start
|
||||
----------
|
||||
.. code-block:: shell
|
||||
@@ -175,17 +113,24 @@ exec.stop
|
||||
typical command to run is "sh /etc/rc.shutdown".
|
||||
|
||||
|
||||
exec.clean
|
||||
----------
|
||||
host.hostname
|
||||
-------------
|
||||
.. code-block:: shell
|
||||
|
||||
exec.clean
|
||||
Run commands in a clean environment. The environment is
|
||||
discarded except for HOME, SHELL, TERM and USER. HOME and SHELL
|
||||
are set to the target login's default values. USER is set to the
|
||||
target login. TERM is imported from the current environment.
|
||||
The environment variables from the login class capability
|
||||
database for the target login are also set.
|
||||
host.hostname
|
||||
The hostname of the jail. Other similar parameters are
|
||||
host.domainname, host.hostuuid and host.hostid.
|
||||
|
||||
|
||||
interface
|
||||
---------
|
||||
.. code-block:: shell
|
||||
|
||||
interface
|
||||
A network interface to add the jail's IP addresses (ip4.addr and
|
||||
ip6.addr) to. An alias for each address will be added to the
|
||||
interface before the jail is created, and will be removed from
|
||||
the interface after the jail is removed.
|
||||
|
||||
|
||||
mount.devfs
|
||||
@@ -206,3 +151,58 @@ mount.fstab
|
||||
mount.fstab
|
||||
An fstab(5) format file containing filesystems to mount before
|
||||
creating a jail.
|
||||
|
||||
|
||||
path
|
||||
----
|
||||
.. code-block:: shell
|
||||
|
||||
path
|
||||
The directory which is to be the root of the jail. Any commands
|
||||
run inside the jail, either by jail or from jexec(8), are run
|
||||
from this directory.
|
||||
|
||||
|
||||
securelevel
|
||||
-----------
|
||||
By default, Bastille containers run at `securelevel = 2;`. See below for the
|
||||
implications of kernel security levels and when they might be altered.
|
||||
|
||||
Note: Bastille does not currently have any mechanism to automagically change
|
||||
securelevel settings. My recommendation is this only be altered manually on a
|
||||
case-by-case basis and that "Highly secure mode" is a sane default for most use
|
||||
cases.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
The kernel runs with five different security levels. Any super-user
|
||||
process can raise the level, but no process can lower it. The security
|
||||
levels are:
|
||||
|
||||
-1 Permanently insecure mode - always run the system in insecure mode.
|
||||
This is the default initial value.
|
||||
|
||||
0 Insecure mode - immutable and append-only flags may be turned off.
|
||||
All devices may be read or written subject to their permissions.
|
||||
|
||||
1 Secure mode - the system immutable and system append-only flags may
|
||||
not be turned off; disks for mounted file systems, /dev/mem and
|
||||
/dev/kmem may not be opened for writing; /dev/io (if your platform
|
||||
has it) may not be opened at all; kernel modules (see kld(4)) may
|
||||
not be loaded or unloaded. The kernel debugger may not be entered
|
||||
using the debug.kdb.enter sysctl. A panic or trap cannot be forced
|
||||
using the debug.kdb.panic and other sysctl's.
|
||||
|
||||
2 Highly secure mode - same as secure mode, plus disks may not be
|
||||
opened for writing (except by mount(2)) whether mounted or not.
|
||||
This level precludes tampering with file systems by unmounting
|
||||
them, but also inhibits running newfs(8) while the system is multi-
|
||||
user.
|
||||
|
||||
In addition, kernel time changes are restricted to less than or
|
||||
equal to one second. Attempts to change the time by more than this
|
||||
will log the message "Time adjustment clamped to +1 second".
|
||||
|
||||
3 Network secure mode - same as highly secure mode, plus IP packet
|
||||
filter rules (see ipfw(8), ipfirewall(4) and pfctl(8)) cannot be
|
||||
changed and dummynet(4) or pf(4) configuration cannot be adjusted.
|
||||
|
||||
36
docs/chapters/migration.rst
Normal file
36
docs/chapters/migration.rst
Normal file
@@ -0,0 +1,36 @@
|
||||
Stop the running jail and export it:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
iocage stop jailname
|
||||
iocage export jailname
|
||||
|
||||
Move the backup files (.zip and .sha256) into Bastille backup dir (default: /usr/local/bastille/backups/):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
mv /iocage/images/jailname_$(date +%F).* /usr/local/bastille/backups/
|
||||
|
||||
for remote systems you could use rsync:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
rsync -avh /iocage/images/jailname_$(date +%F).* root@10.0.1.10:/usr/local/bastille/backups/
|
||||
|
||||
|
||||
Import the iocage backup file (use zip file name)
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille import jailname_$(date +%F).zip
|
||||
|
||||
Set your new ip address and interface:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
vim /usr/local/bastille/jails/jailname/jail.conf
|
||||
interface = bastille0;
|
||||
ip4.addr = "192.168.0.1";
|
||||
|
||||
|
||||
You can use you primary network interface instead of the virtual bastille0 interface as well if you know what you’re doing.
|
||||
@@ -1,39 +1,44 @@
|
||||
Network Requirements
|
||||
====================
|
||||
Here's the scenario. You've installed Bastille at home or in the cloud and want
|
||||
to get started putting applications in secure little containers, but how do I
|
||||
get these containers on the network?
|
||||
to get started putting applications in secure little containers, but how do you
|
||||
get these containers on the network? Bastille tries to be flexible about how to
|
||||
network containerized applications. Four methods are described here.
|
||||
|
||||
Bastille tries to be flexible about how to network containerized applications.
|
||||
The two most common methods are described here. Consider both options to decide
|
||||
which design work best for your needs. One of the methods works better across
|
||||
clouds while the other is simpler if used in local area networks.
|
||||
1. Home or Small Office
|
||||
|
||||
As you've probably seen, Bastille containers require certain information when
|
||||
they are created. An IP address has to be assigned to the container through
|
||||
which all network traffic will flow.
|
||||
2. Cloud with IPV4 and multiple IPV6
|
||||
|
||||
When the container is started the IP address assigned at creation will be bound
|
||||
to a network interface. In FreeBSD these interfaces have different names, but
|
||||
look something like `em0`, `bge0`, `re0`, etc. On a virtual machine it may be
|
||||
`vtnet0`. You get the idea...
|
||||
3. Cloud with single IPV4 (internal bridge)
|
||||
|
||||
**Note: if you are running in the cloud and only have a single public IP you
|
||||
may want the Public Network option. See below.**
|
||||
4. Cloud with a single IPV4 (external bridge)
|
||||
|
||||
Please choose the option which is most appropriate for your environment.
|
||||
|
||||
Local Area Network
|
||||
------------------
|
||||
I will cover the local area network (LAN) method first. This method is simpler
|
||||
to get going and works well in a home network (or similar) where adding alias
|
||||
IP addresses is no problem.
|
||||
First a few notes. Bastille tries to verify that the interface name you provide
|
||||
is a valid interface. In FreeBSD network interfaces have different names, but
|
||||
look something like `em0`, `bge0`, `re0`, `vtnet0` etc. Running the ifconfig
|
||||
commend will tell you the name of your existing interfaces. Bastille also
|
||||
checks for a valid syntax IP4 or IP6 address. When you are testing calling out
|
||||
from your containers, please note that the ping command is disabled within the
|
||||
containers, because raw socket access are a security hole. Instead, install and
|
||||
test with `wget`/`curl`/`fetch` instead.
|
||||
|
||||
Bastille allows you to define the interface you want the IP attached to when
|
||||
you create it. An example:
|
||||
Shared Interface on Home or Small Office Network
|
||||
================================================
|
||||
If you have just one computer, or a home or small office network, where you are
|
||||
separated from the rest of the internet by a router. So you are free to use
|
||||
`private IP addresses
|
||||
<https://www.lifewire.com/what-is-a-private-ip-address-2625970>`_.
|
||||
|
||||
In this environment, to use Bastille, just create the container, give it a
|
||||
unique private ip address, and attach its ip address to your primary interface.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille create alcatraz 12.1-RELEASE 192.168.1.50 em0
|
||||
bastille create alcatraz 13.2-RELEASE 192.168.1.50 em0
|
||||
|
||||
You may have to change em0
|
||||
|
||||
When the `alcatraz` container is started it will add `192.168.1.50` as an IP
|
||||
alias to the `em0` interface. It will then simply be another member of the
|
||||
@@ -41,26 +46,172 @@ hosts network. Other networked systems (firewall permitting) should be able to
|
||||
reach services at that address.
|
||||
|
||||
This method is the simplest. All you need to know is the name of your network
|
||||
interface and a free IP on your current network.
|
||||
interface and a free IP on your local network.
|
||||
|
||||
(Bastille does try to verify that the interface name you provide it is a valid
|
||||
interface. This validation has not been exhaustively tested yet in Bastille's
|
||||
beta state.)
|
||||
Shared Interface on IPV6 network (vultr.com)
|
||||
============================================
|
||||
Some ISP's, such as `Vultr <https://vultr.com>`_, give you a single ipv4 address,
|
||||
and a large block of ipv6 addresses. You can then assign a unique ipv6 address
|
||||
to each Bastille Container.
|
||||
|
||||
On a virtual machine such as vultr.com the virtual interface may be `vtnet0`.
|
||||
So we issue the command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille create alcatraz 13.2-RELEASE 2001:19f0:6c01:114c::100 vtnet0
|
||||
|
||||
We could also write the ipv6 address as 2001:19f0:6c01:114c:0:100
|
||||
|
||||
The tricky part are the ipv6 addresses. IPV6 is a string of 8 4 digit
|
||||
hexadecimal characters. At vultr they said:
|
||||
|
||||
Your server was assigned the following six section subnet:
|
||||
|
||||
2001:19f0:6c01:114c:: / 64
|
||||
|
||||
The `vultr ipv6 subnet calculator
|
||||
<https://www.vultr.com/resources/subnet-calculator-ipv6/?prefix_length=64&display=long&ipv6_address=2001%3Adb8%3Aacad%3Ae%3A%3A%2F64>`_
|
||||
is helpful in making sense of that ipv6 address.
|
||||
|
||||
We could have also written that IPV6 address as 2001:19f0:6c01:114c:0:0
|
||||
|
||||
Where the /64 basicaly means that the first 64 bits of the address (4x4
|
||||
character hexadecimal) values define the network, and the remaining characters,
|
||||
we can assign as we want to the Bastille Container. In the actual bastille
|
||||
create command given above, it was defined to be 100. But we also have to tell
|
||||
the host operating system that we are now using this address. This is done on
|
||||
freebsd with the following command
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ifconfig_vtnet0_alias0="inet6 2001:19f0:6c01:114c::100 prefixlen 64"
|
||||
|
||||
At that point your container can talk to the world, and the world can ping your
|
||||
container. Of course when you reboot the machine, that command will be
|
||||
forgotten. To make it permanent, prefix the same command with `sysrc`
|
||||
|
||||
Just remember you cannot ping out from the container. Instead, install and
|
||||
use `wget`/`curl`/`fetch` to test the connectivity.
|
||||
|
||||
|
||||
Virtual Network (VNET)
|
||||
======================
|
||||
(Added in 0.6.x) VNET is supported on FreeBSD 12+ only.
|
||||
|
||||
Virtual Network (VNET) creates a private network interface for a container.
|
||||
This includes a unique hardware address. This is required for VPN, DHCP, and
|
||||
similar containers.
|
||||
|
||||
To create a VNET based container use the `-V` option, an IP/netmask and
|
||||
external interface.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille create -V azkaban 13.2-RELEASE 192.168.1.50/24 em0
|
||||
|
||||
Bastille will automagically create the bridge interface and connect /
|
||||
disconnect containers as they are started and stopped. A new interface will be
|
||||
created on the host matching the pattern `interface0bridge`. In the example
|
||||
here, `em0bridge`.
|
||||
|
||||
The `em0` interface will be attached to the bridge along with the unique
|
||||
container interfaces as they are started and stopped. These interface names
|
||||
match the pattern `eXb_bastilleX`. Internally to the containers these
|
||||
interfaces are presented as `vnet0`.
|
||||
|
||||
VNET also requires a custom devfs ruleset. Create the file as needed on the
|
||||
host system:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
## /etc/devfs.rules (NOT .conf)
|
||||
|
||||
[bastille_vnet=13]
|
||||
add include $devfsrules_hide_all
|
||||
add include $devfsrules_unhide_basic
|
||||
add include $devfsrules_unhide_login
|
||||
add include $devfsrules_jail
|
||||
add include $devfsrules_jail_vnet
|
||||
add path 'bpf*' unhide
|
||||
|
||||
Lastly, you may want to consider these three `sysctl` values:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
net.link.bridge.pfil_bridge=0
|
||||
net.link.bridge.pfil_onlyip=0
|
||||
net.link.bridge.pfil_member=0
|
||||
|
||||
Below is the definition of what these three parameters are used for and mean:
|
||||
|
||||
|
||||
net.link.bridge.pfil_onlyip Controls the handling of non-IP packets
|
||||
which are not passed to pfil(9). Set to 1
|
||||
to only allow IP packets to pass (subject
|
||||
to firewall rules), set to 0 to uncondi-
|
||||
tionally pass all non-IP Ethernet frames.
|
||||
|
||||
net.link.bridge.pfil_member Set to 1 to enable filtering on the incom-
|
||||
ing and outgoing member interfaces, set to
|
||||
0 to disable it.
|
||||
|
||||
net.link.bridge.pfil_bridge Set to 1 to enable filtering on the bridge
|
||||
interface, set to 0 to disable it.
|
||||
|
||||
|
||||
**Regarding Routes**
|
||||
|
||||
Bastille will attempt to auto-detect the default route from the host system and
|
||||
assign it to the VNET container. This auto-detection may not always be accurate
|
||||
for your needs for the particular container. In this case you'll need to add a
|
||||
default route manually or define the preferred default route in the
|
||||
`bastille.conf`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille sysrc TARGET defaultrouter=aa.bb.cc.dd
|
||||
bastille service TARGET routing restart
|
||||
|
||||
To define a default route / gateway for all VNET containers define the value in
|
||||
`bastille.conf`:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
bastille_network_gateway=aa.bb.cc.dd
|
||||
|
||||
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 13.2-RELEASE 192.168.1.50/24 bridge0
|
||||
|
||||
Bastille will automagically create the interface, attach it to the specified
|
||||
bridge and connect / disconnect containers as they are started and stopped.
|
||||
The bridge needs to be created/enabled before creating and starting the jail.
|
||||
|
||||
Public Network
|
||||
--------------
|
||||
In this section I'll describe how to network containers in a public network
|
||||
such as a cloud hosting provider (AWS, digital ocean, vultr, etc)
|
||||
==============
|
||||
In this section we describe how to network containers in a public network
|
||||
such as a cloud hosting provider who only provides you with a single ip address.
|
||||
(AWS, Digital Ocean, etc) (The exception is vultr.com, which does
|
||||
provide you with lots of IPV6 addresses and does a great job supporting FreeBSD!)
|
||||
|
||||
In the public cloud you don't often have access to multiple private IP
|
||||
addresses for your virtual machines. This means if you want to create multiple
|
||||
containers and assign them all IP addresses, you'll need to create a new
|
||||
So if you only have a single IP address and if you want to create multiple
|
||||
containers and assign them all unique IP addresses, you'll need to create a new
|
||||
network.
|
||||
|
||||
What I recommend is creating a cloned loopback interface (`bastille0`) and
|
||||
loopback (bastille0)
|
||||
--------------------
|
||||
What we recommend is creating a cloned loopback interface (`bastille0`) and
|
||||
assigning all the containers private (rfc1918) addresses on that interface. The
|
||||
setup I develop on and use Bastille day to day uses the `10.0.0.0/8` address
|
||||
setup I develop on and use Bastille day-to-day uses the `10.0.0.0/8` address
|
||||
range. I have the ability to use whatever address I want within that range
|
||||
because I've created my own private network. The host system then acts as the
|
||||
firewall, permitting and denying traffic as needed.
|
||||
@@ -81,7 +232,6 @@ First, create the loopback interface:
|
||||
ishmael ~ # sysrc cloned_interfaces+=lo1
|
||||
ishmael ~ # sysrc ifconfig_lo1_name="bastille0"
|
||||
ishmael ~ # service netif cloneup
|
||||
ishmael ~ # ifconfig bastille0 inet 10.17.89.10
|
||||
|
||||
Second, enable the firewall:
|
||||
|
||||
@@ -96,18 +246,17 @@ Create the firewall rules:
|
||||
.. code-block:: shell
|
||||
|
||||
ext_if="vtnet0"
|
||||
|
||||
|
||||
set block-policy return
|
||||
scrub in on $ext_if all fragment reassemble
|
||||
|
||||
set skip on lo
|
||||
nat on $ext_if from bastille0:network to any -> ($ext_if)
|
||||
|
||||
## rdr example
|
||||
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
|
||||
|
||||
table <jails> persist
|
||||
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
|
||||
|
||||
@@ -119,17 +268,32 @@ to containers are:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
nat on $ext_if from bastille0:network to any -> ($ext_if)
|
||||
|
||||
## rdr example
|
||||
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
|
||||
nat on $ext_if from <jails> to any -> ($ext_if:0)
|
||||
|
||||
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
|
||||
|
||||
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 TARGET tcp 2001 22 # Redirects tcp port 2001 on host to 22 on jail
|
||||
bastille rdr TARGET udp 2053 53 # Same for udp
|
||||
bastille rdr TARGET list # List dynamic rdr rules
|
||||
bastille rdr TARGET clear # Clear dynamic rdr rules
|
||||
|
||||
Note that if you are redirecting ports where the host is also listening (eg.
|
||||
ssh) you should make sure that the host service is not listening on the cloned
|
||||
interface - eg. for ssh set sshd_flags in rc.conf
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sshd_flags="-o ListenAddress=<host-address>"
|
||||
|
||||
Finally, start up the firewall:
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
=========
|
||||
bootstrap
|
||||
=========
|
||||
|
||||
@@ -21,20 +22,42 @@ 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
|
||||
|
||||
ishmael ~ # bastille bootstrap 11.3-RELEASE [update]
|
||||
ishmael ~ # bastille bootstrap 12.0-RELEASE
|
||||
ishmael ~ # bastille bootstrap 12.1-RELEASE
|
||||
|
||||
ishmael ~ # bastille bootstrap 14.0-RELEASE [update]
|
||||
ishmael ~ # bastille bootstrap 13.2-RELEASE [update]
|
||||
|
||||
To `bootstrap` a HardenedBSD release, run the bootstrap sub-command with the
|
||||
build version as the argument.
|
||||
|
||||
.. 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)
|
||||
before they are extracted for use.
|
||||
|
||||
EOL Releases
|
||||
------------
|
||||
|
||||
It is sometimes necessary to run end-of-life releases for testing or legacy
|
||||
application support. Dy default Bastille will only install supported releases
|
||||
but you can bootstrap EOL / unsupported releases with a simple trick.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # export BASTILLE_URL_FREEBSD=http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/
|
||||
ishmael ~ # bastille bootstrap 11.2-RELEASE
|
||||
|
||||
By overriding the BASTILLE_URL_FREEBSD variable you can now bootstrap archived
|
||||
releases from the FTP archive.
|
||||
|
||||
Tips
|
||||
----
|
||||
|
||||
|
||||
17
docs/chapters/subcommands/clone.rst
Normal file
17
docs/chapters/subcommands/clone.rst
Normal file
@@ -0,0 +1,17 @@
|
||||
=====
|
||||
clone
|
||||
=====
|
||||
|
||||
To clone a container and make a duplicate use the `bastille clone`
|
||||
sub-command..
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille clone azkaban rikers ip
|
||||
[azkaban]:
|
||||
|
||||
Syntax requires a name for the new container and an IP address assignment.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille clone [TARGET] [NEW_NAME] [IPADRESS].
|
||||
@@ -6,7 +6,7 @@ To execute commands within the container you can use `bastille cmd`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille cmd folsom 'ps -auxw'
|
||||
ishmael ~ # bastille cmd folsom ps -auxw
|
||||
[folsom]:
|
||||
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
|
||||
root 71464 0.0 0.0 14536 2000 - IsJ 4:52PM 0:00.00 /usr/sbin/syslogd -ss
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
=======
|
||||
console
|
||||
=======
|
||||
|
||||
@@ -8,27 +9,6 @@ root login.
|
||||
|
||||
ishmael ~ # bastille console folsom
|
||||
[folsom]:
|
||||
FreeBSD 12.1-RELEASE-p1 GENERIC
|
||||
|
||||
Welcome to FreeBSD!
|
||||
|
||||
Release Notes, Errata: https://www.FreeBSD.org/releases/
|
||||
Security Advisories: https://www.FreeBSD.org/security/
|
||||
FreeBSD Handbook: https://www.FreeBSD.org/handbook/
|
||||
FreeBSD FAQ: https://www.FreeBSD.org/faq/
|
||||
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
|
||||
FreeBSD Forums: https://forums.FreeBSD.org/
|
||||
|
||||
Documents installed with the system are in the /usr/local/share/doc/freebsd/
|
||||
directory, or can be installed later with: pkg install en-freebsd-doc
|
||||
For other languages, replace "en" with a language code like de or fr.
|
||||
|
||||
Show the version of FreeBSD installed: freebsd-version ; uname -a
|
||||
Please include that output and any error messages when posting questions.
|
||||
Introduction to manual pages: man man
|
||||
FreeBSD directory layout: man hier
|
||||
|
||||
Edit /etc/motd to change this login announcement.
|
||||
root@folsom:~ #
|
||||
|
||||
At this point you are logged in to the container and have full shell access. The
|
||||
|
||||
16
docs/chapters/subcommands/convert.rst
Normal file
16
docs/chapters/subcommands/convert.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
=======
|
||||
convert
|
||||
=======
|
||||
|
||||
To convert a thin container to a thick container use `bastille convert`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille convert azkaban
|
||||
[azkaban]:
|
||||
|
||||
Syntax requires only the target container to convert.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille convert TARGET
|
||||
@@ -1,3 +1,4 @@
|
||||
==
|
||||
cp
|
||||
==
|
||||
|
||||
@@ -7,15 +8,15 @@ This command allows efficiently copying files from host to container(s).
|
||||
|
||||
ishmael ~ # bastille cp ALL /tmp/resolv.conf-cf etc/resolv.conf
|
||||
[bastion]:
|
||||
|
||||
|
||||
[unbound0]:
|
||||
|
||||
|
||||
[unbound1]:
|
||||
|
||||
|
||||
[squid]:
|
||||
|
||||
|
||||
[nginx]:
|
||||
|
||||
|
||||
[folsom]:
|
||||
|
||||
Unless you see errors reported in the output the `cp` was successful.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
======
|
||||
create
|
||||
======
|
||||
|
||||
@@ -13,7 +14,7 @@ bootstrapped release and a private (rfc1918) IP address.
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille create folsom 11.3-RELEASE 10.17.89.10 [interface]
|
||||
|
||||
|
||||
RELEASE: 11.3-RELEASE.
|
||||
NAME: folsom.
|
||||
IP: 10.17.89.10.
|
||||
@@ -21,6 +22,15 @@ bootstrapped release and a private (rfc1918) IP address.
|
||||
This command will create a 11.3-RELEASE container assigning the 10.17.89.10 ip
|
||||
address to the new system.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille create alcatraz 13.2-RELEASE 10.17.89.113/24
|
||||
|
||||
|
||||
The above code will create a jail with a /24 mask. At the time of this documentation you
|
||||
can only use CIDR notation, and not use a netmask 255.255.255.0 to accomplish this.
|
||||
|
||||
|
||||
I recommend using private (rfc1918) ip address ranges for your container. These
|
||||
ranges include:
|
||||
|
||||
@@ -30,3 +40,13 @@ ranges include:
|
||||
|
||||
Bastille does its best to validate the submitted ip is valid. This has not been
|
||||
thouroughly tested--I generally use the 10/8 range.
|
||||
|
||||
A couple of notes about the created jails. First, MOTD has been disabled inside
|
||||
of the jails because it does not give information about the jail, but about the host
|
||||
system. This caused confusion for some users, so we implemented the .hushlogin which
|
||||
silences the MOTD at login.
|
||||
|
||||
Also, uname does not work from within a jail. Much like MOTD, it gives you the version
|
||||
information about the host system instead of the jail. If you need to check the version
|
||||
of freebsd running on the jail use the freebsd-version command to get accurate information.
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
=======
|
||||
destroy
|
||||
=======
|
||||
|
||||
|
||||
16
docs/chapters/subcommands/edit.rst
Normal file
16
docs/chapters/subcommands/edit.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
====
|
||||
edit
|
||||
====
|
||||
|
||||
To edit container configuration use `bastille edit`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille edit azkaban [filename]
|
||||
|
||||
Syntax requires a target an optional filename. By default the file edited will
|
||||
be `jail.conf`. Other common filenames are `fstab` or `rctl.conf`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille edit TARGET
|
||||
31
docs/chapters/subcommands/export.rst
Normal file
31
docs/chapters/subcommands/export.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
======
|
||||
export
|
||||
======
|
||||
|
||||
Exporting a container creates an archive or image that can be sent to a
|
||||
different machine to be imported later. These exported archives can be used as
|
||||
container backups.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
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 and they
|
||||
can be exported only when the jail is not running.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille export | option(s) | TARGET | PATH
|
||||
|
||||
Available options are:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
--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.
|
||||
@@ -2,7 +2,7 @@
|
||||
htop
|
||||
====
|
||||
|
||||
This one runs `htop` inside the container.
|
||||
This one runs `htop` inside the container.
|
||||
note: won't work if you don't have htop installed in the container.
|
||||
|
||||
|
||||
|
||||
16
docs/chapters/subcommands/import.rst
Normal file
16
docs/chapters/subcommands/import.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
======
|
||||
import
|
||||
======
|
||||
|
||||
Import a container backup image or archive.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille import /path/to/archive.file
|
||||
|
||||
The import sub-command supports both UFS and ZFS storage. ZFS based containers
|
||||
will use ZFS snapshots. UFS based containers will use `txz` archives.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille import file [option]
|
||||
@@ -7,19 +7,29 @@ Bastille sub-commands
|
||||
|
||||
bootstrap
|
||||
cmd
|
||||
clone
|
||||
console
|
||||
convert
|
||||
cp
|
||||
create
|
||||
destroy
|
||||
edit
|
||||
export
|
||||
htop
|
||||
import
|
||||
mount
|
||||
pkg
|
||||
rdr
|
||||
rename
|
||||
restart
|
||||
service
|
||||
setup
|
||||
start
|
||||
stop
|
||||
sysrc
|
||||
tags
|
||||
top
|
||||
update
|
||||
umount
|
||||
update
|
||||
upgrade
|
||||
verify
|
||||
|
||||
16
docs/chapters/subcommands/mount.rst
Normal file
16
docs/chapters/subcommands/mount.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
=====
|
||||
mount
|
||||
=====
|
||||
|
||||
To mount storage within the container use `bastille mount`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille mount azkaban /storage/foo /media/foo nullfs ro 0 0
|
||||
[azkaban]:
|
||||
|
||||
Syntax follows standard `/etc/fstab` format:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille mount TARGET host_path container_path [filesystem_type options dump pass_number]
|
||||
@@ -6,78 +6,20 @@ 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
|
||||
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:10:amd64/quarterly, please wait...
|
||||
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
|
||||
[folsom] Installing pkg-1.10.5_5...
|
||||
[folsom] Extracting pkg-1.10.5_5: 100%
|
||||
Updating FreeBSD repository catalogue...
|
||||
pkg: Repository FreeBSD load error: access repo file(/var/db/pkg/repo-FreeBSD.sqlite) failed: No such file or directory
|
||||
[folsom] Fetching meta.txz: 100% 944 B 0.9kB/s 00:01
|
||||
[folsom] Fetching packagesite.txz: 100% 6 MiB 3.4MB/s 00:02
|
||||
Processing entries: 100%
|
||||
FreeBSD repository update completed. 32550 packages processed.
|
||||
All repositories are up to date.
|
||||
Updating database digests format: 100%
|
||||
The following 10 package(s) will be affected (of 0 checked):
|
||||
|
||||
New packages to be INSTALLED:
|
||||
vim-console: 8.1.0342
|
||||
git-lite: 2.19.1
|
||||
zsh: 5.6.2
|
||||
expat: 2.2.6_1
|
||||
curl: 7.61.1
|
||||
libnghttp2: 1.33.0
|
||||
ca_root_nss: 3.40
|
||||
pcre: 8.42
|
||||
gettext-runtime: 0.19.8.1_1
|
||||
indexinfo: 0.3.1
|
||||
|
||||
...[snip]...
|
||||
|
||||
Number of packages to be installed: 10
|
||||
|
||||
|
||||
The process will require 77 MiB more space.
|
||||
17 MiB to be downloaded.
|
||||
|
||||
|
||||
Proceed with this action? [y/N]: y
|
||||
[folsom] [1/10] Fetching vim-console-8.1.0342.txz: 100% 5 MiB 5.8MB/s 00:01
|
||||
[folsom] [2/10] Fetching git-lite-2.19.1.txz: 100% 4 MiB 2.1MB/s 00:02
|
||||
[folsom] [3/10] Fetching zsh-5.6.2.txz: 100% 4 MiB 4.4MB/s 00:01
|
||||
[folsom] [4/10] Fetching expat-2.2.6_1.txz: 100% 109 KiB 111.8kB/s 00:01
|
||||
[folsom] [5/10] Fetching curl-7.61.1.txz: 100% 1 MiB 1.2MB/s 00:01
|
||||
[folsom] [6/10] Fetching libnghttp2-1.33.0.txz: 100% 107 KiB 109.8kB/s 00:01
|
||||
[folsom] [7/10] Fetching ca_root_nss-3.40.txz: 100% 287 KiB 294.3kB/s 00:01
|
||||
[folsom] [8/10] Fetching pcre-8.42.txz: 100% 1 MiB 1.2MB/s 00:01
|
||||
[folsom] [9/10] Fetching gettext-runtime-0.19.8.1_1.txz: 100% 148 KiB 151.3kB/s 00:01
|
||||
[folsom] [10/10] Fetching indexinfo-0.3.1.txz: 100% 6 KiB 5.7kB/s 00:01
|
||||
Checking integrity... done (0 conflicting)
|
||||
[folsom] [1/10] Installing libnghttp2-1.33.0...
|
||||
[folsom] [1/10] Extracting libnghttp2-1.33.0: 100%
|
||||
[folsom] [2/10] Installing ca_root_nss-3.40...
|
||||
[folsom] [2/10] Extracting ca_root_nss-3.40: 100%
|
||||
[folsom] [3/10] Installing indexinfo-0.3.1...
|
||||
[folsom] [3/10] Extracting indexinfo-0.3.1: 100%
|
||||
[folsom] [4/10] Installing expat-2.2.6_1...
|
||||
[folsom] [4/10] Extracting expat-2.2.6_1: 100%
|
||||
[folsom] [5/10] Installing curl-7.61.1...
|
||||
[folsom] [5/10] Extracting curl-7.61.1: 100%
|
||||
[folsom] [6/10] Installing pcre-8.42...
|
||||
[folsom] [6/10] Extracting pcre-8.42: 100%
|
||||
[folsom] [7/10] Installing gettext-runtime-0.19.8.1_1...
|
||||
[folsom] [7/10] Extracting gettext-runtime-0.19.8.1_1: 100%
|
||||
[folsom] [8/10] Installing vim-console-8.1.0342...
|
||||
[folsom] [8/10] Extracting vim-console-8.1.0342: 100%
|
||||
[folsom] [9/10] Installing git-lite-2.19.1...
|
||||
===> Creating groups.
|
||||
Creating group 'git_daemon' with gid '964'.
|
||||
===> Creating users
|
||||
Creating user 'git_daemon' with uid '964'.
|
||||
[folsom] [9/10] Extracting git-lite-2.19.1: 100%
|
||||
[folsom] [10/10] Installing zsh-5.6.2...
|
||||
[folsom] [10/10] Extracting zsh-5.6.2: 100%
|
||||
|
||||
...[snip]...
|
||||
|
||||
|
||||
The PKG sub-command can, of course, do more than just `install`. The
|
||||
expectation is that you can fully leverage the pkg manager. This means,
|
||||
@@ -97,7 +39,7 @@ expectation is that you can fully leverage the pkg manager. This means,
|
||||
Processing candidates (1 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
|
||||
[unbound0]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[unbound0] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
@@ -109,7 +51,7 @@ expectation is that you can fully leverage the pkg manager. This means,
|
||||
Processing candidates (0 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
|
||||
[unbound1]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[unbound1] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
@@ -121,7 +63,7 @@ expectation is that you can fully leverage the pkg manager. This means,
|
||||
Processing candidates (0 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
|
||||
[squid]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[squid] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
@@ -133,7 +75,7 @@ expectation is that you can fully leverage the pkg manager. This means,
|
||||
Processing candidates (0 candidates): 100%
|
||||
Checking integrity... done (0 conflicting)
|
||||
Your packages are up to date.
|
||||
|
||||
|
||||
[nginx]:
|
||||
Updating pkg.bastillebsd.org repository catalogue...
|
||||
[nginx] Fetching meta.txz: 100% 560 B 0.6kB/s 00:01
|
||||
@@ -144,21 +86,21 @@ expectation is that you can fully leverage the pkg manager. This means,
|
||||
Checking for upgrades (1 candidates): 100%
|
||||
Processing candidates (1 candidates): 100%
|
||||
The following 1 package(s) will be affected (of 0 checked):
|
||||
|
||||
|
||||
Installed packages to be UPGRADED:
|
||||
nginx-lite: 1.14.0_14,2 -> 1.14.1,2
|
||||
|
||||
nginx-lite: 1.23.0 -> 1.24.0_12,3
|
||||
|
||||
Number of packages to be upgraded: 1
|
||||
|
||||
|
||||
315 KiB to be downloaded.
|
||||
|
||||
|
||||
Proceed with this action? [y/N]: y
|
||||
[nginx] [1/1] Fetching nginx-lite-1.14.1,2.txz: 100% 315 KiB 322.8kB/s 00:01
|
||||
Checking integrity... done (0 conflicting)
|
||||
[nginx] [1/1] Upgrading nginx-lite from 1.14.0_14,2 to 1.14.1,2...
|
||||
[nginx] [1/1] Upgrading nginx-lite from 1.23.0 to 1.24.0_12,3...
|
||||
===> Creating groups.
|
||||
Using existing group 'www'.
|
||||
===> Creating users
|
||||
Using existing user 'www'.
|
||||
[nginx] [1/1] Extracting nginx-lite-1.14.1,2: 100%
|
||||
[nginx] [1/1] Extracting nginx-lite-1.24.0_12: 100%
|
||||
You may need to manually remove /usr/local/etc/nginx/nginx.conf if it is no longer needed.
|
||||
|
||||
26
docs/chapters/subcommands/rdr.rst
Normal file
26
docs/chapters/subcommands/rdr.rst
Normal file
@@ -0,0 +1,26 @@
|
||||
===
|
||||
rdr
|
||||
===
|
||||
|
||||
`bastille rdr` allows you to configure dynamic rdr rules for your containers
|
||||
without modifying pf.conf (assuming you are using the `bastille0` interface
|
||||
for a private network and have enabled `rdr-anchor 'rdr/*'` in /etc/pf.conf
|
||||
as described in the Networking section).
|
||||
|
||||
Note: you need to be careful if host services are configured to run
|
||||
on all interfaces as this will include the jail interface - you should
|
||||
specify the interface they run on in rc.conf (or other config files)
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
# bastille rdr --help
|
||||
Usage: bastille rdr TARGET [clear] | [list] | [tcp <host_port> <jail_port>] | [udp <host_port> <jail_port>]
|
||||
# bastille rdr dev1 tcp 2001 22
|
||||
# bastille rdr dev1 list
|
||||
rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22
|
||||
# bastille rdr dev1 udp 2053 53
|
||||
# bastille rdr dev1 list
|
||||
rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22
|
||||
rdr on em0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53
|
||||
# bastille rdr dev1 clear
|
||||
nat cleared
|
||||
13
docs/chapters/subcommands/rename.rst
Normal file
13
docs/chapters/subcommands/rename.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
======
|
||||
rename
|
||||
======
|
||||
|
||||
Rename a container.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille rename azkaban arkham
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille rename TARGET new_name
|
||||
@@ -1,3 +1,4 @@
|
||||
=======
|
||||
restart
|
||||
=======
|
||||
|
||||
@@ -8,6 +9,6 @@ To restart a container you can use the `bastille restart` command.
|
||||
ishmael ~ # bastille restart folsom
|
||||
[folsom]:
|
||||
folsom: removed
|
||||
|
||||
|
||||
[folsom]:
|
||||
folsom: created
|
||||
|
||||
@@ -11,3 +11,6 @@ running inside the containers.
|
||||
ishmael ~ # bastille service web01 'nginx start'
|
||||
ishmael ~ # bastille service db01 'mysql-server restart'
|
||||
ishmael ~ # bastille service proxy 'nginx configtest'
|
||||
ishmael ~ # bastille service proxy 'nginx enable'
|
||||
ishmael ~ # bastille service proxy 'nginx disable'
|
||||
ishmael ~ # bastille service proxy 'nginx delete'
|
||||
|
||||
16
docs/chapters/subcommands/setup.rst
Normal file
16
docs/chapters/subcommands/setup.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
=====
|
||||
setup
|
||||
=====
|
||||
|
||||
The `setup` sub-command attempts to automatically configure a host system for
|
||||
Bastille containers. This allows you to configure networking, firewall, and storage
|
||||
options for a Bastille host with one command.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille setup -h ## display setup help
|
||||
ishmael ~ # bastille setup bastille0 ## only configure loopback interface
|
||||
ishmael ~ # bastille setup pf ## only configure default firewall
|
||||
ishmael ~ # bastille setup zfs ## only configure ZFS storage
|
||||
ishmael ~ # bastille setup vnet ## only configure VNET bridge
|
||||
ishmael ~ # bastille setup ## configure all of the above
|
||||
@@ -1,3 +1,4 @@
|
||||
=====
|
||||
start
|
||||
=====
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
====
|
||||
stop
|
||||
====
|
||||
|
||||
|
||||
13
docs/chapters/subcommands/tags.rst
Normal file
13
docs/chapters/subcommands/tags.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
====
|
||||
tags
|
||||
====
|
||||
|
||||
The `tags` sub-command adds, removes or lists arbitrary tags on your containers.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille tags -h ## display tags help
|
||||
ishmael ~ # bastille tags TARGET add tag1,tag2 ## add the tags "tag1" and "tag2" to TARGET
|
||||
ishmael ~ # bastille tags TARGET delete tag2 ## delete tag "tag2" from TARGET
|
||||
ishmael ~ # bastille tags TARGET list ## list tags assigned to TARGET
|
||||
ishmael ~ # bastille tags ALL list ## list tags from ALL containers
|
||||
@@ -2,7 +2,7 @@
|
||||
top
|
||||
===
|
||||
|
||||
This one runs `top` in that container.
|
||||
This one runs `top` in that container.
|
||||
|
||||
|
||||
.. image:: ../../images/top.png
|
||||
|
||||
16
docs/chapters/subcommands/umount.rst
Normal file
16
docs/chapters/subcommands/umount.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
======
|
||||
umount
|
||||
======
|
||||
|
||||
To unmount storage from a container use `bastille umount`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille umount azkaban /media/foo
|
||||
[azkaban]:
|
||||
|
||||
Syntax requires only the container path to unmount:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
Usage: bastille umount TARGET container_path
|
||||
@@ -10,14 +10,14 @@ If no updates are available, a message will be shown:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille update 11.2-RELEASE
|
||||
ishmael ~ # bastille update 11.4-RELEASE
|
||||
Looking up update.FreeBSD.org mirrors... 2 mirrors found.
|
||||
Fetching metadata signature for 11.2-RELEASE from update4.freebsd.org... done.
|
||||
Fetching metadata signature for 11.4-RELEASE from update4.freebsd.org... done.
|
||||
Fetching metadata index... done.
|
||||
Inspecting system... done.
|
||||
Preparing to download files... done.
|
||||
|
||||
No updates needed to update system to 11.2-RELEASE-p4.
|
||||
|
||||
No updates needed to update system to 11.4-RELEASE-p4.
|
||||
No updates are available to install.
|
||||
|
||||
|
||||
@@ -25,17 +25,17 @@ The older the release, however, the more updates will be available:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille update 10.4-RELEASE
|
||||
ishmael ~ # bastille update 13.2-RELEASE
|
||||
Looking up update.FreeBSD.org mirrors... 2 mirrors found.
|
||||
Fetching metadata signature for 10.4-RELEASE from update1.freebsd.org... done.
|
||||
Fetching metadata signature for 13.2-RELEASE from update1.freebsd.org... done.
|
||||
Fetching metadata index... done.
|
||||
Fetching 2 metadata patches.. done.
|
||||
Applying metadata patches... done.
|
||||
Fetching 2 metadata files... done.
|
||||
Inspecting system... done.
|
||||
Preparing to download files... done.
|
||||
|
||||
The following files will be added as part of updating to 10.4-RELEASE-p13:
|
||||
|
||||
The following files will be added as part of updating to 13.2-RELEASE-p4:
|
||||
...[snip]...
|
||||
|
||||
To be safe, you may want to restart any containers that have been updated live.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
=======
|
||||
upgrade
|
||||
=======
|
||||
|
||||
This command lets you upgrade a release to a new release. Depending on the
|
||||
workflow this can be similar to a `bootstrap`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille upgrade 11.2-RELEASE 12.0-RELEASE
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Targeting
|
||||
=========
|
||||
|
||||
Bastille uses a `command-target-args` syntax, meaning that each command
|
||||
Bastille uses a `command target arguments` syntax, meaning that each command
|
||||
requires a target. Targets are usually containers, but can also be releases.
|
||||
|
||||
Targeting a containers is done by providing the exact containers name.
|
||||
Targeting a container is done by providing the exact containers name.
|
||||
|
||||
Targeting a release is done by providing the release name. (Note: do note
|
||||
Targeting a release is done by providing the release name. (Note: do not
|
||||
include the `-pX` point-release version.)
|
||||
|
||||
Bastille includes a pre-defined keyword ALL to target all running containers.
|
||||
@@ -25,25 +25,25 @@ Examples: Containers
|
||||
| command | target | args | description |
|
||||
+===========+========+==================+=============================================================+
|
||||
| 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 |
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
| pkg | ALL | audit | (CVE) audit packages in ALL containers |
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
| sysrc | web01 | nginx_enable=YES | execute `sysrc nginx_enable=YES` in web01 container |
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
+-----------+--------+------------------+-------------------------------------------------------------+
|
||||
| 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|
|
||||
+----+------+----+---+------------------+--------------+----------------------------------------------+
|
||||
| create | folsom | 12.0-RELEASE 10.17.89.10 | create 12.0 container named `folsom` with IP |
|
||||
+-----------+--------+------------------+--------------+----------------------------------------------+
|
||||
+----+------+----+---+---------------------------------+----------------------------------------------+
|
||||
| create | folsom | 13.2-RELEASE 10.17.89.10 | create 13.2 container named `folsom` with IP |
|
||||
+-----------+--------+---------------------------------+----------------------------------------------+
|
||||
|
||||
|
||||
Examples: Releases
|
||||
@@ -56,11 +56,9 @@ Examples: Releases
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| command | target | args | description |
|
||||
+===========+==============+==============+=============================================================+
|
||||
| bootstrap | 12.0-RELEASE | --- | bootstrap 12.0-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| update | 11.3-RELEASE | --- | update 11.2-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| upgrade | 11.2-RELEASE | 11.3-RELEASE | update 11.2-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| verify | 11.3-RELEASE | --- | update 11.2-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| bootstrap | 13.2-RELEASE | --- | bootstrap 13.2-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| update | 12.4-RELEASE | --- | update 12.4-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
| verify | 12.4-RELEASE | --- | verify 12.4-RELEASE release |
|
||||
+-----------+--------------+--------------+-------------------------------------------------------------+
|
||||
|
||||
@@ -1,59 +1,63 @@
|
||||
========
|
||||
Template
|
||||
========
|
||||
Looking for ready made CI/CD validated `Bastille Templates`_?
|
||||
|
||||
Bastille supports a templating system allowing you to apply files, pkgs and
|
||||
execute commands inside the containers automatically.
|
||||
|
||||
Currently supported template hooks are: `PRE`, `OVERLAY`, `PKG`, `SYSRC`, `CMD`.
|
||||
Planned template hooks include: `FSTAB`, `PF`, `LOG`.
|
||||
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. Simply create a new directory named after the template. eg;
|
||||
the template hooks.
|
||||
|
||||
.. code-block:: shell
|
||||
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
|
||||
`Bastillefile` and the template hook (see below) files are replaced with
|
||||
template hook commands.
|
||||
|
||||
mkdir -p /usr/local/bastille/templates/username/base
|
||||
Template Automation Hooks
|
||||
-------------------------
|
||||
|
||||
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;
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| HOOK | format | example |
|
||||
+=========+===================+=========================================+
|
||||
| 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 |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| LIMITS | resource value | memoryuse 1G |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| MOUNT | fstab syntax | /host/path container/path nullfs ro 0 0 |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| RDR | tcp port port | tcp 2200 22 (hostport jailport) |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| SERVICE | service command | 'nginx start' OR 'postfix reload' |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
| SYSRC | sysrc command(s) | nginx_enable=YES |
|
||||
+---------+-------------------+-----------------------------------------+
|
||||
|
||||
.. code-block:: shell
|
||||
Note: SYSRC requires that NO quotes be used or that quotes (`"`) be escaped
|
||||
ie; (`\\"`)
|
||||
|
||||
echo "zsh vim-console git-lite htop" > /usr/local/bastille/templates/username/base/PKG
|
||||
echo "/usr/bin/chsh -s /usr/local/bin/zsh" > /usr/local/bastille/templates/username/base/CMD
|
||||
echo "etc\nrootjn usr" > /usr/local/bastille/templates/username/base/OVERLAY
|
||||
|
||||
Template hooks are executed in specific order and require specific syntax to
|
||||
work as expected. This table outlines those requirements:
|
||||
|
||||
|
||||
+---------+------------------+--------------------------------------+
|
||||
| HOOK | format | example |
|
||||
+=========+==================+======================================+
|
||||
| PRE | /bin/sh command | mkdir -p /usr/local/my_app/html |
|
||||
+---------+------------------+--------------------------------------+
|
||||
| OVERLAY | path(s) | etc root usr (one per line) |
|
||||
+---------+------------------+--------------------------------------+
|
||||
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
|
||||
+---------+------------------+--------------------------------------+
|
||||
| SYSRC | sysrc command(s) | nginx_enable=YES |
|
||||
+---------+------------------+--------------------------------------+
|
||||
| SERVICE | service command | 'nginx start' OR 'postfix reload' |
|
||||
+---------+------------------+--------------------------------------+
|
||||
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
|
||||
+---------+------------------+--------------------------------------+
|
||||
|
||||
Note: SYSRC requires that NO quotes be used or that quotes (`"`) be escaped.
|
||||
ie; `\"`)
|
||||
Place these uppercase template hook commands into a `Bastillefile` in any order
|
||||
and automate container setup as needed.
|
||||
|
||||
In addition to supporting template hooks, Bastille supports overlaying
|
||||
files into the container. This is done by placing the files in their full path,
|
||||
using the template directory as "/".
|
||||
|
||||
An example here may help. Think of `bastille/templates/username/base`, our
|
||||
An example here may help. Think of `bastille/templates/username/template`, our
|
||||
example template, as the root of our filesystem overlay. If you create an
|
||||
`etc/hosts` or `etc/resolv.conf` *inside* the base template directory, these
|
||||
`etc/hosts` or `etc/resolv.conf` *inside* the template directory, these
|
||||
can be overlayed into your container.
|
||||
|
||||
Note: due to the way FreeBSD segregates user-space, the majority of your
|
||||
@@ -61,17 +65,16 @@ overlayed template files will be in `usr/local`. The few general
|
||||
exceptions are the `etc/hosts`, `etc/resolv.conf`, and
|
||||
`etc/rc.conf.local`.
|
||||
|
||||
After populating `usr/local/` with custom config files that your container will
|
||||
After populating `usr/local` with custom config files that your container will
|
||||
use, be sure to include `usr` in the template OVERLAY definition. eg;
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
echo "etc\nusr" > /usr/local/bastille/templates/username/base/OVERLAY
|
||||
echo "CP usr /" >> /usr/local/bastille/templates/username/template/Bastillefile
|
||||
|
||||
The above example "etc usr" will include anything under "etc" and "usr"
|
||||
inside the template. You do not need to list individual files. Just
|
||||
include the top-level directory name. List these top-level directories one per
|
||||
line.
|
||||
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
|
||||
name. List these top-level directories one per line.
|
||||
|
||||
Applying Templates
|
||||
------------------
|
||||
@@ -84,7 +87,7 @@ directory names in the `bastille/templates` directory.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille template ALL username/base
|
||||
ishmael ~ # bastille template ALL username/template
|
||||
[proxy01]:
|
||||
Copying files...
|
||||
Copy complete.
|
||||
@@ -107,7 +110,7 @@ directory names in the `bastille/templates` directory.
|
||||
Executing final command(s).
|
||||
chsh: user information updated
|
||||
Template Complete.
|
||||
|
||||
|
||||
[web01]:
|
||||
Copying files...
|
||||
Copy complete.
|
||||
@@ -136,3 +139,37 @@ directory names in the `bastille/templates` directory.
|
||||
chsh: user information updated
|
||||
Template Complete.
|
||||
|
||||
.. _Bastille Templates: https://gitlab.com/BastilleBSD-Templates
|
||||
|
||||
Using Ports in Templates
|
||||
------------------------
|
||||
|
||||
Sometimes when you make a template you need special options for a package, or you need a newer version than what is in the pkgs. The solution for these cases, or a case like minecraft server that has NO compiled option, is to use the ports. A working example of this is the minecraft server template in the template repo. The main lines needed to use this is first to mount the ports directory, then compile the port. Below is an example of the minecraft template where this was used.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ARG MINECRAFT_MEMX="1024M"
|
||||
ARG MINECRAFT_MEMS="1024M"
|
||||
ARG MINECRAFT_ARGS=""
|
||||
CONFIG set enforce_statfs=1;
|
||||
CONFIG set allow.mount.fdescfs;
|
||||
CONFIG set allow.mount.procfs;
|
||||
RESTART
|
||||
PKG dialog4ports tmux openjdk17
|
||||
MOUNT /usr/ports usr/ports nullfs ro 0 0
|
||||
CP etc /
|
||||
CP var /
|
||||
CMD make -C /usr/ports/games/minecraft-server install clean
|
||||
CP usr /
|
||||
SYSRC minecraft_enable=YES
|
||||
SYSRC minecraft_memx=${MINECRAFT_MEMX}
|
||||
SYSRC minecraft_mems=${MINECRAFT_MEMS}
|
||||
SYSRC minecraft_args=${MINECRAFT_ARGS}
|
||||
SERVICE minecraft restart
|
||||
RDR tcp 25565 25565
|
||||
|
||||
The MOUNT line mounts the ports directory, then the CMD make line makes the port. This can be modified to use any port in the port tree.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
41
docs/chapters/upgrading.rst
Normal file
41
docs/chapters/upgrading.rst
Normal file
@@ -0,0 +1,41 @@
|
||||
=========
|
||||
Upgrading
|
||||
=========
|
||||
This document outlines upgrading jails hosted using Bastille.
|
||||
|
||||
Bastille can "bootstrap" multiple versions of FreeBSD to be used by jails. All jails do not NEED to be the same version (even if they often are), the only requirement here is that the "bootstrapped" versions are less than or equal to the host version of FreeBSD.
|
||||
|
||||
To upgrade Bastille jails for a minor release (ie; 13.1→13.2) you can do the following:
|
||||
|
||||
1. ensure the new release version is bootstrapped and updated to the latest patch release: `bastille bootstrap 13.2-RELEASE update`
|
||||
2. stop the jail(s) that need to be updated.
|
||||
3. use `bastille edit TARGET fstab` to manually update the jail mounts from 13.1 to 13.2 release path.
|
||||
4. start the jail(s) that were edited
|
||||
5. upgrade complete!
|
||||
|
||||
To upgrade Bastille jails for a major release (ie; 12.4→13.2) you can do the following:
|
||||
|
||||
1. ensure the new version is bootstrapped and update to the latest patch release: `bastille bootstrap 13.2-RELEASE update`
|
||||
2. stop the jail(s) that need to be updated.
|
||||
3. use `bastille edit TARGET fstab` to manually update the jail mounts from 12.4 to 13.2 release path.
|
||||
4. start the jail(s) that were edited
|
||||
5. Force the reinstallation or upgrade of all installed packages (ABI change): `pkg upgrade -f` within each jail (or `bastille pkg ALL upgrade -f`)
|
||||
6. restart the affected jail(s)
|
||||
7. upgrade complete!
|
||||
|
||||
Revert Upgrade / Downgrade Process
|
||||
----------------------------------
|
||||
The downgrade process (not usually needed) is similar to the upgrade process only in reverse.
|
||||
|
||||
If you did a minor upgrade changing the release path from 13.1 to 13.2, stop the jail and revert that change. Downgrade complete.
|
||||
|
||||
If you did a major upgrade changing the release path from 12.4 to 13.2, stop the jail and revert that change. The pkg reinstallation will also need to be repeated after the jail restarts on the previous release.
|
||||
|
||||
Old Releases
|
||||
----------------------------------
|
||||
After upgrading all jails from one release to the next you may find that you now have bootstrapped a release that is no longer used. Once you've decided that you no longer need the option to revert the change you can destroy the old release.
|
||||
|
||||
|
||||
`bastille list releases` to list all bootstrapped releases.
|
||||
|
||||
`bastille destroy X.Y-RELEASE` to fully delete the release.
|
||||
@@ -3,35 +3,47 @@ Usage
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ishmael ~ # bastille -h
|
||||
ishmael ~ # bastille help
|
||||
Bastille is an open-source system for automating deployment and management of
|
||||
containerized applications on FreeBSD.
|
||||
|
||||
|
||||
Usage:
|
||||
bastille command [ALL|glob] [args]
|
||||
|
||||
bastille command TARGET [args]
|
||||
|
||||
Available Commands:
|
||||
bootstrap Bootstrap a FreeBSD release for container base.
|
||||
cmd Execute arbitrary command on targeted container(s).
|
||||
clone Clone an existing container.
|
||||
config Get or set a config value for the targeted container(s).
|
||||
console Console into a running container.
|
||||
convert Convert a Thin container into a Thick container.
|
||||
cp cp(1) files from host to targeted container(s).
|
||||
create Create a new thin container or a thick container if -T|--thick option specified.
|
||||
destroy Destroy a stopped container or a FreeBSD release.
|
||||
help Help about any command
|
||||
edit Edit container configuration files (advanced).
|
||||
export Exports a specified container.
|
||||
help Help about any command.
|
||||
htop Interactive process viewer (requires htop).
|
||||
list List containers, releases, templates, or logs.
|
||||
import Import a specified container.
|
||||
limits Apply resources limits to targeted container(s). See rctl(8).
|
||||
list List containers (running and stopped).
|
||||
mount Mount a volume inside the targeted container(s).
|
||||
pkg Manipulate binary packages within targeted container(s). See pkg(8).
|
||||
rdr Redirect host port to container port.
|
||||
rename Rename a container.
|
||||
restart Restart a running container.
|
||||
service Manage services within targeted containers(s).
|
||||
service Manage services within targeted container(s).
|
||||
start Start a stopped container.
|
||||
stop Stop a running container.
|
||||
sysrc Safely edit rc files within targeted container(s).
|
||||
template Apply file templates to targeted container(s).
|
||||
top Display and update information about the top(1) cpu processes.
|
||||
umount Unmount a volume from within the targeted container(s).
|
||||
update Update container base -pX release.
|
||||
upgrade Upgrade container release to X.Y-RELEASE.
|
||||
verify Compare release against a "known good" index.
|
||||
zfs Manage (get|set) zfs attributes on targeted container(s).
|
||||
|
||||
zfs Manage (get|set) ZFS attributes on targeted container(s).
|
||||
|
||||
Use "bastille -v|--version" for version information.
|
||||
Use "bastille command -h|--help" for more information about a command.
|
||||
|
||||
|
||||
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.
|
||||
14
docs/conf.py
14
docs/conf.py
@@ -8,13 +8,13 @@ else:
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'Bastille'
|
||||
copyright = '2018-2019, Christer Edwards'
|
||||
copyright = '2018-2023, Christer Edwards'
|
||||
author = 'Christer Edwards'
|
||||
|
||||
# The short X.Y version
|
||||
version = '0.5.20191125'
|
||||
version = '0.10.20231125'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '0.5.20191125-beta'
|
||||
release = '0.10.20231125-beta'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
@@ -26,10 +26,10 @@ templates_path = ['_templates']
|
||||
|
||||
source_suffix = ['.rst', '.md']
|
||||
|
||||
from recommonmark.parser import CommonMarkParser
|
||||
source_parsers = {
|
||||
'.md': CommonMarkParser,
|
||||
}
|
||||
#from recommonmark.parser import CommonMarkParser
|
||||
#source_parsers = {
|
||||
# '.md': CommonMarkParser,
|
||||
#}
|
||||
|
||||
master_doc = 'index'
|
||||
language = None
|
||||
|
||||
@@ -12,12 +12,17 @@ https://docs.bastillebsd.org.
|
||||
:caption: Contents:
|
||||
|
||||
chapters/installation
|
||||
chapters/upgrading
|
||||
chapters/networking
|
||||
chapters/usage
|
||||
chapters/targeting
|
||||
chapters/upgrading
|
||||
chapters/subcommands/index
|
||||
chapters/template
|
||||
chapters/jail-config
|
||||
chapters/zfs-support
|
||||
chapters/gcp
|
||||
chapters/migration
|
||||
|
||||
copyright
|
||||
|
||||
|
||||
1
docs/requirements.txt
Normal file
1
docs/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
docutils < 0.18
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,24 +28,24 @@
|
||||
# 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.
|
||||
|
||||
## root check first.
|
||||
bastille_root_check() {
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
## so we can make it colorful
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
||||
|
||||
## permission denied
|
||||
echo -e "${COLOR_RED}Bastille: Permission Denied${COLOR_RESET}" 1>&2
|
||||
echo -e "${COLOR_RED}root / sudo / doas required${COLOR_RESET}" 1>&2
|
||||
exit 1
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
## check for config existance
|
||||
bastille_conf_check() {
|
||||
if [ ! -r "/usr/local/etc/bastille/bastille.conf" ]; then
|
||||
error_exit "Missing Configuration"
|
||||
fi
|
||||
}
|
||||
|
||||
bastille_root_check
|
||||
bastille_conf_check
|
||||
|
||||
## we only load the config if root_check passes
|
||||
## we only load the config if conf_check passes
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
# Set default values for config properties added during the current major version:
|
||||
: "${bastille_network_pf_ext_if:=ext_if}"
|
||||
: "${bastille_network_pf_table:=jails}"
|
||||
|
||||
## bastille_prefix should be 0750
|
||||
## this restricts file system access to privileged users
|
||||
@@ -53,21 +53,16 @@ bastille_perms_check() {
|
||||
if [ -d "${bastille_prefix}" ]; then
|
||||
BASTILLE_PREFIX_PERMS=$(stat -f "%Op" "${bastille_prefix}")
|
||||
if [ "${BASTILLE_PREFIX_PERMS}" != 40750 ]; then
|
||||
echo -e "${COLOR_RED}Insecure permissions on ${bastille_prefix}${COLOR_RESET}" 1>&2
|
||||
echo -e "${COLOR_RED}Try: chmod 0750 ${bastille_prefix}${COLOR_RESET}" 1>&2
|
||||
echo
|
||||
exit 1
|
||||
error_notify "Insecure permissions on ${bastille_prefix}"
|
||||
error_exit "Try: chmod 0750 ${bastille_prefix}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
bastille_perms_check
|
||||
|
||||
## we only load the config if root_check passes
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
## version
|
||||
BASTILLE_VERSION="0.5.20191125RC"
|
||||
BASTILLE_VERSION="0.10.20231125"
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
@@ -79,26 +74,40 @@ Usage:
|
||||
|
||||
Available Commands:
|
||||
bootstrap Bootstrap a FreeBSD release for container base.
|
||||
clone Clone an existing container.
|
||||
cmd Execute arbitrary command on targeted container(s).
|
||||
config Get or set a config value for the targeted container(s).
|
||||
console Console into a running container.
|
||||
convert Convert a Thin container into a Thick container.
|
||||
cp cp(1) files from host to targeted container(s).
|
||||
create Create a new thin container or a thick container if -T|--thick option specified.
|
||||
destroy Destroy a stopped container or a FreeBSD release.
|
||||
help Help about any command
|
||||
edit Edit container configuration files (advanced).
|
||||
export Exports a specified container.
|
||||
help Help about any command.
|
||||
htop Interactive process viewer (requires htop).
|
||||
import Import a specified container.
|
||||
limits Apply resources limits to targeted container(s). See rctl(8).
|
||||
list List containers (running and stopped).
|
||||
mount Mount a volume inside the targeted container(s).
|
||||
pkg Manipulate binary packages within targeted container(s). See pkg(8).
|
||||
rcp reverse cp(1) files from a single container to the host.
|
||||
rdr Redirect host port to container port.
|
||||
rename Rename a container.
|
||||
restart Restart a running container.
|
||||
service Manage services within targeted container(s).
|
||||
setup Attempt to auto-configure network, firewall and storage on new installs.
|
||||
start Start a stopped container.
|
||||
stop Stop a running container.
|
||||
sysrc Safely edit rc files within targeted container(s).
|
||||
tags Add or remove tags to targeted container(s).
|
||||
template Apply file templates to targeted container(s).
|
||||
top Display and update information about the top(1) cpu processes.
|
||||
umount Unmount a volume from within the targeted container(s).
|
||||
update Update container base -pX release.
|
||||
upgrade Upgrade container release to X.Y-RELEASE.
|
||||
verify Compare release against a "known good" index.
|
||||
zfs Manage (get|set) zfs attributes on targeted container(s).
|
||||
zfs Manage (get|set) ZFS attributes on targeted container(s).
|
||||
|
||||
Use "bastille -v|--version" for version information.
|
||||
Use "bastille command -h|--help" for more information about a command.
|
||||
@@ -112,40 +121,100 @@ EOF
|
||||
CMD=$1
|
||||
shift
|
||||
|
||||
target_all_jails() {
|
||||
_JAILS=$(/usr/sbin/jls name)
|
||||
JAILS=""
|
||||
for _jail in ${_JAILS}; do
|
||||
_JAILPATH=$(/usr/sbin/jls -j "${_jail}" path)
|
||||
if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then
|
||||
JAILS="${JAILS} ${_jail}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check_target_is_running() {
|
||||
if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "${CMD}" in
|
||||
version|-v|--version)
|
||||
echo -e "${COLOR_GREEN}${BASTILLE_VERSION}${COLOR_RESET}"
|
||||
info "${BASTILLE_VERSION}"
|
||||
exit 0
|
||||
;;
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
bootstrap|create|destroy|export|import|list|rdr|restart|setup|start|update|upgrade|verify)
|
||||
# Nothing "extra" to do for these commands. -- cwells
|
||||
;;
|
||||
clone|config|cmd|console|convert|cp|edit|htop|limits|mount|pkg|rcp|rename|service|stop|sysrc|tags|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'
|
||||
elif [ "${1}" != 'help' ] && [ "${1}" != '-h' ] && [ "${1}" != '--help' ]; then
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
# Filter out all non-commands
|
||||
case "${CMD}" in
|
||||
cmd|cp|create|destroy|list|pkg|restart|start|stop|sysrc|template|verify)
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
target_all_jails
|
||||
elif [ "${CMD}" = "pkg" ] && [ "${TARGET}" = '-H' ] || [ "${TARGET}" = '--host' ]; then
|
||||
TARGET="${1}"
|
||||
USE_HOST_PKG=1
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
target_all_jails
|
||||
else
|
||||
JAILS="${TARGET}"
|
||||
check_target_is_running
|
||||
fi
|
||||
shift
|
||||
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
|
||||
else
|
||||
JAILS="${TARGET}"
|
||||
|
||||
# Ensure the target exists. -- cwells
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
error_exit "[${TARGET}]: Not found."
|
||||
fi
|
||||
|
||||
case "${CMD}" in
|
||||
cmd|console|htop|pkg|service|stop|sysrc|template|top)
|
||||
check_target_is_running
|
||||
;;
|
||||
convert|rename)
|
||||
# Require the target to be stopped. -- cwells
|
||||
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
|
||||
;;
|
||||
update|upgrade)
|
||||
;;
|
||||
service|console|bootstrap|htop|top)
|
||||
;;
|
||||
bootstrap|update|upgrade|zfs)
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
*) # Filter out all non-commands
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
SCRIPTPATH="${bastille_sharedir}/${CMD}.sh"
|
||||
if [ -f "${SCRIPTPATH}" ]; then
|
||||
: ${UMASK:=022}
|
||||
umask ${UMASK}
|
||||
: "${UMASK:=022}"
|
||||
umask "${UMASK}"
|
||||
|
||||
: ${SH:=sh}
|
||||
: "${SH:=sh}"
|
||||
|
||||
exec ${SH} "${SCRIPTPATH}" "$@"
|
||||
if [ -n "${PARAMS}" ]; then
|
||||
exec "${SH}" "${SCRIPTPATH}" "${PARAMS}"
|
||||
else
|
||||
exec "${SH}" "${SCRIPTPATH}" "$@"
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_RED}${SCRIPTPATH} not found.${COLOR_RESET}" 1>&2
|
||||
error_exit "${SCRIPTPATH} not found."
|
||||
fi
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#####################
|
||||
## [ BastilleBSD ] ##
|
||||
#####################
|
||||
|
||||
## default paths
|
||||
bastille_prefix=/usr/local/bastille ## default: "/usr/local/bastille"
|
||||
bastille_cachedir=${bastille_prefix}/cache ## default: ${bastille_prefix}/cache
|
||||
bastille_jailsdir=${bastille_prefix}/jails ## default: ${bastille_prefix}/jails
|
||||
bastille_logsdir=${bastille_prefix}/logs ## default: ${bastille_prefix}/logs
|
||||
bastille_releasesdir=${bastille_prefix}/releases ## default: ${bastille_prefix}/releases
|
||||
bastille_templatesdir=${bastille_prefix}/templates ## default: ${bastille_prefix}/templates
|
||||
|
||||
## bastille scripts directory (assumed by bastille pkg)
|
||||
bastille_sharedir=/usr/local/share/bastille ## default: "/usr/local/share/bastille"
|
||||
|
||||
## bootstrap archives (base, lib32, ports, src, test)
|
||||
bastille_bootstrap_archives="base" ## default: "base"
|
||||
|
||||
## default timezone
|
||||
bastille_tzdata="etc/UTC" ## default: "etc/UTC"
|
||||
|
||||
## default jail resolv.conf
|
||||
bastille_resolv_conf="/etc/resolv.conf" ## default: "/etc/resolv.conf"
|
||||
|
||||
## ZFS options
|
||||
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_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off"
|
||||
|
||||
## Networking
|
||||
bastille_jail_loopback="lo1" ## default: "lo1"
|
||||
bastille_jail_interface="bastille0" ## default: "bastille0"
|
||||
bastille_jail_external="" ## default: ""
|
||||
bastille_jail_addr="10.17.89.10" ## default: "10.17.89.10"
|
||||
bastille_jail_gateway="" ## default: ""
|
||||
68
usr/local/etc/bastille/bastille.conf.sample
Normal file
68
usr/local/etc/bastille/bastille.conf.sample
Normal file
@@ -0,0 +1,68 @@
|
||||
#####################
|
||||
## [ BastilleBSD ] ##
|
||||
#####################
|
||||
|
||||
## default paths
|
||||
bastille_prefix="/usr/local/bastille" ## default: "/usr/local/bastille"
|
||||
bastille_backupsdir="${bastille_prefix}/backups" ## default: "${bastille_prefix}/backups"
|
||||
bastille_cachedir="${bastille_prefix}/cache" ## default: "${bastille_prefix}/cache"
|
||||
bastille_jailsdir="${bastille_prefix}/jails" ## default: "${bastille_prefix}/jails"
|
||||
bastille_releasesdir="${bastille_prefix}/releases" ## default: "${bastille_prefix}/releases"
|
||||
bastille_templatesdir="${bastille_prefix}/templates" ## default: "${bastille_prefix}/templates"
|
||||
bastille_logsdir="/var/log/bastille" ## default: "/var/log/bastille"
|
||||
|
||||
## pf configuration path
|
||||
bastille_pf_conf="/etc/pf.conf" ## default: "/etc/pf.conf"
|
||||
|
||||
## bastille scripts directory (assumed by bastille pkg)
|
||||
bastille_sharedir="/usr/local/share/bastille" ## default: "/usr/local/share/bastille"
|
||||
|
||||
## bootstrap archives, which components of the OS to install.
|
||||
## base - The base OS, kernel + userland
|
||||
## lib32 - Libraries for compatibility with 32 bit binaries
|
||||
## ports - The FreeBSD ports (3rd party applications) tree
|
||||
## src - The source code to the kernel + userland
|
||||
## test - The FreeBSD test suite
|
||||
## this is a whitespace separated list:
|
||||
## bastille_bootstrap_archives="base lib32 ports src test"
|
||||
bastille_bootstrap_archives="base" ## default: "base"
|
||||
|
||||
## default timezone
|
||||
bastille_tzdata="" ## default: empty to use host's time zone
|
||||
|
||||
## default jail resolv.conf
|
||||
bastille_resolv_conf="/etc/resolv.conf" ## default: "/etc/resolv.conf"
|
||||
|
||||
## bootstrap urls
|
||||
bastille_url_freebsd="http://ftp.freebsd.org/pub/FreeBSD/releases/" ## default: "http://ftp.freebsd.org/pub/FreeBSD/releases/"
|
||||
bastille_url_hardenedbsd="https://installers.hardenedbsd.org/pub/" ## default: "https://installer.hardenedbsd.org/pub/HardenedBSD/releases/"
|
||||
bastille_url_midnightbsd="https://www.midnightbsd.org/ftp/MidnightBSD/releases/" ## default: "https://www.midnightbsd.org/pub/MidnightBSD/releases/"
|
||||
|
||||
## ZFS options
|
||||
bastille_zfs_enable="" ## default: ""
|
||||
bastille_zfs_zpool="" ## default: ""
|
||||
bastille_zfs_prefix="bastille" ## default: "${bastille_zfs_zpool}/bastille"
|
||||
bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off"
|
||||
|
||||
## 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"
|
||||
bastille_export_options="" ## default "" predefined export options, e.g. "--safe --gz"
|
||||
|
||||
## Networking
|
||||
bastille_network_loopback="bastille0" ## default: "bastille0"
|
||||
bastille_network_pf_ext_if="ext_if" ## default: "ext_if"
|
||||
bastille_network_pf_table="jails" ## default: "jails"
|
||||
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: "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
|
||||
@@ -29,8 +29,8 @@ restart_cmd="bastille_stop && bastille_start"
|
||||
|
||||
bastille_start()
|
||||
{
|
||||
if [ ! -n "${bastille_list}" ]; then
|
||||
echo "${bastille_list} is undefined"
|
||||
if [ -z "${bastille_list}" ]; then
|
||||
echo "bastille_list is undefined"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -44,14 +44,16 @@ bastille_start()
|
||||
|
||||
bastille_stop()
|
||||
{
|
||||
if [ ! -n "${bastille_list}" ]; then
|
||||
echo "${bastille_list} is undefined"
|
||||
if [ -z "${bastille_list}" ]; then
|
||||
echo "bastille_list is undefined"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local _jail
|
||||
|
||||
for _jail in ${bastille_list}; do
|
||||
## reverse order of list for shutdown ## fixes #389
|
||||
bastille_revlist=$(echo "${bastille_list}" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }')
|
||||
for _jail in ${bastille_revlist}; do
|
||||
echo "Stopping Bastille Container: ${_jail}"
|
||||
${command} stop ${_jail}
|
||||
done
|
||||
|
||||
BIN
usr/local/man/man8/bastille.8.gz
Normal file
BIN
usr/local/man/man8/bastille.8.gz
Normal file
Binary file not shown.
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille bootstrap [release|template] [update].${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille bootstrap [release|template] [update|arch]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,118 +42,58 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Validate ZFS parameters first.
|
||||
bastille_root_check
|
||||
|
||||
#Validate if ZFS is enabled in rc.conf and bastille.conf.
|
||||
if [ "$(sysrc -n zfs_enable)" = "YES" ] && [ ! "${bastille_zfs_enable}" = "YES" ]; then
|
||||
warn "ZFS is enabled in rc.conf but not bastille.conf. Do you want to continue? (N|y)"
|
||||
read answer
|
||||
case $answer in
|
||||
no|No|n|N|"")
|
||||
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_enable."
|
||||
;;
|
||||
yes|Yes|y|Y) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Validate ZFS parameters.
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
## check for the ZFS pool and bastille prefix
|
||||
if [ -z "${bastille_zfs_zpool}" ]; then
|
||||
echo -e "${COLOR_RED}ERROR: Missing ZFS parameters, see bastille_zfs_zpool.${COLOR_RESET}"
|
||||
exit 1
|
||||
elif [ -z "${bastille_zfs_prefix}" ]; then
|
||||
echo -e "${COLOR_RED}ERROR: Missing ZFS parameters, see bastille_zfs_prefix.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_zpool."
|
||||
elif [ -z "${bastille_zfs_prefix}" ]; then
|
||||
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_prefix."
|
||||
elif ! zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then
|
||||
echo -e "${COLOR_RED}ERROR: ${bastille_zfs_zpool} is not a ZFS pool.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ERROR: ${bastille_zfs_zpool} is not a ZFS pool."
|
||||
fi
|
||||
|
||||
## check for the ZFS dataset prefix if already exist
|
||||
if [ -d "/${bastille_zfs_zpool}/${bastille_zfs_prefix}" ]; then
|
||||
if [ -d "/${bastille_zfs_zpool}/${bastille_zfs_prefix}" ]; then
|
||||
if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" > /dev/null 2>&1; then
|
||||
echo -e "${COLOR_RED}ERROR: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ERROR: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
bootstrap_network_interfaces() {
|
||||
validate_release_url() {
|
||||
## check upstream url, else warn user
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
RELEASE="${NAME_VERIFY}"
|
||||
if ! fetch -qo /dev/null "${UPSTREAM_URL}/MANIFEST" 2>/dev/null; then
|
||||
error_exit "Unable to fetch MANIFEST. See 'bootstrap urls'."
|
||||
fi
|
||||
info "Bootstrapping ${PLATFORM_OS} distfiles..."
|
||||
|
||||
## test for both options empty
|
||||
if [ -z ${bastille_jail_loopback} ] && [ -z ${bastille_jail_external} ]; then
|
||||
echo -e "${COLOR_RED}Please set preferred loopback or external interface.${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}See bastille.conf.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
# Alternate RELEASE/ARCH fetch support
|
||||
if [ "${OPTION}" = "--i386" ] || [ "${OPTION}" = "--32bit" ]; then
|
||||
ARCH="i386"
|
||||
RELEASE="${RELEASE}-${ARCH}"
|
||||
fi
|
||||
|
||||
## test for required variables -- external
|
||||
if [ -z ${bastille_jail_loopback} ] && [ ! -z ${bastille_jail_external} ]; then
|
||||
|
||||
## test for existing interface
|
||||
ifconfig ${bastille_jail_external} 2>&1 >/dev/null
|
||||
if [ $? = 0 ]; then
|
||||
|
||||
## create ifconfig alias
|
||||
ifconfig ${bastille_jail_external} inet ${bastille_jail_addr} alias && \
|
||||
echo -e "${COLOR_GREEN}IP alias added to ${bastille_jail_external} successfully.${COLOR_RESET}"
|
||||
echo
|
||||
|
||||
## attempt to ping gateway
|
||||
echo -e "${COLOR_YELLOW}Attempting to ping default gateway...${COLOR_RESET}"
|
||||
ping -c3 -t3 -S ${bastille_jail_addr} ${bastille_jail_gateway}
|
||||
if [ $? = 0 ]; then
|
||||
echo
|
||||
echo -e "${COLOR_GREEN}External networking appears functional.${COLOR_RESET}"
|
||||
echo
|
||||
else
|
||||
echo -e "${COLOR_RED}Unable to ping default gateway.${COLOR_RESET}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
## test for required variables -- loopback
|
||||
if [ -z ${bastille_jail_external} ] && [ ! -z ${bastille_jail_loopback} ] && \
|
||||
[ ! -z ${bastille_jail_addr} ]; then
|
||||
|
||||
echo -e "${COLOR_GREEN}Detecting...${COLOR_RESET}"
|
||||
## test for existing interface
|
||||
ifconfig ${bastille_jail_interface} >&2 >/dev/null
|
||||
|
||||
## if above return code is 1; create interface
|
||||
if [ $? = 1 ]; then
|
||||
sysrc ifconfig_${bastille_jail_loopback}_name | grep ${bastille_jail_interface} >&2 >/dev/null
|
||||
if [ $? = 1 ]; then
|
||||
echo
|
||||
echo -e "${COLOR_GREEN}Defining secure loopback interface.${COLOR_RESET}"
|
||||
sysrc cloned_interfaces+="${bastille_jail_loopback}" &&
|
||||
sysrc ifconfig_${bastille_jail_loopback}_name="${bastille_jail_interface}"
|
||||
sysrc ifconfig_${bastille_jail_interface}_aliases+="inet ${bastille_jail_addr}/32"
|
||||
|
||||
## create and name interface; assign address
|
||||
echo
|
||||
echo -e "${COLOR_GREEN}Creating secure loopback interface.${COLOR_RESET}"
|
||||
ifconfig ${bastille_jail_loopback} create name ${bastille_jail_interface}
|
||||
ifconfig ${bastille_jail_interface} up
|
||||
ifconfig ${bastille_jail_interface} inet ${bastille_jail_addr}/32
|
||||
|
||||
## reload firewall
|
||||
pfctl -f /etc/pf.conf
|
||||
|
||||
## look for nat rule for bastille_jail_addr
|
||||
echo -e "${COLOR_GREEN}Detecting NAT from bastille0 interface...${COLOR_RESET}"
|
||||
pfctl -s nat | grep nat | grep ${bastille_jail_addr}
|
||||
if [ $? = 0 ]; then
|
||||
## test connectivity; ping from bastille_jail_addr
|
||||
echo
|
||||
echo -e "${COLOR_YELLOW}Attempting to ping default gateway...${COLOR_RESET}"
|
||||
ping -c3 -t3 -S ${bastille_jail_addr} ${bastille_jail_gateway}
|
||||
if [ $? = 0 ]; then
|
||||
echo
|
||||
echo -e "${COLOR_GREEN}Private networking appears functional.${COLOR_RESET}"
|
||||
echo
|
||||
else
|
||||
echo -e "${COLOR_RED}Unable to ping default gateway.${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}See https://github.com/BastilleBSD/bastille/blob/master/README.md#etcpfconf.${COLOR_RESET}"
|
||||
echo -e
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_RED}Unable to detect firewall 'nat' rule.${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}See https://github.com/BastilleBSD/bastille/blob/master/README.md#etcpfconf.${COLOR_RESET}"
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_RED}Interface ${bastille_jail_loopback} already configured; bailing out.${COLOR_RESET}"
|
||||
fi
|
||||
else
|
||||
echo -e "${COLOR_RED}Interface ${bastille_jail_interface} already active; bailing out.${COLOR_RESET}"
|
||||
fi
|
||||
bootstrap_directories
|
||||
bootstrap_release
|
||||
else
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -164,41 +103,63 @@ bootstrap_directories() {
|
||||
## ${bastille_prefix}
|
||||
if [ ! -d "${bastille_prefix}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ];then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_prefix} ${bastille_zfs_zpool}/${bastille_zfs_prefix}
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_prefix}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_prefix}"
|
||||
chmod 0750 "${bastille_prefix}"
|
||||
fi
|
||||
chmod 0750 "${bastille_prefix}"
|
||||
fi
|
||||
|
||||
## ${bastille_backupsdir}
|
||||
if [ ! -d "${bastille_backupsdir}" ]; then
|
||||
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"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_backupsdir}"
|
||||
fi
|
||||
chmod 0750 "${bastille_backupsdir}"
|
||||
fi
|
||||
|
||||
## ${bastille_cachedir}
|
||||
if [ ! -d "${bastille_cachedir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${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}
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_cachedir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache"
|
||||
# Don't create unused/stale cache/RELEASE directory on Linux jails creation.
|
||||
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 [ ! -z "${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
|
||||
|
||||
## ${bastille_jailsdir}
|
||||
if [ ! -d "${bastille_jailsdir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_jailsdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_jailsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_jailsdir}"
|
||||
@@ -208,8 +169,8 @@ bootstrap_directories() {
|
||||
## ${bastille_logsdir}
|
||||
if [ ! -d "${bastille_logsdir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_logsdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/logs
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_logsdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/logs"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_logsdir}"
|
||||
@@ -219,8 +180,8 @@ bootstrap_directories() {
|
||||
## ${bastille_templatesdir}
|
||||
if [ ! -d "${bastille_templatesdir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_templatesdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_templatesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_templatesdir}"
|
||||
@@ -230,18 +191,19 @@ bootstrap_directories() {
|
||||
## ${bastille_releasesdir}
|
||||
if [ ! -d "${bastille_releasesdir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_releasesdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_releasesdir}/${RELEASE} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases"
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_releasesdir}/${RELEASE}"
|
||||
fi
|
||||
|
||||
## create subsequent releases/XX.X-RELEASE datasets
|
||||
elif [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_releasesdir}/${RELEASE} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_releasesdir}/${RELEASE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_releasesdir}/${RELEASE}"
|
||||
@@ -250,93 +212,201 @@ bootstrap_directories() {
|
||||
}
|
||||
|
||||
bootstrap_release() {
|
||||
## if release exists, quit
|
||||
## if release exists quit, else bootstrap additional distfiles
|
||||
if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then
|
||||
echo -e "${COLOR_RED}Bootstrap appears complete.${COLOR_RESET}"
|
||||
exit 1
|
||||
## check distfiles list and skip existing cached files
|
||||
bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/base//")
|
||||
bastille_cached_files=$(ls "${bastille_cachedir}/${RELEASE}" | grep -v "MANIFEST" | tr -d ".txz")
|
||||
for distfile in ${bastille_cached_files}; do
|
||||
bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/${distfile}//")
|
||||
done
|
||||
|
||||
## check if release already bootstrapped, else continue bootstrapping
|
||||
if [ -z "${bastille_bootstrap_archives}" ]; then
|
||||
error_notify "Bootstrap appears complete."
|
||||
else
|
||||
info "Bootstrapping additional distfiles..."
|
||||
fi
|
||||
fi
|
||||
|
||||
for _archive in ${bastille_bootstrap_archives}; do
|
||||
## check if the dist files already exists then extract
|
||||
FETCH_VALIDATION="0"
|
||||
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
|
||||
echo -e "${COLOR_GREEN}Extracting FreeBSD ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
|
||||
/usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
|
||||
exit 1
|
||||
info "Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz."
|
||||
if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
|
||||
## silence motd at container login
|
||||
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
|
||||
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
|
||||
else
|
||||
error_exit "Failed to extract ${_archive}.txz."
|
||||
fi
|
||||
else
|
||||
## get the manifest for dist files checksum validation
|
||||
if [ ! -f "${bastille_cachedir}/${RELEASE}/MANIFEST" ]; then
|
||||
fetch ${UPSTREAM_URL}/MANIFEST -o ${bastille_cachedir}/${RELEASE}/MANIFEST || FETCH_VALIDATION="1"
|
||||
fi
|
||||
## get the manifest for dist files checksum validation
|
||||
if [ ! -f "${bastille_cachedir}/${RELEASE}/MANIFEST" ]; then
|
||||
fetch "${UPSTREAM_URL}/MANIFEST" -o "${bastille_cachedir}/${RELEASE}/MANIFEST" || FETCH_VALIDATION="1"
|
||||
fi
|
||||
|
||||
if [ "${FETCH_VALIDATION}" -ne "0" ]; then
|
||||
## perform cleanup only for stale/empty directories on failure
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
if [ ! "$(ls -A ${bastille_cachedir}/${RELEASE})" ]; then
|
||||
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}
|
||||
fi
|
||||
if [ ! "$(ls -A ${bastille_releasesdir}/${RELEASE})" ]; then
|
||||
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}
|
||||
fi
|
||||
fi
|
||||
if [ "${FETCH_VALIDATION}" -ne "0" ]; 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_cachedir}/${RELEASE}")" ]; then
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${RELEASE}"
|
||||
fi
|
||||
if [ -d "${bastille_cachedir}/${RELEASE}" ]; then
|
||||
if [ ! "$(ls -A ${bastille_cachedir}/${RELEASE})" ]; then
|
||||
rm -rf ${bastille_cachedir}/${RELEASE}
|
||||
fi
|
||||
if [ ! "$(ls -A "${bastille_releasesdir}/${RELEASE}")" ]; then
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"
|
||||
fi
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
if [ ! "$(ls -A ${bastille_releasesdir}/${RELEASE})" ]; then
|
||||
rm -rf ${bastille_releasesdir}/${RELEASE}
|
||||
fi
|
||||
fi
|
||||
echo -e "${COLOR_RED}Bootstrap failed.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
if [ -d "${bastille_cachedir}/${RELEASE}" ]; then
|
||||
if [ ! "$(ls -A "${bastille_cachedir}/${RELEASE}")" ]; then
|
||||
rm -rf "${bastille_cachedir:?}/${RELEASE}"
|
||||
fi
|
||||
fi
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
if [ ! "$(ls -A "${bastille_releasesdir}/${RELEASE}")" ]; then
|
||||
rm -rf "${bastille_releasesdir:?}/${RELEASE}"
|
||||
fi
|
||||
fi
|
||||
error_exit "Bootstrap failed."
|
||||
fi
|
||||
|
||||
## 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
|
||||
echo -e "${COLOR_RED}Failed to fetch ${_archive}.txz.${COLOR_RESET}"
|
||||
error_notify "Failed to fetch ${_archive}.txz."
|
||||
fi
|
||||
fi
|
||||
|
||||
## compare checksums on the fetched dist files
|
||||
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
|
||||
SHA256_DIST=$(grep -w "${_archive}.txz" ${bastille_cachedir}/${RELEASE}/MANIFEST | awk '{print $2}')
|
||||
SHA256_FILE=$(sha256 -q ${bastille_cachedir}/${RELEASE}/${_archive}.txz)
|
||||
SHA256_DIST=$(grep -w "${_archive}.txz" "${bastille_cachedir}/${RELEASE}/MANIFEST" | awk '{print $2}')
|
||||
SHA256_FILE=$(sha256 -q "${bastille_cachedir}/${RELEASE}/${_archive}.txz")
|
||||
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
|
||||
echo -e "${COLOR_RED}Failed validation for ${_archive}.txz, please retry bootstrap!${COLOR_RESET}"
|
||||
rm ${bastille_cachedir}/${RELEASE}/${_archive}.txz
|
||||
exit 1
|
||||
rm "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
|
||||
error_exit "Failed validation for ${_archive}.txz. Please retry bootstrap!"
|
||||
else
|
||||
echo -e "${COLOR_GREEN}Validated checksum for ${RELEASE}:${_archive}.txz.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}MANIFEST:${SHA256_DIST}${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}DOWNLOAD:${SHA256_FILE}${COLOR_RESET}"
|
||||
info "Validated checksum for ${RELEASE}: ${_archive}.txz"
|
||||
info "MANIFEST: ${SHA256_DIST}"
|
||||
info "DOWNLOAD: ${SHA256_FILE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
## extract the fetched dist files
|
||||
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
|
||||
echo -e "${COLOR_GREEN}Extracting FreeBSD ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
|
||||
/usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
|
||||
exit 1
|
||||
info "Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz."
|
||||
if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
|
||||
## silence motd at container login
|
||||
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
|
||||
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
|
||||
else
|
||||
error_exit "Failed to extract ${_archive}.txz."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
||||
echo -e "${COLOR_GREEN}Bootstrap successful.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}See 'bastille --help' for available commands.${COLOR_RESET}"
|
||||
info "Bootstrap successful."
|
||||
info "See 'bastille --help' for available commands."
|
||||
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|focal|jammy|buster|bullseye|bookworm)
|
||||
info "Increasing APT::Cache-Start"
|
||||
echo "APT::Cache-Start 251658240;" > "${bastille_releasesdir}"/${DIR_BOOTSTRAP}/etc/apt/apt.conf.d/00aptitude
|
||||
;;
|
||||
esac
|
||||
|
||||
info "Bootstrap successful."
|
||||
info "See 'bastille --help' for available commands."
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -345,138 +415,197 @@ bootstrap_template() {
|
||||
## ${bastille_templatesdir}
|
||||
if [ ! -d "${bastille_templatesdir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint=${bastille_templatesdir} ${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_templatesdir}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/templates"
|
||||
fi
|
||||
else
|
||||
mkdir -p "${bastille_templatesdir}"
|
||||
fi
|
||||
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
|
||||
fi
|
||||
|
||||
## define basic variables
|
||||
_url=${BASTILLE_TEMPLATE_URL}
|
||||
_user=${BASTILLE_TEMPLATE_USER}
|
||||
_repo=${BASTILLE_TEMPLATE_REPO}
|
||||
_repo=${BASTILLE_TEMPLATE_REPO%.*} # Remove the trailing ".git"
|
||||
_template=${bastille_templatesdir}/${_user}/${_repo}
|
||||
|
||||
## support for non-git
|
||||
if [ ! -x /usr/local/bin/git ]; then
|
||||
echo -e "${COLOR_RED}We're gonna have to use fetch. Strap in.${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}Not yet implemented...${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## support for git
|
||||
if [ -x /usr/local/bin/git ]; then
|
||||
if ! which -s git; then
|
||||
error_notify "Git not found."
|
||||
error_exit "Not yet implemented."
|
||||
else
|
||||
if [ ! -d "${_template}/.git" ]; then
|
||||
/usr/local/bin/git clone "${_url}" "${_template}" ||\
|
||||
echo -e "${COLOR_RED}Clone unsuccessful.${COLOR_RESET}"
|
||||
echo
|
||||
git clone "${_url}" "${_template}" ||\
|
||||
error_notify "Clone unsuccessful."
|
||||
elif [ -d "${_template}/.git" ]; then
|
||||
cd ${_template} &&
|
||||
/usr/local/bin/git pull ||\
|
||||
echo -e "${COLOR_RED}Template update unsuccessful.${COLOR_RESET}"
|
||||
echo
|
||||
git -C "${_template}" pull ||\
|
||||
error_notify "Template update unsuccessful."
|
||||
fi
|
||||
fi
|
||||
|
||||
## template validation
|
||||
_hook_validate=0
|
||||
for _hook in PRE FSTAB PF PKG SYSRC CMD; do
|
||||
if [ -s ${_template}/${_hook} ]; then
|
||||
_hook_validate=$((_hook_validate+1))
|
||||
echo -e "${COLOR_GREEN}Detected ${_hook} hook.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
|
||||
cat "${_template}/${_hook}"
|
||||
echo
|
||||
fi
|
||||
done
|
||||
|
||||
# template overlay
|
||||
if [ -s ${_template}/OVERLAY ]; then
|
||||
_hook_validate=$((_hook_validate+1))
|
||||
echo -e "${COLOR_GREEN}Detected OVERLAY hook.${COLOR_RESET}"
|
||||
while read _dir; do
|
||||
echo -e "${COLOR_GREEN}[${_dir}]:${COLOR_RESET}"
|
||||
if [ -x $(which tree) ]; then
|
||||
tree -a ${_template}/${_dir}
|
||||
fi
|
||||
done < ${_template}/OVERLAY
|
||||
echo
|
||||
fi
|
||||
if [ -s ${_template}/CONFIG ]; then
|
||||
echo -e "${COLOR_GREEN}Detected CONFIG hook.${COLOR_RESET}"
|
||||
echo -e "${COLOR_YELLOW}CONFIG deprecated; rename to OVERLAY.${COLOR_RESET}"
|
||||
while read _dir; do
|
||||
echo -e "${COLOR_GREEN}[${_dir}]:${COLOR_RESET}"
|
||||
if [ -x $(which tree) ]; then
|
||||
tree -a ${_template}/${_dir}
|
||||
fi
|
||||
done < ${_template}/CONFIG
|
||||
fi
|
||||
|
||||
## remove bad templates
|
||||
if [ ${_hook_validate} -lt 1 ]; then
|
||||
echo -e "${COLOR_GREEN}Template validation failed.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}Deleting template.${COLOR_RESET}"
|
||||
rm -rf ${_template}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if validated; ready to use
|
||||
if [ ${_hook_validate} -gt 0 ]; then
|
||||
echo -e "${COLOR_GREEN}Template ready to use.${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
bastille verify "${_user}/${_repo}"
|
||||
}
|
||||
|
||||
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" ] || [ "${OPTION}" = "--32bit" ]; then
|
||||
HW_MACHINE="i386"
|
||||
HW_MACHINE_ARCH="i386"
|
||||
else
|
||||
error_exit "Unsupported architecture."
|
||||
fi
|
||||
fi
|
||||
|
||||
## allow override bootstrap URLs via environment variables
|
||||
[ -n ${BASTILLE_URL_FREEBSD} ] && bastille_url_freebsd="${BASTILLE_URL_FREEBSD}"
|
||||
[ -n ${BASTILLE_URL_HARDENEDBSD} ] && bastille_url_hardenedbsd="${BASTILLE_URL_HARDENEDBSD}"
|
||||
[ -n ${BASTILLE_URL_MIDNIGHTBSD} ] && bastille_url_midnightbsd="${BASTILLE_URL_MIDNIGHTBSD}"
|
||||
|
||||
## Filter sane release names
|
||||
case "${1}" in
|
||||
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]')
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
RELEASE="${NAME_VERIFY}"
|
||||
UPSTREAM_URL="http://ftp.freebsd.org/pub/FreeBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/${RELEASE}"
|
||||
bootstrap_directories
|
||||
bootstrap_release
|
||||
else
|
||||
usage
|
||||
fi
|
||||
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:]')
|
||||
UPSTREAM_URL=$(echo "${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}" | sed 's/releases/snapshots/')
|
||||
PLATFORM_OS="FreeBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
*-RELEASE|*-release|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9])
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([0-9]{1,2})\.[0-9](-RELEASE|-RC[1-9]|-BETA[1-9])$' | tr '[:lower:]' '[:upper:]')
|
||||
UPSTREAM_URL="${bastille_url_freebsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_VERIFY}"
|
||||
PLATFORM_OS="FreeBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
|
||||
## check for HardenedBSD releases name
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
RELEASE="${NAME_VERIFY}"
|
||||
UPSTREAM_URL="https://installer.hardenedbsd.org/pub/HardenedBSD/releases/${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-${RELEASE}"
|
||||
bootstrap_directories
|
||||
bootstrap_release
|
||||
else
|
||||
usage
|
||||
fi
|
||||
## check for HardenedBSD releases name(previous infrastructure, keep for reference)
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
|
||||
UPSTREAM_URL="${bastille_url_hardenedbsd}${HW_MACHINE}/${HW_MACHINE_ARCH}/hardenedbsd-${NAME_VERIFY}"
|
||||
PLATFORM_OS="HardenedBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
http?://github.com/*/*|http?://gitlab.com/*/*)
|
||||
*-stable-build-[0-9]*|*-STABLE-BUILD-[0-9]*)
|
||||
## check for HardenedBSD(specific stable build releases)
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build)-([0-9]{1,3})$' | sed 's/BUILD/build/g' | sed 's/STABLE/stable/g')
|
||||
NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-build-[0-9]\{1,3\}//g')
|
||||
NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-//g')
|
||||
UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}"
|
||||
PLATFORM_OS="HardenedBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
*-stable-build-latest|*-stable-BUILD-LATEST|*-STABLE-BUILD-LATEST)
|
||||
## check for HardenedBSD(latest stable build release)
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '([0-9]{1,2})(-stable-build-latest)$' | sed 's/STABLE/stable/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g')
|
||||
NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/-BUILD-LATEST//g')
|
||||
NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/[0-9]\{1,2\}-stable-BUILD-//g')
|
||||
UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}"
|
||||
PLATFORM_OS="HardenedBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
current-build-[0-9]*|CURRENT-BUILD-[0-9]*)
|
||||
## check for HardenedBSD(specific current build releases)
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build)-([0-9]{1,3})' | sed 's/BUILD/build/g' | sed 's/CURRENT/current/g')
|
||||
NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g')
|
||||
NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-//g')
|
||||
UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/${NAME_BUILD}"
|
||||
PLATFORM_OS="HardenedBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
current-build-latest|current-BUILD-LATEST|CURRENT-BUILD-LATEST)
|
||||
## check for HardenedBSD(latest current build release)
|
||||
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '(current-build-latest)' | sed 's/CURRENT/current/g' | sed 's/build/BUILD/g' | sed 's/latest/LATEST/g')
|
||||
NAME_RELEASE=$(echo "${NAME_VERIFY}" | sed 's/current-.*/current/g')
|
||||
NAME_BUILD=$(echo "${NAME_VERIFY}" | sed 's/current-BUILD-//g')
|
||||
UPSTREAM_URL="${bastille_url_hardenedbsd}${NAME_RELEASE}/${HW_MACHINE}/${HW_MACHINE_ARCH}/installer/${NAME_BUILD}"
|
||||
PLATFORM_OS="HardenedBSD"
|
||||
validate_release_url
|
||||
;;
|
||||
http?://*/*/*)
|
||||
BASTILLE_TEMPLATE_URL=${1}
|
||||
BASTILLE_TEMPLATE_USER=$(echo "${1}" | awk -F / '{ print $4 }')
|
||||
BASTILLE_TEMPLATE_REPO=$(echo "${1}" | awk -F / '{ print $5 }')
|
||||
echo -e "${COLOR_GREEN}Template: ${1}${COLOR_RESET}"
|
||||
echo
|
||||
bootstrap_template
|
||||
;;
|
||||
network)
|
||||
bootstrap_network_interfaces
|
||||
git@*:*/*)
|
||||
BASTILLE_TEMPLATE_URL=${1}
|
||||
git_repository=$(echo "${1}" | awk -F : '{ print $2 }')
|
||||
BASTILLE_TEMPLATE_USER=$(echo "${git_repository}" | awk -F / '{ print $1 }')
|
||||
BASTILLE_TEMPLATE_REPO=$(echo "${git_repository}" | awk -F / '{ print $2 }')
|
||||
bootstrap_template
|
||||
;;
|
||||
#adding Ubuntu Bionic as valid "RELEASE" for POC @hackacad
|
||||
ubuntu_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
|
||||
;;
|
||||
ubuntu_jammy|jammy|ubuntu-jammy)
|
||||
PLATFORM_OS="Ubuntu/Linux"
|
||||
LINUX_FLAVOR="jammy"
|
||||
DIR_BOOTSTRAP="Ubuntu_2204"
|
||||
ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX}
|
||||
debootstrap_release
|
||||
;;
|
||||
debian_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
|
||||
;;
|
||||
debian_bookworm|bookworm|debian-bookworm)
|
||||
PLATFORM_OS="Debian/Linux"
|
||||
LINUX_FLAVOR="bookworm"
|
||||
DIR_BOOTSTRAP="Debian12"
|
||||
ARCH_BOOTSTRAP=${HW_MACHINE_ARCH_LINUX}
|
||||
debootstrap_release
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${2}" in
|
||||
case "${OPTION}" in
|
||||
update)
|
||||
bastille update "${RELEASE}"
|
||||
;;
|
||||
|
||||
210
usr/local/share/bastille/clone.sh
Normal file
210
usr/local/share/bastille/clone.sh
Normal file
@@ -0,0 +1,210 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille clone [TARGET] [NEW_NAME] [IPADRESS]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
NEWNAME="${1}"
|
||||
IP="${2}"
|
||||
|
||||
validate_ip() {
|
||||
IPX_ADDR="ip4.addr"
|
||||
IP6_MODE="disable"
|
||||
ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))')
|
||||
if [ -n "${ip6}" ]; then
|
||||
info "Valid: (${ip6})."
|
||||
IPX_ADDR="ip6.addr"
|
||||
IP6_MODE="new"
|
||||
else
|
||||
local IFS
|
||||
if echo "${IP}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then
|
||||
TEST_IP=$(echo "${IP}" | cut -d / -f1)
|
||||
IFS=.
|
||||
set ${TEST_IP}
|
||||
for quad in 1 2 3 4; do
|
||||
if eval [ \$$quad -gt 255 ]; then
|
||||
error_exit "Invalid: (${TEST_IP})"
|
||||
fi
|
||||
done
|
||||
if ifconfig | grep -qwF "${TEST_IP}"; then
|
||||
warn "Warning: IP address already in use (${TEST_IP})."
|
||||
else
|
||||
info "Valid: (${IP})."
|
||||
fi
|
||||
else
|
||||
error_exit "Invalid: (${IP})."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
update_jailconf() {
|
||||
# Update jail.conf
|
||||
JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf"
|
||||
if [ -f "${JAIL_CONFIG}" ]; then
|
||||
if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then
|
||||
sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|exec.consolelog = .*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|path = .*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|mount.fstab = .*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|${TARGET} {|${NEWNAME} {|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|${IPX_ADDR} = .*;|${IPX_ADDR} = ${IP};|" "${JAIL_CONFIG}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if grep -qw "vnet;" "${JAIL_CONFIG}"; then
|
||||
update_jailconf_vnet
|
||||
fi
|
||||
}
|
||||
|
||||
update_jailconf_vnet() {
|
||||
bastille_jail_rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf"
|
||||
|
||||
# Determine number of containers and define an uniq_epair
|
||||
local list_jails_num=$(bastille list jails | wc -l | awk '{print $1}')
|
||||
local num_range=$(expr "${list_jails_num}" + 1)
|
||||
jail_list=$(bastille list jail)
|
||||
for _num in $(seq 0 "${num_range}"); do
|
||||
if [ -n "${jail_list}" ]; then
|
||||
if ! grep -q "e0b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then
|
||||
uniq_epair="bastille${_num}"
|
||||
# Update the exec.* with uniq_epair when cloning jails.
|
||||
sed -i '' "s|vnet.interface = e0b_bastille.*;|vnet.interface = e0b_${uniq_epair};|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|exec.prestart += \"jib addm bastille[0-9]|exec.prestart += \"jib addm ${uniq_epair}|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|exec.prestart += \"ifconfig e0a_bastille[0-9].*|exec.prestart += \"ifconfig e0a_${uniq_epair} description \\\\\"vnet host interface for Bastille jail ${NEWNAME}\\\\\"\";|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|exec.poststop += \"jib destroy bastille[0-9]\";|exec.poststop += \"jib destroy ${uniq_epair}\";|" "${JAIL_CONFIG}"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Rename interface to new uniq_epair
|
||||
sed -i '' "s|ifconfig_e0b_bastille.*_name|ifconfig_e0b_${uniq_epair}_name|" "${bastille_jail_rc_conf}"
|
||||
|
||||
# If 0.0.0.0 set DHCP, else set static IP address
|
||||
if [ "${IP}" == "0.0.0.0" ]; then
|
||||
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
|
||||
else
|
||||
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
|
||||
fi
|
||||
}
|
||||
|
||||
update_fstab() {
|
||||
# Update fstab to use the new name
|
||||
FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab"
|
||||
if [ -f "${FSTAB_CONFIG}" ]; then
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9]|-CURRENT)|([0-9]{1,2}(-stable-build-[0-9]{1,3}|-stable-LAST))|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)' "${FSTAB_CONFIG}" | uniq)
|
||||
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}")
|
||||
FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0"
|
||||
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
|
||||
# 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 additional fstab paths with new jail path
|
||||
sed -i '' "s|${bastille_jailsdir}/${TARGET}/root/|${bastille_jailsdir}/${NEWNAME}/root/|" "${FSTAB_CONFIG}"
|
||||
fi
|
||||
}
|
||||
|
||||
clone_jail() {
|
||||
# Attempt container clone
|
||||
info "Attempting to clone '${TARGET}' to ${NEWNAME}..."
|
||||
if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
# Replicate the existing container
|
||||
DATE=$(date +%F-%H%M%S)
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
|
||||
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" | zfs recv "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"
|
||||
|
||||
# Cleanup source temporary snapshots
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_clone_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
|
||||
|
||||
# Cleanup target temporary snapshots
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}"
|
||||
fi
|
||||
else
|
||||
# Just clone the jail directory
|
||||
# Check if container is running
|
||||
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'."
|
||||
fi
|
||||
|
||||
# Perform container file copy(archive mode)
|
||||
cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
fi
|
||||
else
|
||||
error_exit "${NEWNAME} already exists."
|
||||
fi
|
||||
|
||||
# Generate jail configuration files
|
||||
update_jailconf
|
||||
update_fstab
|
||||
|
||||
# Display the exist status
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_exit "An error has occurred while attempting to clone '${TARGET}'."
|
||||
else
|
||||
info "Cloned '${TARGET}' to '${NEWNAME}' successfully."
|
||||
fi
|
||||
}
|
||||
|
||||
## don't allow for dots(.) in container names
|
||||
if echo "${NEWNAME}" | grep -q "[.]"; then
|
||||
error_exit "Container names may not contain a dot(.)!"
|
||||
fi
|
||||
|
||||
## check if ip address is valid
|
||||
if [ -n "${IP}" ]; then
|
||||
validate_ip
|
||||
else
|
||||
usage
|
||||
fi
|
||||
|
||||
clone_jail
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,11 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille cmd TARGET command.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille cmd TARGET command"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,22 +42,41 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -eq 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
bastille_root_check
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
COUNT=0
|
||||
RETURN=0
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
jexec -l ${_jail} $@
|
||||
COUNT=$(($COUNT+1))
|
||||
info "[${_jail}]:"
|
||||
|
||||
if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/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,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2014-2015 Bryan Drewery <bdrewery@FreeBSD.org>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
@@ -11,7 +11,7 @@
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
|
||||
119
usr/local/share/bastille/common.sh
Normal file
119
usr/local/share/bastille/common.sh
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
COLOR_RED=
|
||||
COLOR_GREEN=
|
||||
COLOR_YELLOW=
|
||||
COLOR_RESET=
|
||||
|
||||
bastille_root_check() {
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
## permission denied
|
||||
error_notify "Bastille: Permission Denied"
|
||||
error_exit "root / sudo / doas required"
|
||||
fi
|
||||
}
|
||||
|
||||
enable_color() {
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
}
|
||||
|
||||
# If "NO_COLOR" environment variable is present, or we aren't speaking to a
|
||||
# tty, disable output colors.
|
||||
if [ -z "${NO_COLOR}" -a -t 1 ]; then
|
||||
enable_color
|
||||
fi
|
||||
|
||||
# Notify message on error, but do not exit
|
||||
error_notify() {
|
||||
echo -e "${COLOR_RED}$*${COLOR_RESET}" 1>&2
|
||||
}
|
||||
|
||||
# Notify message on error and exit
|
||||
error_exit() {
|
||||
error_notify $@
|
||||
exit 1
|
||||
}
|
||||
|
||||
info() {
|
||||
echo -e "${COLOR_GREEN}$*${COLOR_RESET}"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
172
usr/local/share/bastille/config.sh
Normal file
172
usr/local/share/bastille/config.sh
Normal file
@@ -0,0 +1,172 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille config TARGET get|set propertyName [newValue]"
|
||||
}
|
||||
|
||||
# we need jail(8) to parse the config file so it can expand variables etc
|
||||
print_jail_conf() {
|
||||
|
||||
# we need to pass a literal \n to jail to get each parameter on its own
|
||||
# line
|
||||
jail -f "$1" -e '
|
||||
'
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -eq 1 ] || [ $# -gt 3 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
ACTION=$1
|
||||
shift
|
||||
|
||||
case $ACTION in
|
||||
get)
|
||||
if [ $# -ne 1 ]; then
|
||||
error_notify 'Too many parameters for a "get" operation.'
|
||||
usage
|
||||
fi
|
||||
;;
|
||||
set) ;;
|
||||
*) error_exit 'Only get and set are supported.' ;;
|
||||
esac
|
||||
|
||||
PROPERTY=$1
|
||||
shift
|
||||
VALUE="$@"
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
FILE="${bastille_jailsdir}/${_jail}/jail.conf"
|
||||
if [ ! -f "${FILE}" ]; then
|
||||
error_notify "jail.conf does not exist for jail: ${_jail}"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "${ACTION}" = 'get' ]; then
|
||||
_output=$(
|
||||
print_jail_conf "${FILE}" | awk -F= -v property="${PROPERTY}" '
|
||||
$1 == property {
|
||||
# note that we have found the property
|
||||
found = 1;
|
||||
# check if there is a value for this property
|
||||
if (NF == 2) {
|
||||
# remove any quotes surrounding the string
|
||||
sub(/^"/, "", $2);
|
||||
sub(/"$/, "", $2);
|
||||
print $2;
|
||||
} else {
|
||||
# no value, just the property name
|
||||
print "enabled";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
END {
|
||||
# if we have not found anything we need to print a special
|
||||
# string
|
||||
if (! found) {
|
||||
print("not set");
|
||||
# let the caller know that this is a warn condition
|
||||
exit(120);
|
||||
}
|
||||
}'
|
||||
)
|
||||
# check if our output is a warning or regular
|
||||
if [ $? -eq 120 ]; then
|
||||
warn "${_output}"
|
||||
else
|
||||
echo "${_output}"
|
||||
fi
|
||||
else # Setting the value. -- cwells
|
||||
if [ -n "${VALUE}" ]; then
|
||||
VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g')
|
||||
if echo "${VALUE}" | grep ' ' > /dev/null 2>&1; then # Contains a space, so wrap in quotes. -- cwells
|
||||
VALUE="'${VALUE}'"
|
||||
fi
|
||||
LINE=" ${PROPERTY} = ${VALUE};"
|
||||
else
|
||||
LINE=" ${PROPERTY};"
|
||||
fi
|
||||
|
||||
# add the value to the config file, replacing any existing value or, if
|
||||
# there is none, at the end
|
||||
#
|
||||
# awk doesn't have "inplace" editing so we use a temp file
|
||||
_tmpfile=$(mktemp) || error_exit "unable to set because mktemp failed"
|
||||
cp "${FILE}" "${_tmpfile}" && \
|
||||
awk -F= -v line="${LINE}" -v property="${PROPERTY}" '
|
||||
BEGIN {
|
||||
# build RE as string as we can not expand vars in RE literals
|
||||
prop_re = "^[[:space:]]*" property "[[:space:]]*$";
|
||||
}
|
||||
$1 ~ prop_re && !found {
|
||||
# we already have an entry in the config for this property so
|
||||
# we need to substitute our line here rather than keep the
|
||||
# existing line
|
||||
print(line);
|
||||
# note we have already found the property
|
||||
found = 1;
|
||||
# move onto the next line
|
||||
next;
|
||||
}
|
||||
$1 == "}" {
|
||||
# reached the end of the stanza so if we have not already
|
||||
# added our line we need to do so now
|
||||
if (! found) {
|
||||
print(line);
|
||||
}
|
||||
}
|
||||
{
|
||||
# print each uninteresting line unchanged
|
||||
print;
|
||||
}
|
||||
' "${_tmpfile}" > "${FILE}"
|
||||
rm "${_tmpfile}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Only display this message once at the end (not for every jail). -- cwells
|
||||
if [ "${ACTION}" = 'set' ]; then
|
||||
info "A restart is required for the changes to be applied. See 'bastille restart ${TARGET}'."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,11 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille console TARGET [user]'.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille console TARGET [user]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,27 +42,48 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -gt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
bastille_root_check
|
||||
|
||||
USER="${1}"
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
validate_user() {
|
||||
if jexec -l "${_jail}" id "${USER}" >/dev/null 2>&1; then
|
||||
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}" $LOGIN -f "${USER}"
|
||||
else
|
||||
echo "Invalid shell for user ${USER}"
|
||||
fi
|
||||
else
|
||||
echo "User ${USER} has no shell"
|
||||
fi
|
||||
else
|
||||
echo "Unknown user ${USER}"
|
||||
fi
|
||||
}
|
||||
|
||||
check_fib() {
|
||||
fib=$(grep 'exec.fib' "${bastille_jailsdir}/${_jail}/jail.conf" | awk '{print $3}' | sed 's/\;//g')
|
||||
if [ -n "${fib}" ]; then
|
||||
_setfib="setfib -F ${fib}"
|
||||
else
|
||||
_setfib=""
|
||||
fi
|
||||
}
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
if [ ! -z "${USER}" ]; then
|
||||
jexec -l ${_jail} /usr/bin/login -f "${USER}"
|
||||
info "[${_jail}]:"
|
||||
LOGIN="$(jexec -l "${_jail}" which login)"
|
||||
if [ -n "${USER}" ]; then
|
||||
validate_user
|
||||
else
|
||||
jexec -l ${_jail} /usr/bin/login -f root
|
||||
LOGIN="$(jexec -l "${_jail}" which login)"
|
||||
${_setfib} jexec -l "${_jail}" $LOGIN -f root
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
157
usr/local/share/bastille/convert.sh
Normal file
157
usr/local/share/bastille/convert.sh
Normal file
@@ -0,0 +1,157 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille convert TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
convert_symlinks() {
|
||||
# Work with the symlinks, revert on first cp error
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
# Retrieve old symlinks temporarily
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ -L "${_link}" ]; then
|
||||
mv "${_link}" "${_link}.old"
|
||||
fi
|
||||
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
|
||||
cp -a "${bastille_releasesdir}/${RELEASE}/${_link}" "${bastille_jailsdir}/${TARGET}/root/${_link}"
|
||||
fi
|
||||
if [ "$?" -ne 0 ]; then
|
||||
revert_convert
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove the old symlinks on success
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ -L "${_link}.old" ]; then
|
||||
rm -r "${_link}.old"
|
||||
fi
|
||||
done
|
||||
else
|
||||
error_exit "Release must be bootstrapped first. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
revert_convert() {
|
||||
# Revert the conversion on first cp error
|
||||
error_notify "A problem has occurred while copying the files. Reverting changes..."
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ -d "${_link}" ]; then
|
||||
chflags -R noschg "${bastille_jailsdir}/${TARGET}/root/${_link}"
|
||||
rm -rf "${bastille_jailsdir}/${TARGET}/root/${_link}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Restore previous symlinks
|
||||
for _link in ${SYMLINKS}; do
|
||||
if [ -L "${_link}.old" ]; then
|
||||
mv "${_link}.old" "${_link}"
|
||||
fi
|
||||
done
|
||||
error_exit "Changes for '${TARGET}' has been reverted."
|
||||
}
|
||||
|
||||
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 -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"
|
||||
|
||||
# Work with the symlinks
|
||||
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"
|
||||
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!"
|
||||
exit 0
|
||||
else
|
||||
error_exit "Can't determine release version. See 'bastille bootstrap'."
|
||||
fi
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille create'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if is a thin container
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}/root/.bastille" ]; then
|
||||
error_exit "${TARGET} is not a thin container."
|
||||
elif ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
|
||||
error_exit "${TARGET} is not a thin container."
|
||||
fi
|
||||
|
||||
# Make sure the user agree with the conversion
|
||||
# Be interactive here since this cannot be easily undone
|
||||
while :; do
|
||||
error_notify "Warning: container conversion from thin to thick can't be undone!"
|
||||
read -p "Do you really wish to convert '${TARGET}' into a thick container? [y/N]:" yn
|
||||
case ${yn} in
|
||||
[Yy]) start_convert;;
|
||||
[Nn]) exit 0;;
|
||||
esac
|
||||
done
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,39 +28,53 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille cp TARGET HOST_PATH CONTAINER_PATH${COLOR_RESET}"
|
||||
exit 1
|
||||
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 [ $# -gt 3 ] || [ $# -lt 3 ]; then
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
CPSOURCE="${2}"
|
||||
CPDEST="${3}"
|
||||
bastille_root_check
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
case "${OPTION}" in
|
||||
-q|--quiet)
|
||||
OPTION="-a"
|
||||
;;
|
||||
*)
|
||||
OPTION="-av"
|
||||
;;
|
||||
esac
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
bastille_jail_path="$(jls -j "${_jail}" path)"
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
cp -av "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}"
|
||||
echo
|
||||
info "[${_jail}]:"
|
||||
bastille_jail_path="${bastille_jailsdir}/${_jail}/root"
|
||||
cp "${OPTION}" "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}"
|
||||
RETURN="$?"
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
# Display the return status for reference
|
||||
echo -e "Returned: ${RETURN}\n"
|
||||
else
|
||||
echo
|
||||
return "${RETURN}"
|
||||
fi
|
||||
done
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,95 +28,156 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille destroy [container|release]${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille destroy [force] | [container|release]"
|
||||
}
|
||||
|
||||
destroy_jail() {
|
||||
bastille_jail_base="${bastille_jailsdir}/${NAME}" ## dir
|
||||
bastille_jail_log="${bastille_logsdir}/${NAME}_console.log" ## file
|
||||
local OPTIONS
|
||||
bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir
|
||||
bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file
|
||||
|
||||
if [ $(jls name | grep -w "${NAME}") ]; then
|
||||
echo -e "${COLOR_RED}Jail running.${COLOR_RESET}"
|
||||
echo -e "${COLOR_RED}See 'bastille stop ${NAME}'.${COLOR_RESET}"
|
||||
exit 1
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ "${FORCE}" = "1" ]; then
|
||||
bastille stop "${TARGET}"
|
||||
else
|
||||
error_notify "Jail running."
|
||||
error_exit "See 'bastille stop ${TARGET}'."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "${bastille_jail_base}" ]; then
|
||||
echo -e "${COLOR_RED}Jail not found.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Jail not found."
|
||||
fi
|
||||
|
||||
if [ -d "${bastille_jail_base}" ]; then
|
||||
echo -e "${COLOR_GREEN}Deleting Jail: ${NAME}.${COLOR_RESET}"
|
||||
info "Deleting Jail: ${TARGET}."
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
if [ ! -z "${NAME}" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
if [ -n "${TARGET}" ]; then
|
||||
OPTIONS="-r"
|
||||
if [ "${FORCE}" = "1" ]; then
|
||||
OPTIONS="-rf"
|
||||
fi
|
||||
## remove jail zfs dataset recursively
|
||||
zfs destroy -r ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}
|
||||
zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "${bastille_jail_base}" ]; then
|
||||
## removing all flags
|
||||
chflags -R noschg ${bastille_jail_base}
|
||||
chflags -R noschg "${bastille_jail_base}"
|
||||
|
||||
## remove jail base
|
||||
rm -rf ${bastille_jail_base}
|
||||
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)
|
||||
echo -e "${COLOR_GREEN}Note: jail console logs archived.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}${bastille_jail_log}-$(date +%F)${COLOR_RESET}"
|
||||
mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)"
|
||||
info "Note: jail console logs archived."
|
||||
info "${bastille_jail_log}-$(date +%F)"
|
||||
fi
|
||||
|
||||
## clear any active rdr rules
|
||||
if [ ! -z "$(pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null)" ]; then
|
||||
info "Clearing RDR rules:"
|
||||
pfctl -a "rdr/${TARGET}" -Fn
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
destroy_rel() {
|
||||
bastille_rel_base="${bastille_releasesdir}/${NAME}" ## dir
|
||||
local OPTIONS
|
||||
|
||||
## check release name match before destroy
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
TARGET="${NAME_VERIFY}"
|
||||
else
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_rel_base="${bastille_releasesdir}/${TARGET}" ## dir
|
||||
|
||||
## check if this release have containers child
|
||||
BASE_HASCHILD="0"
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
|
||||
for _jail in ${JAIL_LIST}; do
|
||||
if grep -qwo "${NAME}" ${bastille_jailsdir}/${_jail}/fstab 2>/dev/null; then
|
||||
echo -e "${COLOR_RED}Notice: (${_jail}) depends on ${NAME} base.${COLOR_RESET}"
|
||||
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
|
||||
|
||||
if [ ! -d "${bastille_rel_base}" ]; then
|
||||
echo -e "${COLOR_RED}Release base not found.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Release base not found."
|
||||
else
|
||||
if [ "${BASE_HASCHILD}" -eq "0" ]; then
|
||||
echo -e "${COLOR_GREEN}Deleting base: ${NAME}.${COLOR_RESET}"
|
||||
info "Deleting base: ${TARGET}"
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ ! -z "${bastille_zfs_zpool}" ]; then
|
||||
zfs destroy ${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${NAME}
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
if [ -n "${TARGET}" ]; then
|
||||
OPTIONS="-r"
|
||||
if [ "${FORCE}" = "1" ]; then
|
||||
OPTIONS="-rf"
|
||||
fi
|
||||
zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${TARGET}"
|
||||
if [ "${FORCE}" = "1" ]; then
|
||||
if [ -d "${bastille_cachedir}/${TARGET}" ]; then
|
||||
zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${TARGET}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "${bastille_rel_base}" ]; then
|
||||
## removing all flags
|
||||
chflags -R noschg ${bastille_rel_base}
|
||||
chflags -R noschg "${bastille_rel_base}"
|
||||
|
||||
## remove jail base
|
||||
rm -rf ${bastille_rel_base}
|
||||
rm -rf "${bastille_rel_base}"
|
||||
fi
|
||||
|
||||
if [ "${FORCE}" = "1" ]; then
|
||||
## remove cache on force
|
||||
if [ -d "${bastille_cachedir}/${TARGET}" ]; then
|
||||
rm -rf "${bastille_cachedir}/${TARGET}"
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
else
|
||||
echo -e "${COLOR_RED}Cannot destroy base with containers child.${COLOR_RESET}"
|
||||
error_notify "Cannot destroy base with child containers."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -128,37 +189,77 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
## reset this options
|
||||
FORCE=""
|
||||
|
||||
## handle additional options
|
||||
case "${1}" in
|
||||
-f|--force|force)
|
||||
FORCE="1"
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
error_notify "Unknown Option."
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
TARGET="${1}"
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
NAME="$1"
|
||||
bastille_root_check
|
||||
|
||||
## check what should we clean
|
||||
case "${NAME}" in
|
||||
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
|
||||
case "${TARGET}" in
|
||||
*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current)
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${NAME}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]')
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
NAME="${NAME_VERIFY}"
|
||||
destroy_rel
|
||||
else
|
||||
usage
|
||||
fi
|
||||
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|*-RC[1-9]|*-rc[1-9]|*-BETA[1-9])
|
||||
## check for FreeBSD releases name
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9]|-BETA[1-9])$' | 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 "${NAME}" | grep -iwE '^([1-9]{2,2})(-stable-LAST|-STABLE-last|-stable-last|-STABLE-LAST)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
|
||||
if [ -n "${NAME_VERIFY}" ]; then
|
||||
NAME="${NAME_VERIFY}"
|
||||
destroy_rel
|
||||
else
|
||||
usage
|
||||
fi
|
||||
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;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/;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;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/;s/build/BUILD/g;s/latest/LATEST/g')
|
||||
destroy_rel
|
||||
;;
|
||||
Ubuntu_1804|Ubuntu_2004|Ubuntu_2204|UBUNTU_1804|UBUNTU_2004|UBUNTU_2204)
|
||||
## check for Linux releases
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Ubuntu_1804)$|(Ubuntu_2004)$|(Ubuntu_2204)$' | sed 's/UBUNTU/Ubuntu/g;s/ubuntu/Ubuntu/g')
|
||||
destroy_rel
|
||||
;;
|
||||
Debian10|Debian11|Debian12|DEBIAN10|DEBIAN11|DEBIAN12)
|
||||
## check for Linux releases
|
||||
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '(Debian10)$|(Debian11)$|(Debian12)$' | sed 's/DEBIAN/Debian/g')
|
||||
destroy_rel
|
||||
;;
|
||||
*)
|
||||
|
||||
## just destroy a jail
|
||||
destroy_jail
|
||||
;;
|
||||
|
||||
63
usr/local/share/bastille/edit.sh
Normal file
63
usr/local/share/bastille/edit.sh
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille edit TARGET [filename]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
usage
|
||||
elif [ $# -eq 1 ]; then
|
||||
TARGET_FILENAME="${1}"
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
if [ -z "${EDITOR}" ]; then
|
||||
EDITOR=vi
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
if [ -n "${TARGET_FILENAME}" ]; then
|
||||
"${EDITOR}" "${bastille_jailsdir}/${_jail}/${TARGET_FILENAME}"
|
||||
else
|
||||
"${EDITOR}" "${bastille_jailsdir}/${_jail}/jail.conf"
|
||||
fi
|
||||
done
|
||||
394
usr/local/share/bastille/export.sh
Normal file
394
usr/local/share/bastille/export.sh
Normal file
@@ -0,0 +1,394 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
# 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
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check for unsupported actions
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
error_exit "Batch export is unsupported."
|
||||
fi
|
||||
|
||||
if [ $# -gt 5 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
zfs_enable_check() {
|
||||
# Temporarily disable ZFS so we can create a standard backup archive
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
bastille_zfs_enable="NO"
|
||||
fi
|
||||
}
|
||||
|
||||
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 "${DIR_EXPORT}" ]; then
|
||||
if [ -d "${DIR_EXPORT}" ]; then
|
||||
# Set the user defined export directory
|
||||
bastille_backupsdir="${DIR_EXPORT}"
|
||||
else
|
||||
error_exit "Error: Path not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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
|
||||
if [ -n "${RAW_EXPORT}" ]; then
|
||||
FILE_EXT=""
|
||||
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}" \
|
||||
> "${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
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
# Check if backups directory/dataset exist
|
||||
if [ ! -d "${bastille_backupsdir}" ]; then
|
||||
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
if [ -n "${TARGET}" ]; then
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
error_exit "[${TARGET}]: Not found."
|
||||
fi
|
||||
|
||||
# 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,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille htop TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille htop TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,26 +42,18 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
bastille_root_check
|
||||
|
||||
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
|
||||
echo -e "${COLOR_RED}htop not found on ${_jail}.${COLOR_RESET}"
|
||||
error_notify "htop not found on ${_jail}."
|
||||
elif [ -x "${bastille_jail_path}/usr/local/bin/htop" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
info "[${_jail}]:"
|
||||
jexec -l ${_jail} /usr/local/bin/htop
|
||||
fi
|
||||
echo -e "${COLOR_RESET}"
|
||||
|
||||
640
usr/local/share/bastille/import.sh
Normal file
640
usr/local/share/bastille/import.sh
Normal file
@@ -0,0 +1,640 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
# 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
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 3 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
TARGET="${1}"
|
||||
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 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
|
||||
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
|
||||
fi
|
||||
}
|
||||
|
||||
update_zfsmount() {
|
||||
# Update the mountpoint property on the received ZFS data stream
|
||||
OLD_ZFS_MOUNTPOINT=$(zfs get -H mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" | awk '{print $3}')
|
||||
NEW_ZFS_MOUNTPOINT="${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
if [ "${NEW_ZFS_MOUNTPOINT}" != "${OLD_ZFS_MOUNTPOINT}" ]; then
|
||||
info "Updating ZFS mountpoint..."
|
||||
zfs set mountpoint="${bastille_jailsdir}/${TARGET_TRIM}/root" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
|
||||
fi
|
||||
|
||||
# Mount new container ZFS datasets
|
||||
if ! zfs mount | grep -qw "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}$"; then
|
||||
zfs mount "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
fi
|
||||
if ! zfs mount | grep -qw "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root$"; then
|
||||
zfs mount "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
|
||||
fi
|
||||
}
|
||||
|
||||
update_jailconf() {
|
||||
# Update jail.conf paths
|
||||
JAIL_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
|
||||
if [ -f "${JAIL_CONFIG}" ]; then
|
||||
if ! grep -qw "path = ${bastille_jailsdir}/${TARGET_TRIM}/root;" "${JAIL_CONFIG}"; then
|
||||
info "Updating jail.conf..."
|
||||
sed -i '' "s|exec.consolelog.*=.*;|exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${TARGET_TRIM}/root;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;|" "${JAIL_CONFIG}"
|
||||
fi
|
||||
|
||||
# Check for the jib script
|
||||
if grep -qw "vnet" "${JAIL_CONFIG}"; then
|
||||
vnet_requirements
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
update_fstab() {
|
||||
# Update fstab .bastille mountpoint on thin containers only
|
||||
# Set some variables
|
||||
FSTAB_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/fstab"
|
||||
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}")
|
||||
FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0"
|
||||
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
|
||||
# If both variables are set, compare and update as needed
|
||||
if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}"; then
|
||||
info "Updating fstab..."
|
||||
sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
generate_config() {
|
||||
# Attempt to read previous config file and set required variables accordingly
|
||||
# If we can't get a valid interface, fallback to lo1 and warn user
|
||||
info "Generating jail.conf..."
|
||||
DEVFS_RULESET=4
|
||||
|
||||
if [ "${FILE_EXT}" = ".zip" ]; then
|
||||
# Gather some bits from foreign/iocage config files
|
||||
JSON_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/config.json"
|
||||
if [ -n "${JSON_CONFIG}" ]; then
|
||||
IPV4_CONFIG=$(grep -wo '\"ip4_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip4_addr://')
|
||||
IPV6_CONFIG=$(grep -wo '\"ip6_addr\": \".*\"' "${JSON_CONFIG}" | tr -d '" ' | sed 's/ip6_addr://')
|
||||
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
|
||||
|
||||
# See if we need to generate a vnet network section
|
||||
if [ "${IS_VNET_JAIL:-0}" = "1" ]; then
|
||||
NETBLOCK=$(generate_vnet_jail_netblock "${TARGET_TRIM}" "" "${VNET_DEFAULT_INTERFACE}")
|
||||
vnet_requirements
|
||||
else
|
||||
# If there are multiple IP/NIC let the user configure network
|
||||
if [ -n "${IPV4_CONFIG}" ]; then
|
||||
if ! echo "${IPV4_CONFIG}" | grep -q '.*,.*'; then
|
||||
NETIF_CONFIG=$(echo "${IPV4_CONFIG}" | grep '.*|' | sed 's/|.*//g')
|
||||
if [ -z "${NETIF_CONFIG}" ]; then
|
||||
config_netif
|
||||
fi
|
||||
IPX_ADDR="ip4.addr"
|
||||
IP_CONFIG="${IPV4_CONFIG}"
|
||||
IP6_MODE="disable"
|
||||
fi
|
||||
elif [ -n "${IPV6_CONFIG}" ]; then
|
||||
if ! echo "${IPV6_CONFIG}" | grep -q '.*,.*'; then
|
||||
NETIF_CONFIG=$(echo "${IPV6_CONFIG}" | grep '.*|' | sed 's/|.*//g')
|
||||
if [ -z "${NETIF_CONFIG}" ]; then
|
||||
config_netif
|
||||
fi
|
||||
IPX_ADDR="ip6.addr"
|
||||
IP_CONFIG="${IPV6_CONFIG}"
|
||||
IP6_MODE="new"
|
||||
fi
|
||||
elif [ -n "${IPVX_CONFIG}" ]; then
|
||||
if ! echo "${IPVX_CONFIG}" | grep -q '.*,.*'; then
|
||||
NETIF_CONFIG=$(echo "${IPVX_CONFIG}" | grep '.*|' | sed 's/|.*//g')
|
||||
if [ -z "${NETIF_CONFIG}" ]; then
|
||||
config_netif
|
||||
fi
|
||||
IPX_ADDR="ip4.addr"
|
||||
IP_CONFIG="${IPVX_CONFIG}"
|
||||
IP6_MODE="disable"
|
||||
if echo "${IPVX_CONFIG}" | sed 's/.*|//' | grep -Eq '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))'; then
|
||||
IPX_ADDR="ip6.addr"
|
||||
IP6_MODE="new"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Let the user configure network manually
|
||||
if [ -z "${NETIF_CONFIG}" ]; then
|
||||
NETIF_CONFIG="lo1"
|
||||
IPX_ADDR="ip4.addr"
|
||||
IP_CONFIG="-"
|
||||
IP6_MODE="disable"
|
||||
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
|
||||
|
||||
if [ "${IS_THIN_JAIL:-0}" = "1" ]; then
|
||||
if [ -z "${CONFIG_RELEASE}" ]; then
|
||||
# Fallback to host version
|
||||
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
|
||||
warn "Warning: ${CONFIG_RELEASE} was set by default!"
|
||||
fi
|
||||
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
|
||||
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
|
||||
>> "${bastille_jailsdir}/${TARGET_TRIM}/fstab"
|
||||
|
||||
# Work with the symlinks
|
||||
cd "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
update_symlinks
|
||||
else
|
||||
# Generate new empty fstab file
|
||||
touch "${bastille_jailsdir}/${TARGET_TRIM}/fstab"
|
||||
fi
|
||||
|
||||
# Generate a basic jail configuration file on foreign imports
|
||||
cat << EOF > "${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
|
||||
${TARGET_TRIM} {
|
||||
devfs_ruleset = ${DEVFS_RULESET};
|
||||
enforce_statfs = 2;
|
||||
exec.clean;
|
||||
exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;
|
||||
exec.start = '/bin/sh /etc/rc';
|
||||
exec.stop = '/bin/sh /etc/rc.shutdown';
|
||||
host.hostname = ${TARGET_TRIM};
|
||||
mount.devfs;
|
||||
mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;
|
||||
path = ${bastille_jailsdir}/${TARGET_TRIM}/root;
|
||||
securelevel = 2;
|
||||
|
||||
${NETBLOCK}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
update_config() {
|
||||
# Update an existing jail configuration
|
||||
# The config on select archives does not provide a clear way to determine
|
||||
# the base release, so lets try to get it from the base/COPYRIGHT file,
|
||||
# otherwise warn user and fallback to host system release
|
||||
CONFIG_RELEASE=$(grep -wo 'releng/[0-9]\{2\}.[0-9]/COPYRIGHT' "${bastille_jailsdir}/${TARGET_TRIM}/root/COPYRIGHT" | sed 's|releng/||;s|/COPYRIGHT|-RELEASE|')
|
||||
if [ -z "${CONFIG_RELEASE}" ]; then
|
||||
# Fallback to host version
|
||||
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
|
||||
warn "Warning: ${CONFIG_RELEASE} was set by default!"
|
||||
fi
|
||||
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
|
||||
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
|
||||
>> "${bastille_jailsdir}/${TARGET_TRIM}/fstab"
|
||||
|
||||
# Work with the symlinks
|
||||
cd "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
update_symlinks
|
||||
}
|
||||
|
||||
workout_components() {
|
||||
if [ "${FILE_EXT}" = ".tar" ]; then
|
||||
# Workaround to determine the tarball path/components before extract(assumes path/jails/target)
|
||||
JAIL_PATH=$(tar -tvf ${bastille_backupsdir}/${TARGET} | grep -wo "/.*/jails/${TARGET_TRIM}" | tail -n1)
|
||||
JAIL_DIRS=$(echo ${JAIL_PATH} | grep -o '/' | wc -l)
|
||||
DIRS_PLUS=$(expr ${JAIL_DIRS} + 1)
|
||||
|
||||
# Workaround to determine the jail.conf path before extract(assumes path/qjail.config/target)
|
||||
JAIL_CONF=$(tar -tvf ${bastille_backupsdir}/${TARGET} | grep -wo "/.*/qjail.config/${TARGET_TRIM}")
|
||||
CONF_TRIM=$(echo ${JAIL_CONF} | grep -o '/' | wc -l)
|
||||
fi
|
||||
}
|
||||
|
||||
vnet_requirements() {
|
||||
# VNET jib script requirement
|
||||
if [ ! "$(command -v jib)" ]; then
|
||||
if [ -f "/usr/share/examples/jails/jib" ] && [ ! -f "/usr/local/bin/jib" ]; then
|
||||
install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib
|
||||
else
|
||||
warn "Warning: Unable to locate/install jib script required by VNET jails."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
config_netif() {
|
||||
# Get interface from bastille configuration
|
||||
if [ -n "${bastille_network_loopback}" ]; then
|
||||
NETIF_CONFIG="${bastille_network_loopback}"
|
||||
elif [ -n "${bastille_network_shared}" ]; then
|
||||
NETIF_CONFIG="${bastille_network_shared}"
|
||||
else
|
||||
NETIF_CONFIG=
|
||||
fi
|
||||
}
|
||||
|
||||
update_symlinks() {
|
||||
# Work with the symlinks
|
||||
SYMLINKS="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/ports usr/sbin usr/share usr/src"
|
||||
|
||||
# Just warn user to bootstrap the release if missing
|
||||
if [ ! -d "${bastille_releasesdir}/${CONFIG_RELEASE}" ]; then
|
||||
warn "Warning: ${CONFIG_RELEASE} must be bootstrapped. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
# Update old symlinks
|
||||
info "Updating 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
|
||||
}
|
||||
|
||||
create_zfs_datasets() {
|
||||
# Prepare the ZFS environment and restore from file
|
||||
info "Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
|
||||
info "Preparing ZFS environment..."
|
||||
|
||||
# Create required ZFS datasets, mountpoint inherited from system
|
||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
|
||||
}
|
||||
|
||||
remove_zfs_datasets() {
|
||||
# Perform cleanup on failure
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
|
||||
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
error_exit "Failed to extract files from '${TARGET}' archive."
|
||||
}
|
||||
|
||||
jail_import() {
|
||||
# Attempt to import container from file
|
||||
FILE_TRIM=$(echo "${TARGET}" | sed 's/\.xz//g;s/\.gz//g;s/\.tgz//g;s/\.txz//g;s/\.zip//g;s/\.tar\.gz//g;s/\.tar//g')
|
||||
FILE_EXT=$(echo "${TARGET}" | sed "s/${FILE_TRIM}//g")
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -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} image."
|
||||
info "Receiving ZFS data stream..."
|
||||
xz ${bastille_decompress_xz_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}" = ".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
|
||||
|
||||
# Extract required files to the new datasets
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar --exclude='root' -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 2 -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${TARGET_TRIM}/root"
|
||||
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
|
||||
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
|
||||
|
||||
# Extract required files from the zip archive
|
||||
cd "${bastille_backupsdir}" && unzip -j "${TARGET}"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_exit "Failed to extract files from '${TARGET}' archive."
|
||||
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
|
||||
fi
|
||||
info "Receiving ZFS data stream..."
|
||||
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 ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root"
|
||||
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
|
||||
# Keep old configuration files for user reference
|
||||
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/fstab" ]; then
|
||||
mv "${bastille_jailsdir}/${TARGET_TRIM}/fstab" "${bastille_jailsdir}/${TARGET_TRIM}/fstab.old"
|
||||
fi
|
||||
|
||||
# Cleanup unwanted files
|
||||
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
|
||||
|
||||
# Generate fstab and jail.conf files
|
||||
generate_config
|
||||
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
|
||||
# Attempt to import a foreign/ezjail container
|
||||
# Prepare the ZFS environment and restore from existing .tar.gz file
|
||||
create_zfs_datasets
|
||||
|
||||
# Extract required files to the new datasets
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar --exclude='ezjail/' -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
remove_zfs_datasets
|
||||
else
|
||||
generate_config
|
||||
fi
|
||||
elif [ "${FILE_EXT}" = ".tar" ]; then
|
||||
# Attempt to import a foreign/qjail container
|
||||
# Prepare the ZFS environment and restore from existing .tar file
|
||||
create_zfs_datasets
|
||||
workout_components
|
||||
|
||||
# Extract required files to the new datasets
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${DIRS_PLUS}" -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${JAIL_PATH}"
|
||||
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" ]; then
|
||||
mv "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" "${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
|
||||
fi
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
remove_zfs_datasets
|
||||
else
|
||||
update_config
|
||||
fi
|
||||
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
|
||||
fi
|
||||
else
|
||||
# Import from standard supported archives on UFS systems
|
||||
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..."
|
||||
mkdir "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
mv "${bastille_jailsdir}/${TARGET_TRIM}/ezjail" "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
generate_config
|
||||
elif [ "${FILE_EXT}" = ".tar" ]; then
|
||||
# Attempt to import/configure foreign/qjail container
|
||||
info "Extracting files from '${TARGET}' archive..."
|
||||
mkdir -p "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
workout_components
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${DIRS_PLUS}" -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${JAIL_PATH}"
|
||||
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" ]; then
|
||||
mv "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" "${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
|
||||
fi
|
||||
update_config
|
||||
else
|
||||
error_exit "Unsupported archive format."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_exit "Failed to import from '${TARGET}' archive."
|
||||
else
|
||||
# Update the jail.conf and fstab if required
|
||||
# This is required on foreign imports only
|
||||
update_jailconf
|
||||
update_fstab
|
||||
if [ -z "${USER_IMPORT}" ]; then
|
||||
info "Container '${TARGET_TRIM}' imported successfully."
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
error_exit "Jails directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
# Check for user specified file location
|
||||
if echo "${TARGET}" | grep -q '\/'; then
|
||||
GETDIR="${TARGET}"
|
||||
TARGET=$(echo ${TARGET} | awk -F '\/' '{print $NF}')
|
||||
bastille_backupsdir=$(echo ${GETDIR} | sed "s/${TARGET}//")
|
||||
fi
|
||||
|
||||
# Check if backups directory/dataset exist
|
||||
if [ ! -d "${bastille_backupsdir}" ]; then
|
||||
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
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\}$\|_[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]*.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
|
||||
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 "$(/usr/sbin/jls name | awk "/^${TARGET_TRIM}$/")" ]; then
|
||||
error_exit "A running jail matches name."
|
||||
elif [ -n "${TARGET_TRIM}" ]; then
|
||||
if [ -d "${bastille_jailsdir}/${TARGET_TRIM}" ]; then
|
||||
error_exit "Container: ${TARGET_TRIM} already exists."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${TARGET}" ]; then
|
||||
jail_import
|
||||
fi
|
||||
82
usr/local/share/bastille/limits.sh
Normal file
82
usr/local/share/bastille/limits.sh
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
# Ressource limits added by Sven R github.com/hackacad
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_notify "Usage: bastille limits TARGET option value"
|
||||
echo -e "Example: bastille limits JAILNAME memoryuse 1G"
|
||||
exit 1
|
||||
}
|
||||
|
||||
RACCT_ENABLE=$(sysctl -n kern.racct.enable)
|
||||
if [ "${RACCT_ENABLE}" != '1' ]; then
|
||||
echo "Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot"
|
||||
# exit 1
|
||||
fi
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
OPTION="${1}"
|
||||
VALUE="${2}"
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
|
||||
_rctl_rule="jail:${_jail}:${OPTION}:deny=${VALUE}/jail"
|
||||
_rctl_rule_log="jail:${_jail}:${OPTION}:log=${VALUE}/jail"
|
||||
|
||||
# Check whether the entry already exists and, if so, update it. -- cwells
|
||||
if grep -qs "jail:${_jail}:${OPTION}:deny" "${bastille_jailsdir}/${_jail}/rctl.conf"; then
|
||||
_escaped_option=$(echo "${OPTION}" | sed 's/\//\\\//g')
|
||||
_escaped_rctl_rule=$(echo "${_rctl_rule}" | sed 's/\//\\\//g')
|
||||
sed -i '' -E "s/jail:${_jail}:${_escaped_option}:deny.+/${_escaped_rctl_rule}/" "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
else # Just append the entry. -- cwells
|
||||
echo "${_rctl_rule}" >> "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
echo "${_rctl_rule_log}" >> "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
fi
|
||||
|
||||
echo -e "${OPTION} ${VALUE}"
|
||||
rctl -a "${_rctl_rule}" "${_rctl_rule_log}"
|
||||
echo -e "${COLOR_RESET}"
|
||||
done
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,53 +28,213 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille list [release|template|(jail|container)|log].${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]"
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
jls -N
|
||||
if [ "${1}" = help -o "${1}" = "-h" -o "${1}" = "--help" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
/usr/sbin/jls
|
||||
fi
|
||||
|
||||
if [ "${1}" == "-j" ]; then
|
||||
/usr/sbin/jls -N --libxo json
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TARGET=
|
||||
|
||||
list_all(){
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
DEFAULT_VALUE="-"
|
||||
SPACER=2
|
||||
MAX_LENGTH_JAIL_NAME=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h -m 1 -e "^.* {$" | awk '{ print length($1) }' | sort -nr | head -n 1)
|
||||
MAX_LENGTH_JAIL_NAME=${MAX_LENGTH_JAIL_NAME:-3}
|
||||
if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi
|
||||
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))" ""
|
||||
if [ -n "${TARGET}" ]; then
|
||||
# Query all info for a specific jail.
|
||||
JAIL_LIST="${TARGET}"
|
||||
else
|
||||
# Query all info for all jails(default).
|
||||
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
|
||||
fi
|
||||
for _JAIL in ${JAIL_LIST}; do
|
||||
if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then
|
||||
JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }')
|
||||
IS_FREEBSD_JAIL=0
|
||||
if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" -o -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" -o "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi
|
||||
IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0}
|
||||
IS_LINUX_JAIL=0
|
||||
if [ "$(grep -c "^linprocfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_LINUX_JAIL=1; fi
|
||||
IS_LINUX_JAIL=${IS_LINUX_JAIL:-0}
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${JAIL_NAME}$/")" ]; then
|
||||
JAIL_STATE="Up"
|
||||
if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then
|
||||
JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet 2> /dev/null | sed -n "/.inet /{s///;s/ .*//;p;}")
|
||||
if [ ! "${JAIL_IP}" ]; then JAIL_IP=$(jexec -l ${JAIL_NAME} ifconfig -n vnet0 inet6 2> /dev/null | awk '/inet6 / && (!/fe80::/ || !/%vnet0/)' | sed -n "/.inet6 /{s///;s/ .*//;p;}"); fi
|
||||
else
|
||||
JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip4.addr 2> /dev/null)
|
||||
if [ "${JAIL_IP}" = "-" ]; then JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip6.addr 2> /dev/null); fi
|
||||
fi
|
||||
JAIL_HOSTNAME=$(/usr/sbin/jls -j ${JAIL_NAME} host.hostname 2> /dev/null)
|
||||
JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s/%s:%s"",",$7,$14,$18 }' | sed "s/,$//")
|
||||
JAIL_PATH=$(/usr/sbin/jls -j ${JAIL_NAME} path 2> /dev/null)
|
||||
if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then
|
||||
JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null)
|
||||
fi
|
||||
if [ "${IS_LINUX_JAIL}" -eq 1 ]; then
|
||||
JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }')
|
||||
fi
|
||||
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
|
||||
}
|
||||
|
||||
list_release(){
|
||||
if [ -d "${bastille_releasesdir}" ]; then
|
||||
REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g")
|
||||
for _REL in ${REL_LIST}; do
|
||||
if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" -o -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then
|
||||
if [ "${2}" == "-p" -a -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then
|
||||
REL_PATCH_LEVEL=$(sed -n "s/^USERLAND_VERSION=\"\(.*\)\"$/\1/p" "${bastille_releasesdir}/${_REL}/bin/freebsd-version" 2> /dev/null)
|
||||
REL_PATCH_LEVEL=${REL_PATCH_LEVEL:-${_REL}}
|
||||
echo "${REL_PATCH_LEVEL}"
|
||||
else
|
||||
echo "${_REL}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
list_template(){
|
||||
find "${bastille_templatesdir}" -type d -maxdepth 2
|
||||
}
|
||||
|
||||
list_jail(){
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
|
||||
for _JAIL in ${JAIL_LIST}; do
|
||||
if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then
|
||||
echo "${_JAIL}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
list_log(){
|
||||
find "${bastille_logsdir}" -type f -maxdepth 1
|
||||
}
|
||||
|
||||
list_limit(){
|
||||
rctl -h jail:
|
||||
}
|
||||
|
||||
list_import(){
|
||||
ls "${bastille_backupsdir}" | grep -v ".sha256$"
|
||||
}
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
case "${1}" in
|
||||
all|-a|--all)
|
||||
list_all
|
||||
;;
|
||||
release|releases)
|
||||
if [ -d "${bastille_releasesdir}" ]; then
|
||||
REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g")
|
||||
for _REL in ${REL_LIST}; do
|
||||
if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" ]; then
|
||||
#echo "${bastille_releasesdir}/${_REL}"
|
||||
echo "${_REL}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
list_release
|
||||
;;
|
||||
template|templates)
|
||||
find "${bastille_templatesdir}" -type d -maxdepth 2
|
||||
list_template
|
||||
;;
|
||||
jail|jails|container|containers)
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
|
||||
for _JAIL in ${JAIL_LIST}; do
|
||||
if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then
|
||||
echo "${_JAIL}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
list_jail
|
||||
;;
|
||||
log|logs)
|
||||
find "${bastille_logsdir}" -type f -maxdepth 1
|
||||
list_log
|
||||
;;
|
||||
limit|limits)
|
||||
list_limit
|
||||
;;
|
||||
import|imports|export|exports|backup|backups)
|
||||
list_import
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
# Check if we want to query all info for a specific jail instead.
|
||||
if [ -f "${bastille_jailsdir}/${1}/jail.conf" ]; then
|
||||
TARGET="${1}"
|
||||
list_all
|
||||
else
|
||||
usage
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
122
usr/local/share/bastille/mount.sh
Normal file
122
usr/local/share/bastille/mount.sh
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille mount TARGET host_path container_path [filesystem_type options dump pass_number]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
usage
|
||||
elif [ $# -eq 2 ]; then
|
||||
_fstab="$@ nullfs ro 0 0"
|
||||
else
|
||||
_fstab="$@"
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
## assign needed variables
|
||||
_hostpath=$(echo "${_fstab}" | awk '{print $1}')
|
||||
_jailpath=$(echo "${_fstab}" | awk '{print $2}')
|
||||
_type=$(echo "${_fstab}" | awk '{print $3}')
|
||||
_perms=$(echo "${_fstab}" | awk '{print $4}')
|
||||
_checks=$(echo "${_fstab}" | awk '{print $5" "$6}')
|
||||
|
||||
## if any variables are empty, bail out
|
||||
if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z "${_perms}" ] || [ -z "${_checks}" ]; then
|
||||
error_notify "FSTAB format not recognized."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, procfs"
|
||||
if [ "${_hostpath}" == "tmpfs" -a "$_type" == "tmpfs" ] || [ "${_hostpath}" == "linprocfs" -a "${_type}" == "linprocfs" ] || [ "${_hostpath}" == "linsysfs" -a "${_type}" == "linsysfs" ] || [ "${_hostpath}" == "proc" -a "${_type}" == "procfs" ] || [ "${_hostpath}" == "fdesc" -a "${_type}" == "fdescfs" ] ; then
|
||||
warn "Detected advanced mount type ${_hostpath}"
|
||||
elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then
|
||||
error_notify "Detected invalid host path or incorrect mount type in FSTAB."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if mount permissions are not "ro" or "rw"
|
||||
if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then
|
||||
error_notify "Detected invalid mount permissions in FSTAB."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if check & pass are not "0 0 - 1 1"; bail out
|
||||
if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != "0 1" ] && [ "${_checks}" != "1 1" ]; then
|
||||
error_notify "Detected invalid fstab options in FSTAB."
|
||||
warn "Format: /host/path jail/path nullfs ro 0 0"
|
||||
warn "Read: ${_fstab}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
|
||||
## aggregate variables into FSTAB entry
|
||||
_fullpath="${bastille_jailsdir}/${_jail}/root/${_jailpath}"
|
||||
_fstab_entry="${_hostpath} ${_fullpath} ${_type} ${_perms} ${_checks}"
|
||||
|
||||
## Create mount point if it does not exist. -- cwells
|
||||
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:]]${_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
|
||||
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
|
||||
done
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille pkg TARGET command [args]${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille pkg [-H|--host] TARGET command [args]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,22 +41,38 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
bastille_root_check
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
errors=0
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
jexec -l ${_jail} /usr/sbin/pkg $@
|
||||
info "[${_jail}]:"
|
||||
bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path)
|
||||
if [ -f "/usr/sbin/mport" ]; then
|
||||
if ! jexec -l -U root "${_jail}" /usr/sbin/mport "$@"; then
|
||||
errors=1
|
||||
fi
|
||||
elif [ -f "${bastille_jail_path}/usr/bin/apt" ]; then
|
||||
if ! jexec -l "${_jail}" /usr/bin/apt "$@"; then
|
||||
errors=1
|
||||
fi
|
||||
elif [ "${USE_HOST_PKG}" = 1 ]; then
|
||||
if ! /usr/sbin/pkg -j "${_jail}" "$@"; then
|
||||
errors=1
|
||||
fi
|
||||
else
|
||||
if ! jexec -l -U root "${_jail}" /usr/sbin/pkg "$@"; then
|
||||
errors=1
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
if [ $errors -ne 0 ]; then
|
||||
error_exit "Failed to apply on some jails, please check logs"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
77
usr/local/share/bastille/rcp.sh
Normal file
77
usr/local/share/bastille/rcp.sh
Normal file
@@ -0,0 +1,77 @@
|
||||
#!/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:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille rcp [OPTION] TARGET CONTAINER_PATH HOST_PATH"
|
||||
}
|
||||
|
||||
CPSOURCE="${1}"
|
||||
CPDEST="${2}"
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
-q|--quiet)
|
||||
OPTION="${1}"
|
||||
CPSOURCE="${2}"
|
||||
CPDEST="${3}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" = "ALL" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
case "${OPTION}" in
|
||||
-q|--quiet)
|
||||
OPTION="-a"
|
||||
;;
|
||||
*)
|
||||
OPTION="-av"
|
||||
;;
|
||||
esac
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
bastille_jail_path="${bastille_jailsdir}/${_jail}/root"
|
||||
cp "${OPTION}" "${bastille_jail_path}/${CPSOURCE}" "${CPDEST}"
|
||||
RETURN="$?"
|
||||
echo
|
||||
return "${RETURN}"
|
||||
done
|
||||
216
usr/local/share/bastille/rdr.sh
Normal file
216
usr/local/share/bastille/rdr.sh
Normal file
@@ -0,0 +1,216 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille rdr TARGET [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
TARGET="${1}"
|
||||
JAIL_NAME=""
|
||||
JAIL_IP=""
|
||||
JAIL_IP6=""
|
||||
EXT_IF=""
|
||||
shift
|
||||
|
||||
check_jail_validity() {
|
||||
# Can only redirect to single jail
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
error_exit "Can only redirect to a single jail."
|
||||
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 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 jail ip6 address (ip6.addr) is valid (non-VNET only)
|
||||
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
|
||||
if [ "$(bastille config $TARGET get ip6)" != 'disable' ] && [ "$(bastille config $TARGET get ip6)" != 'not set' ]; then
|
||||
JAIL_IP6=$(/usr/sbin/jls -j "${TARGET}" ip6.addr 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# Check if rdr-anchor is defined in pf.conf
|
||||
if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
|
||||
error_exit "rdr-anchor not found in pf.conf"
|
||||
fi
|
||||
|
||||
# Check if ext_if is defined in pf.conf
|
||||
if [ -n "${bastille_pf_conf}" ]; then
|
||||
EXT_IF=$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf})
|
||||
if [ -z "${EXT_IF}" ]; then
|
||||
error_exit "bastille_network_pf_ext_if (${bastille_network_pf_ext_if}) not defined in pf.conf"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 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 $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP" "$3" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
if [ -n "$JAIL_IP6" ]; then
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP6" "$3" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
fi
|
||||
}
|
||||
|
||||
# function: load rdr rule with log via pfctl
|
||||
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 $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP" "$jail_port" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
if [ -n "$JAIL_IP6" ]; then
|
||||
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
|
||||
printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP6" "$jail_port" ) \
|
||||
| pfctl -a "rdr/${JAIL_NAME}" -f-
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
list)
|
||||
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)
|
||||
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|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
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
164
usr/local/share/bastille/rename.sh
Normal file
164
usr/local/share/bastille/rename.sh
Normal file
@@ -0,0 +1,164 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille rename TARGET NEW_NAME"
|
||||
}
|
||||
|
||||
validate_name() {
|
||||
local NAME_VERIFY=${NEWNAME}
|
||||
local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')
|
||||
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
|
||||
}
|
||||
|
||||
# Handle special-case commands first
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
NEWNAME="${1}"
|
||||
|
||||
update_jailconf() {
|
||||
# Update jail.conf
|
||||
JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf"
|
||||
if [ -f "${JAIL_CONFIG}" ]; then
|
||||
if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then
|
||||
sed -i '' "s|host.hostname.*=.*${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|exec.consolelog.*=.*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}"
|
||||
sed -i '' "s|${TARGET}.*{|${NEWNAME} {|" "${JAIL_CONFIG}"
|
||||
# Rename vnet interface
|
||||
sed -i '' "/vnet.interface/s|_${TARGET}\";|_${NEWNAME}\";|" "${JAIL_CONFIG}"
|
||||
sed -i '' "/ifconfig/s|_${TARGET}|_${NEWNAME}|" "${JAIL_CONFIG}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
update_fstab() {
|
||||
# Update fstab to use the new name
|
||||
FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab"
|
||||
if [ -f "${FSTAB_CONFIG}" ]; then
|
||||
# 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-9])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
|
||||
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}")
|
||||
FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0"
|
||||
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
|
||||
# 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
|
||||
}
|
||||
|
||||
change_name() {
|
||||
# Attempt container name change
|
||||
info "Attempting to rename '${TARGET}' to ${NEWNAME}..."
|
||||
if [ "${bastille_zfs_enable}" = "YES" ]; then
|
||||
if [ -n "${bastille_zfs_zpool}" ] && [ -n "${bastille_zfs_prefix}" ]; then
|
||||
# Check and rename container ZFS dataset accordingly
|
||||
# Perform additional checks in case of non-ZFS existing containers
|
||||
if zfs list | grep -qw "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"; then
|
||||
if ! zfs rename -f "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"; then
|
||||
error_exit "Can't rename '${TARGET}' dataset."
|
||||
fi
|
||||
else
|
||||
# Check and rename container directory instead
|
||||
if ! zfs list | grep -qw "jails/${TARGET}$"; then
|
||||
mv "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Check if container is a zfs/dataset before rename attempt
|
||||
# Perform additional checks in case of bastille.conf miss-configuration
|
||||
if zfs list | grep -qw "jails/${TARGET}$"; then
|
||||
ZFS_DATASET_ORIGIN=$(zfs list | grep -w "jails/${TARGET}$" | awk '{print $1}')
|
||||
ZFS_DATASET_TARGET=$(echo "${ZFS_DATASET_ORIGIN}" | sed "s|\/${TARGET}||")
|
||||
if [ -n "${ZFS_DATASET_ORIGIN}" ] && [ -n "${ZFS_DATASET_TARGET}" ]; then
|
||||
if ! zfs rename -f "${ZFS_DATASET_ORIGIN}" "${ZFS_DATASET_TARGET}/${NEWNAME}"; then
|
||||
error_exit "Can't rename '${TARGET}' dataset."
|
||||
fi
|
||||
else
|
||||
error_exit "Can't determine the ZFS origin path of '${TARGET}'."
|
||||
fi
|
||||
else
|
||||
# Just rename the jail directory
|
||||
mv "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update jail configuration files accordingly
|
||||
update_jailconf
|
||||
update_fstab
|
||||
|
||||
# Check exit status and notify
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_exit "An error has occurred while attempting to rename '${TARGET}'."
|
||||
else
|
||||
info "Renamed '${TARGET}' to '${NEWNAME}' successfully."
|
||||
fi
|
||||
}
|
||||
|
||||
## validate jail name
|
||||
if [ -n "${NEWNAME}" ]; then
|
||||
validate_name
|
||||
fi
|
||||
|
||||
## check if a jail already exists with the new name
|
||||
if [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
|
||||
error_exit "Jail: ${NEWNAME} already exists."
|
||||
fi
|
||||
|
||||
change_name
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille service TARGET service_name action${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille service TARGET service_name action"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,23 +41,14 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 -o $# -gt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET=$1
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
bastille_root_check
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
jexec -l ${_jail} /usr/sbin/service $@
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/sbin/service "$@"
|
||||
echo
|
||||
done
|
||||
|
||||
131
usr/local/share/bastille/setup.sh
Normal file
131
usr/local/share/bastille/setup.sh
Normal file
@@ -0,0 +1,131 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille setup [pf|bastille0|zfs|vnet]"
|
||||
}
|
||||
|
||||
# Check for too many args
|
||||
if [ $# -gt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
# Configure bastille0 network interface
|
||||
configure_bastille0() {
|
||||
info "Configuring bastille0 loopback interface"
|
||||
sysrc cloned_interfaces+=lo1
|
||||
sysrc ifconfig_lo1_name="bastille0"
|
||||
|
||||
info "Bringing up new interface: bastille0"
|
||||
service netif cloneup
|
||||
}
|
||||
|
||||
configure_vnet() {
|
||||
info "Configuring bridge interface"
|
||||
sysrc cloned_interfaces+=bridge1
|
||||
sysrc ifconfig_bridge1_name=bastille1
|
||||
|
||||
info "Bringing up new interface: bastille1"
|
||||
service netif cloneup
|
||||
}
|
||||
|
||||
# Configure pf firewall
|
||||
configure_pf() {
|
||||
if [ ! -f "${bastille_pf_conf}" ]; then
|
||||
local ext_if
|
||||
ext_if=$(netstat -rn | awk '/default/ {print $4}' | head -n1)
|
||||
info "Determined default network interface: ($ext_if)"
|
||||
info "${bastille_pf_conf} does not exist: creating..."
|
||||
|
||||
## creating pf.conf
|
||||
cat << EOF > ${bastille_pf_conf}
|
||||
## generated by bastille setup
|
||||
ext_if="$ext_if"
|
||||
|
||||
set block-policy return
|
||||
scrub in on \$ext_if all fragment reassemble
|
||||
set skip on lo
|
||||
|
||||
table <jails> persist
|
||||
nat on \$ext_if from <jails> to any -> (\$ext_if:0)
|
||||
rdr-anchor "rdr/*"
|
||||
|
||||
block in all
|
||||
pass out quick keep state
|
||||
antispoof for \$ext_if inet
|
||||
pass in inet proto tcp from any to any port ssh flags S/SA keep state
|
||||
EOF
|
||||
sysrc pf_enable=YES
|
||||
else
|
||||
error_exit "${bastille_pf_conf} already exists. Exiting."
|
||||
fi
|
||||
}
|
||||
|
||||
# Configure ZFS
|
||||
configure_zfs() {
|
||||
if [ ! "$(kldstat -m zfs)" ]; then
|
||||
info "ZFS module not loaded; skipping..."
|
||||
else
|
||||
## attempt to determine bastille_zroot from `zpool list`
|
||||
bastille_zroot=$(zpool list | grep -v NAME | awk '{print $1}')
|
||||
sysrc -f "${bastille_prefix}/bastille.conf" bastille_zfs_enable=YES
|
||||
sysrc -f "${bastille_prefix}/bastille.conf" bastille_zfs_zpool="${bastille_zroot}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run all base functions (w/o vnet) if no args
|
||||
if [ $# -eq 0 ]; then
|
||||
sysrc bastille_enable=YES
|
||||
configure_bastille0
|
||||
configure_pf
|
||||
configure_zfs
|
||||
fi
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
pf|firewall)
|
||||
configure_pf
|
||||
;;
|
||||
bastille0|loopback)
|
||||
configure_bastille0
|
||||
;;
|
||||
zfs|storage)
|
||||
configure_zfs
|
||||
;;
|
||||
bastille1|vnet|bridge)
|
||||
configure_vnet
|
||||
;;
|
||||
esac
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille start TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille start TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -47,29 +46,65 @@ if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(/usr/local/bin/bastille list jails)
|
||||
JAILS=$(bastille list jails)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(/usr/local/bin/bastille list jails | grep -w "${TARGET}")
|
||||
JAILS=$(bastille list jails | awk "/^${TARGET}$/")
|
||||
## check if exist
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
error_exit "[${TARGET}]: Not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
## test if running
|
||||
if [ $(jls name | grep -w ${_jail}) ]; then
|
||||
echo -e "${COLOR_RED}[${_jail}]: Already started.${COLOR_RESET}"
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then
|
||||
error_notify "[${_jail}]: Already started."
|
||||
|
||||
## test if not running
|
||||
elif [ ! $(jls name | grep -w ${_jail}) ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c ${_jail}
|
||||
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)
|
||||
if ! ifconfig | grep "^${_interface}:" >/dev/null; then
|
||||
error_notify "Error: ${_interface} interface does not exist."
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
## update ${bastille_jail_loopback}:network with added/removed addresses
|
||||
if [ ! -z ${bastille_jail_loopback} ]; then
|
||||
pfctl -f /etc/pf.conf
|
||||
## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry
|
||||
ip=$(bastille config "${_jail}" get ip4.addr)
|
||||
if [ -n "${ip}" ]; then
|
||||
if ifconfig | grep -wF "${ip}" >/dev/null; then
|
||||
error_notify "Error: IP address (${ip}) already in use."
|
||||
continue
|
||||
fi
|
||||
## add ip4.addr to firewall table
|
||||
pfctl -q -t "${bastille_network_pf_table}" -T add "${ip}"
|
||||
fi
|
||||
|
||||
## start the container
|
||||
info "[${_jail}]:"
|
||||
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}"
|
||||
|
||||
## add rctl limits
|
||||
if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then
|
||||
while read _limits; do
|
||||
rctl -a "${_limits}"
|
||||
done < "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
fi
|
||||
|
||||
## add rdr rules
|
||||
if [ -s "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then
|
||||
while read _rules; do
|
||||
bastille rdr "${_jail}" ${_rules}
|
||||
done < "${bastille_jailsdir}/${_jail}/rdr.conf"
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille stop TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille stop TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,33 +42,41 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
bastille_root_check
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
## test if not running
|
||||
if [ ! $(jls name | grep -w "${_jail}") ]; then
|
||||
echo -e "${COLOR_RED}[${_jail}]: Not started.${COLOR_RESET}"
|
||||
|
||||
## test if running
|
||||
elif [ $(jls name | grep -w "${_jail}") ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r ${_jail}
|
||||
if [ "$(/usr/sbin/jls name | awk "/^${_jail}$/")" ]; then
|
||||
## Capture ip4.addr address while still running
|
||||
_ip="$(/usr/sbin/jls -j ${_jail} ip4.addr)"
|
||||
|
||||
## update ${bastille_jail_loopback}:network with added/removed addresses
|
||||
if [ ! -z ${bastille_jail_loopback} ]; then
|
||||
pfctl -f /etc/pf.conf
|
||||
# Check if pfctl is present
|
||||
if which -s pfctl; then
|
||||
if [ "$(bastille rdr ${_jail} list)" ]; then
|
||||
bastille rdr ${_jail} clear
|
||||
fi
|
||||
fi
|
||||
|
||||
## remove rctl limits
|
||||
if [ -s "${bastille_jailsdir}/${_jail}/rctl.conf" ]; then
|
||||
while read _limits; do
|
||||
rctl -r "${_limits}"
|
||||
done < "${bastille_jailsdir}/${_jail}/rctl.conf"
|
||||
fi
|
||||
|
||||
## stop container
|
||||
info "[${_jail}]:"
|
||||
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}"
|
||||
|
||||
## remove (captured above) ip4.addr from firewall table
|
||||
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 "${bastille_network_pf_table}" -T delete "${_ip}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille sysrc TARGET args${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille sysrc TARGET args"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,23 +41,14 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
bastille_root_check
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
jexec -l ${_jail} /usr/sbin/sysrc $@
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/sbin/sysrc "$@"
|
||||
echo -e "${COLOR_RESET}"
|
||||
done
|
||||
|
||||
104
usr/local/share/bastille/tags.sh
Normal file
104
usr/local/share/bastille/tags.sh
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
# Ressource limits added by Lars Engels github.com/bsdlme
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_notify "Usage: bastille tags TARGET add tag1[,tag2,...]"
|
||||
error_notify " bastille tags TARGET delete tag1[,tag2,...]"
|
||||
error_notify " bastille tags TARGET list [tag]"
|
||||
echo -e "Example: bastille tags JAILNAME add database,mysql"
|
||||
echo -e " bastille tags JAILNAME delete mysql"
|
||||
echo -e " bastille tags ALL list"
|
||||
echo -e " bastille tags ALL list mysql"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -lt 1 -o $# -gt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
ACTION="${1}"
|
||||
TAGS="${2}"
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
bastille_jail_tags="${bastille_jailsdir}/${_jail}/tags"
|
||||
case ${ACTION} in
|
||||
add)
|
||||
for _tag in $(echo ${TAGS} | tr , ' '); do
|
||||
echo ${_tag} >> "${bastille_jail_tags}"
|
||||
tmpfile="$(mktemp)"
|
||||
sort "${bastille_jail_tags}" | uniq > "${tmpfile}"
|
||||
mv "${tmpfile}" "${bastille_jail_tags}"
|
||||
done
|
||||
;;
|
||||
del*)
|
||||
for _tag in $(echo ${TAGS} | tr , ' '); do
|
||||
[ ! -f "${bastille_jail_tags}" ] && break # skip if no tags file
|
||||
tmpfile="$(mktemp)"
|
||||
grep -Ev "^${_tag}\$" "${bastille_jail_tags}" > "${tmpfile}"
|
||||
mv "${tmpfile}" "${bastille_jail_tags}"
|
||||
# delete tags file if empty
|
||||
[ ! -s "${bastille_jail_tags}" ] && rm "${bastille_jail_tags}"
|
||||
done
|
||||
;;
|
||||
list)
|
||||
if [ -n "${TAGS}" ]; then
|
||||
[ -n "$(echo ${TAGS} | grep ,)" ] && usage # Only one tag per query
|
||||
[ ! -f "${bastille_jail_tags}" ] && continue # skip if there is no tags file
|
||||
grep -qE "^${TAGS}\$" "${bastille_jail_tags}"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "${_jail}"
|
||||
continue
|
||||
fi
|
||||
else
|
||||
if [ -f "${bastille_jail_tags}" ]; then
|
||||
echo -n "${_jail}: "
|
||||
xargs < "${bastille_jail_tags}"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,174 +28,366 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille template TARGET project/template.${COLOR_RESET}"
|
||||
exit 1
|
||||
bastille_usage() {
|
||||
error_exit "Usage: bastille template TARGET|--convert project/template"
|
||||
}
|
||||
|
||||
post_command_hook() {
|
||||
_jail=$1
|
||||
_cmd=$2
|
||||
_args=$3
|
||||
|
||||
case $_cmd in
|
||||
rdr)
|
||||
echo -e ${_args}
|
||||
esac
|
||||
}
|
||||
|
||||
get_arg_name() {
|
||||
echo "${1}" | sed -E 's/=.*//'
|
||||
}
|
||||
|
||||
parse_arg_value() {
|
||||
# Parses the value after = and then escapes back/forward slashes and single quotes in it. -- cwells
|
||||
echo "${1}" | sed -E 's/[^=]+=?//' | sed -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/'\''/'\''\\'\'\''/g'
|
||||
}
|
||||
|
||||
get_arg_value() {
|
||||
_name_value_pair="${1}"
|
||||
shift
|
||||
_arg_name="$(get_arg_name "${_name_value_pair}")"
|
||||
|
||||
# Remaining arguments in $@ are the script arguments, which take precedence. -- cwells
|
||||
for _script_arg in "$@"; do
|
||||
case ${_script_arg} in
|
||||
--arg)
|
||||
# Parse whatever is next. -- cwells
|
||||
_next_arg='true' ;;
|
||||
*)
|
||||
if [ "${_next_arg}" = 'true' ]; then # This is the parameter after --arg. -- cwells
|
||||
_next_arg=''
|
||||
if [ "$(get_arg_name "${_script_arg}")" = "${_arg_name}" ]; then
|
||||
parse_arg_value "${_script_arg}"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check the ARG_FILE if one was provided. --cwells
|
||||
if [ -n "${ARG_FILE}" ]; then
|
||||
# To prevent a false empty value, only parse the value if this argument exists in the file. -- cwells
|
||||
if grep "^${_arg_name}=" "${ARG_FILE}" > /dev/null 2>&1; then
|
||||
parse_arg_value "$(grep "^${_arg_name}=" "${ARG_FILE}")"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# Return the default value, which may be empty, from the name=value pair. -- cwells
|
||||
parse_arg_value "${_name_value_pair}"
|
||||
}
|
||||
|
||||
render() {
|
||||
_file_path="${1}/${2}"
|
||||
if [ -d "${_file_path}" ]; then # Recursively render every file in this directory. -- cwells
|
||||
echo "Rendering Directory: ${_file_path}"
|
||||
find "${_file_path}" \( -type d -name .git -prune \) -o -type f
|
||||
find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | $(eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}")
|
||||
elif [ -f "${_file_path}" ]; then
|
||||
echo "Rendering File: ${_file_path}"
|
||||
eval "sed -i '' ${ARG_REPLACEMENTS} '${_file_path}'"
|
||||
else
|
||||
warn "Path not found for render: ${2}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
bastille_usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
|
||||
usage
|
||||
if [ $# -lt 1 ]; then
|
||||
bastille_usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
|
||||
TEMPLATE="${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${bastille_templatesdir}"/"${TEMPLATE}" ]; then
|
||||
echo -e "${COLOR_RED}${TEMPLATE} not found.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
bastille_root_check
|
||||
|
||||
## global variables
|
||||
TEMPLATE="${1}"
|
||||
bastille_template=${bastille_templatesdir}/${TEMPLATE}
|
||||
bastille_template_TARGET=${bastille_template}/TARGET
|
||||
bastille_template_INCLUDE=${bastille_template}/INCLUDE
|
||||
bastille_template_PRE=${bastille_template}/PRE
|
||||
bastille_template_OVERLAY=${bastille_template}/OVERLAY
|
||||
bastille_template_FSTAB=${bastille_template}/FSTAB
|
||||
bastille_template_PF=${bastille_template}/PF
|
||||
bastille_template_PKG=${bastille_template}/PKG
|
||||
bastille_template_SYSRC=${bastille_template}/SYSRC
|
||||
bastille_template_SERVICE=${bastille_template}/SERVICE
|
||||
bastille_template_CMD=${bastille_template}/CMD
|
||||
if [ -z "${HOOKS}" ]; then
|
||||
HOOKS='LIMITS INCLUDE PRE FSTAB PF PKG OVERLAY CONFIG SYSRC SERVICE CMD RENDER'
|
||||
fi
|
||||
|
||||
# Special case conversion of hook-style template files into a Bastillefile. -- cwells
|
||||
if [ "${TARGET}" = '--convert' ]; then
|
||||
if [ -d "${TEMPLATE}" ]; then # A relative path was provided. -- cwells
|
||||
cd "${TEMPLATE}"
|
||||
elif [ -d "${bastille_template}" ]; then
|
||||
cd "${bastille_template}"
|
||||
else
|
||||
error_exit "Template not found: ${TEMPLATE}"
|
||||
fi
|
||||
|
||||
echo "Converting template: ${TEMPLATE}"
|
||||
|
||||
HOOKS="ARG ${HOOKS}"
|
||||
for _hook in ${HOOKS}; do
|
||||
if [ -s "${_hook}" ]; then
|
||||
# Default command is the hook name and default args are the line from the file. -- cwells
|
||||
_cmd="${_hook}"
|
||||
_args_template='${_line}'
|
||||
|
||||
# Replace old hook names with Bastille command names. -- cwells
|
||||
case ${_hook} in
|
||||
CONFIG|OVERLAY)
|
||||
_cmd='CP'
|
||||
_args_template='${_line} /'
|
||||
;;
|
||||
FSTAB)
|
||||
_cmd='MOUNT' ;;
|
||||
PF)
|
||||
_cmd='RDR' ;;
|
||||
PRE)
|
||||
_cmd='CMD' ;;
|
||||
esac
|
||||
|
||||
while read _line; do
|
||||
if [ -z "${_line}" ]; then
|
||||
continue
|
||||
fi
|
||||
eval "_args=\"${_args_template}\""
|
||||
echo "${_cmd} ${_args}" >> Bastillefile
|
||||
done < "${_hook}"
|
||||
echo '' >> Bastillefile
|
||||
rm "${_hook}"
|
||||
fi
|
||||
done
|
||||
|
||||
info "Template converted: ${TEMPLATE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case ${TEMPLATE} in
|
||||
http?://*/*/*)
|
||||
TEMPLATE_DIR=$(echo "${TEMPLATE}" | awk -F / '{ print $4 "/" $5 }')
|
||||
if [ ! -d "${bastille_templatesdir}/${TEMPLATE_DIR}" ]; then
|
||||
info "Bootstrapping ${TEMPLATE}..."
|
||||
if ! bastille bootstrap "${TEMPLATE}"; then
|
||||
error_exit "Failed to bootstrap template: ${TEMPLATE}"
|
||||
fi
|
||||
fi
|
||||
TEMPLATE="${TEMPLATE_DIR}"
|
||||
bastille_template=${bastille_templatesdir}/${TEMPLATE}
|
||||
;;
|
||||
*/*)
|
||||
if [ ! -d "${bastille_templatesdir}/${TEMPLATE}" ]; then
|
||||
if [ ! -d ${TEMPLATE} ]; then
|
||||
error_exit "${TEMPLATE} not found."
|
||||
else
|
||||
bastille_template=${TEMPLATE}
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
error_exit "Template name/URL not recognized."
|
||||
esac
|
||||
|
||||
if [ -z "${JAILS}" ]; then
|
||||
error_exit "Container ${TARGET} is not running."
|
||||
fi
|
||||
|
||||
# Check for an --arg-file parameter. -- cwells
|
||||
for _script_arg in "$@"; do
|
||||
case ${_script_arg} in
|
||||
--arg-file)
|
||||
# Parse whatever is next. -- cwells
|
||||
_next_arg='true' ;;
|
||||
*)
|
||||
if [ "${_next_arg}" = 'true' ]; then # This is the parameter after --arg-file. -- cwells
|
||||
_next_arg=''
|
||||
ARG_FILE="${_script_arg}"
|
||||
break
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "${ARG_FILE}" ] && [ ! -f "${ARG_FILE}" ]; then
|
||||
error_exit "File not found: ${ARG_FILE}"
|
||||
fi
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
## jail-specific variables.
|
||||
bastille_jail_path=$(jls -j "${_jail}" path)
|
||||
info "[${_jail}]:"
|
||||
info "Applying template: ${TEMPLATE}..."
|
||||
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
## jail-specific variables.
|
||||
bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path)
|
||||
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
|
||||
_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
|
||||
fi
|
||||
fi
|
||||
|
||||
## TARGET
|
||||
if [ -s "${bastille_template_TARGET}" ]; then
|
||||
if [ $(grep -w "${_jail}" ${bastille_template_TARGET}) ]; then
|
||||
echo -e "${COLOR_GREEN}TARGET: !${_jail}.${COLOR_RESET}"
|
||||
echo
|
||||
if [ -s "${bastille_template}/TARGET" ]; then
|
||||
if grep -qw "${_jail}" "${bastille_template}/TARGET"; then
|
||||
info "TARGET: !${_jail}."
|
||||
echo
|
||||
continue
|
||||
fi
|
||||
if [ ! $(grep -E "(^|\b)(${_jail}|ALL)($|\b)" ${bastille_template_TARGET}) ]; then
|
||||
echo -e "${COLOR_GREEN}TARGET: ?${_jail}.${COLOR_RESET}"
|
||||
echo
|
||||
if ! grep -Eq "(^|\b)(${_jail}|ALL)($|\b)" "${bastille_template}/TARGET"; then
|
||||
info "TARGET: ?${_jail}."
|
||||
echo
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
## INCLUDE
|
||||
if [ -s "${bastille_template_INCLUDE}" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:INCLUDE -- START${COLOR_RESET}"
|
||||
while read _include; 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_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
|
||||
if [ -z "${_line}" ]; then
|
||||
continue
|
||||
fi
|
||||
_arg_name=$(get_arg_name "${_line}")
|
||||
_arg_value=$(get_arg_value "${_line}" "$@")
|
||||
if [ -z "${_arg_value}" ]; then
|
||||
warn "No value provided for arg: ${_arg_name}"
|
||||
fi
|
||||
ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'"
|
||||
done < "${bastille_template}/ARG"
|
||||
fi
|
||||
|
||||
if [ -s "${bastille_template}/Bastillefile" ]; then
|
||||
# Ignore blank lines and comments. -- cwells
|
||||
SCRIPT=$(grep -v '^[[:blank:]]*$' "${bastille_template}/Bastillefile" | grep -v '^[[:blank:]]*#')
|
||||
# Use a newline as the separator. -- cwells
|
||||
IFS='
|
||||
'
|
||||
set -f
|
||||
for _line in ${SCRIPT}; do
|
||||
# First word converted to lowercase is the Bastille command. -- cwells
|
||||
_cmd=$(echo "${_line}" | awk '{print tolower($1);}')
|
||||
# Rest of the line with "arg" variables replaced will be the arguments. -- cwells
|
||||
_args=$(echo "${_line}" | awk '{$1=""; sub(/^ */, ""); print;}' | eval "sed ${ARG_REPLACEMENTS}")
|
||||
|
||||
# Apply overrides for commands/aliases and arguments. -- cwells
|
||||
case $_cmd in
|
||||
arg) # This is a template argument definition. -- cwells
|
||||
_arg_name=$(get_arg_name "${_args}")
|
||||
_arg_value=$(get_arg_value "${_args}" "$@")
|
||||
if [ -z "${_arg_value}" ]; then
|
||||
warn "No value provided for arg: ${_arg_name}"
|
||||
fi
|
||||
# Build a list of sed commands like this: -e 's/${username}/root/g' -e 's/${domain}/example.com/g'
|
||||
ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'"
|
||||
continue
|
||||
;;
|
||||
cmd)
|
||||
# Escape single-quotes in the command being executed. -- cwells
|
||||
_args=$(echo "${_args}" | sed "s/'/'\\\\''/g")
|
||||
# Allow redirection within the jail. -- cwells
|
||||
_args="sh -c '${_args}'"
|
||||
;;
|
||||
cp|copy)
|
||||
_cmd='cp'
|
||||
# Convert relative "from" path into absolute path inside the template directory. -- cwells
|
||||
if [ "${_args%${_args#?}}" != '/' ] && [ "${_args%${_args#??}}" != '"/' ]; then
|
||||
_args="${bastille_template}/${_args}"
|
||||
fi
|
||||
;;
|
||||
fstab|mount)
|
||||
_cmd='mount' ;;
|
||||
include)
|
||||
_cmd='template' ;;
|
||||
overlay)
|
||||
_cmd='cp'
|
||||
_args="${bastille_template}/${_args} /"
|
||||
;;
|
||||
pkg)
|
||||
_args="install -y ${_args}" ;;
|
||||
render) # This is a path to one or more files needing arguments replaced by values. -- cwells
|
||||
render "${bastille_jail_path}" "${_args}"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! eval "bastille ${_cmd} ${_jail} ${_args}"; then
|
||||
set +f
|
||||
unset IFS
|
||||
error_exit "Failed to execute command: ${_cmd}"
|
||||
fi
|
||||
|
||||
post_command_hook "${_jail}" "${_cmd}" "${_args}"
|
||||
done
|
||||
set +f
|
||||
unset IFS
|
||||
fi
|
||||
|
||||
for _hook in ${HOOKS}; do
|
||||
if [ -s "${bastille_template}/${_hook}" ]; then
|
||||
# Default command is the lowercase hook name and default args are the line from the file. -- cwells
|
||||
_cmd=$(echo "${_hook}" | awk '{print tolower($1);}')
|
||||
_args_template='${_line}'
|
||||
|
||||
# Override default command/args for some hooks. -- cwells
|
||||
case ${_hook} in
|
||||
CONFIG)
|
||||
warn "CONFIG deprecated; rename to OVERLAY."
|
||||
_args_template='${bastille_template}/${_line} /'
|
||||
_cmd='cp' ;;
|
||||
FSTAB)
|
||||
_cmd='mount' ;;
|
||||
INCLUDE)
|
||||
_cmd='template' ;;
|
||||
OVERLAY)
|
||||
_args_template='${bastille_template}/${_line} /'
|
||||
_cmd='cp' ;;
|
||||
PF)
|
||||
info "NOT YET IMPLEMENTED."
|
||||
continue ;;
|
||||
PRE)
|
||||
_cmd='cmd' ;;
|
||||
RENDER) # This is a path to one or more files needing arguments replaced by values. -- cwells
|
||||
render "${bastille_jail_path}" "${_line}"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
info "[${_jail}]:${_hook} -- START"
|
||||
if [ "${_hook}" = 'CMD' ] || [ "${_hook}" = 'PRE' ]; then
|
||||
bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || exit 1
|
||||
elif [ "${_hook}" = 'PKG' ]; then
|
||||
bastille pkg "${_jail}" install -y $(cat "${bastille_template}/PKG") || exit 1
|
||||
bastille pkg "${_jail}" audit -F
|
||||
else
|
||||
while read _line; do
|
||||
if [ -z "${_line}" ]; then
|
||||
continue
|
||||
fi
|
||||
# Replace "arg" variables in this line with the provided values. -- cwells
|
||||
_line=$(echo "${_line}" | eval "sed ${ARG_REPLACEMENTS}")
|
||||
eval "_args=\"${_args_template}\""
|
||||
bastille "${_cmd}" "${_jail}" ${_args} || exit 1
|
||||
done < "${bastille_template}/${_hook}"
|
||||
fi
|
||||
info "[${_jail}]:${_hook} -- END"
|
||||
echo
|
||||
echo -e "${COLOR_GREEN}INCLUDE: ${_include}${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}Bootstrapping ${_include}...${COLOR_RESET}"
|
||||
bastille bootstrap ${_include}
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo -e "${COLOR_GREEN}Applying ${_include}...${COLOR_RESET}"
|
||||
BASTILLE_TEMPLATE_PROJECT=$(echo "${_include}" | awk -F / '{ print $4}')
|
||||
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $5}')
|
||||
bastille template ${_jail} ${BASTILLE_TEMPLATE_PROJECT}/${BASTILLE_TEMPLATE_REPO}
|
||||
done < "${bastille_template_INCLUDE}"
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:INCLUDE -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
|
||||
## PRE
|
||||
if [ -s "${bastille_template_PRE}" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:PRE -- START${COLOR_RESET}"
|
||||
jexec -l ${_jail} /bin/sh < "${bastille_template_PRE}" || exit 1
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:PRE -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
|
||||
## CONFIG / OVERLAY
|
||||
if [ -s "${bastille_template_OVERLAY}" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- START${COLOR_RESET}"
|
||||
while read _dir; do
|
||||
cp -av "${bastille_template}/${_dir}" "${bastille_jail_path}" || exit 1
|
||||
done < ${bastille_template_OVERLAY}
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:OVERLAY -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
if [ -s "${bastille_template}/CONFIG" ]; then
|
||||
echo -e "${COLOR_YELLOW}CONFIG deprecated; rename to OVERLAY.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:CONFIG -- START${COLOR_RESET}"
|
||||
while read _dir; do
|
||||
cp -av "${bastille_template}/${_dir}" "${bastille_jail_path}" || exit 1
|
||||
done < ${bastille_template}/CONFIG
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:CONFIG -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
|
||||
## FSTAB
|
||||
if [ -s "${bastille_template_FSTAB}" ]; then
|
||||
bastille_templatefstab=$(cat "${bastille_template_FSTAB}")
|
||||
echo -e "${COLOR_GREEN}Updating fstab.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}NOT YET IMPLEMENTED.${COLOR_RESET}"
|
||||
fi
|
||||
|
||||
## PF
|
||||
if [ -s "${bastille_template_PF}" ]; then
|
||||
bastille_templatepf=$(cat "${bastille_template_PF}")
|
||||
echo -e "${COLOR_GREEN}Generating PF profile.${COLOR_RESET}"
|
||||
echo -e "${COLOR_GREEN}NOT YET IMPLEMENTED.${COLOR_RESET}"
|
||||
fi
|
||||
|
||||
## PKG (bootstrap + pkg)
|
||||
if [ -s "${bastille_template_PKG}" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- START${COLOR_RESET}"
|
||||
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg bootstrap || exit 1
|
||||
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg audit -F
|
||||
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg install $(cat ${bastille_template_PKG}) || exit 1
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
|
||||
## SYSRC
|
||||
if [ -s "${bastille_template_SYSRC}" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- START${COLOR_RESET}"
|
||||
while read _sysrc; do
|
||||
jexec -l ${_jail} /usr/sbin/sysrc "${_sysrc}" || exit 1
|
||||
done < "${bastille_template_SYSRC}"
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:SYSRC -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
|
||||
## SERVICE
|
||||
if [ -s "${bastille_template_SERVICE}" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- START${COLOR_RESET}"
|
||||
while read _service; do
|
||||
jexec -l ${_jail} /usr/sbin/service ${_service} || exit 1
|
||||
done < "${bastille_template_SERVICE}"
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:SERVICE -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
|
||||
## CMD
|
||||
if [ -s "${bastille_template_CMD}" ]; then
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:CMD -- START${COLOR_RESET}"
|
||||
jexec -l ${_jail} /bin/sh < "${bastille_template_CMD}" || exit 1
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:CMD -- END${COLOR_RESET}"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo -e "${COLOR_GREEN}Template Complete.${COLOR_RESET}"
|
||||
info "Template applied: ${TEMPLATE}"
|
||||
echo
|
||||
done
|
||||
|
||||
11
usr/local/share/bastille/templates/default/base/Bastillefile
Normal file
11
usr/local/share/bastille/templates/default/base/Bastillefile
Normal file
@@ -0,0 +1,11 @@
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
CMD touch /etc/rc.conf
|
||||
SYSRC syslogd_flags="-ss"
|
||||
SYSRC sendmail_enable="NO"
|
||||
SYSRC sendmail_submit_enable="NO"
|
||||
SYSRC sendmail_outbound_enable="NO"
|
||||
SYSRC sendmail_msp_queue_enable="NO"
|
||||
SYSRC cron_flags="-J 60"
|
||||
|
||||
CP "${HOST_RESOLV_CONF}" etc/resolv.conf
|
||||
@@ -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
|
||||
@@ -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,4 @@
|
||||
ARG BASE_TEMPLATE=default/base
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}"
|
||||
15
usr/local/share/bastille/templates/default/vnet/Bastillefile
Normal file
15
usr/local/share/bastille/templates/default/vnet/Bastillefile
Normal file
@@ -0,0 +1,15 @@
|
||||
ARG BASE_TEMPLATE=default/base
|
||||
ARG HOST_RESOLV_CONF=/etc/resolv.conf
|
||||
|
||||
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,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,11 +28,10 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille top TARGET${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille top TARGET"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -42,23 +41,14 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
shift
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
bastille_root_check
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
jexec -l ${_jail} /usr/bin/top
|
||||
info "[${_jail}]:"
|
||||
jexec -l "${_jail}" /usr/bin/top
|
||||
echo -e "${COLOR_RESET}"
|
||||
done
|
||||
|
||||
74
usr/local/share/bastille/umount.sh
Normal file
74
usr/local/share/bastille/umount.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
error_exit "Usage: bastille umount TARGET container_path"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
bastille_root_check
|
||||
|
||||
MOUNT_PATH=$1
|
||||
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
|
||||
_jailpath="${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}"
|
||||
|
||||
if [ ! -d "${_jailpath}" ]; then
|
||||
error_exit "The specified mount point does not exist inside the jail."
|
||||
fi
|
||||
|
||||
# Unmount the volume. -- cwells
|
||||
if ! umount "${_jailpath}"; then
|
||||
error_exit "Failed to unmount volume: ${MOUNT_PATH}"
|
||||
fi
|
||||
|
||||
# Remove the entry from fstab so it is not automounted in the future. -- cwells
|
||||
if ! sed -E -i '' "\, +${_jailpath} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then
|
||||
error_exit "Failed to delete fstab entry: ${_fstab_entry}"
|
||||
fi
|
||||
|
||||
echo "Unmounted: ${MOUNT_PATH}"
|
||||
echo
|
||||
done
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille update release.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille update [release|container|template] | [force]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,21 +42,134 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
RELEASE="${1}"
|
||||
shift
|
||||
bastille_root_check
|
||||
|
||||
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then
|
||||
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
|
||||
TARGET="${1}"
|
||||
OPTION="${2}"
|
||||
|
||||
# Handle options
|
||||
case "${OPTION}" in
|
||||
-f|--force)
|
||||
OPTION="-F"
|
||||
;;
|
||||
*)
|
||||
OPTION=
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check for unsupported actions
|
||||
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 [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" fetch install --currently-running "${RELEASE}"
|
||||
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 [ ! "$(/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
|
||||
error_exit "${TARGET} is not a thick container."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
jail_update() {
|
||||
# Update a thick container
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
jail_check
|
||||
CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null)
|
||||
if [ -z "${CURRENT_VERSION}" ]; then
|
||||
error_exit "Can't determine '${TARGET}' version."
|
||||
else
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" \
|
||||
fetch install --currently-running "${CURRENT_VERSION}"
|
||||
fi
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
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 --currently-running "${TARGET_TRIM}"
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \
|
||||
install --currently-running "${TARGET_TRIM}"
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
fi
|
||||
}
|
||||
|
||||
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 [ "${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
|
||||
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
|
||||
exit 1
|
||||
jail_update
|
||||
fi
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,12 +28,11 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille upgrade release newrelease.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille upgrade release newrelease | target newrelease | target install | [force]"
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
@@ -43,23 +42,112 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
|
||||
if [ $# -gt 3 ] || [ $# -lt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
RELEASE="$1"
|
||||
shift
|
||||
NEWRELEASE="$1"
|
||||
bastille_root_check
|
||||
|
||||
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then
|
||||
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
|
||||
TARGET="$1"
|
||||
NEWRELEASE="$2"
|
||||
OPTION="$3"
|
||||
|
||||
# Check for unsupported actions
|
||||
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
|
||||
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" -r "${NEWRELEASE}" upgrade
|
||||
# Handle options
|
||||
case "${OPTION}" in
|
||||
-f|--force)
|
||||
OPTION="-F"
|
||||
;;
|
||||
*)
|
||||
OPTION=
|
||||
;;
|
||||
esac
|
||||
|
||||
jail_check() {
|
||||
# Check if the jail is thick and is running
|
||||
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
|
||||
error_exit "${TARGET} is not a thick container."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
release_check() {
|
||||
# Validate the release
|
||||
if ! echo "${NEWRELEASE}" | grep -q "[0-9]\{2\}.[0-9]-[RELEASE,BETA,RC]"; then
|
||||
error_exit "${NEWRELEASE} is not a valid release."
|
||||
fi
|
||||
}
|
||||
|
||||
release_upgrade() {
|
||||
# Upgrade a release
|
||||
if [ -d "${bastille_releasesdir}/${TARGET}" ]; then
|
||||
release_check
|
||||
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
|
||||
}
|
||||
|
||||
jail_upgrade() {
|
||||
# Upgrade a thick container
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
jail_check
|
||||
release_check
|
||||
CURRENT_VERSION=$(jexec -l ${TARGET} freebsd-version)
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" --currently-running "${CURRENT_VERSION}" -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
|
||||
}
|
||||
|
||||
jail_updates_install() {
|
||||
# Finish installing upgrade on a thick container
|
||||
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
jail_check
|
||||
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" install
|
||||
else
|
||||
error_exit "${TARGET} not found. See 'bastille bootstrap'."
|
||||
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
|
||||
if [ "${NEWRELEASE}" = "install" ]; then
|
||||
release_updates_install
|
||||
else
|
||||
release_upgrade
|
||||
fi
|
||||
elif [ "${NEWRELEASE}" = "install" ]; then
|
||||
jail_updates_install
|
||||
else
|
||||
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
|
||||
exit 1
|
||||
jail_upgrade
|
||||
fi
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,35 +28,151 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille verify release.${COLOR_RESET}"
|
||||
exit 1
|
||||
bastille_usage() {
|
||||
error_exit "Usage: bastille verify [release|template]"
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" --currently-running "${RELEASE}" IDS
|
||||
else
|
||||
error_exit "${RELEASE} not found. See 'bastille bootstrap'."
|
||||
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
|
||||
|
||||
for _hook in TARGET INCLUDE PRE OVERLAY FSTAB PF PKG SYSRC SERVICE CMD Bastillefile; do
|
||||
_path=${_template_path}/${_hook}
|
||||
if [ -s "${_path}" ]; then
|
||||
_hook_validate=$((_hook_validate+1))
|
||||
info "Detected ${_hook} hook."
|
||||
|
||||
## line count must match newline count
|
||||
if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then
|
||||
info "[${_hook}]:"
|
||||
error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]."
|
||||
error_notify "Line numbers don't match line breaks."
|
||||
echo
|
||||
error_exit "Template validation failed."
|
||||
## if INCLUDE; recursive verify
|
||||
elif [ "${_hook}" = 'INCLUDE' ]; then
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
echo
|
||||
while read _include; do
|
||||
info "[${_hook}]:[${_include}]:"
|
||||
TEMPLATE_INCLUDE="${_include}"
|
||||
handle_template_include
|
||||
done < "${_path}"
|
||||
|
||||
## if tree; tree -a bastille_template/_dir
|
||||
elif [ "${_hook}" = 'OVERLAY' ]; then
|
||||
info "[${_hook}]:"
|
||||
cat "${_path}"
|
||||
echo
|
||||
while read _dir; do
|
||||
info "[${_hook}]:[${_dir}]:"
|
||||
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}"
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
## remove bad templates
|
||||
if [ "${_hook_validate}" -lt 1 ]; then
|
||||
error_notify "No valid template hooks found."
|
||||
error_notify "Template discarded."
|
||||
rm -rf "${bastille_template}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## if validated; ready to use
|
||||
if [ "${_hook_validate}" -gt 0 ]; then
|
||||
info "Template ready to use."
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle special-case commands first.
|
||||
case "$1" in
|
||||
help|-h|--help)
|
||||
usage
|
||||
bastille_usage
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
|
||||
usage
|
||||
bastille_usage
|
||||
fi
|
||||
|
||||
RELEASE=$1
|
||||
bastille_root_check
|
||||
|
||||
if [ ! -z "$(freebsd-version | grep -i HBSD)" ]; then
|
||||
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
|
||||
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" IDS
|
||||
else
|
||||
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
case "$1" in
|
||||
*-RELEASE|*-release|*-RC[1-9]|*-rc[1-9])
|
||||
RELEASE=$1
|
||||
verify_release
|
||||
;;
|
||||
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
|
||||
RELEASE=$1
|
||||
verify_release
|
||||
;;
|
||||
http?*)
|
||||
bastille_usage
|
||||
;;
|
||||
*/*)
|
||||
BASTILLE_TEMPLATE=$1
|
||||
verify_template
|
||||
;;
|
||||
*)
|
||||
bastille_usage
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2019, Christer Edwards <christer.edwards@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2018-2023, Christer Edwards <christer.edwards@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
@@ -28,42 +28,49 @@
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
. /usr/local/share/bastille/colors.pre.sh
|
||||
. /usr/local/share/bastille/common.sh
|
||||
. /usr/local/etc/bastille/bastille.conf
|
||||
|
||||
usage() {
|
||||
echo -e "${COLOR_RED}Usage: bastille zfs TARGET [set|get|snap] [key=value|date]'${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "Usage: bastille zfs TARGET [set|get|snap] [key=value|date]'"
|
||||
}
|
||||
|
||||
zfs_snapshot() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
zfs snapshot ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}
|
||||
info "[${_jail}]:"
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
zfs_destroy_snapshot() {
|
||||
for _jail in ${JAILS}; do
|
||||
info "[${_jail}]:"
|
||||
zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
zfs_set_value() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
zfs $ATTRIBUTE ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}
|
||||
info "[${_jail}]:"
|
||||
zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
zfs_get_value() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
zfs get $ATTRIBUTE ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}
|
||||
info "[${_jail}]:"
|
||||
zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
zfs_disk_usage() {
|
||||
for _jail in ${JAILS}; do
|
||||
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
|
||||
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}
|
||||
info "[${_jail}]:"
|
||||
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
|
||||
echo
|
||||
done
|
||||
}
|
||||
@@ -75,48 +82,39 @@ help|-h|--help)
|
||||
;;
|
||||
esac
|
||||
|
||||
bastille_root_check
|
||||
|
||||
## check ZFS enabled
|
||||
if [ ! "${bastille_zfs_enable}" = "YES" ]; then
|
||||
echo -e "${COLOR_RED}ZFS not enabled.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ZFS not enabled."
|
||||
fi
|
||||
|
||||
## check zpool defined
|
||||
if [ -z "${bastille_zfs_zpool}" ]; then
|
||||
echo -e "${COLOR_RED}ZFS zpool not defined.${COLOR_RESET}"
|
||||
exit 1
|
||||
error_exit "ZFS zpool not defined."
|
||||
fi
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
|
||||
if [ "${TARGET}" = 'ALL' ]; then
|
||||
JAILS=$(jls name)
|
||||
fi
|
||||
|
||||
if [ "${TARGET}" != 'ALL' ]; then
|
||||
JAILS=$(jls name | grep -w "${TARGET}")
|
||||
fi
|
||||
|
||||
case "$2" in
|
||||
case "$1" in
|
||||
set)
|
||||
ATTRIBUTE=$3
|
||||
JAILS=${JAILS}
|
||||
ATTRIBUTE=$2
|
||||
zfs_set_value
|
||||
;;
|
||||
get)
|
||||
ATTRIBUTE=$3
|
||||
JAILS=${JAILS}
|
||||
ATTRIBUTE=$2
|
||||
zfs_get_value
|
||||
;;
|
||||
snap|snapshot)
|
||||
TAG=$3
|
||||
JAILS=${JAILS}
|
||||
TAG=$2
|
||||
zfs_snapshot
|
||||
;;
|
||||
destroy_snap|destroy_snapshot)
|
||||
TAG=$2
|
||||
zfs_destroy_snapshot
|
||||
;;
|
||||
df|usage)
|
||||
zfs_disk_usage
|
||||
;;
|
||||
|
||||
Reference in New Issue
Block a user