Compare commits

...

186 Commits

Author SHA1 Message Date
Christer Edwards
113beb54e7 Merge pull request #317 from cedwards/release-prep-20210115
version bump for 0.8.20210115
2021-01-15 20:31:11 -07:00
Christer Edwards
2c5fff7ec7 version bump for 0.8.20210115 2021-01-15 20:28:34 -07:00
Christer Edwards
ae5feaa3df Merge pull request #316 from cedwards/2021-updates
update 2021 copyright
2021-01-15 20:11:04 -07:00
Christer Edwards
6fa744bbda update 2021 copyright 2021-01-15 20:00:26 -07:00
Christer Edwards
5b8fcf5a4d Merge pull request #311 from JRGTH/master
Don't start empty jails, don't apply template if Bastillefile is empty
2021-01-15 19:51:40 -07:00
Jose
15c1505187 Revert jail enable|disable feature by now, requested for later review 2021-01-15 22:28:08 -04:00
Christer Edwards
49e24c9ec9 Merge pull request #313 from cedwards/rdr-standardization
rdr now persists rules by default; rdr.sh cleanup
2021-01-14 19:16:35 -07:00
Jose
2474382756 Improve interface validation on vnet jail creation 2021-01-12 23:15:39 -04:00
Jose
87944a0fd0 Don't allow underscore in jail name beginning, remove jail from bastille_list on destroy 2021-01-10 18:55:02 -04:00
Jose
6aa84cb3f5 Small cosmetic/typo corrections 2021-01-10 02:26:40 -04:00
Jose
ed8ff8bd80 Fix to properly upgrade base releases 2021-01-09 21:24:05 -04:00
Christer Edwards
74fdcbdcb5 rdr now persists rules by default; rdr.sh cleanup 2021-01-09 15:42:24 -07:00
Jose
996e7e2b40 Option to enable/disable jail auto-start using sysrc 2021-01-09 16:18:11 -04:00
Jose
665cc19ce6 Properly link shared ports on thin jails 2021-01-08 22:37:18 -04:00
Jose
d2fcc011be Feature option for safe ZFS jail exports, config update 2021-01-08 20:30:03 -04:00
Jose
b528289815 Don't start empty jails unless templates defined, code improvements 2021-01-08 20:26:31 -04:00
Christer Edwards
110346f9f7 Merge pull request #312 from yaazkal/patch-2
export: Clarifies that UFS jails must be stopped
2021-01-08 17:13:23 -07:00
yaazkal
099f09c8b0 export: Clarifies that UFS jails must be stopped 2021-01-08 17:54:31 -05:00
Jose
083e019081 Don't start empty jails, don't apply template if Bastillefile is empty 2021-01-08 02:05:30 -04:00
Christer Edwards
4824d95d68 Merge pull request #307 from cedwards/rdr-fix-20210101
fix %s->%d regression
2021-01-05 18:30:46 -07:00
Christer Edwards
cc870b2667 fix %s->%d regression 2021-01-05 18:24:02 -07:00
Christer Edwards
67362ff309 Merge pull request #306 from cedwards/rdr-fix-20210101
add required 'pass' to rdr rules
2021-01-05 18:07:05 -07:00
Christer Edwards
6f043d62e5 add required 'pass' to rdr rules 2021-01-05 18:00:28 -07:00
Christer Edwards
7c271df2f5 Merge pull request #301 from cedwards/release-prep-20210101
version bumps for release preparation
2021-01-01 09:32:55 -07:00
Christer Edwards
c9b02fa1dd Merge pull request #302 from cedwards/vnet-checks
adding a couple vnet exceptions for ip4.addr checks
2021-01-01 09:27:16 -07:00
Christer Edwards
83a83e087e adding a couple vnet exceptions for ip4.addr checks 2021-01-01 09:23:26 -07:00
Christer Edwards
a0feac3f66 version bumps for release preparation 2021-01-01 09:13:44 -07:00
Christer Edwards
4136f8fff4 Merge pull request #296 from chriswells0/require-interface
Verify interface exists when starting jail.
2020-12-31 15:00:46 -07:00
Christer Edwards
1120a0eebd Merge pull request #279 from chriswells0/default-templates
Use templates for configuring new jails.
2020-12-31 15:00:13 -07:00
Christer Edwards
c337994414 Merge pull request #297 from hackacad/zfs_bootstrap
Check if ZFS is enabled in rc.conf and bastille.conf
2020-12-23 09:56:20 -07:00
Christer Edwards
d9ee2e190d Merge pull request #298 from hackacad/stop_rdr
stop.sh: clear rdr
2020-12-23 09:55:32 -07:00
Bike Dude
ca8819d7b6 stop.sh: clear rdr 2020-12-15 10:21:11 +01:00
Bike Dude
32a1278326 add ZFS check on bootstrap 2020-12-15 09:21:26 +01:00
Bike Dude
cbd60032fc add ZFS check on bootstrap 2020-12-15 09:12:02 +01:00
Chris Wells
a56c37983c Verify interface exists when starting non-vnet jail.
Closes #128.
2020-12-14 12:24:22 -05:00
Christer Edwards
2e5811b1ee Merge pull request #294 from BastilleBSD/247-fix-documentation
update devfs.rules documentation
2020-12-13 11:14:27 -07:00
Christer Edwards
857b5d430b cleanup patch; vnet specific 2020-12-13 11:11:15 -07:00
Christer Edwards
a3d2f69b71 cleanup patch; vnet specific 2020-12-13 11:10:29 -07:00
Christer Edwards
7150b63391 update VNET devfs documentation 2020-12-13 11:05:25 -07:00
Christer Edwards
31dfa2bfba Merge pull request #293 from chriswells0/grep-fixes
Fix grep when UTF-8 is not used.
2020-12-13 09:10:36 -07:00
Chris Wells
7675286cd3 Fix grep when UTF-8 is not used.
Support tabs and spaces in templates/config.
2020-12-12 19:17:20 -05:00
Christer Edwards
be6b1adfb9 Merge pull request #285 from chriswells0/hook-conversion
Add ability to convert "hook" files to Bastillefile format.
2020-12-12 12:05:35 -07:00
Christer Edwards
4e843be9e3 Merge pull request #276 from chriswells0/render-message
Display message about file/directory being rendered.
2020-12-12 11:55:04 -07:00
Christer Edwards
62c8060b53 Merge pull request #286 from chriswells0/document-limits
Add missing subcommands (limits/config) to docs.
2020-12-12 11:54:25 -07:00
Christer Edwards
01494ad3fd Merge pull request #289 from chriswells0/limits-fixes
Update existing limit when a new value is provided.
2020-12-12 11:54:05 -07:00
Christer Edwards
574f655cc8 Merge pull request #290 from andrewhotlab/master
Respect exec.fib parameter in console command
2020-12-12 11:53:38 -07:00
Christer Edwards
160040d2e9 Merge pull request #291 from JRGTH/master
Update help usage on update command
2020-12-12 11:52:46 -07:00
Christer Edwards
73c500ce3e Merge pull request #288 from chriswells0/config-fixes
Properly escape config property and value.
2020-12-12 11:52:04 -07:00
Christer Edwards
81ff4a3243 Merge pull request #287 from chriswells0/default-args
Provide JAIL_NAME and JAIL_IP as default template args.
2020-12-12 11:51:05 -07:00
Christer Edwards
7c134184c6 Merge pull request #292 from PetruGarstea/feature/rctl-logging
log rctl events to /var/log/messages
2020-12-12 11:48:07 -07:00
Chris Wells
54f6ef62cd Properly escape config property and value. 2020-12-11 18:27:58 -05:00
Petru Garstea
02f9df6cc0 log rctl events to /var/log/messages 2020-12-11 15:47:48 -05:00
Jose
c6ad100d8a Update help usage on update command 2020-12-02 06:41:45 -04:00
Andrew
7d44a39a01 Respect jexec.fib parameter in console command
If parameter "exec.fib" exists in jail.conf, use it when jexec'ing into the jail.
2020-12-01 13:03:15 +01:00
Chris Wells
c2839f859e Use templates for configuring new jails.
Allow user to override default templates.

Closes #205.
2020-11-29 14:19:41 -05:00
Chris Wells
b90d8c60f7 Update existing limit when a new value is provided.
Closes #233.
2020-11-29 11:34:18 -05:00
Chris Wells
5518273881 Provide JAIL_NAME and JAIL_IP as default template args.
Closes #280.
2020-11-28 19:55:41 -05:00
Chris Wells
a47b0a43c9 Add missing subcommands (limits/config) to docs. 2020-11-28 19:03:46 -05:00
Chris Wells
30a8a93fe9 Display message about file/directory being rendered. 2020-11-28 18:54:14 -05:00
Chris Wells
554f2293c1 Add ability to convert "hook" files to Bastillefile format. 2020-11-28 17:50:39 -05:00
Christer Edwards
b0c27329c9 Merge pull request #284 from chriswells0/stopped-jail-actions
Fix bug preventing commands against stopped jails.
2020-11-28 13:12:52 -07:00
Chris Wells
351020d137 Fix bug preventing commands against stopped jails. 2020-11-28 14:04:15 -05:00
Christer Edwards
ce57d05081 Merge pull request #282 from chriswells0/zfs-case
Use uppercase ZFS when appropriate.
2020-11-28 11:05:09 -07:00
Christer Edwards
0a9ae633e3 Merge pull request #283 from chriswells0/edit-config
Add 'config' command to get/set jail config properties.
2020-11-28 11:01:13 -07:00
Chris Wells
4c9f1aca25 Add 'config' command to get/set jail config properties. 2020-11-28 12:09:56 -05:00
Chris Wells
5e9578ca5e Use uppercase ZFS when appropriate. 2020-11-27 19:20:47 -05:00
Christer Edwards
a9ea02b743 Merge pull request #281 from tobiastom/patch-1
Clarified the `RENDER` functionality.
2020-11-27 10:10:25 -07:00
Christer Edwards
1ffa999f08 Merge pull request #278 from chriswells0/warn-function
Create info() and warn() for cleaner print statements.
2020-11-27 10:09:29 -07:00
Christer Edwards
e1cda4ba15 Merge pull request #273 from JRGTH/master
Upgrade thick jails from bastille
2020-11-27 10:07:35 -07:00
Tobias Tom
64b869e295 Clarified the RENDER functionality. 2020-11-27 12:01:05 +00:00
Christer Edwards
8d3b83bd44 Merge pull request #277 from chriswells0/rdr-ranges
Allow port ranges in RDR parameters.
2020-11-26 07:54:18 -07:00
Chris Wells
8b4d18f8f3 Create info() and warn() for cleaner print statements. 2020-11-25 21:19:08 -05:00
Chris Wells
cc513c3bed Allow port ranges in RDR parameters. 2020-11-25 20:29:15 -05:00
Jose
dd9e55bb9b Update command enhancement and code improvements 2020-11-24 08:38:49 -04:00
Jose
52643c7e07 Add upgrade release validation 2020-11-22 20:01:14 -04:00
Jose
3dc2db84b0 Upgrade thick jails from bastille 2020-11-21 00:33:06 -04:00
Christer Edwards
3c79e1d82b Merge pull request #267 from JRGTH/master
Option to create standard backups on ZFS setups
2020-11-10 13:10:22 -07:00
Christer Edwards
67d2fdcbbb Merge pull request #261 from cbaecker/non-bastille_vs_ALL
Prevent acting on non-bastille jails when using target ALL
2020-11-10 13:07:28 -07:00
Christer Edwards
2483fdd0f0 Merge pull request #255 from chriswells0/template-args
Add support for template args
2020-11-10 13:05:33 -07:00
Chris Wells
2225f48f05 Add support for template args
Closes 211.
2020-10-30 16:05:06 -04:00
Christer Edwards
5b096e82ed Merge pull request #269 from mattaudesse/normalize-template-sh-indentation
Normalize indentation in usr/local/share/bastille/template.sh
2020-10-23 07:31:09 -06:00
Matt Audesse
8bef2bfe63 Normalize indentation in usr/local/share/bastille/template.sh 2020-10-23 07:58:40 -04:00
Christer Edwards
20b6f2ffe6 Merge pull request #268 from tobiastom/feature/persistent-rdr
Make RDR rules persistent between bastille restarts.
2020-10-19 09:08:52 -06:00
Tobias Tom
7d78358f9f Make RDR rules persistent between bastille restarts. 2020-10-19 15:17:46 +01:00
Jose
855dcf3eae Fix to use SYNCDHCP by default while cloning jails 2020-10-17 17:34:25 -04:00
Jose
bc07ff2389 Export command bug fixes and enhancements 2020-10-16 14:48:36 -04:00
Jose
67a9c65912 Option to create standard backups on ZFS setups 2020-10-15 16:20:25 -04:00
Christer Edwards
917b4d8d0b Merge pull request #266 from JRGTH/master
Don't create or modify etc/fstab and etc/crontab on empty jail creation
2020-10-15 11:48:59 -06:00
Jose
ace6c9ab29 Don't create or modify etc/fstab and etc/crontab on empty jail creation 2020-10-15 13:18:55 -04:00
Christer Edwards
5e9e58dd92 Merge pull request #264 from bsdlme/patch-2
Fix pass in rule comment for dynamic rdr
2020-10-13 07:45:17 -06:00
Lars E
2b9aa0ecd3 Fix pass in rule comment for dynamic rdr 2020-10-13 15:43:08 +02:00
Carsten BÃcker
0c5225571f Fix whitespace 2020-09-30 10:41:14 +00:00
Carsten BÃcker
9fd83714c8 Restrict to running jails 2020-09-30 10:36:58 +00:00
Carsten BÃcker
8725e9ccac Prevent acting on non-bastille jails when using target ALL 2020-09-30 09:05:44 +00:00
Christer Edwards
bf5fd4ef2a Merge pull request #258 from yaazkal/patch-1
Update README.md clarifying pf config example
2020-09-22 09:50:21 -06:00
Christer Edwards
5b36a9e762 Merge pull request #257 from chriswells0/rdr-typo
Fix typo in rdr documentation
2020-09-22 09:49:19 -06:00
Christer Edwards
5766d66078 Merge pull request #256 from chriswells0/dev-permissions
Use root as owner when installing from Makefile
2020-09-22 09:49:05 -06:00
Christer Edwards
935118fc99 Merge pull request #251 from chriswells0/require-running-jail
Require target to be running for specific commands
2020-09-22 09:48:28 -06:00
Christer Edwards
976aa077b6 Merge pull request #250 from chriswells0/error-functions
Create and leverage global error functions
2020-09-22 09:47:23 -06:00
yaazkal
cbff4e326d Update README.md clarifying pf config example
Change the pf.conf example in order to prevent issues (jails not allowed to access internet correctly) when the network interface has IP aliases. Many thanks to @cedwards and @chriswells0 for the hints.
2020-09-18 17:53:05 -05:00
Chris Wells
3ca32fa1bc Fix typo in rdr documentation 2020-09-05 21:19:51 -04:00
Chris Wells
fddb762b45 Use root as owner when installing from Makefile 2020-09-05 21:15:01 -04:00
Christer Edwards
a4fcf0100b Merge pull request #249 from chriswells0/cp-alias-fix
Map COPY alias in Bastillefile to use cp subcommand
2020-08-30 20:24:59 -06:00
Chris Wells
c6aded8d0a Ensure target is specified and exists in 1 place instead of many.
Require target to be running for commands that need it.
Closes #239.
2020-08-30 20:15:22 -04:00
Chris Wells
aaffc882f9 Create and leverage global error functions 2020-08-30 10:57:14 -04:00
Chris Wells
94df833e6b Map COPY alias in Bastillefile to use cp subcommand 2020-08-29 19:22:26 -04:00
Christer Edwards
3c070bf908 Merge pull request #248 from cedwards/support-current
initial support for X-current (dev) containers
2020-08-28 14:32:54 -06:00
Christer Edwards
a369ed399d initial support for X-current (dev) containers 2020-08-28 14:13:54 -06:00
Christer Edwards
0ce53f4c4e Merge pull request #246 from JRGTH/master
Fix for bastille bootstrap + update command
2020-08-27 13:33:37 -06:00
Jose
abd80b151f Fix for bastille bootstrap + update command 2020-08-26 14:47:27 -04:00
Christer Edwards
8b196ffaeb Merge pull request #231 from tobiastom/bugfix/templates
Fixed the overlay command in Bastillefile
2020-08-20 16:26:08 -06:00
Tobias Tom
5a9034ff18 Added overlay command to be compatibile with the hooks. 2020-08-20 17:03:21 +01:00
Christer Edwards
7e27bcd36c Merge pull request #242 from tobiastom/feature/fstab-in-template
Added fstab alias to mount command in Bastillefiles.
2020-08-19 11:52:29 -06:00
Christer Edwards
3ebfb69305 Merge pull request #229 from JRGTH/master
Initial alternate architecture fetch/create support
2020-08-19 11:49:11 -06:00
Christer Edwards
d09644dc23 Merge pull request #243 from tobiastom/feature/display-failed-command
Use the correct variable to display the failed template command.
2020-08-19 11:40:19 -06:00
Tobias Tom
1dd2280e2c Use the correct variable to display the failed template command. 2020-08-18 15:02:23 +01:00
Tobias Tom
14dbc09b7c Added fstab alias to mount command in Bastillefiles. 2020-08-18 14:58:19 +01:00
Christer Edwards
388cb39607 Merge pull request #232 from hackacad/master
limits needs 3 args
2020-08-10 20:01:42 -06:00
Christer Edwards
ad749e8a75 Merge pull request #236 from bmac2/master
update to include Bastillefile as a valid HOOK in verify process
2020-08-07 10:26:51 -06:00
Barry McCormick
85176e35da update to include Bastillefile as a valid HOOK in verify process 2020-08-07 09:24:24 -07:00
Jose
a0b0eadc68 Display return status on bastille cp batch/loop 2020-07-31 08:51:47 -04:00
Jose
709f00a2ac Improve bastille/cp return status 2020-07-31 04:07:58 -04:00
hackacad
dc1b1f838a limits needs 3 args 2020-07-28 19:15:43 +02:00
Tobias Tom
24b4985371 Renamed cp command to overlay to match the documentation. 2020-07-27 15:06:19 +01:00
Jose
3872f93063 Post-creation jail misc configuration 2020-07-24 15:37:50 -04:00
Jose
3c19c5b183 Initial alternate architecture fetch/create support 2020-07-24 10:47:28 -04:00
Christer Edwards
5edf9cbe51 Merge pull request #224 from cedwards/update-20200714
update to 0.7.20200714
2020-07-13 21:49:31 -06:00
Christer Edwards
845bb9106f update to 0.7.20200714 2020-07-13 21:48:03 -06:00
Christer Edwards
9150da4a5f Merge pull request #223 from cedwards/docs_update-20200714
update docs for 0.7.20200714 release
2020-07-13 21:45:51 -06:00
Christer Edwards
d3d4a9c030 updating subcommand index 2020-07-13 19:32:44 -06:00
Christer Edwards
da15b4f59a update docs for 0.7.20200714 release 2020-07-13 19:27:23 -06:00
Christer Edwards
93bc945e90 Merge pull request #222 from cedwards/BUG-195
update bastille log path
2020-07-13 12:50:01 -06:00
Christer Edwards
b9efa0ad04 update bastille log path 2020-07-10 08:18:21 -06:00
Christer Edwards
579cf76a38 Merge pull request #221 from JRGTH/master
Force unmount any filesystems before jail rename, error handling
2020-07-10 08:10:36 -06:00
Christer Edwards
328112c74e Merge pull request #218 from chriswells0/template-subcommands
Execute template hooks using Bastille subcommands
2020-07-10 08:10:16 -06:00
Jose
428fd59925 Recursively destroy base release to deal with previous snapshots 2020-07-09 22:26:06 -04:00
Chris Wells
0fd46b50e5 Merge branch 'master' into template-subcommands 2020-07-09 20:38:43 -04:00
Jose
77274adb95 Force unmount any filesystems before jail rename, error handling 2020-07-09 20:00:25 -04:00
Christer Edwards
af6f0064d6 Merge pull request #220 from cynix/fix_template_fstab
Deduplicate template fstab entries using their full paths.
2020-07-08 19:30:02 -06:00
cynix
ed50e3fa04 Fix deduplication in 'mount' command as well 2020-06-22 00:19:02 +10:00
cynix
d01ca09eaa Deduplicate template fstab entries using their full paths.
This allows a fstab entry that happens to be a substring of the
jail path (or that of an existing entry) to be added correctly.
2020-06-22 00:06:40 +10:00
Chris Wells
7cdbe9ac3d Merge branch 'master' into template-subcommands 2020-06-20 15:15:14 -04:00
Jose
012510e312 Append PATH over defined PATH, fix colors.pre on bastille command 2020-06-20 11:53:38 -04:00
Jose
d7413d29ec Define local variables just once 2020-06-20 11:53:38 -04:00
Jose
8d98b8f6ec User option to force destroy jail in ZFS 2020-06-20 11:53:38 -04:00
Chris Wells
016523253a Add mount and umount commands to manage volumes inside containers. 2020-06-20 11:53:38 -04:00
X86BSD
a0f4752287 Correct a typo
Compatibility was spelled wrong.
2020-06-20 11:53:38 -04:00
X86BSD
7514e800f4 Clarify description of bastille_bootstrap_archives
Make it clear its a white space separated list not a ',' separated list.
2020-06-20 11:53:38 -04:00
Marius van Witzenburg
b98b841a1c Add vagrant support for testing 2020-06-20 11:53:38 -04:00
Chris Wells
26c41543c2 Add Bastillefile support to templates. 2020-06-20 11:53:35 -04:00
Gleb Popov
d92aeb3f70 clone cmd is listed twice, fix it 2020-06-20 11:50:15 -04:00
Christer Edwards
99bd323897 Merge pull request #215 from JRGTH/master
Option to force destroy jail in ZFS
2020-06-19 08:45:36 -06:00
Christer Edwards
3fccba30d6 Merge pull request #216 from chriswells0/mount
Add mount and umount commands to manage volumes inside containers.
2020-06-19 08:44:18 -06:00
Christer Edwards
547aa27816 Merge pull request #213 from X86BSD/patch-1
Clarify description of bastille_bootstrap_archives
2020-06-19 08:43:21 -06:00
Christer Edwards
e9c2a4d7b6 Merge pull request #209 from mariusvw/feature/vagrant
Add vagrant support for testing
2020-06-19 08:42:31 -06:00
Christer Edwards
8b00e0adf4 Merge pull request #217 from chriswells0/bastillefile
Add Bastillefile support to templates.
2020-06-19 08:42:03 -06:00
Christer Edwards
457e95a08b Merge pull request #219 from arrowd/patch-1
clone cmd is listed twice, fix it
2020-06-19 08:40:57 -06:00
Gleb Popov
0cbf8e93dd clone cmd is listed twice, fix it 2020-06-17 10:19:12 +04:00
Jose
932f1afae1 Append PATH over defined PATH, fix colors.pre on bastille command 2020-05-25 22:09:17 -04:00
Jose
6fb6e49c6c Define local variables just once 2020-05-25 19:35:38 -04:00
Chris Wells
42bafe7619 Execute template hooks using Bastille subcommands 2020-05-24 20:41:11 -04:00
Chris Wells
61ee522f18 Add Bastillefile support to templates. 2020-05-23 21:03:12 -04:00
Chris Wells
1d21ff58fe Add mount and umount commands to manage volumes inside containers. 2020-05-23 18:35:00 -04:00
Jose
0658a343d3 Merge remote-tracking branch 'upstream/master' 2020-05-22 21:47:52 -04:00
Jose
147e7d5db3 User option to force destroy jail in ZFS 2020-05-22 21:46:03 -04:00
Christer Edwards
b515565bde Merge pull request #210 from mariusvw/feature/config-check
Feature/config check
2020-05-20 09:52:46 -06:00
Christer Edwards
a28201f53e Merge pull request #207 from JRGTH/master
Feature add, create empty jail and minor maintenance
2020-05-20 09:51:16 -06:00
Jose
c98ea0a380 Improve checks in rename, update any spaces/tabs in jail.conf, remove redundant code 2020-05-12 02:47:26 -04:00
Jose
9344b2f647 Allow rename legacy jail directory even if zfs is explicitly configured 2020-05-10 11:03:38 -04:00
Jose
33588397ad Error handling, don't delete legacy directory unless really empty 2020-05-10 10:09:17 -04:00
Jose
d47e2a7cfb Bugfix on bastille rename, let zfs inherit mountpoint 2020-05-10 08:12:19 -04:00
Jose
8826f53d9a Minor code cleanup 2020-05-09 15:41:34 -04:00
Jose
f84fd4ad85 Improve name validation for create and rename, add error_notify function 2020-05-09 15:31:15 -04:00
Jose
e07f6cb0ed Add proper name valoidation in rename command, don't allow blanks in names 2020-05-09 13:59:58 -04:00
Jose
a607dc2719 Properly check for home dir and symlink 2020-05-07 22:50:43 -04:00
X86BSD
b6b76fb7ae Correct a typo
Compatibility was spelled wrong.
2020-05-03 17:21:08 -05:00
X86BSD
3035e86d55 Clarify description of bastille_bootstrap_archives
Make it clear its a white space separated list not a ',' separated list.
2020-05-03 16:59:33 -05:00
Jose
702a0b8318 Update config, missing quotes added 2020-04-25 08:43:59 -04:00
Jose
9617a2ab9a Update sendmail rcvars, code consistency maintenance. 2020-04-25 08:26:12 -04:00
Marius van Witzenburg
b80bbfe838 Add check for config existance and readable 2020-04-21 02:34:02 +02:00
Marius van Witzenburg
cdda90fa69 Remove duplicate config loading 2020-04-21 02:33:38 +02:00
Marius van Witzenburg
5c0e5dea35 Removed duplicate for colors.pre.sh 2020-04-21 00:23:17 +02:00
Marius van Witzenburg
4d9d4f61ef Add vagrant support for testing 2020-04-21 00:02:30 +02:00
Jose
a98032e912 Feature add, create empty jail and minor maintenance 2020-04-18 18:02:11 -04:00
Christer Edwards
268008b967 Merge pull request #206 from JRGTH/master
Fix for pfctl on start/stop commands, clean up excess double quotes
2020-04-16 08:16:26 -06:00
Jose
f54151cf94 Fix for pfctl on start/stop commands, clean up excess double quotes 2020-04-16 07:53:53 -04:00
71 changed files with 2262 additions and 1222 deletions

View File

@@ -7,13 +7,21 @@ Christer Edwards [christer.edwards@gmail.com]
## Contributors (code)
- Barry McCormick
- Brian Downs
- Carsten Bäcker
- Chris Wells
- Dave Cottlehuber
- Giacomo Olgeni
- Gleb Popov
- JP Mens
- Jose Rivera
- Juan David Hurtado G.
- Lars E.
- Marius van Witzenburg
- Matt Audesse
- Paul C.
- Petru T. Garstea
- Sven R.
- Tobias Tom
### Special thanks
Software doesn't happen in a vacuum. Thank you to the following people who may

View File

@@ -1,6 +1,6 @@
BSD 3-Clause License
Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -5,7 +5,7 @@ all:
install:
@echo "Installing Bastille"
@echo
@cp -av usr /
@cp -Rv usr /
@echo
@echo "This method is for testing / development."

138
README.md
View File

@@ -45,7 +45,7 @@ Available Commands:
bootstrap Bootstrap a FreeBSD release for container base.
clone Clone an existing container.
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).
@@ -58,6 +58,7 @@ Available Commands:
import Import a container archive or image.
limits Apply resources limits to targeted container(s). See rctl(8).
list List containers, releases, templates, logs, limits or backups.
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.
restart Restart a running container.
@@ -67,17 +68,18 @@ Available Commands:
sysrc Safely edit rc files within targeted container(s).
template Apply automation templates to targeted container(s).
top Display and update information about the top(1) cpu processes.
umount Unmount a volume from within the targeted container(s).
update Update container base -pX release.
upgrade Upgrade container release to X.Y-RELEASE.
verify Verify bootstrapped release or automation template.
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.6-beta
## 0.8-beta
This document outlines the basic usage of the Bastille container management
framework. This release is still considered beta.
@@ -120,7 +122,7 @@ 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)
nat on $ext_if from <jails> to any -> ($ext_if:0)
## static rdr example
# rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
@@ -140,6 +142,9 @@ 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.
* Note that if multiple interface aliases are in place, the index `($ext_if:0)`
can be changed accordingly; so if you want to send traffic out the second IP alias
of the interface, change the value to `($ext_if:1)` and so on.
* Make sure to include the last line (`port ssh`) or you'll end up locked
out of a remote system.
@@ -148,7 +153,7 @@ containers are:
```
table <jails> persist
nat on $ext_if from <jails> to any -> ($ext_if)
nat on $ext_if from <jails> to any -> ($ext_if:0)
## rdr example
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
@@ -363,10 +368,6 @@ VNET also requires a custom `devfs` ruleset. Create the file as needed on the ho
**/etc/devfs.rules**
```
[bastille_vnet=13]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add include $devfsrules_jail
add path 'bpf*' unhide
```
@@ -627,8 +628,8 @@ Templates](https://gitlab.com/BastilleBSD-Templates)?
Bastille supports a templating system allowing you to apply files, pkgs and
execute commands inside the container automatically.
Currently supported template hooks are: `LIMITS`, `INCLUDE`, `PRE`, `FSTAB`,
`PKG`, `OVERLAY`, `SYSRC`, `SERVICE`, `CMD`.
Currently supported template hooks are: `ARG`, `LIMITS`, `INCLUDE`, `PRE`,
`FSTAB`, `PKG`, `OVERLAY`, `SYSRC`, `SERVICE`, `CMD`, `RENDER`.
Planned template hooks include: `PF`, `LOG`
Templates are created in `${bastille_prefix}/templates` and can leverage any of
@@ -651,17 +652,19 @@ echo "usr" > /usr/local/bastille/templates/username/base-template/OVERLAY
Template hooks are executed in specific order and require specific syntax to
work as expected. This table outlines that order and those requirements:
| SUPPORTED | format | example |
|-----------|---------------------|------------------------------------------------|
| LIMITS | resource value | memoryuse 1G |
| INCLUDE | template path/URL | http?://TEMPLATE_URL or username/base-template |
| PRE | /bin/sh command | mkdir -p /usr/local/path |
| FSTAB | fstab syntax | /host/path container/path nullfs ro 0 0 |
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
| OVERLAY | paths (one/line) | etc usr |
| SYSRC | sysrc command(s) | nginx_enable=YES |
| SERVICE | service command(s) | nginx restart |
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
| SUPPORTED | format | example |
|-----------|-----------------------|------------------------------------------------|
| ARG | name=value (one/line) | domain=example.com (omit value for no default) |
| LIMITS | resource value | memoryuse 1G |
| INCLUDE | template path/URL | http?://TEMPLATE_URL or username/base-template |
| PRE | /bin/sh command | mkdir -p /usr/local/path |
| FSTAB | fstab syntax | /host/path container/path nullfs ro 0 0 |
| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop |
| OVERLAY | paths (one/line) | etc usr |
| SYSRC | sysrc command(s) | nginx_enable=YES |
| SERVICE | service command(s) | nginx restart |
| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh |
| RENDER | paths (one/line) | /usr/local/etc/nginx |
| PLANNED | format | example |
|---------|------------------|----------------------------------------------------------------|
@@ -670,6 +673,13 @@ work as expected. This table outlines that order and those requirements:
Note: SYSRC requires NO quotes or that quotes (`"`) be escaped. ie; `\"`)
Any name provided in the ARG file can be used as a variable in the other hooks.
For example, `name=value` in the ARG file will cause instances of `${name}`
to be replaced with `value`. The `RENDER` hook can be used to specify existing files or
directories inside the jail whose contents should have the variables replaced. Values can be
specified either through the command line when applying the template or as a default in the ARG
file.
In addition to supporting template hooks, Bastille supports overlaying files
into the container. This is done by placing the files in their full path, using the
template directory as "/".
@@ -696,6 +706,50 @@ The above example will include anything under "etc" and "usr" inside
the template. You do not need to list individual files. Just include the
top-level directory name.
For more control over the order of operations when applying a template,
create a `Bastillefile` inside the base template directory. Each line in
the file should begin with an uppercase reference to a Bastille command
followed by its arguments (omitting the target, which is deduced from the
`template` arguments). Lines beginning with `#` are treated as comments.
Variables can also be defined using `ARG` with one `name=value` pair per
line. Subsequent references to `${name}` would be replaced by `value`.
Note that argument values are not available for use until after the point
at which they are defined in the file. Both `${JAIL_NAME}` and `${JAIL_IP}`
are made available in templates without having to define them as args.
Bastillefile example:
```shell
LIMITS memoryuse 1G
# This value can be overridden when the template is applied.
ARG domain=example.com
# Replace all argument variables inside the nginx config.
RENDER /usr/local/etc/nginx
# Install and start nginx.
PKG nginx
SYSRC nginx_enable=YES
SERVICE nginx restart
# Copy files to nginx.
CP www/ usr/local/www/nginx-dist/
# Use the "domain" arg to create a file on the server containing the domain.
CMD echo "${domain}" > /usr/local/www/nginx-dist/domain.txt
# Create a file on the server containing the jail's hostname.
CMD hostname > /usr/local/www/nginx-dist/hostname.txt
# Forward TCP port 80 on the host to port 80 in the container.
RDR tcp 80 80
```
Use the following command to convert a hook-based template into the Bastillefile format:
```shell
bastille template --convert my-template
```
Applying Templates
------------------
@@ -706,8 +760,12 @@ Bastille includes a `template` sub-command. This sub-command requires a target
and a template name. As covered in the previous section, template names
correspond to directory names in the `bastille/templates` directory.
To provide values for arguments defined by `ARG` in the template, pass the
optional `--arg` parameter as many times as needed. Alternatively, use
`--arg-file <fileName>` with one `name=value` pair per line.
```shell
ishmael ~ # bastille template folsom username/base
ishmael ~ # bastille template folsom username/base --arg domain=example.com
[folsom]:
Copying files...
Copy complete.
@@ -880,7 +938,7 @@ validation are not used.
bastille zfs
------------
This sub-command allows managing zfs attributes for the targeted container(s).
This sub-command allows managing ZFS attributes for the targeted container(s).
Common usage includes setting container quotas.
**set quota**
@@ -906,7 +964,7 @@ Note: On UFS systems containers must be stopped before export.
```shell
ishmael ~ # bastille export folsom
Exporting 'folsom' to a compressed .xz archive.
Sending zfs data stream...
Sending ZFS data stream...
100 % 1057.2 KiB / 9231.5 KiB = 0.115 0:01
Exported '/usr/local/bastille/jails/backups/folsom_2020-01-26-19:23:04.xz' successfully.
@@ -921,7 +979,7 @@ ishmael ~ # bastille import folsom_2020-01-26-19:22:23.xz
Validating file: folsom_2020-01-26-19:22:23.xz...
File validation successful!
Importing 'folsom' from compressed .xz archive.
Receiving zfs data stream...
Receiving ZFS data stream...
/usr/local/bastille/jails/backups/folsom_2020-01-26-19:22:23.xz (1/1)
100 % 626.4 KiB / 9231.5 KiB = 0.068 0:02
Container 'folsom' imported successfully.
@@ -933,12 +991,38 @@ bastille clone
Please be aware that no host specific keys or hashes will be regenerated.
E. g. remove OpenSSH host keys to avoid duplicate host keys `rm /etc/ssh/ssh_host_*`
Usage: `bastille clone [TARGET] [NEWJAIL] [NEW_IPADRRESS]
Usage: `bastille clone [TARGET] [NEWJAIL] [NEW_IPADRRESS]`
```shell
ishmael ~ # bastille clone sourcejail targetjail 10.17.89.11
```
bastille mount
---------------
`bastille mount` will nullfs mount a path from the host inside the container.
Uses the same format as an fstab entry.
Filesystem type, options, dump, and pass number are optional and default to: nullfs ro 0 0
Usage: `bastille mount [TARGET] [HOST_PATH] [CONTAINER_PATH] [FILESYSTEM_TYPE] [OPTIONS] [DUMP] [PASS_NUMBER]`
```shell
ishmael ~ # bastille mount targetjail /host/path container/path
[targetjail]:
Added: /host/path container/path nullfs ro 0 0
```
bastille umount
---------------
`bastille umount` will unmount a volume from inside the container.
Usage: `bastille umount [TARGET] [CONTAINER_PATH]`
```shell
ishmael ~ # bastille umount targetjail container/path
[targetjail]:
Unmounted: container/path
```
Example (create, start, console)
================================
This example creates, starts and consoles into the container.

24
Vagrantfile vendored Normal file
View File

@@ -0,0 +1,24 @@
# -*- 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-12.1-RELEASE"
vm_config.vm.box_version = "2019.11.01"
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"
end
end

View File

@@ -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.6.20200202`.
Current version is `0.8.20210115`.
To install from the FreeBSD package repository:

View File

@@ -17,7 +17,7 @@ template looks like this:
devfs_ruleset = 4;
enforce_statfs = 2;
exec.clean;
exec.consolelog = /usr/local/bastille/logs/{name}_console.log;
exec.consolelog = /var/log/bastille/{name}_console.log;
exec.start = '/bin/sh /etc/rc';
exec.stop = '/bin/sh /etc/rc.shutdown';
host.hostname = {name};

View File

@@ -5,29 +5,26 @@ to get started putting applications in secure little containers, but how do I
get these containers on the network?
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.
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.
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...
Three methods are described here. Consider each options when deciding
which design work best for your needs. One of the methods works better in the
cloud while the others are simpler if used in local area networks.
**Note: if you are running in the cloud and only have a single public IP you
may want the Public Network option. See below.**
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.
Shared Interface (IP alias)
---------------------------
In FreeBSD network interfaces have different names, but look something like
`em0`, `bge0`, `re0`, etc. On a virtual machine it may be `vtnet0`. You get the
idea...
Bastille allows you to define the interface you want the IP attached to when
you create it. An example:
@@ -43,13 +40,78 @@ 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.
(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.)
Bastille tries to verify that the interface name you provide it is a valid
interface. It also checks for a valid syntax IP4 or IP6 address.
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 12.1-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 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
**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.
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)
@@ -58,9 +120,11 @@ 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
network.
loopback (bastille0)
--------------------
What I 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.
@@ -116,7 +180,7 @@ Create the firewall rules:
# If you are using dynamic rdr also need to ensure that the external port
# range you are using is open
# pass in inet proto tcp any to any port <rdr-start>:<rdr-end>
# pass in inet proto tcp from any to any port <rdr-start>:<rdr-end>
- Make sure to change the `ext_if` variable to match your host system interface.
- Make sure to include the last line (`port ssh`) or you'll end up locked out.

View File

@@ -1,3 +1,4 @@
=========
bootstrap
=========
@@ -26,8 +27,7 @@ release version as the argument.
.. code-block:: shell
ishmael ~ # bastille bootstrap 11.3-RELEASE [update]
ishmael ~ # bastille bootstrap 12.0-RELEASE
ishmael ~ # bastille bootstrap 11.4-RELEASE [update]
ishmael ~ # bastille bootstrap 12.1-RELEASE
This command will ensure the required directory structures are in place and

View 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].

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -1,3 +1,4 @@
==
cp
==

View File

@@ -1,3 +1,4 @@
======
create
======

View File

@@ -1,3 +1,4 @@
=======
destroy
=======

View 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

View File

@@ -0,0 +1,19 @@
======
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 TARGET

View 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]

View File

@@ -7,18 +7,27 @@ Bastille sub-commands
bootstrap
cmd
clone
console
convert
cp
create
destroy
edit
export
htop
import
mount
pkg
rdr
rename
restart
service
start
stop
sysrc
top
umount
update
upgrade
verify

View 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]

View File

@@ -9,7 +9,7 @@ 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
sepcify the interface they run on in rc.conf (or other config files)
specify the interface they run on in rc.conf (or other config files)
.. code-block:: shell

View 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

View File

@@ -1,3 +1,4 @@
=======
restart
=======

View File

@@ -1,3 +1,4 @@
=====
start
=====

View File

@@ -1,3 +1,4 @@
====
stop
====

View 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

View File

@@ -7,4 +7,4 @@ workflow this can be similar to a `bootstrap`.
.. code-block:: shell
ishmael ~ # bastille upgrade 11.2-RELEASE 12.0-RELEASE
ishmael ~ # bastille upgrade 12.0-RELEASE 12.1-RELEASE

View File

@@ -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.
@@ -42,7 +42,7 @@ Examples: Containers
+-----------+--------+-----+------------+-------------------------------------------------------------+
| cp | bastion03 | /tmp/resolv.conf-cf etc/resolv.conf | copy host-path to container-path in bastion03|
+----+------+----+---+------------------+--------------+----------------------------------------------+
| create | folsom | 12.0-RELEASE 10.17.89.10 | create 12.0 container named `folsom` with IP |
| create | folsom | 12.1-RELEASE 10.17.89.10 | create 12.1 container named `folsom` with IP |
+-----------+--------+------------------+--------------+----------------------------------------------+
@@ -56,11 +56,11 @@ Examples: Releases
+-----------+--------------+--------------+-------------------------------------------------------------+
| command | target | args | description |
+===========+==============+==============+=============================================================+
| bootstrap | 12.0-RELEASE | --- | bootstrap 12.0-RELEASE release |
| bootstrap | 12.1-RELEASE | --- | bootstrap 12.1-RELEASE release |
+-----------+--------------+--------------+-------------------------------------------------------------+
| update | 11.3-RELEASE | --- | update 11.2-RELEASE release |
| update | 11.4-RELEASE | --- | update 11.4-RELEASE release |
+-----------+--------------+--------------+-------------------------------------------------------------+
| upgrade | 11.2-RELEASE | 11.3-RELEASE | update 11.2-RELEASE release |
| upgrade | 11.3-RELEASE | 11.4-RELEASE | update 11.4-RELEASE release |
+-----------+--------------+--------------+-------------------------------------------------------------+
| verify | 11.3-RELEASE | --- | update 11.2-RELEASE release |
| verify | 11.4-RELEASE | --- | update 11.4-RELEASE release |
+-----------+--------------+--------------+-------------------------------------------------------------+

View File

@@ -9,27 +9,20 @@ execute commands inside the containers automatically.
Currently supported template hooks are: `LIMITS`, `INCLUDE`, `PRE`, `FSTAB`,
`PKG`, `OVERLAY`, `SYSRC`, `SERVICE`, `CMD`.
Planned template hooks include: `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;
the template hooks.
.. code-block:: 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;
.. code-block:: shell
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 "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:
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.
Template Automation Hooks
-------------------------
+---------+-------------------+-----------------------------------------+
| HOOK | format | example |
@@ -56,13 +49,16 @@ work as expected. This table outlines those requirements:
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
@@ -75,7 +71,7 @@ use, be sure to include `usr` in the template OVERLAY definition. eg;
.. code-block:: shell
echo "usr" > /usr/local/bastille/templates/username/base/OVERLAY
echo "usr" > /usr/local/bastille/templates/username/template/OVERLAY
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
@@ -92,7 +88,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.

View File

@@ -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.

View File

@@ -8,13 +8,13 @@ else:
# -- Project information -----------------------------------------------------
project = 'Bastille'
copyright = '2018-2020, Christer Edwards'
copyright = '2018-2021, Christer Edwards'
author = 'Christer Edwards'
# The short X.Y version
version = '0.6.20200202'
version = '0.8.20210115'
# The full version, including alpha/beta/rc tags
release = '0.6.20200202-beta'
release = '0.8.20210115-beta'
# -- General configuration ---------------------------------------------------

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,26 +28,32 @@
# 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.
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
. /usr/local/share/bastille/common.sh
## 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
## 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
error_notify "Bastille: Permission Denied"
error_exit "root / sudo / doas required"
fi
}
bastille_root_check
## we only load the config if root_check passes
## check for config existance
bastille_conf_check() {
if [ ! -r "/usr/local/etc/bastille/bastille.conf" ]; then
error_exit "Missing Configuration"
fi
}
bastille_conf_check
## we only load the config if conf_check passes
. /usr/local/etc/bastille/bastille.conf
. /usr/local/share/bastille/colors.pre.sh
## bastille_prefix should be 0750
## this restricts file system access to privileged users
@@ -55,21 +61,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.6.20200414"
BASTILLE_VERSION="0.8.20210115"
usage() {
cat << EOF
@@ -83,6 +84,7 @@ 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).
@@ -93,7 +95,9 @@ Available Commands:
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.
rename Rename a container.
@@ -104,10 +108,11 @@ Available Commands:
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.
@@ -124,26 +129,64 @@ shift
# 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|import|list|rdr|restart|start|update|upgrade|verify)
# Nothing "extra" to do for these commands. -- cwells
;;
clone|config|cmd|console|convert|cp|edit|export|htop|limits|mount|pkg|rename|service|stop|sysrc|template|top|umount|zfs)
# 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
bootstrap|clone|cmd|console|convert|cp|create)
if [ "${TARGET}" = 'ALL' ]; then
_JAILS=$(jls name)
JAILS=""
for _jail in ${_JAILS}; do
_JAILPATH=$(jls -j "${_jail}" path)
if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then
JAILS="${JAILS} ${_jail}"
fi
done
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)
# Require the target to be running. -- cwells
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
fi
;;
convert|rename)
# Require the target to be stopped. -- cwells
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'."
fi
;;
esac
fi
export TARGET
export JAILS
fi
;;
destroy|edit|export|htop|import|limits|list)
;;
pkg|rdr|rename|restart|service|start|stop|sysrc)
;;
template|top|update|upgrade|verify|zfs)
;;
*)
usage
*) # Filter out all non-commands
usage
;;
esac
@@ -154,7 +197,11 @@ if [ -f "${SCRIPTPATH}" ]; then
: "${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

View File

@@ -3,18 +3,25 @@
#####################
## 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_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_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"
## bastille scripts directory (assumed by bastille pkg)
bastille_sharedir=/usr/local/share/bastille ## default: "/usr/local/share/bastille"
bastille_sharedir="/usr/local/share/bastille" ## default: "/usr/local/share/bastille"
## bootstrap archives (base, lib32, ports, src, test)
## 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
@@ -41,3 +48,10 @@ bastille_decompress_xz_options="-c -d -v" ## default
bastille_network_loopback="bastille0" ## default: "bastille0"
bastille_network_shared="" ## default: ""
bastille_network_gateway="" ## 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_thin="default/thin" ## default: "default/thin"
bastille_template_vnet="default/vnet" ## default: "default/vnet"

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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,25 +42,35 @@ help|-h|--help)
;;
esac
# Validate ZFS parameters first.
#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)
continue
;;
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
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_zpool."
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_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
@@ -71,10 +80,16 @@ validate_release_url() {
if [ -n "${NAME_VERIFY}" ]; then
RELEASE="${NAME_VERIFY}"
if ! fetch -qo /dev/null "${UPSTREAM_URL}/MANIFEST" 2>/dev/null; then
echo -e "${COLOR_RED}Unable to fetch MANIFEST, See 'bootstrap urls'.${COLOR_RESET}"
exit 1
error_exit "Unable to fetch MANIFEST. See 'bootstrap urls'."
fi
echo -e "${COLOR_GREEN}Bootstrapping ${PLATFORM_OS} distfiles...${COLOR_RESET}"
info "Bootstrapping ${PLATFORM_OS} distfiles..."
# Alternate RELEASE/ARCH fetch support
if [ "${OPTION}" = "--i386" -o "${OPTION}" = "--32bit" ]; then
ARCH="i386"
RELEASE="${RELEASE}-${ARCH}"
fi
bootstrap_directories
bootstrap_release
else
@@ -163,6 +178,7 @@ bootstrap_directories() {
else
mkdir -p "${bastille_templatesdir}"
fi
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
fi
## ${bastille_releasesdir}
@@ -200,10 +216,9 @@ bootstrap_release() {
## check if release already bootstrapped, else continue bootstrapping
if [ -z "${bastille_bootstrap_archives}" ]; then
echo -e "${COLOR_RED}Bootstrap appears complete.${COLOR_RESET}"
exit 1
error_exit "Bootstrap appears complete."
else
echo -e "${COLOR_GREEN}Bootstrapping additional distfiles...${COLOR_RESET}"
info "Bootstrapping additional distfiles..."
fi
fi
@@ -211,14 +226,13 @@ bootstrap_release() {
## 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 ${PLATFORM_OS} ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
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
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
exit 1
error_exit "Failed to extract ${_archive}.txz."
fi
else
## get the manifest for dist files checksum validation
@@ -248,8 +262,7 @@ bootstrap_release() {
rm -rf "${bastille_releasesdir}/${RELEASE}"
fi
fi
echo -e "${COLOR_RED}Bootstrap failed.${COLOR_RESET}"
exit 1
error_exit "Bootstrap failed."
fi
## fetch for missing dist files
@@ -257,7 +270,7 @@ bootstrap_release() {
fetch "${UPSTREAM_URL}/${_archive}.txz" -o "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
if [ "$?" -ne 0 ]; 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
@@ -266,34 +279,32 @@ bootstrap_release() {
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
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 ${PLATFORM_OS} ${RELEASE} ${_archive}.txz.${COLOR_RESET}"
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
echo -e "${COLOR_RED}Failed to extract ${_archive}.txz.${COLOR_RESET}"
exit 1
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
}
@@ -308,6 +319,7 @@ bootstrap_template() {
else
mkdir -p "${bastille_templatesdir}"
fi
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
fi
## define basic variables
@@ -318,16 +330,15 @@ bootstrap_template() {
## support for non-git
if [ ! -x "$(which git)" ]; then
echo -e "${COLOR_RED}Git not found.${COLOR_RESET}"
echo -e "${COLOR_RED}Not yet implemented.${COLOR_RESET}"
exit 1
error_notify "Git not found."
error_exit "Not yet implemented."
elif [ -x "$(which git)" ]; then
if [ ! -d "${_template}/.git" ]; then
$(which git) clone "${_url}" "${_template}" ||\
echo -e "${COLOR_RED}Clone unsuccessful.${COLOR_RESET}"
error_notify "Clone unsuccessful."
elif [ -d "${_template}/.git" ]; then
cd "${_template}" && $(which git) pull ||\
echo -e "${COLOR_RED}Template update unsuccessful.${COLOR_RESET}"
error_notify "Template update unsuccessful."
fi
fi
@@ -337,9 +348,28 @@ bootstrap_template() {
HW_MACHINE=$(sysctl hw.machine | awk '{ print $2 }')
HW_MACHINE_ARCH=$(sysctl hw.machine_arch | awk '{ print $2 }')
RELEASE="${1}"
OPTION="${2}"
# Alternate RELEASE/ARCH fetch support(experimental)
if [ -n "${OPTION}" ] && [ "${OPTION}" != "${HW_MACHINE}" ] && [ "${OPTION}" != "update" ]; then
# Supported architectures
if [ "${OPTION}" = "--i386" -o "${OPTION}" = "--32bit" ]; then
HW_MACHINE="i386"
HW_MACHINE_ARCH="i386"
else
error_exit "Unsupported architecture."
fi
fi
## Filter sane release names
case "${1}" in
*-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|*-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:]')
@@ -401,7 +431,7 @@ http?://github.com/*/*|http?://gitlab.com/*/*)
;;
esac
case "${2}" in
case "${OPTION}" in
update)
bastille update "${RELEASE}"
;;

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,17 +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 clone [TARGET] [NEW_NAME] [IPADRESS].${COLOR_RESET}"
exit 1
}
error_notify() {
# Notify message on error and exit
echo -e "$*" >&2
exit 1
usage() {
error_exit "Usage: bastille clone [TARGET] [NEW_NAME] [IPADRESS]"
}
# Handle special-case commands first
@@ -48,21 +42,19 @@ help|-h|--help)
;;
esac
if [ $# -ne 3 ]; then
if [ $# -ne 2 ]; then
usage
fi
TARGET="${1}"
NEWNAME="${2}"
IP="${3}"
shift
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
echo -e "${COLOR_GREEN}Valid: (${ip6}).${COLOR_RESET}"
info "Valid: (${ip6})."
IPX_ADDR="ip6.addr"
IP6_MODE="new"
else
@@ -73,18 +65,16 @@ validate_ip() {
set ${TEST_IP}
for quad in 1 2 3 4; do
if eval [ \$$quad -gt 255 ]; then
echo "Invalid: (${TEST_IP})"
exit 1
error_exit "Invalid: (${TEST_IP})"
fi
done
if ifconfig | grep -qw "${TEST_IP}"; then
echo -e "${COLOR_YELLOW}Warning: ip address already in use (${TEST_IP}).${COLOR_RESET}"
warn "Warning: IP address already in use (${TEST_IP})."
else
echo -e "${COLOR_GREEN}Valid: (${IP}).${COLOR_RESET}"
info "Valid: (${IP})."
fi
else
echo -e "${COLOR_RED}Invalid: (${IP}).${COLOR_RESET}"
exit 1
error_exit "Invalid: (${IP})."
fi
fi
}
@@ -130,7 +120,7 @@ update_jailconf_vnet() {
# If 0.0.0.0 set DHCP, else set static IP address
if [ "${IP}" == "0.0.0.0" ]; then
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="DHCP"
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
else
sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
fi
@@ -140,7 +130,7 @@ update_fstab() {
# Update fstab to use the new name
FSTAB_CONFIG="${bastille_jailsdir}/${NEWNAME}/fstab"
if [ -f "${FSTAB_CONFIG}" ]; then
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET}/root/.bastille" "${FSTAB_CONFIG}")
FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${NEWNAME}/root/.bastille nullfs ro 0 0"
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
@@ -154,39 +144,35 @@ update_fstab() {
clone_jail() {
# Attempt container clone
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_GREEN}Attempting to clone '${TARGET}' to ${NEWNAME}...${COLOR_RESET}"
if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
# Replicate the existing container
DATE=$(date +%F-%H%M%S)
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}" | zfs recv "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"
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 source temporary snapshots
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_clone_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_clone_${DATE}"
# Cleanup target temporary snapshots
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}"
fi
else
# Just clone the jail directory
# Check if container is running
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop ${TARGET}'.${COLOR_RESET}"
fi
# Perform container file copy(archive mode)
cp -a "${bastille_jailsdir}/${TARGET}" "${bastille_jailsdir}/${NEWNAME}"
# 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
error_notify "${COLOR_RED}${NEWNAME} already exists.${COLOR_RESET}"
# Just clone the jail directory
# Check if container is running
if [ -n "$(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_notify "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
error_exit "${NEWNAME} already exists."
fi
# Generate jail configuration files
@@ -195,16 +181,15 @@ clone_jail() {
# Display the exist status
if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}An error has occurred while attempting to clone '${TARGET}'.${COLOR_RESET}"
error_exit "An error has occurred while attempting to clone '${TARGET}'."
else
echo -e "${COLOR_GREEN}Cloned '${TARGET}' to '${NEWNAME}' successfully.${COLOR_RESET}"
info "Cloned '${TARGET}' to '${NEWNAME}' successfully."
fi
}
## don't allow for dots(.) in container names
if echo "${NEWNAME}" | grep -q "[.]"; then
echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}"
exit 1
error_exit "Container names may not contain a dot(.)!"
fi
## check if ip address is valid

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 cmd TARGET command.${COLOR_RESET}"
exit 1
error_exit "Usage: bastille cmd TARGET command"
}
# Handle special-case commands first.
@@ -42,22 +41,12 @@ help|-h|--help)
;;
esac
if [ $# -lt 2 ]; then
if [ $# -eq 0 ]; then
usage
fi
TARGET="${1}"
shift
if [ "${TARGET}" = 'ALL' ]; then
JAILS=$(jls name)
fi
if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(jls name | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
jexec -l "${_jail}" "$@"
echo
done

View File

@@ -0,0 +1,50 @@
#!/bin/sh
#
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
. /usr/local/share/bastille/colors.pre.sh
# 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}"
}

View File

@@ -0,0 +1,115 @@
#!/bin/sh
#
# Copyright (c) 2018-2021, 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]"
}
# Handle special-case commands first.
case "$1" in
help|-h|--help)
usage
;;
esac
if [ $# -eq 1 ] || [ $# -gt 3 ]; then
usage
fi
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
ESCAPED_PROPERTY=$(echo "${PROPERTY}" | sed 's/\./\\\./g')
MATCH_LINE=$(grep "^[[:blank:]]*${ESCAPED_PROPERTY}[[:blank:]=;]" "${FILE}" 2>/dev/null)
MATCH_FOUND=$?
if [ "${ACTION}" = 'get' ]; then
if [ $MATCH_FOUND -ne 0 ]; then
warn "not set"
elif ! echo "${MATCH_LINE}" | grep '=' > /dev/null 2>&1; then
echo "enabled"
else
VALUE=$(echo "${MATCH_LINE}" | sed -E 's/.+= *(.+) *;$/\1/' 2>/dev/null)
if [ $? -ne 0 ]; then
error_notify "Failed to get value."
else
echo "${VALUE}"
fi
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
if [ $MATCH_FOUND -ne 0 ]; then # No match, so insert the property at the end. -- cwells
echo "$(awk -v line="${LINE}" '$0 == "}" { print line; } 1 { print $0; }' "${FILE}")" > "${FILE}"
else # Replace the existing value. -- cwells
sed -i '' -E "s/ *${ESCAPED_PROPERTY}[ =;].*/${LINE}/" "${FILE}"
fi
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

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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,21 +42,12 @@ help|-h|--help)
;;
esac
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
if [ $# -gt 1 ]; then
usage
fi
TARGET="${1}"
shift
USER="${1}"
if [ "${TARGET}" = 'ALL' ]; then
JAILS=$(jls name)
fi
if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(jls name | awk "/^${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)"
@@ -74,12 +65,22 @@ validate_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}"
info "[${_jail}]:"
if [ -n "${USER}" ]; then
validate_user
else
jexec -l "${_jail}" /usr/bin/login -f root
check_fib
${_setfib} jexec -l "${_jail}" /usr/bin/login -f root
fi
echo
done

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 convert TARGET.${COLOR_RESET}"
exit 1
error_exit "Usage: bastille convert TARGET"
}
# Handle special-case commands first.
@@ -43,20 +42,10 @@ help|-h|--help)
;;
esac
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
if [ $# -ne 0 ]; then
usage
fi
TARGET="${1}"
shift
error_notify()
{
# Notify message on error and exit
echo -e "$*" >&2
exit 1
}
convert_symlinks() {
# Work with the symlinks, revert on first cp error
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
@@ -86,13 +75,13 @@ convert_symlinks() {
fi
done
else
error_notify "${COLOR_RED}Release must be bootstrapped first, See 'bastille bootstrap'.${COLOR_RESET}"
error_exit "Release must be bootstrapped first. See 'bastille bootstrap'."
fi
}
revert_convert() {
# Revert the conversion on first cp error
echo -e "${COLOR_RED}A problem has occurred while copying the files, reverting changes...${COLOR_RESET}"
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}"
@@ -106,16 +95,16 @@ revert_convert() {
mv "${_link}.old" "${_link}"
fi
done
error_notify "${COLOR_GREEN}Changes for '${TARGET}' has been reverted.${COLOR_RESET}"
error_exit "Changes for '${TARGET}' has been reverted."
}
start_convert() {
# Attempt container conversion and handle some errors
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_GREEN}Converting '${TARGET}' into a thickjail, this may take a while...${COLOR_RESET}"
info "Converting '${TARGET}' into a thickjail. This may take a while..."
# Set some variables
RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${bastille_jailsdir}/${TARGET}/fstab")
RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${bastille_jailsdir}/${TARGET}/fstab")
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"
@@ -129,32 +118,27 @@ start_convert() {
sed -i '' -E "s|${FSTABMOD}|# Converted from thin to thick container on $(date)|g" "${bastille_jailsdir}/${TARGET}/fstab"
mv "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/root/.bastille.old"
echo -e "${COLOR_GREEN}Conversion of '${TARGET}' completed successfully!${COLOR_RESET}"
info "Conversion of '${TARGET}' completed successfully!"
exit 0
else
error_notify "${COLOR_RED}Can't determine release version, See 'bastille bootstrap'.${COLOR_RESET}"
error_exit "Can't determine release version. See 'bastille bootstrap'."
fi
else
error_notify "${COLOR_RED}${TARGET} not found. See 'bastille create'.${COLOR_RESET}"
error_exit "${TARGET} not found. See 'bastille create'."
fi
}
# Check if container is running
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop'.${COLOR_RESET}"
fi
# Check if is a thin container
if [ ! -d "${bastille_jailsdir}/${TARGET}/root/.bastille" ]; then
error_notify "${COLOR_RED}${TARGET} is not a thin container.${COLOR_RESET}"
error_exit "${TARGET} is not a thin container."
elif ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
error_notify "${COLOR_RED}${TARGET} is not a thin container.${COLOR_RESET}"
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
echo -e "${COLOR_RED}Warning: container conversion from thin to thick can't be undone!${COLOR_RESET}"
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;;

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 cp TARGET HOST_PATH CONTAINER_PATH${COLOR_RESET}"
exit 1
error_exit "Usage: bastille cp TARGET HOST_PATH CONTAINER_PATH"
}
# Handle special-case commands first.
@@ -43,24 +42,23 @@ help|-h|--help)
;;
esac
if [ $# -gt 3 ] || [ $# -lt 3 ]; then
if [ $# -ne 2 ]; then
usage
fi
TARGET="${1}"
CPSOURCE="${2}"
CPDEST="${3}"
if [ "${TARGET}" = 'ALL' ]; then
JAILS=$(jls name)
fi
if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(jls name | awk "/^${TARGET}$/")
fi
CPSOURCE="${1}"
CPDEST="${2}"
for _jail in ${JAILS}; do
bastille_jail_path="$(jls -j "${_jail}" path)"
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
bastille_jail_path="${bastille_jailsdir}/${_jail}/root"
cp -av "${CPSOURCE}" "${bastille_jail_path}/${CPDEST}"
echo
RETURN="$?"
if [ "${TARGET}" = "ALL" ]; then
# Display the return status for reference
echo -e "Returned: ${RETURN}\n"
else
echo
return "${RETURN}"
fi
done

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,21 +28,28 @@
# 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 create [option] name release ip [interface].${COLOR_RESET}"
exit 1
error_exit "Usage: bastille create [option] name release ip [interface]"
}
running_jail() {
if [ -n "$(jls name | awk "/^${NAME}$/")" ]; then
echo -e "${COLOR_RED}A running jail matches name.${COLOR_RESET}"
exit 1
error_exit "A running jail matches name."
elif [ -d "${bastille_jailsdir}/${NAME}" ]; then
echo -e "${COLOR_RED}Jail: ${NAME} already created.${COLOR_RESET}"
exit 1
error_exit "Jail: ${NAME} already created."
fi
}
validate_name() {
local NAME_VERIFY=${NAME}
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
}
@@ -51,7 +58,7 @@ validate_ip() {
IP6_MODE="disable"
ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))')
if [ -n "${ip6}" ]; then
echo -e "${COLOR_GREEN}Valid: (${ip6}).${COLOR_RESET}"
info "Valid: (${ip6})."
IPX_ADDR="ip6.addr"
IP6_MODE="new"
else
@@ -67,13 +74,12 @@ validate_ip() {
fi
done
if ifconfig | grep -qw "${TEST_IP}"; then
echo -e "${COLOR_YELLOW}Warning: ip address already in use (${TEST_IP}).${COLOR_RESET}"
warn "Warning: IP address already in use (${TEST_IP})."
else
echo -e "${COLOR_GREEN}Valid: (${IP}).${COLOR_RESET}"
info "Valid: (${IP})."
fi
else
echo -e "${COLOR_RED}Invalid: (${IP}).${COLOR_RESET}"
exit 1
error_exit "Invalid: (${IP})."
fi
fi
}
@@ -81,17 +87,15 @@ validate_ip() {
validate_netif() {
local LIST_INTERFACES=$(ifconfig -l)
if echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then
echo -e "${COLOR_GREEN}Valid: (${INTERFACE}).${COLOR_RESET}"
info "Valid: (${INTERFACE})."
else
echo -e "${COLOR_RED}Invalid: (${INTERFACE}).${COLOR_RESET}"
exit 1
error_exit "Invalid: (${INTERFACE})."
fi
}
validate_netconf() {
if [ -n "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
echo -e "${COLOR_RED}Invalid network configuration.${COLOR_RESET}"
exit 1
error_exit "Invalid network configuration."
fi
}
@@ -104,6 +108,17 @@ validate_release() {
fi
}
generate_minimal_conf() {
cat << EOF > "${bastille_jail_conf}"
${NAME} {
host.hostname = ${NAME};
mount.fstab = ${bastille_jail_fstab};
path = ${bastille_jail_path};
}
EOF
touch "${bastille_jail_fstab}"
}
generate_jail_conf() {
cat << EOF > "${bastille_jail_conf}"
${NAME} {
@@ -161,7 +176,7 @@ ${NAME} {
vnet;
vnet.interface = e0b_${uniq_epair};
exec.prestart += "jib addm ${uniq_epair} ${INTERFACE}";
exec.prestart += "jib addm ${uniq_epair} ${bastille_jail_conf_interface}";
exec.poststop += "jib destroy ${uniq_epair}";
}
EOF
@@ -187,160 +202,150 @@ create_jail() {
fi
fi
else
mkdir -p "${bastille_jailsdir}/${NAME}"
mkdir -p "${bastille_jailsdir}/${NAME}/root"
fi
fi
if [ ! -d "${bastille_jail_base}" ]; then
mkdir -p "${bastille_jail_base}"
fi
if [ -z "${EMPTY_JAIL}" ]; then
if [ ! -d "${bastille_jail_base}" ]; then
mkdir -p "${bastille_jail_base}"
fi
if [ ! -d "${bastille_jail_path}/usr/home" ]; then
mkdir -p "${bastille_jail_path}/usr/home"
fi
if [ ! -d "${bastille_jail_path}/usr/local" ]; then
mkdir -p "${bastille_jail_path}/usr/local"
fi
if [ ! -d "${bastille_jail_path}/usr/local" ]; then
mkdir -p "${bastille_jail_path}/usr/local"
fi
if [ ! -d "${bastille_jail_template}" ]; then
mkdir -p "${bastille_jail_template}"
fi
if [ ! -d "${bastille_jail_template}" ]; then
mkdir -p "${bastille_jail_template}"
fi
if [ ! -f "${bastille_jail_fstab}" ]; then
if [ -z "${THICK_JAIL}" ]; then
echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}"
else
touch "${bastille_jail_fstab}"
fi
fi
if [ ! -f "${bastille_jail_conf}" ]; then
if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
local bastille_jail_conf_interface=${bastille_network_shared}
fi
if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then
local bastille_jail_conf_interface=${bastille_network_loopback}
fi
if [ -n "${INTERFACE}" ]; then
local bastille_jail_conf_interface=${INTERFACE}
fi
## generate the jail configuration file
if [ -n "${VNET_JAIL}" ]; then
generate_vnet_jail_conf
else
generate_jail_conf
fi
fi
## using relative paths here
## MAKE SURE WE'RE IN THE RIGHT PLACE
cd "${bastille_jail_path}"
echo
info "NAME: ${NAME}."
info "IP: ${IP}."
if [ -n "${INTERFACE}" ]; then
info "INTERFACE: ${INTERFACE}."
fi
info "RELEASE: ${RELEASE}."
echo
if [ ! -f "${bastille_jail_fstab}" ]; then
if [ -z "${THICK_JAIL}" ]; then
echo -e "${bastille_releasesdir}/${RELEASE} ${bastille_jail_base} nullfs ro 0 0" > "${bastille_jail_fstab}"
LINK_LIST="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/sbin usr/share usr/src"
for _link in ${LINK_LIST}; do
ln -sf /.bastille/${_link} ${_link}
done
# Properly link shared ports on thin jails in read-write.
if [ -d "${bastille_releasesdir}/${RELEASE}/usr/ports" ]; then
if [ ! -d "${bastille_jail_path}/usr/ports" ]; then
mkdir ${bastille_jail_path}/usr/ports
fi
echo -e "${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jail_path}/usr/ports nullfs rw 0 0" >> "${bastille_jail_fstab}"
fi
fi
if [ -z "${THICK_JAIL}" ]; then
## rw
## copy only required files for thin jails
FILE_LIST=".cshrc .profile COPYRIGHT dev etc media mnt net proc root tmp var usr/obj usr/tests"
for files in ${FILE_LIST}; do
if [ -f "${bastille_releasesdir}/${RELEASE}/${files}" ] || [ -d "${bastille_releasesdir}/${RELEASE}/${files}" ]; then
cp -a "${bastille_releasesdir}/${RELEASE}/${files}" "${bastille_jail_path}/${files}"
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
bastille destroy "${NAME}"
error_exit "Failed to copy release files. Please retry create!"
fi
fi
done
else
touch "${bastille_jail_fstab}"
fi
fi
info "Creating a thickjail. This may take a while..."
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
## perform release base replication
if [ ! -f "${bastille_jail_conf}" ]; then
if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
local bastille_jail_conf_interface=${bastille_network_shared}
fi
if [ -n "${bastille_network_loopback}" ] && [ -z "${bastille_network_shared}" ]; then
local bastille_jail_conf_interface=${bastille_network_loopback}
fi
if [ -n "${INTERFACE}" ]; then
local bastille_jail_conf_interface=${INTERFACE}
fi
## sane bastille zfs options
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
## generate the jail configuration file
if [ -n "${VNET_JAIL}" ]; then
generate_vnet_jail_conf
else
generate_jail_conf
fi
fi
## take a temp snapshot of the base release
SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)"
zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
## using relative paths here
## MAKE SURE WE'RE IN THE RIGHT PLACE
cd "${bastille_jail_path}"
echo
echo -e "${COLOR_GREEN}NAME: ${NAME}.${COLOR_RESET}"
echo -e "${COLOR_GREEN}IP: ${IP}.${COLOR_RESET}"
if [ -n "${INTERFACE}" ]; then
echo -e "${COLOR_GREEN}INTERFACE: ${INTERFACE}.${COLOR_RESET}"
fi
echo -e "${COLOR_GREEN}RELEASE: ${RELEASE}.${COLOR_RESET}"
echo
## replicate the release base to the new thickjail and set the default mountpoint
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" | \
zfs receive "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
zfs set ${ZFS_OPTIONS} mountpoint=none "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
zfs inherit mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
if [ -z "${THICK_JAIL}" ]; then
for _link in bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/sbin usr/share usr/src; do
ln -sf /.bastille/${_link} ${_link}
done
fi
## cleanup temp snapshots initially
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}"
## link home properly
ln -s usr/home home
if [ -z "${THICK_JAIL}" ]; then
## rw
## copy only required files for thin jails
FILE_LIST=".cshrc .profile COPYRIGHT dev etc media mnt net proc root tmp var usr/obj usr/tests"
for files in ${FILE_LIST}; do
if [ -f "${bastille_releasesdir}/${RELEASE}/${files}" ] || [ -d "${bastille_releasesdir}/${RELEASE}/${files}" ]; then
cp -a "${bastille_releasesdir}/${RELEASE}/${files}" "${bastille_jail_path}/${files}"
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
bastille destroy "${NAME}"
error_exit "Failed release base replication. Please retry create!"
fi
fi
else
## copy all files for thick jails
cp -a "${bastille_releasesdir}/${RELEASE}/" "${bastille_jail_path}"
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
echo -e "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}"
bastille destroy "${NAME}"
exit 1
error_exit "Failed to copy release files. Please retry create!"
fi
fi
done
else
echo -e "${COLOR_GREEN}Creating a thickjail, this may take a while...${COLOR_RESET}"
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
## perform release base replication
## sane bastille zfs options
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
## take a temp snapshot of the base release
SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)"
zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
## replicate the release base to the new thickjail and set the default mountpoint
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" | \
zfs receive "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
zfs set ${ZFS_OPTIONS} mountpoint=none "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
zfs inherit mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"
## cleanup temp snapshots initially
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}"
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
echo -e "${COLOR_RED}Failed release base replication, please retry create!${COLOR_RESET}"
bastille destroy "${NAME}"
exit 1
fi
fi
else
## copy all files for thick jails
cp -a "${bastille_releasesdir}/${RELEASE}/" "${bastille_jail_path}"
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
echo -e "${COLOR_RED}Failed to copy release files, please retry create!${COLOR_RESET}"
bastille destroy "${NAME}"
exit 1
fi
fi
fi
## rc.conf
## + syslogd_flags="-ss"
## + sendmail_none="NONE"
## + cron_flags="-J 60" ## cedwards 20181118
if [ ! -f "${bastille_jail_rc_conf}" ]; then
touch "${bastille_jail_rc_conf}"
sysrc -f "${bastille_jail_rc_conf}" syslogd_flags=-ss
sysrc -f "${bastille_jail_rc_conf}" sendmail_enable=NONE
sysrc -f "${bastille_jail_rc_conf}" cron_flags='-J 60'
## create home directory if missing
if [ ! -d "${bastille_jail_path}/usr/home" ]; then
mkdir -p "${bastille_jail_path}/usr/home"
fi
## link home properly
if [ ! -L "home" ]; then
ln -s usr/home home
fi
## TZ: configurable (default: Etc/UTC)
ln -s "/usr/share/zoneinfo/${bastille_tzdata}" etc/localtime
# Post-creation jail misc configuration
# Create a dummy fstab file
touch "etc/fstab"
# Disables adjkerntz, avoids spurious error messages
sed -i '' 's|[0-9],[0-9]\{2\}.*[0-9]-[0-9].*root.*kerntz -a|#& # Disabled by bastille|' "etc/crontab"
## VNET specific
if [ -n "${VNET_JAIL}" ]; then
## rename interface to generic vnet0
uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//')
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" "ifconfig_${uniq_epair}_name"=vnet0
## if 0.0.0.0 set DHCP
## else set static address
if [ "${IP}" == "0.0.0.0" ]; then
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP"
else
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}"
if [ -n "${bastille_network_gateway}" ]; then
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" defaultrouter="${bastille_network_gateway}"
else
/usr/sbin/sysrc -f "${bastille_jail_rc_conf}" defaultrouter="$(netstat -rn | awk '/default/ {print $2}')"
fi
fi
## VNET requires jib script
if [ ! "$(command -v jib)" ]; then
if [ -f /usr/share/examples/jails/jib ] && [ ! -f /usr/local/bin/jib ]; then
@@ -348,15 +353,64 @@ create_jail() {
fi
fi
fi
else
## Generate minimal configuration for empty jail
generate_minimal_conf
fi
## resolv.conf (default: copy from host)
if [ ! -f "${bastille_jail_resolv_conf}" ]; then
cp -L "${bastille_resolv_conf}" "${bastille_jail_resolv_conf}"
# Set strict permissions on the jail by default
chmod 0700 "${bastille_jailsdir}/${NAME}"
# Jail must be started before applying the default template. -- cwells
if [ -z "${EMPTY_JAIL}" ]; then
bastille start "${NAME}"
elif [ -n "${EMPTY_JAIL}" ]; then
# Don't start empty jails unless a template defined.
if [ -n "${bastille_template_empty}" ]; then
bastille start "${NAME}"
fi
fi
## TZ: configurable (default: Etc/UTC)
ln -s "/usr/share/zoneinfo/${bastille_tzdata}" etc/localtime
if [ -n "${VNET_JAIL}" ]; then
if [ -n "${bastille_template_vnet}" ]; then
## rename interface to generic vnet0
uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//')
_gateway=''
_ifconfig=SYNCDHCP
if [ "${IP}" != "0.0.0.0" ]; then # not using DHCP, so set static address.
_ifconfig="inet ${IP}"
if [ -n "${bastille_network_gateway}" ]; then
_gateway="${bastille_network_gateway}"
else
_gateway="$(netstat -rn | awk '/default/ {print $2}')"
fi
fi
bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg IFCONFIG="${_ifconfig}"
fi
elif [ -n "${THICK_JAIL}" ]; then
if [ -n "${bastille_template_thick}" ]; then
bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
fi
elif [ -n "${EMPTY_JAIL}" ]; then
if [ -n "${bastille_template_empty}" ]; then
bastille template "${NAME}" ${bastille_template_empty} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
fi
else # Thin jail.
if [ -n "${bastille_template_thin}" ]; then
bastille template "${NAME}" ${bastille_template_thin} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}"
fi
fi
# Apply values changed by the template. -- cwells
if [ -z "${EMPTY_JAIL}" ]; then
bastille restart "${NAME}"
elif [ -n "${EMPTY_JAIL}" ]; then
# Don't restart empty jails unless a template defined.
if [ -n "${bastille_template_empty}" ]; then
bastille restart "${NAME}"
fi
fi
}
# Handle special-case commands first.
@@ -372,6 +426,7 @@ if echo "$3" | grep '@'; then
fi
## reset this options
EMPTY_JAIL=""
THICK_JAIL=""
VNET_JAIL=""
@@ -384,6 +439,10 @@ if [ "${1}" = "-T" -o "${1}" = "--thick" -o "${1}" = "thick" ] && \
else
## handle single options
case "${1}" in
-E|--empty|empty)
shift
EMPTY_JAIL="1"
;;
-T|--thick|thick)
shift
THICK_JAIL="1"
@@ -393,7 +452,7 @@ else
VNET_JAIL="1"
;;
-*)
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}"
error_notify "Unknown Option."
usage
;;
esac
@@ -404,64 +463,100 @@ RELEASE="$2"
IP="$3"
INTERFACE="$4"
if [ $# -gt 4 ] || [ $# -lt 3 ]; then
usage
if [ -n "${EMPTY_JAIL}" ]; then
if [ $# -ne 1 ]; then
usage
fi
else
if [ $# -gt 4 ] || [ $# -lt 3 ]; then
usage
fi
fi
## don't allow for dots(.) in container names
if echo "${NAME}" | grep -q "[.]"; then
echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}"
exit 1
## validate jail name
if [ -n "${NAME}" ]; then
validate_name
fi
## verify release
case "${RELEASE}" 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:]')
validate_release
;;
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
## check for HardenedBSD releases name(previous infrastructure)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
validate_release
;;
*-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')
validate_release
;;
*-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')
validate_release
;;
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')
validate_release
;;
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')
validate_release
;;
*)
echo -e "${COLOR_RED}Unknown Release.${COLOR_RESET}"
usage
;;
esac
if [ -z "${EMPTY_JAIL}" ]; then
## verify release
case "${RELEASE}" in
*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current)
## check for FreeBSD releases name
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
validate_release
;;
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
## check for FreeBSD releases name
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
validate_release
;;
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)
## check for HardenedBSD releases name(previous infrastructure)
NAME_VERIFY=$(echo "${RELEASE}" | grep -iwE '^([1-9]{2,2})(-stable-last)$' | sed 's/STABLE/stable/g' | sed 's/last/LAST/g')
validate_release
;;
*-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')
validate_release
;;
*-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')
validate_release
;;
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')
validate_release
;;
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')
validate_release
;;
*)
error_notify "Unknown Release."
usage
;;
esac
## check for name/root/.bastille
if [ -d "${bastille_jailsdir}/${NAME}/root/.bastille" ]; then
echo -e "${COLOR_RED}Jail: ${NAME} already created. ${NAME}/root/.bastille exists.${COLOR_RESET}"
exit 1
fi
## check for name/root/.bastille
if [ -d "${bastille_jailsdir}/${NAME}/root/.bastille" ]; then
error_exit "Jail: ${NAME} already created. ${NAME}/root/.bastille exists."
fi
## check for required release
if [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then
echo -e "${COLOR_RED}Release must be bootstrapped first; see 'bastille bootstrap'.${COLOR_RESET}"
exit 1
## check for required release
if [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then
error_exit "Release must be bootstrapped first; see 'bastille bootstrap'."
fi
## check if ip address is valid
if [ -n "${IP}" ]; then
validate_ip
else
usage
fi
## check if interface is valid
if [ -n "${INTERFACE}" ]; then
validate_netif
validate_netconf
elif [ -n "${VNET_JAIL}" ]; then
if [ -z "${INTERFACE}" ]; then
if [ -z "${bastille_network_shared}" ]; then
# User must specify interface on vnet jails.
error_exit "Error: Network interface not defined."
else
validate_netconf
fi
fi
else
validate_netconf
fi
else
info "Creating empty jail: ${NAME}."
fi
## check if a running jail matches name or already exist
@@ -469,19 +564,27 @@ if [ -n "${NAME}" ]; then
running_jail
fi
## check if ip address is valid
if [ -n "${IP}" ]; then
validate_ip
else
usage
# May not exist on deployments created before Bastille 0.7.20200714, so creating it. -- cwells
if [ ! -e "${bastille_templatesdir}/default" ]; then
ln -s "${bastille_sharedir}/templates/default" "${bastille_templatesdir}/default"
fi
## check if interface is valid
if [ -n "${INTERFACE}" ]; then
validate_netif
validate_netconf
else
validate_netconf
# These variables were added after Bastille 0.7.20200714, so they may not exist in the user's config.
# We're checking for existence of the variables rather than empty since empty is a valid value. -- cwells
if [ -z ${bastille_template_base+x} ]; then
bastille_template_base='default/base'
fi
if [ -z ${bastille_template_empty+x} ]; then
bastille_template_empty='default/empty'
fi
if [ -z ${bastille_template_thick+x} ]; then
bastille_template_thick='default/thick'
fi
if [ -z ${bastille_template_thin+x} ]; then
bastille_template_thin='default/thin'
fi
if [ -z ${bastille_template_vnet+x} ]; then
bastille_template_vnet='default/vnet'
fi
create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}"

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,15 +28,15 @@
# 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 [option] | [container|release]${COLOR_RESET}"
exit 1
error_exit "Usage: bastille destroy [option] | [container|release]"
}
destroy_jail() {
local OPTIONS
bastille_jail_base="${bastille_jailsdir}/${TARGET}" ## dir
bastille_jail_log="${bastille_logsdir}/${TARGET}_console.log" ## file
@@ -44,24 +44,26 @@ destroy_jail() {
if [ "${FORCE}" = "1" ]; then
bastille stop "${TARGET}"
else
echo -e "${COLOR_RED}Jail running.${COLOR_RESET}"
echo -e "${COLOR_RED}See 'bastille stop ${TARGET}'.${COLOR_RESET}"
exit 1
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: ${TARGET}.${COLOR_RESET}"
info "Deleting Jail: ${TARGET}."
if [ "${bastille_zfs_enable}" = "YES" ]; 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/${TARGET}"
zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"
fi
fi
fi
@@ -74,16 +76,22 @@ destroy_jail() {
rm -rf "${bastille_jail_base}"
fi
# Remove target from bastille_list if exist
# Mute sysrc output here as it may be undesirable on large startup list
if [ -n "$(sysrc -qn bastille_list | tr -s " " "\n" | awk "/^${TARGET}$/")" ]; then
sysrc bastille_list-="${TARGET}" > /dev/null
fi
## archive jail log
if [ -f "${bastille_jail_log}" ]; then
mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)"
echo -e "${COLOR_GREEN}Note: jail console logs archived.${COLOR_RESET}"
echo -e "${COLOR_GREEN}${bastille_jail_log}-$(date +%F)${COLOR_RESET}"
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
echo -e "${COLOR_GREEN}Clearing RDR rules:${COLOR_RESET}"
info "Clearing RDR rules:"
pfctl -a "rdr/${TARGET}" -Fn
fi
echo
@@ -91,6 +99,8 @@ destroy_jail() {
}
destroy_rel() {
local OPTIONS
## check release name match before destroy
if [ -n "${NAME_VERIFY}" ]; then
TARGET="${NAME_VERIFY}"
@@ -106,24 +116,29 @@ destroy_rel() {
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
for _jail in ${JAIL_LIST}; do
if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then
echo -e "${COLOR_RED}Notice: (${_jail}) depends on ${TARGET} base.${COLOR_RESET}"
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
BASE_HASCHILD="1"
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: ${TARGET}.${COLOR_RESET}"
info "Deleting base: ${TARGET}"
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${TARGET}"
if [ "${FORCE}" = "1" ]; then
if [ -d "${bastille_cachedir}/${TARGET}" ]; then
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/cache/${TARGET}"
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
@@ -145,7 +160,7 @@ destroy_rel() {
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
}
@@ -167,7 +182,7 @@ case "${1}" in
shift
;;
-*)
echo -e "${COLOR_RED}Unknown Option.${COLOR_RESET}"
error_notify "Unknown Option."
usage
;;
esac
@@ -180,9 +195,14 @@ fi
## check what should we clean
case "${TARGET}" in
*-RELEASE|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
*-CURRENT|*-CURRENT-I386|*-CURRENT-i386|*-current)
## check for FreeBSD releases name
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RC[1-2])$' | tr '[:lower:]' '[:upper:]')
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-CURRENT|-CURRENT-i386)$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
destroy_rel
;;
*-RELEASE|*-RELEASE-I386|*-RELEASE-i386|*-release|*-RC1|*-rc1|*-RC2|*-rc2)
## check for FreeBSD releases name
NAME_VERIFY=$(echo "${TARGET}" | grep -iwE '^([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])$' | tr '[:lower:]' '[:upper:]' | sed 's/I/i/g')
destroy_rel
;;
*-stable-LAST|*-STABLE-last|*-stable-last|*-STABLE-LAST)

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 edit TARGET [filename]${COLOR_RESET}"
exit 1
error_exit "Usage: bastille edit TARGET [filename]"
}
# Handle special-case commands first.
@@ -43,26 +42,16 @@ help|-h|--help)
;;
esac
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
if [ $# -gt 1 ]; then
usage
fi
TARGET="${1}"
if [ $# == 2 ]; then
TARGET_FILENAME="${2}"
elif [ $# -eq 1 ]; then
TARGET_FILENAME="${1}"
fi
if [ -z "${EDITOR}" ]; then
EDITOR=vi
fi
if [ "${TARGET}" = 'ALL' ]; then
JAILS=$(bastille list jails)
fi
if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(bastille list jails | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
if [ -n "${TARGET_FILENAME}" ]; then
"${EDITOR}" "${bastille_jailsdir}/${_jail}/${TARGET_FILENAME}"

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 export TARGET.${COLOR_RESET}"
exit 1
error_exit "Usage: bastille export TARGET [option] | PATH"
}
# Handle special-case commands first
@@ -43,77 +42,109 @@ help|-h|--help)
;;
esac
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
# Check for unsupported actions
if [ "${TARGET}" = "ALL" ]; then
error_exit "Batch export is unsupported."
fi
if [ $# -gt 2 ] || [ $# -lt 0 ]; then
usage
fi
TARGET="${1}"
shift
OPTION="${1}"
EXPATH="${2}"
SAFE_EXPORT=
error_notify()
{
# Notify message on error and exit
echo -e "$*" >&2
exit 1
# Handle some options
if [ -n "${OPTION}" ]; then
if [ "${OPTION}" = "-t" -o "${OPTION}" = "--txz" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then
# Temporarily disable ZFS so we can create a standard backup archive
bastille_zfs_enable="NO"
fi
elif [ "${OPTION}" = "-s" -o "${OPTION}" = "--safe" ]; then
SAFE_EXPORT="1"
elif echo "${OPTION}" | grep -q "\/"; then
if [ -d "${OPTION}" ]; then
EXPATH="${OPTION}"
else
error_exit "Error: Path not found."
fi
else
error_notify "Invalid option!"
usage
fi
fi
# Export directory check
if [ -n "${EXPATH}" ]; then
if [ -d "${EXPATH}" ]; then
# Set the user defined export directory
bastille_backupsdir="${EXPATH}"
else
error_exit "Error: Path not found."
fi
fi
create_zfs_snap(){
# Take a recursive temporary snapshot
info "Creating temporary ZFS snapshot for export..."
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
}
jail_export()
{
# Attempt to export the container
DATE=$(date +%F-%H%M%S)
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
FILE_EXT="xz"
echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Sending zfs data stream...${COLOR_RESET}"
# Take a recursive temporary snapshot
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
FILE_EXT="xz"
# Export the container recursively and cleanup temporary snapshots
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" | \
xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_export_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
if [ -n "${SAFE_EXPORT}" ]; then
info "Safely exporting '${TARGET}' to a compressed .${FILE_EXT} archive."
bastille stop ${TARGET}
create_zfs_snap
bastille start ${TARGET}
else
info "Hot exporting '${TARGET}' to a compressed .${FILE_EXT} archive."
create_zfs_snap
fi
else
# Create standard backup archive
FILE_EXT="txz"
echo -e "${COLOR_GREEN}Exporting '${TARGET}' to a compressed .${FILE_EXT} archive...${COLOR_RESET}"
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
fi
if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}Failed to export '${TARGET}' container.${COLOR_RESET}"
else
# Generate container checksum file
cd "${bastille_backupsdir}"
sha256 -q "${TARGET}_${DATE}.${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
echo -e "${COLOR_GREEN}Exported '${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}' successfully.${COLOR_RESET}"
exit 0
info "Sending ZFS data stream..."
# Export the container recursively and cleanup temporary snapshots
zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" | \
xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}/root@bastille_export_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}"
fi
else
error_notify "${COLOR_RED}Container '${TARGET}' does not exist.${COLOR_RESET}"
# Create standard backup archive
FILE_EXT="txz"
info "Exporting '${TARGET}' to a compressed .${FILE_EXT} archive..."
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}"
fi
if [ "$?" -ne 0 ]; then
error_exit "Failed to export '${TARGET}' container."
else
# Generate container checksum file
cd "${bastille_backupsdir}"
sha256 -q "${TARGET}_${DATE}.${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}' successfully."
exit 0
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_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
fi
# Check if is a ZFS system
if [ "${bastille_zfs_enable}" != "YES" ]; then
# Check if container is running and ask for stop in UFS systems
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop'.${COLOR_RESET}"
error_exit "${TARGET} is running. See 'bastille stop'."
fi
fi

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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,16 @@ 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 | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
bastille_jail_path=$(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}"

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 import file [option].${COLOR_RESET}"
exit 1
error_exit "Usage: bastille import file [option]"
}
# Handle special-case commands first
@@ -51,46 +50,40 @@ TARGET="${1}"
OPTION="${2}"
shift
error_notify() {
# Notify message on error and exit
echo -e "$*" >&2
exit 1
}
validate_archive() {
# Compare checksums on the target archive
# Skip validation for unsupported archives
if [ "${FILE_EXT}" != ".tar.gz" ] && [ "${FILE_EXT}" != ".tar" ]; then
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
if [ -f "${bastille_backupsdir}/${FILE_TRIM}.sha256" ]; then
echo -e "${COLOR_GREEN}Validating file: ${TARGET}...${COLOR_RESET}"
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_notify "${COLOR_RED}Failed validation for ${TARGET}.${COLOR_RESET}"
error_exit "Failed validation for ${TARGET}."
else
echo -e "${COLOR_GREEN}File validation successful!${COLOR_RESET}"
info "File validation successful!"
fi
else
# Check if user opt to force import
if [ "${OPTION}" = "-f" -o "${OPTION}" = "force" ]; then
echo -e "${COLOR_YELLOW}Warning: Skipping archive validation!${COLOR_RESET}"
warn "Warning: Skipping archive validation!"
else
error_notify "${COLOR_RED}Checksum file not found, See 'bastille import TARGET -f'${COLOR_RESET}"
error_exit "Checksum file not found. See 'bastille import TARGET -f'."
fi
fi
fi
else
echo -e "${COLOR_YELLOW}Warning: Skipping archive validation!${COLOR_RESET}"
warn "Warning: Skipping archive validation!"
fi
}
update_zfsmount() {
# Update the mountpoint property on the received zfs data stream
# Update the mountpoint property on the received ZFS data stream
OLD_ZFS_MOUNTPOINT=$(zfs get -H mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" | awk '{print $3}')
NEW_ZFS_MOUNTPOINT="${bastille_jailsdir}/${TARGET_TRIM}/root"
if [ "${NEW_ZFS_MOUNTPOINT}" != "${OLD_ZFS_MOUNTPOINT}" ]; then
echo -e "${COLOR_GREEN}Updating zfs mountpoint...${COLOR_RESET}"
info "Updating ZFS mountpoint..."
zfs set mountpoint="${bastille_jailsdir}/${TARGET_TRIM}/root" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
fi
@@ -108,10 +101,10 @@ update_jailconf() {
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
echo -e "${COLOR_GREEN}Updating jail.conf...${COLOR_RESET}"
sed -i '' "s|exec.consolelog.*= .*;|exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;|" "${JAIL_CONFIG}"
sed -i '' "s|path.*= .*;|path = ${bastille_jailsdir}/${TARGET_TRIM}/root;|" "${JAIL_CONFIG}"
sed -i '' "s|mount.fstab.*= .*;|mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;|" "${JAIL_CONFIG}"
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
fi
}
@@ -120,13 +113,13 @@ 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|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-2])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}")
FSTAB_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
echo -e "${COLOR_GREEN}Updating fstab...${COLOR_RESET}"
info "Updating fstab..."
sed -i '' "s|${FSTAB_CURRENT}|${FSTAB_NEWCONF}|" "${FSTAB_CONFIG}"
fi
fi
@@ -135,7 +128,7 @@ update_fstab() {
generate_config() {
# Attempt to read previous config file and set required variables accordingly
# If we can't get a valid interface, fallback to lo1 and warn user
echo -e "${COLOR_GREEN}Generating jail.conf...${COLOR_RESET}"
info "Generating jail.conf..."
if [ "${FILE_EXT}" = ".zip" ]; then
# Gather some bits from foreign/iocage config files
@@ -195,7 +188,7 @@ generate_config() {
IPX_ADDR="ip4.addr"
IP_CONFIG="-"
IP6_MODE="disable"
echo -e "${COLOR_YELLOW}Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration${COLOR_RESET}"
warn "Warning: See 'bastille edit ${TARGET_TRIM} jail.conf' for manual network configuration."
fi
if [ "${FILE_EXT}" = ".tar.gz" ]; then
@@ -203,7 +196,7 @@ generate_config() {
if [ -z "${CONFIG_RELEASE}" ]; then
# Fallback to host version
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} was set by default!${COLOR_RESET}"
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" \
@@ -248,7 +241,7 @@ update_config() {
if [ -z "${CONFIG_RELEASE}" ]; then
# Fallback to host version
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} was set by default!${COLOR_RESET}"
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" \
@@ -289,11 +282,11 @@ update_symlinks() {
# Just warn user to bootstrap the release if missing
if [ ! -d "${bastille_releasesdir}/${CONFIG_RELEASE}" ]; then
echo -e "${COLOR_YELLOW}Warning: ${CONFIG_RELEASE} must be bootstrapped, See 'bastille bootstrap'.${COLOR_RESET}"
warn "Warning: ${CONFIG_RELEASE} must be bootstrapped. See 'bastille bootstrap'."
fi
# Update old symlinks
echo -e "${COLOR_GREEN}Updating symlinks...${COLOR_RESET}"
info "Updating symlinks..."
for _link in ${SYMLINKS}; do
if [ -L "${_link}" ]; then
ln -sf /.bastille/${_link} ${_link}
@@ -303,8 +296,8 @@ update_symlinks() {
create_zfs_datasets() {
# Prepare the ZFS environment and restore from file
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Preparing zfs environment...${COLOR_RESET}"
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}"
@@ -315,7 +308,7 @@ remove_zfs_datasets() {
# Perform cleanup on failure
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
error_notify "${COLOR_RED}Failed to extract files from '${TARGET}' archive.${COLOR_RESET}"
error_exit "Failed to extract files from '${TARGET}' archive."
}
jail_import() {
@@ -328,8 +321,8 @@ jail_import() {
if [ -n "${bastille_zfs_zpool}" ]; then
if [ "${FILE_EXT}" = ".xz" ]; then
# Import from compressed xz on ZFS systems
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} archive.${COLOR_RESET}"
echo -e "${COLOR_GREEN}Receiving zfs data stream...${COLOR_RESET}"
info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} archive."
info "Receiving ZFS data stream..."
xz ${bastille_decompress_xz_options} "${bastille_backupsdir}/${TARGET}" | \
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
@@ -341,7 +334,7 @@ jail_import() {
create_zfs_datasets
# Extract required files to the new datasets
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
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
@@ -349,17 +342,17 @@ jail_import() {
fi
elif [ "${FILE_EXT}" = ".zip" ]; then
# Attempt to import a foreign/iocage container
echo -e "${COLOR_GREEN}Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive.${COLOR_RESET}"
# Sane bastille zfs options
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_notify "${COLOR_RED}Failed to extract files from '${TARGET}' archive.${COLOR_RESET}"
error_exit "Failed to extract files from '${TARGET}' archive."
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
fi
echo -e "${COLOR_GREEN}Receiving zfs data stream...${COLOR_RESET}"
info "Receiving ZFS data stream..."
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${FILE_TRIM}"
zfs set ${ZFS_OPTIONS} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
zfs receive -u "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root"
@@ -383,7 +376,7 @@ jail_import() {
create_zfs_datasets
# Extract required files to the new datasets
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
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
@@ -398,7 +391,7 @@ jail_import() {
workout_components
# Extract required files to the new datasets
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
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
@@ -411,24 +404,24 @@ jail_import() {
update_config
fi
else
error_notify "${COLOR_RED}Unknown archive format.${COLOR_RESET}"
error_exit "Unknown archive format."
fi
fi
else
# Import from standard supported archives on UFS systems
if [ "${FILE_EXT}" = ".txz" ]; then
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
info "Extracting files from '${TARGET}' archive..."
tar -Jxf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
# Attempt to import/configure foreign/ezjail container
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
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
echo -e "${COLOR_GREEN}Extracting files from '${TARGET}' archive...${COLOR_RESET}"
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}"
@@ -438,22 +431,22 @@ jail_import() {
fi
update_config
else
error_notify "${COLOR_RED}Unsupported archive format.${COLOR_RESET}"
error_exit "Unsupported archive format."
fi
fi
if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}Failed to import from '${TARGET}' archive.${COLOR_RESET}"
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
echo -e "${COLOR_GREEN}Container '${TARGET_TRIM}' imported successfully.${COLOR_RESET}"
info "Container '${TARGET_TRIM}' imported successfully."
exit 0
fi
else
error_notify "${COLOR_RED}Jails directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"
error_exit "Jails directory/dataset does not exist. See 'bastille bootstrap'."
fi
}
@@ -466,7 +459,7 @@ fi
# Check if backups directory/dataset exist
if [ ! -d "${bastille_backupsdir}" ]; then
error_notify "${COLOR_RED}Backups directory/dataset does not exist, See 'bastille bootstrap'.${COLOR_RESET}"
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
fi
# Check if archive exist then trim archive name
@@ -477,17 +470,17 @@ if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
TARGET_TRIM=$(echo "${TARGET}" | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.xz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.txz//;s/_[0-9]*-[0-9]*-[0-9]*.zip//;s/-[0-9]\{12\}.[0-9]\{2\}.tar.gz//;s/@[0-9]\{12\}.[0-9]\{2\}.tar//")
fi
else
error_notify "${COLOR_RED}Unrecognized archive name.${COLOR_RESET}"
error_exit "Unrecognized archive name."
fi
else
error_notify "${COLOR_RED}Archive '${TARGET}' not found.${COLOR_RESET}"
error_exit "Archive '${TARGET}' not found."
fi
# Check if a running jail matches name or already exist
if [ -n "$(jls name | awk "/^${TARGET_TRIM}$/")" ]; then
error_notify "${COLOR_RED}A running jail matches name.${COLOR_RESET}"
error_exit "A running jail matches name."
elif [ -d "${bastille_jailsdir}/${TARGET_TRIM}" ]; then
error_notify "${COLOR_RED}Container: ${TARGET_TRIM} already exist.${COLOR_RESET}"
error_exit "Container: ${TARGET_TRIM} already exists."
fi
jail_import

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
# Ressource limits added by Sven R github.com/hackacad
#
@@ -29,10 +29,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 limits TARGET option value${COLOR_RESET}"
error_notify "Usage: bastille limits TARGET option value"
echo -e "Example: bastille limits JAILNAME memoryuse 1G"
exit 1
}
@@ -40,6 +41,7 @@ usage() {
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.
@@ -49,26 +51,30 @@ help|-h|--help)
;;
esac
if [ $# -lt 2 ]; then
if [ $# -ne 2 ]; then
usage
fi
TARGET="${1}"
OPTION="${2}"
VALUE="${3}"
shift
if [ "${TARGET}" = 'ALL' ]; then
JAILS=$(jls name)
fi
if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(jls name | awk "/^${TARGET}$/")
fi
OPTION="${1}"
VALUE="${2}"
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
echo -e "${TYPE} ${VALUE}"
rctl -a jail:"${_jail}":"${OPTION}":deny="${VALUE}/jail"
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

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 list [-j] [release|template|(jail|container)|log|limit|(import|export|backup)].${COLOR_RESET}"
exit 1
error_exit "Usage: bastille list [-j] [release|template|(jail|container)|log|limit|(import|export|backup)]"
}
if [ $# -eq 0 ]; then

View File

@@ -0,0 +1,117 @@
#!/bin/sh
#
# Copyright (c) 2018-2021, 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
## 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 or type is not "nullfs"
if [ ! -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
_jailpath="${bastille_jailsdir}/${_jail}/root/${_jailpath}"
_fstab_entry="${_hostpath} ${_jailpath} ${_type} ${_perms} ${_checks}"
## Create mount point if it does not exist. -- cwells
if [ ! -d "${bastille_jailsdir}/${_jail}/root/${_jailpath}" ]; then
if ! mkdir -p "${bastille_jailsdir}/${_jail}/root/${_jailpath}"; then
error_exit "Failed to create mount point inside jail."
fi
fi
## if entry doesn't exist, add; else show existing entry
if ! egrep -q "[[:blank:]]${_jailpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab" 2> /dev/null; then
if ! echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"; then
error_exit "Failed to create fstab entry: ${_fstab_entry}"
fi
echo "Added: ${_fstab_entry}"
else
egrep "[[:blank:]]${_jailpath}[[:blank:]]" "${bastille_jailsdir}/${_jail}/fstab"
fi
mount -F "${bastille_jailsdir}/${_jail}/fstab" -a
echo
done

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 TARGET command [args]"
}
# Handle special-case commands first.
@@ -42,22 +41,12 @@ 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 | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
jexec -l "${_jail}" /usr/sbin/pkg "$@"
echo
done

View File

@@ -1,5 +1,8 @@
#!/bin/sh
#
# Copyright (c) 2018-2021, 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:
#
@@ -25,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 rdr TARGET [clear] | [list] | [tcp <host_port> <jail_port>] | [udp <host_port> <jail_port>]${COLOR_RESET}"
exit 1
error_exit "Usage: bastille rdr TARGET [clear|list|(tcp|udp host_port jail_port)]"
}
# Handle special-case commands first.
@@ -49,37 +51,48 @@ shift
# Can only redirect to single jail
if [ "${TARGET}" = 'ALL' ]; then
echo -e "${COLOR_RED}Can only redirect to single jail${COLOR_RESET}"
exit 1
error_exit "Can only redirect to a single jail."
fi
# Check jail name valid
# Check if jail name is valid
JAIL_NAME=$(jls -j "${TARGET}" name 2>/dev/null)
if [ -z "${JAIL_NAME}" ]; then
echo -e "${COLOR_RED}Jail not found: ${TARGET}${COLOR_RESET}"
exit 1
error_exit "Jail not found: ${TARGET}"
fi
# Check jail ip4 address valid
JAIL_IP=$(jls -j "${TARGET}" ip4.addr 2>/dev/null)
if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
echo -e "${COLOR_RED}Jail IP not found: ${TARGET}${COLOR_RESET}"
exit 1
# Check if jail ip4 address (ip4.addr) is valid (non-VNET only)
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
JAIL_IP=$(jls -j "${TARGET}" ip4.addr 2>/dev/null)
if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
error_exit "Jail IP not found: ${TARGET}"
fi
fi
# Check rdr-anchor is setup in pf.conf
# Check if rdr-anchor is defined in pf.conf
if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
echo -e "${COLOR_RED}rdr-anchor not found in pf.conf${COLOR_RESET}"
exit 1
error_exit "rdr-anchor not found in pf.conf"
fi
# Check ext_if is setup in pf.conf
# Check if ext_if is defined in pf.conf
EXT_IF=$(grep '^[[:space:]]*ext_if[[:space:]]*=' /etc/pf.conf)
if [ -z "${JAIL_NAME}" ]; then
echo -e "${COLOR_RED}ext_if not defined in pf.conf${COLOR_RESET}"
exit 1
if [ -z "${EXT_IF}" ]; then
error_exit "ext_if not defined in pf.conf"
fi
# function: write rule to rdr.conf
persist_rdr_rule() {
if ! grep -qs "$1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then
echo "$1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"
fi
}
# function: load rdr rule via pfctl
load_rdr_rule() {
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
printf '%s\nrdr pass on $ext_if inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$1" "$2" "$JAIL_IP" "$3" ) \
| pfctl -a "rdr/${JAIL_NAME}" -f-
}
while [ $# -gt 0 ]; do
case "$1" in
list)
@@ -90,22 +103,12 @@ while [ $# -gt 0 ]; do
pfctl -a "rdr/${JAIL_NAME}" -Fn
shift
;;
tcp)
tcp|udp)
if [ $# -lt 3 ]; then
usage
fi
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
printf '%s\nrdr on $ext_if inet proto tcp to port %d -> %s port %d\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
| pfctl -a "rdr/${JAIL_NAME}" -f-
shift 3
;;
udp)
if [ $# -lt 3 ]; then
usage
fi
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
printf '%s\nrdr on $ext_if inet proto udp to port %d -> %s port %d\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
| pfctl -a "rdr/${JAIL_NAME}" -f-
persist_rdr_rule $1 $2 $3
load_rdr_rule $1 $2 $3
shift 3
;;
*)

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,18 +28,21 @@
# 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 rename [TARGET] [NEW_NAME].${COLOR_RESET}"
exit 1
error_exit "Usage: bastille rename TARGET NEW_NAME"
}
error_notify() {
# Notify message on error and exit
echo -e "$*" >&2
exit 1
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
@@ -49,29 +52,22 @@ help|-h|--help)
;;
esac
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
if [ $# -ne 1 ]; then
usage
fi
TARGET="${1}"
NEWNAME="${2}"
shift
if echo "${NEWNAME}" | grep -q "[.]"; then
echo -e "${COLOR_RED}Container names may not contain a dot(.)!${COLOR_RESET}"
exit 1
fi
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}"
sed -i '' "s|host.hostname.*=.*${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}"
sed -i '' "s|exec.consolelog.*=.*;|exec.consolelog = ${bastille_logsdir}/${NEWNAME}_console.log;|" "${JAIL_CONFIG}"
sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${NEWNAME}/root;|" "${JAIL_CONFIG}"
sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${NEWNAME}/fstab;|" "${JAIL_CONFIG}"
sed -i '' "s|${TARGET}.*{|${NEWNAME} {|" "${JAIL_CONFIG}"
fi
fi
}
@@ -94,40 +90,61 @@ update_fstab() {
change_name() {
# Attempt container name change
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_GREEN}Attempting to rename '${TARGET}' to ${NEWNAME}...${COLOR_RESET}"
if [ "${bastille_zfs_enable}" = "YES" ]; then
if [ -n "${bastille_zfs_zpool}" ]; then
# Rename ZFS dataset and mount points accordingly
zfs rename "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}"
zfs set mountpoint="${bastille_jailsdir}/${NEWNAME}/root" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root"
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
else
error_notify "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
fi
# Update jail configuration files accordingly
update_jailconf
update_fstab
# Remove the old jail directory if exist
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
rm -r "${bastille_jailsdir}/${TARGET}"
fi
# Check exit status and notify
if [ "$?" -ne 0 ]; then
error_notify "${COLOR_RED}An error has occurred while attempting to rename '${TARGET}'.${COLOR_RESET}"
error_exit "An error has occurred while attempting to rename '${TARGET}'."
else
echo -e "${COLOR_GREEN}Renamed '${TARGET}' to '${NEWNAME}' successfully.${COLOR_RESET}"
info "Renamed '${TARGET}' to '${NEWNAME}' successfully."
fi
}
# Check if container is running
if [ -n "$(jls name | awk "/^${TARGET}$/")" ]; then
error_notify "${COLOR_RED}${TARGET} is running, See 'bastille stop'.${COLOR_RESET}"
## 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

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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,12 @@ help|-h|--help)
;;
esac
if [ $# -lt 2 ]; then
if [ $# -ne 2 ]; then
usage
fi
TARGET=$1
shift
if [ "${TARGET}" = 'ALL' ]; then
JAILS=$(jls name)
fi
if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(jls name | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
jexec -l "${_jail}" /usr/sbin/service "$@"
echo
done

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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.
@@ -57,28 +56,37 @@ if [ "${TARGET}" != 'ALL' ]; then
JAILS=$(bastille list jails | awk "/^${TARGET}$/")
## check if exist
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_RED}[${TARGET}]: Not found.${COLOR_RESET}"
error_exit "[${TARGET}]: Not found."
fi
fi
for _jail in ${JAILS}; do
## test if running
if [ "$(jls name | awk "/^${_jail}$/")" ]; then
echo -e "${COLOR_RED}[${_jail}]: Already started.${COLOR_RESET}"
error_notify "[${_jail}]: Already started."
## test if not running
elif [ ! "$(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
## warn if matching configured (but not online) ip4.addr, ignore if there's no ip4.addr entry
ip=$(grep 'ip4.addr' "${bastille_jailsdir}/${_jail}/jail.conf" | awk '{print $3}' | sed 's/\;//g')
if [ -n "${ip}" ]; then
if ifconfig | grep -w "${ip}" >/dev/null; then
echo -e "${COLOR_RED}Error: IP address (${ip}) already in use.${COLOR_RESET}"
exit 1
error_notify "Error: IP address (${ip}) already in use."
continue
fi
fi
## start the container
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -c "${_jail}"
## add rctl limits
@@ -88,9 +96,18 @@ for _jail in ${JAILS}; do
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
## add ip4.addr to firewall table:jails
if grep "interface = ${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
pfctl -q -t jails -T add "$(jls -j "${_jail}" ip4.addr)"
if [ -n "${bastille_network_loopback}" ]; then
if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
pfctl -q -t jails -T add "$(jls -j ${_jail} ip4.addr)"
fi
fi
fi
echo

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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,32 +42,22 @@ 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 | awk "/^${TARGET}$/")
## check if exist or not running
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
echo -e "${COLOR_RED}[${TARGET}]: Not found.${COLOR_RESET}"
elif [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
echo -e "${COLOR_RED}[${TARGET}]: Not started.${COLOR_RESET}"
fi
fi
for _jail in ${JAILS}; do
## test if running
if [ "$(jls name | awk "/^${_jail}$/")" ]; then
## remove ip4.addr from firewall table:jails
if grep "interface = ${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
pfctl -q -t jails -T delete "$(jls -j "${_jail}" ip4.addr)"
if [ -n "${bastille_network_loopback}" ]; then
if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then
pfctl -q -t jails -T delete "$(jls -j ${_jail} ip4.addr)"
fi
fi
if [ "$(bastille rdr ${_jail} list)" ]; then
bastille rdr ${_jail} clear
fi
## remove rctl limits
@@ -79,7 +68,7 @@ for _jail in ${JAILS}; do
fi
## stop container
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}"
fi
echo

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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,12 @@ 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 | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
jexec -l "${_jail}" /usr/sbin/sysrc "$@"
echo -e "${COLOR_RESET}"
done

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,12 +28,81 @@
# 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
bastille_usage() {
echo -e "${COLOR_RED}Usage: bastille template TARGET project/template.${COLOR_RESET}"
exit 1
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.
@@ -43,243 +112,275 @@ help|-h|--help)
;;
esac
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
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 | awk "/^${TARGET}$/")
fi
## global variables
TEMPLATE="${1}"
shift
if [ ! -d "${bastille_templatesdir}/${TEMPLATE}" ]; then
echo -e "${COLOR_RED}${TEMPLATE} not found.${COLOR_RESET}"
exit 1
bastille_template=${bastille_templatesdir}/${TEMPLATE}
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?://github.com/*/*|http?://gitlab.com/*/*)
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
error_exit "${TEMPLATE} not found."
fi
;;
*)
error_exit "Template name/URL not recognized."
esac
if [ -z "${JAILS}" ]; then
echo -e "${COLOR_RED}Container ${TARGET} is not running.${COLOR_RESET}"
exit 1
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
## global variables
bastille_template=${bastille_templatesdir}/${TEMPLATE}
for _jail in ${JAILS}; do
info "[${_jail}]:"
info "Applying template: ${TEMPLATE}..."
## jail-specific variables.
bastille_jail_path=$(jls -j "${_jail}" path)
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then
_jail_ip=$(jls -j "${_jail}" ip4.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 -qw "${_jail}" "${bastille_template}/TARGET"; then
echo -e "${COLOR_GREEN}TARGET: !${_jail}.${COLOR_RESET}"
info "TARGET: !${_jail}."
echo
continue
fi
if ! grep -Eq "(^|\b)(${_jail}|ALL)($|\b)" "${bastille_template}/TARGET"; then
echo -e "${COLOR_GREEN}TARGET: ?${_jail}.${COLOR_RESET}"
info "TARGET: ?${_jail}."
echo
continue
fi
fi
## LIMITS (RCTL)
if [ -s "${bastille_template}/LIMITS" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:LIMITS -- START${COLOR_RESET}"
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"
continue
fi
while read _limits; do
## define the key and value
_limit_key=$(echo "${_limits}" | awk '{print $1}')
_limit_value=$(echo "${_limits}" | awk '{print $2}')
_rctl_rule="jail:${_jail}:${_limit_key}:deny=${_limit_value}/jail"
## if entry doesn't exist, add; else show existing entry
if ! grep -qs "${_rctl_rule}" "${bastille_jailsdir}/${_jail}/rctl.conf"; then
echo "${_rctl_rule}" >> "${bastille_jailsdir}/${_jail}/rctl.conf"
echo "${_limits}"
else
echo "${_limits}"
# Build a list of sed commands like this: -e 's/${username}/root/g' -e 's/${domain}/example.com/g'
# Values provided by default (without being defined by the user) are listed here. -- cwells
ARG_REPLACEMENTS="-e 's/\${JAIL_IP}/${_jail_ip}/g' -e 's/\${JAIL_NAME}/${_jail}/g'"
# 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
## apply limits to system
rctl -a "${_rctl_rule}" || exit 1
done < "${bastille_template}/LIMITS"
echo -e "${COLOR_GREEN}[${_jail}]:LIMITS -- END${COLOR_RESET}"
echo
_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
## INCLUDE
if [ -s "${bastille_template}/INCLUDE" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:INCLUDE -- START${COLOR_RESET}"
while read _include; do
echo
echo -e "${COLOR_GREEN}INCLUDE: ${_include}${COLOR_RESET}"
echo -e "${COLOR_GREEN}Bootstrapping ${_include}...${COLOR_RESET}"
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}")
case ${_include} in
http?://github.com/*/*|http?://gitlab.com/*/*)
bastille bootstrap "${_include}"
;;
*/*)
BASTILLE_TEMPLATE_USER=$(echo "${_include}" | awk -F / '{ print $1 }')
BASTILLE_TEMPLATE_REPO=$(echo "${_include}" | awk -F / '{ print $2 }')
bastille template "${_jail}" "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
;;
*)
echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}"
exit 1
;;
# 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
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
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
## 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
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}'
## FSTAB
if [ -s "${bastille_template}/FSTAB" ]; then
echo -e "${COLOR_GREEN}[${_jail}]:FSTAB -- START${COLOR_RESET}"
while read _fstab; do
## 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}')
# 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
## if any variables are empty, bail out
if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z "${_perms}" ] || [ -z "${_checks}" ]; then
echo -e "${COLOR_RED}FSTAB format not recognized.${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
exit 1
fi
## if host path doesn't exist or type is not "nullfs"
if [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then
echo -e "${COLOR_RED}Detected invalid host path or incorrect mount type in FSTAB.${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
exit 1
fi
## if mount permissions are not "ro" or "rw"
if [ "${_perms}" != "ro" ] && [ "${_perms}" != "rw" ]; then
echo -e "${COLOR_RED}Detected invalid mount permissions in FSTAB.${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
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
echo -e "${COLOR_RED}Detected invalid fstab options in FSTAB.${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Format: /host/path jail/path nullfs ro 0 0${COLOR_RESET}"
echo -e "${COLOR_YELLOW}Read: ${_fstab}${COLOR_RESET}"
exit 1
fi
## aggregate variables into FSTAB entry
_fstab_entry="${_hostpath} ${bastille_jailsdir}/${_jail}/root/${_jailpath} ${_type} ${_perms} ${_checks}"
## if entry doesn't exist, add; else show existing entry
if ! grep -q "${_jailpath}" "${bastille_jailsdir}/${_jail}/fstab"; then
echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab"
echo "Added: ${_fstab_entry}"
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
grep "${_jailpath}" "${bastille_jailsdir}/${_jail}/fstab"
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
done < "${bastille_template}/FSTAB"
mount -F "${bastille_jailsdir}/${_jail}/fstab" -a
echo -e "${COLOR_GREEN}[${_jail}]:FSTAB -- END${COLOR_RESET}"
echo
fi
info "[${_jail}]:${_hook} -- END"
echo
fi
done
## PF
if [ -s "${bastille_template}/PF" ]; then
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 install $(cat "${bastille_template}/PKG") || exit 1
jexec -l "${_jail}" env ASSUME_ALWAYS_YES=YES /usr/sbin/pkg audit -F
echo -e "${COLOR_GREEN}[${_jail}]:PKG -- 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
## 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

View 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

View File

@@ -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}"

View File

@@ -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}"

View File

@@ -0,0 +1,13 @@
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 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

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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,12 @@ 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 | awk "/^${TARGET}$/")
fi
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
jexec -l "${_jail}" /usr/bin/top
echo -e "${COLOR_RESET}"
done

View File

@@ -0,0 +1,72 @@
#!/bin/sh
#
# Copyright (c) 2018-2021, 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
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

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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|container].${COLOR_RESET}"
exit 1
error_exit "Usage: bastille update [release|container] | [option]"
}
# Handle special-case commands first.
@@ -43,46 +42,72 @@ help|-h|--help)
;;
esac
if [ $# -gt 1 ] || [ $# -lt 1 ]; then
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
usage
fi
TARGET="${1}"
shift
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 freebsd-version | grep -qi HBSD; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1
error_exit "Not yet supported on HardenedBSD."
fi
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
if ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
if [ "$(jls name | awk "/^${TARGET}$/")" ]; then
# Update a thick container.
CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null)
if [ -z "${CURRENT_VERSION}" ]; then
echo -e "${COLOR_RED}Can't determine '${TARGET}' version.${COLOR_RESET}"
exit 1
else
env PAGER="/bin/cat" freebsd-update --not-running-from-cron -b "${bastille_jailsdir}/${TARGET}/root" \
fetch install --currently-running "${CURRENT_VERSION}"
fi
else
echo -e "${COLOR_RED}${TARGET} is not running.${COLOR_RESET}"
echo -e "${COLOR_RED}See 'bastille start ${TARGET}'.${COLOR_RESET}"
exit 1
fi
jail_check() {
# Check if the jail is thick and is running
if [ ! "$(jls name | awk "/^${TARGET}$/")" ]; then
error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'."
else
echo -e "${COLOR_RED}${TARGET} is not a thick container.${COLOR_RESET}"
exit 1
if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
error_exit "${TARGET} is not a thick container."
fi
fi
else
}
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
# Update container base(affects child containers).
env PAGER="/bin/cat" freebsd-update --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" \
fetch install --currently-running "${TARGET}"
else
echo -e "${COLOR_RED}${TARGET} not found. See bootstrap.${COLOR_RESET}"
exit 1
error_exit "${TARGET} not found. See 'bastille bootstrap'."
fi
}
# Check what we should update
if echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
release_update
else
jail_update
fi

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -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 | [option]"
}
# Handle special-case commands first.
@@ -43,23 +42,105 @@ help|-h|--help)
;;
esac
if [ $# -gt 2 ] || [ $# -lt 2 ]; then
if [ $# -gt 3 ] || [ $# -lt 2 ]; then
usage
fi
RELEASE="$1"
shift
NEWRELEASE="$1"
TARGET="$1"
NEWRELEASE="$2"
OPTION="$3"
# Check for unsupported actions
if [ "${TARGET}" = "ALL" ]; then
error_exit "Batch upgrade is unsupported."
fi
if freebsd-version | grep -qi HBSD; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1
error_exit "Not yet supported on HardenedBSD."
fi
# Handle options
case "${OPTION}" in
-f|--force)
OPTION="-F"
;;
*)
OPTION=
;;
esac
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" -r "${NEWRELEASE}" upgrade
jail_check() {
# Check if the jail is thick and is running
if [ ! "$(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"; 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

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,25 +28,22 @@
# 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
bastille_usage() {
echo -e "${COLOR_RED}Usage: bastille verify [release|template].${COLOR_RESET}"
exit 1
error_exit "Usage: bastille verify [release|template]"
}
verify_release() {
if freebsd-version | grep -qi HBSD; then
echo -e "${COLOR_RED}Not yet supported on HardenedBSD.${COLOR_RESET}"
exit 1
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
echo -e "${COLOR_RED}${RELEASE} not found. See bootstrap.${COLOR_RESET}"
exit 1
error_exit "${RELEASE} not found. See 'bastille bootstrap'."
fi
}
@@ -54,28 +51,26 @@ verify_template() {
_template_path=${bastille_templatesdir}/${BASTILLE_TEMPLATE}
_hook_validate=0
for _hook in TARGET INCLUDE PRE OVERLAY FSTAB PF PKG SYSRC SERVICE CMD; do
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))
echo -e "${COLOR_GREEN}Detected ${_hook} hook.${COLOR_RESET}"
info "Detected ${_hook} hook."
## line count must match newline count
if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
echo -e "${COLOR_RED}${BASTILLE_TEMPLATE}:${_hook} [failed].${COLOR_RESET}"
echo -e "${COLOR_RED}Line numbers don't match line breaks.${COLOR_RESET}"
info "[${_hook}]:"
error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]."
error_notify "Line numbers don't match line breaks."
echo
echo -e "${COLOR_RED}Template validation failed.${COLOR_RESET}"
exit 1
error_exit "Template validation failed."
## if INCLUDE; recursive verify
elif [ ${_hook} = 'INCLUDE' ]; then
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
info "[${_hook}]:"
cat "${_path}"
echo
while read _include; do
echo -e "${COLOR_GREEN}[${_hook}]:[${_include}]:${COLOR_RESET}"
info "[${_hook}]:[${_include}]:"
case ${_include} in
http?://github.com/*/*|http?://gitlab.com/*/*)
@@ -87,19 +82,18 @@ verify_template() {
bastille verify "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
;;
*)
echo -e "${COLOR_RED}Template INCLUDE content not recognized.${COLOR_RESET}"
exit 1
error_exit "Template INCLUDE content not recognized."
;;
esac
done < "${_path}"
## if tree; tree -a bastille_template/_dir
elif [ ${_hook} = 'OVERLAY' ]; then
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
info "[${_hook}]:"
cat "${_path}"
echo
while read _dir; do
echo -e "${COLOR_GREEN}[${_hook}]:[${_dir}]:${COLOR_RESET}"
info "[${_hook}]:[${_dir}]:"
if [ -x /usr/local/bin/tree ]; then
/usr/local/bin/tree -a "${_template_path}/${_dir}"
else
@@ -108,7 +102,7 @@ verify_template() {
echo
done < "${_path}"
else
echo -e "${COLOR_GREEN}[${_hook}]:${COLOR_RESET}"
info "[${_hook}]:"
cat "${_path}"
echo
fi
@@ -117,15 +111,15 @@ verify_template() {
## remove bad templates
if [ ${_hook_validate} -lt 1 ]; then
echo -e "${COLOR_RED}No valid template hooks found.${COLOR_RESET}"
echo -e "${COLOR_RED}Template discarded.${COLOR_RESET}"
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
echo -e "${COLOR_GREEN}Template ready to use.${COLOR_RESET}"
info "Template ready to use."
fi
}

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2018-2020, Christer Edwards <christer.edwards@gmail.com>
# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,17 +28,16 @@
# 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}"
info "[${_jail}]:"
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
echo
done
@@ -46,7 +45,7 @@ done
zfs_set_value() {
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
echo
done
@@ -54,7 +53,7 @@ done
zfs_get_value() {
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
info "[${_jail}]:"
zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
echo
done
@@ -62,7 +61,7 @@ done
zfs_disk_usage() {
for _jail in ${JAILS}; do
echo -e "${COLOR_GREEN}[${_jail}]:${COLOR_RESET}"
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
@@ -77,44 +76,29 @@ esac
## 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 | awk "/^${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
;;
df|usage)