More readme, more security

This commit is contained in:
Samuel Aubertin 2023-09-21 19:48:53 +02:00
parent 180159c8ab
commit d616996ddf
6 changed files with 115 additions and 58 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
src/cache/
.vagrant

View File

@ -1,5 +1,5 @@
```
██████ ██ ▄█▀▒███████▒ ▒█████ ██▓███ ▄▄▄ ▄████▄ ██ ▄█▀
██████ ██ ▄█▀▒███████▒ ▒█████ ██▓███ ██▄ ▄████▄ ██ ▄█▀
▒██ ▒ ██▄█▒ ▒ ▒ ▒ ▄▀░ ▒██▒ ██▒▓██░ ██ ▒████▄ ▒██▀ ▀█ ██▄█▒
░ ▓██▄ ▓███▄░ ░ ▒ ▄▀▒ ▓▒█ ▒██░ ██▒▓██░ ██▓▒▒██ ▀█▄ ▒▓█ ▄ ▓███▄░
▒ ██▒▓██ █▄ ▄▀▒ ░▒ ▒██ ██░▒██▄█▓▒ ▒░██▄▄▄▄██ ▒▓▓▄ ▄██▒▓██ █▄
@ -12,7 +12,9 @@
-----
*Samuel 'sk4nz' AUBERTIN*
**skz-opack** enables simple execution of [OpenBSD](https://www.openbsd.org) virtual machines from a Linux host or Google Cloud Compute, leveraging Packer and Vagrant, from a Makefile target named `opack`.
**skz-opack** is an automated [OpenBSD](https://www.openbsd.org) bootstrapper.
Leveraging Packer, Vagrant boxes and a bit of black magic (also known as scripting) it enables frictionless execution of this wonderful operating system within a local virtual machine from a Linux host. It can also emit a compliant Google Compute Engine image, ran in the cloud using Terraform.
## Instructions
@ -28,21 +30,45 @@ To get started with **skz-opack**, follow these steps:
- [Vagrant](https://www.vagrantup.com/)
- [Vagrant-Libvirt module](https://github.com/vagrant-libvirt/vagrant-libvirt)
3. Use the project by including `path/to/skz-opack/src/opack.mk` and invoking the `opack` target in your Makefile to create and manage OpenBSD virtual machines with Packer and Vagrant.
## Architecture
3. Use the project by including `path/to/skz-opack/src/opack.mk` and invoking the `opack` target in your Makefile to create a local OpenBSD virtual machine with Packer and Vagrant. Use the 'opack-cloud' target to run the same virtual machine in GCP with Terraform.
## Available make targets
Available make target are:
- `opack`
- `opack-cloud`
- `opack-clean`
- `opack-cleancache`
- `opack-cleanall`
- `opack`: downloads, installs an run OpenBSD in a local VM.
- `opack-cloud`: same as 'opack' but in the GCP cloud.
- `opack-clean`: Destroys the local/cloud VM.
- `opack-cleancache`: Removes the cache containing installation isos and Vagrant boxes.
- `opack-cleanall`: 'opack-clean' and 'opack-cleancache'
## Overridable default options
Every default option ending with an `?` in "src/options.mk" can be overrided in the invoking Makefile. Here is an short list of theses:
- `OPACK_SYS_HOSTNAME`: VM hostname
- `OPACK_SYS_USER`: username to create
- `OPACK_SYS_PASSWORD`: user password
- `OPACK_SYS_DISK_SIZE`: VM disk size, in megabytes
- `OPACK_SYS_MEMORY`: VM RAM, in megabytes
- `OPACK_SYS_CPU`: VM cpu count
- `OPACK_SYS_SERVER`: OpenBSD package mirror
- `OPACK_SYS_ARCHITECTURE`: OpenBSD platform to use (only *amd64* has been tested)
- `OPACK_SYS_RELEASE`: OpenBSD release name aka *74*
- `OPACK_SYS_VERSION`: OpenBSD version aka *7.4* or *snapshots*
- `OPACK_SYS_XENOCARA`: Install Xenocara, the OpenBSD X11 fork
- `OPACK_SYS_SETS`: OpenBSD sets to install
- `OPACK_SYS_TIMEZONE`: Timezone decalred at installation
- `OPACK_SYS_SSH_KEY`: The SSH public key added to the created user
- `OPACK_SYS_ISO_URL`: The installation iso URL
- `OPACK_SYS_ISO_SHA256SUM`: The installation iso SHA256 sum
- `OPACK_SYS_SETS_LOCATION`: The location of installed OpenBSD sets eg *http* or *cd0*
- `OPACK_NO_SIGCHK`: Ignore unsigned sets
- `OPACK_SYS_HEADLESS`: Run Packer installation in headless mode
- `OPACK_AUTODISKLABEL_FILE`: OpenBSD partitioning scheme for installation
- `OPACK_PROVISION_FILE`: Script executed after installation
- `OPACK_RUNTIME_PROVISION_FILE`: Script executed after VM creation
## Examples
### Quick example
Here is the shortest Makefile that can be used to leverage skz-opack:
@ -52,14 +78,13 @@ OPACK_TARGET= demo # the VM name
include path/to/src/opack.mk # mandatory
```
After invokation with `make opack`, it will download, install, and run the latest OpenBSD release in a local VM.
After invokation with `make opack`, it will download, install, and run the latest OpenBSD release in a local VM with the default options.
Once executed, the VM is running and it is possible to log into it using the `vagrant ssh` command.
Then, `make clean` will remove the VM, but not the vagrant box (in order to clean everythin, use `make cleancache`).
Then, `make clean` will remove the VM, but not the vagrant box (in order to clean everything, use `make cleancache`).
### Complex Example
In this example, we will demonstrate how to use **skz-opack** to create an OpenBSD -current virtual machine with 4 CPUs, 1GB of RAM, and name it "run-current."
### Overrides Example
In this example, we will demonstrate how to use overrides in **skz-opack** to create an OpenBSD *-current* virtual machine named "run-current" with 4 CPUs and 1GB of RAM.
```make
OPACK_TARGET= run-current
OPACK_SYS_VERSION= snapshots
@ -81,7 +106,7 @@ In this Makefile:
Making "opack" a dependency target of "all" will ensure **skz-opack** operates before any command in the "all" target. Try it with `make all` !
Once the "opack" target dependency is finished, the Vm is running and the system kernel version is outputted. This example showcases how to customize and run **skz-opack** for your specific needs. Every option ending with an `?` in "src/options.mk" can be overrided in the invoking Makefile.
Once the "opack" target dependency is finished, the VM is running and the system kernel version is outputted. This example showcases how to customize and run **skz-opack** for your specific needs.
### GCP example
@ -89,13 +114,22 @@ TODO
## Troubleshooting
Overrides should happen before the include of "opack.mk".
- To enable debug mode, you can declare 'OPACK_DEBUG=yes' either in your Makefile or at runtime with: 'OPACK_DEBUG=yes make opack'.
- Overrides should happen before the include of "opack.mk".
## Structure
## Architecture
### Security
`OPACK_SYS_USER` can become *root* using the `doas` command.
The `autodisklabel` used for this project is flat, so partitions don't benefit from *nodev*, *nosuid* and *wxallowed* protections.
### Code structure
In the "src" directory, are located the following files:
- **autodisklabel**: This file provides the partitioning layout for the installer and can be customized by using the `OPACK_AUTODISKLABEL_FILE` option.
- **autodisklabel**: This file provides the partitioning layout for the installer and can be customized by using the `OPACK_AUTODISKLABEL_FILE` option.
- **defines.mk**: Contains internal skz-opack definitions for Packer and Vagrant.
- **opack.mk**: To use skz-opack in your projects, simply include this file in your Makefiles.
- **opack-provision.sh**: This file is executed for post-installation provisioning with Packer and can be customized using the `OPACK_PROVISION_FILE` option.

View File

@ -6,11 +6,11 @@ set +x
echo OPACK: Starting provisioning.
sysctl -n kern.version
printf 'permit nopass :wheel\n' > /etc/doas.conf
printf 'PasswordAuthentication yes\nPermitRootLogin yes\n' >> /etc/ssh/sshd_config
pkg_add -u 2> /dev/null || pkg_add -u -D snap 2> /dev/null
rm -f /etc/ssh/ssh_host*
find /var/log -type f | while read f; do echo -ne '' > $f; done
find /tmp -type f | while read f; do echo -ne '' > $f; done
for part in $(df | tail -n+2 | awk '{print $6}'); do dd if=/dev/zero of=$part/EMPTY bs=1M || true; rm -f $part/EMPTY || true; done
sync
sync
echo OPACK: provisionning done.

View File

@ -1,9 +1,17 @@
.PHONY: clean cleancache cleanall opack
.DEFAULT_GOAL := opack
# Enable debugging mode if OPACK_DEBUG is set to 'yes'
OPACK_DEBUG=yes
ifndef OPACK_DEBUG
.SILENT:
endif
OPACK_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
define OPACK_BANNER
██████ ██ ▄█▀▒███████▒ ▒█████ ██▓███ ▄▄▄ ▄████▄ ██ ▄█▀
██████ ██ ▄█▀▒███████▒ ▒█████ ██▓███ ██▄ ▄████▄ ██ ▄█▀
▒██ ▒ ██▄█▒ ▒ ▒ ▒ ▄▀░ ▒██▒ ██▒▓██░ ██ ▒████▄ ▒██▀ ▀█ ██▄█▒
░ ▓██▄ ▓███▄░ ░ ▒ ▄▀▒ ▓▒█ ▒██░ ██▒▓██░ ██▓▒▒██ ▀█▄ ▒▓█ ▄ ▓███▄░
▒ ██▒▓██ █▄ ▄▀▒ ░▒ ▒██ ██░▒██▄█▓▒ ▒░██▄▄▄▄██ ▒▓▓▄ ▄██▒▓██ █▄
@ -29,65 +37,88 @@ include $(OPACK_DIR)/vagrantfile.mk
$(OPACK_PACKER_HTTP_DIR) $(OPACK_PACKER_DIR) ../$(OPACK_CACHE_DIR):
@mkdir -p $@
mkdir -p $@
$(OPACK_PACKER_DIR)/vagrant.key: | $(OPACK_PACKER_DIR)
@curl -s -o $@ https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant
curl -s -o $@ https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant
$(OPACK_PACKER_DIR)/opack.json: | $(OPACK_PACKER_DIR)
@printf '$(subst $(newline),\n,$(OPACK_PACKER_CONTENT))' > $@
printf '$(subst $(newline),\n,$(OPACK_PACKER_CONTENT))' > $@
$(OPACK_PACKER_DIR)/bucket.json:
@printf '{ "name": "$(GCE_BUCKET)", "location": "$(GCE_BUCKET_LOCATION)", "storageClass": "STANDARD", "iamConfiguration": {"uniformBucketLevelAccess": { "enabled": true }, } }' > $@
printf '{ "name": "$(GCE_BUCKET)", "location": "$(GCE_BUCKET_LOCATION)", "storageClass": "STANDARD", "iamConfiguration": {"uniformBucketLevelAccess": { "enabled": true }, } }' > $@
$(OPACK_PACKER_DIR)/opack-cloud.json: | $(OPACK_PACKER_DIR) $(OPACK_PACKER_DIR)/bucket.json
@printf '$(subst $(newline),\n,$(OPACK_PACKER_CLOUD_CONTENT))' > $@
@curl -X POST -s -o /dev/null \
printf '$(subst $(newline),\n,$(OPACK_PACKER_CLOUD_CONTENT))' > $@
curl -X POST -s -o /dev/null \
--data-binary @$(OPACK_PACKER_DIR)/bucket.json \
-H "Authorization: Bearer $(STORAGE_TOKEN)" \
-H "Content-Type: application/json" \
"https://storage.googleapis.com/storage/v1/b?project=$(GCE_PROJECT)"
@curl -X DELETE -s -o /dev/null \
curl -X DELETE -s -o /dev/null \
-H "Authorization: Bearer $(IMAGE_TOKEN)" \
"https://compute.googleapis.com/compute/v1/projects/$(GCE_PROJECT)/global/images/$(OPACK_TARGET)"
$(OPACK_PACKER_HTTP_DIR)/install.conf: | $(OPACK_PACKER_HTTP_DIR)
@printf '$(subst $(newline),\n,$(OPACK_INSTALL_CONTENT))' > $@
printf '$(subst $(newline),\n,$(OPACK_INSTALL_CONTENT))' > $@
$(OPACK_PACKER_HTTP_DIR)/autodisklabel: | $(OPACK_PACKER_HTTP_DIR)
@cp $(OPACK_AUTODISKLABEL_FILE) $@
cp $(OPACK_AUTODISKLABEL_FILE) $@
$(OPACK_PROVISION_FILE):
@echo you need to write $@ && exit 1
echo you need to write $@ && exit 1
../id_ed25519:
@ssh-keygen -q -t ed25519 -f $@ -N '""'
ssh-keygen -q -t ed25519 -f $@ -N '""'
$(OPACK_BOX_FILE): | $(OPACK_PACKER_DIR)/opack.json $(OPACK_PACKER_DIR)/vagrant.key $(OPACK_PROVISION_FILE) $(OPACK_PACKER_HTTP_DIR)/install.conf $(OPACK_PACKER_HTTP_DIR)/autodisklabel
@$(call spinner,cd $(OPACK_PACKER_DIR) && CHECKPOINT_DISABLE=1 PACKER_CACHE_DIR=../../$(OPACK_CACHE_DIR) packer build -timestamp-ui opack.json > opack.log || echo Error Autoinstalling: check $(OPACK_PACKER_DIR)/opack.log,█ Autoinstalling $(OPACK_BOX_TAG) with Packer)
ifndef OPACK_DEBUG
$(call spinner,cd $(OPACK_PACKER_DIR) && (CHECKPOINT_DISABLE=1 PACKER_CACHE_DIR=../../$(OPACK_CACHE_DIR) packer build -timestamp-ui opack.json > opack.log && rm -rf $(OPACK_PACKER_DIR)) || echo Error Autoinstalling: check $(OPACK_PACKER_DIR)/opack.log,█ Autoinstalling $(OPACK_BOX_TAG) with Packer)
else
cd $(OPACK_PACKER_DIR) && CHECKPOINT_DISABLE=1 PACKER_CACHE_DIR=../../$(OPACK_CACHE_DIR) packer build -timestamp-ui opack.json && rm -rf $(OPACK_PACKER_DIR)
endif
$(OPACK_META_FILE): $(OPACK_BOX_FILE)
@printf '$(subst $(OPACK_BOX_FILE_SHA256),$(shell sha256sum $(OPACK_BOX_FILE) | awk '{print $$1}'),$(subst $(newline),\n,$(OPACK_METADATA_CONTENT)))' > $@
@$(call spinner,vagrant box add -f --name $(OPACK_BOX_TAG) $(OPACK_META_FILE) > /dev/null,█ Adding $(OPACK_BOX_FILE) to Vagrant)
printf '$(subst $(OPACK_BOX_FILE_SHA256),$(shell sha256sum $(OPACK_BOX_FILE) | awk '{print $$1}'),$(subst $(newline),\n,$(OPACK_METADATA_CONTENT)))' > $@
ifndef OPACK_DEBUG
$(call spinner,vagrant box add -f --name $(OPACK_BOX_TAG) $(OPACK_META_FILE) > /dev/null,█ Adding $(OPACK_BOX_FILE) to Vagrant)
else
vagrant box add -f --name $(OPACK_BOX_TAG) $(OPACK_META_FILE)
endif
$(OPACK_VAGRANT_FILE):
@printf '$(subst $(newline),\n,$(OPACK_VAGRANT_CONTENT))' > $@
printf '$(subst $(newline),\n,$(OPACK_VAGRANT_CONTENT))' > $@
opack: $(OPACK_META_FILE) $(OPACK_VAGRANT_FILE)
@$(call spinner,vagrant up > /dev/null,█ Starting $(OPACK_HOSTNAME)-$(OPACK_TARGET) with Vagrant)
ifndef OPACK_DEBUG
$(call spinner,vagrant up > /dev/null,█ Starting $(OPACK_HOSTNAME)-$(OPACK_TARGET) with Vagrant)
else
vagrant up
endif
echo "█ skz-opack complete, run 'vagrant ssh' to connect to the machine"
opack-cloud: | $(OPACK_PACKER_DIR)/opack-cloud.json ../id_ed25519 $(OPACK_PROVISION_FILE) $(OPACK_PACKER_HTTP_DIR)/install.conf $(OPACK_PACKER_HTTP_DIR)/autodisklabel
@cd $(OPACK_PACKER_DIR) &&\
cd $(OPACK_PACKER_DIR) &&\
CHECKPOINT_DISABLE=1 PACKER_CACHE_DIR=../../$(OPACK_CACHE_DIR)\
packer build\
-timestamp-ui opack-cloud.json | tee -a ../$@ &&\
rm -rf $(OPACK_PACKER_DIR)
opack-clean:
@-$(call spinner,vagrant destroy -f >/dev/null; cd terraform_??????? 2>/dev/null && terraform destroy -auto-approve && cd .. && rm -rf terraform_???????; rm -rf $(OPACK_VAGRANT_FILE) opack_build_$(OPACK_SHORT_REV) *.log ssh-config .vagrant *.json,█ Cleaning up)
ifndef OPACK_DEBUG
-$(call spinner,vagrant destroy -f >/dev/null; cd terraform_??????? 2>/dev/null && terraform destroy -auto-approve && cd .. && rm -rf terraform_???????; rm -rf $(OPACK_VAGRANT_FILE) opack_build_$(OPACK_SHORT_REV) *.log ssh-config .vagrant *.json,█ Cleaning up)
else
-vagrant destroy -f
-cd terraform_??????? 2>/dev/null && terraform destroy -auto-approve && cd .. && rm -rf terraform_???????
-rm -rf $(OPACK_VAGRANT_FILE) opack_installer_$(OPACK_SHORT_REV) *.log ssh-config .vagrant *.json
endif
opack-cleancache:
@-$(call spinner,vagrant box remove -f --all $(OPACK_BOX_TAG) 2>/dev/null; rm -rf $(OPACK_CACHE_DIR),█ Cleaning up cache)
ifndef OPACK_DEBUG
-$(call spinner,vagrant box remove -f --all $(OPACK_BOX_TAG) 2>/dev/null; rm -rf $(OPACK_CACHE_DIR),█ Cleaning up cache)
else
-vagrant box remove -f --all $(OPACK_BOX_TAG) 2>/dev/null
-rm -rf $(OPACK_CACHE_DIR)
endif
opack-cleanall: clean cleancache
opack-cleanall: opack-clean opack-cleancache

View File

@ -1,20 +1,11 @@
# Enable debugging mode if OPACK_DEBUG is set to 'yes'
OPACK_DEBUG=yes
ifndef OPACK_DEBUG
.SILENT:
$(info OPACK_DEBUG)
else
endif
# Set the hostname of the virtual machine to 'opack' if not specified
OPACK_SYS_HOSTNAME?= opack
# Set the username for the virtual machine to 'opack' if not specified
OPACK_SYS_USER?= opack
OPACK_SYS_USER?= opack
# Set the password for the virtual machine to 'opack' if not specified
OPACK_SYS_PASSWORD?= opack
OPACK_SYS_PASSWORD?= opack
# Set the disk size of the virtual machine to 4096 MB if not specified
OPACK_SYS_DISK_SIZE?= 4096
@ -116,7 +107,7 @@ OPACK_AUTODISKLABEL_FILE?=$(OPACK_DIR)autodisklabel
OPACK_VAGRANT_FILE=Vagrantfile
# Define the runtime provisioning script for Vagrant
OPACK_RUNTIME_PROVISION_FILE?=$(OPACK_DIR)vagrant-provision.sh
OPACK_RUNTIME_PROVISION_FILE?=$(OPACK_DIR)vagrant-provision.sh
ifdef OPACK_DEBUG
$(infoBOX $(OPACK_BOX_FILE))

View File

@ -7,7 +7,7 @@ Vagrant.configure("2") do |config|
config.vm.define "$(OPACK_TARGET)"
config.vm.box = "$(OPACK_BOX_TAG)"
config.ssh.shell = "ksh -l"
config.ssh.username = "root"
config.ssh.username = "$(OPACK_SYS_USER)"
config.ssh.extra_args = "-tt"
config.ssh.sudo_command = "doas env %c"
config.vm.synced_folder ".", "/vagrant", disabled: true