Skip to content

Commit

Permalink
chore: zap script
Browse files Browse the repository at this point in the history
  • Loading branch information
Frieder Paape committed Nov 15, 2024
1 parent c999955 commit 9f55786
Show file tree
Hide file tree
Showing 4 changed files with 515 additions and 50 deletions.
85 changes: 35 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@
# flashbox :zap: :package:

flashbox is an opinionated Confidential VM (CVM) base image designed to run podman pod payloads. It provides a simple way to deploy containerized applications in a secure environment.
flashbox is an opinionated Confidential VM (CVM) base image built for podman pod payloads. With a focus on security balanced against TCB size, designed to give developers the simplest path to TDX VMs.

## Why flashbox?

One command, `./zap` - and you've got yourself a TDX box.

⚠️ **IMPORTANT**: This is an early development release and is not production-ready software. Use with caution.

## Quick Start

1. Deploy the flashbox VM image
- [Bare Metal non-TDX](#bare-metal-non-tdx)
- [Bare Metal TDX](#bare-metal-tdx)
- [Azure Deployment](#azure-deployment)
- [GCP Deployment](#gcp-deployment)
1. Download the latest VM image from the releases page

2. Deploy the flashbox VM:
```bash
# Local deployment (non-TDX)
./zap --mode normal --image flashbox.raw

# Local deployment (TDX)
./zap --mode tdx --image flashbox.raw

# Azure deployment
./zap azure myvm eastus flashbox.azure.vhd

2. Provision and start your containers:
# GCP deployment
./zap gcp myvm us-east4 flashbox.tar.gz
```

### Known Issues

- Azure deployments may encounter an issue with the `--security-type` parameter. See [Azure CLI Issue #29207](https://github.com/Azure/azure-cli/issues/29207#issuecomment-2479343290) for the workaround.

### Considerations

⚠️ **WARNING**: Debug releases come with SSH enabled and a root user without password. Always use the `--ssh-source-ip` option to restrict SSH access in cloud deployments.
⚠️ **IMPORTANT**: If you want to run TDX VMs on bare metal you need to first setup your host environment properly. For this, follow the instructions in the [canonical/tdx](https://github.com/canonical/tdx) repo.

3. Provision and start your containers:
```bash
# Upload pod configuration and environment variables
curl -X POST -F "[email protected]" -F "env=@env" http://flashbox:24070/upload
Expand All @@ -22,16 +47,14 @@ curl -X POST http://flashbox:24070/start

## Pod Configuration

### Docker Compose Users

If you're coming from Docker Compose, you can convert your existing configurations to podman pod format. The pod configuration format is similar to Kubernetes manifests (YAML manifests).
### Docker Compose Migration

To convert a Docker Compose file to a podman pod configuration:
If you're coming from Docker Compose, you can convert your existing configurations:
```bash
podman-compose generate-k8s docker-compose.yml > pod.yaml
```

See the [official documentation on differences between Docker Compose and Podman](https://docs.podman.io/en/latest/markdown/podman-compose.1.html) for more details on migration.
See the [official documentation on differences between Docker Compose and Podman](https://docs.podman.io/en/latest/markdown/podman-compose.1.html) for migration details.

### Example Configuration

Expand All @@ -49,17 +72,12 @@ spec:
- name: web-container
image: nginx:latest
env:
- name: DB_HOST
value: "localhost"
- name: API_PORT
value: "3000"
- name: DATABASE_URL
value: "${DATABASE_URL}"
ports:
- containerPort: 80
hostPort: 8080
```
### Non-Attestable Variable Configuration
flashbox allows you to provision secrets and configuration variables that should remain outside the attestation flow. This is done through a separate `env` file that is processed independently of the pod configuration.
Expand All @@ -80,36 +98,3 @@ env:
```

Variables in the env file will be substituted into the pod configuration at runtime, keeping them separate from the attestation process. This is useful for both secrets and configuration that may vary between deployments.

## Deployment Options

### Bare Metal non-TDX
[TO BE FILLED: Bare metal non-TDX deployment instructions]

### Bare Metal TDX
[TO BE FILLED: Bare metal TDX deployment instructions]

### Azure Deployment
[TO BE FILLED: Azure deployment instructions]

### GCP Deployment
[TO BE FILLED: GCP deployment instructions]

## Security Considerations

- flashbox runs in a Confidential VM environment, providing enhanced security for your workloads
- Configuration variables can be separated from pod configurations using the env file
- The env file contents are not included in the attestation flow, providing flexibility for deployment-specific configurations

## API Endpoints

- `POST http://flashbox:24070/upload`: Upload pod configuration and environment files
- `POST http://flashbox:24070/start`: Start the configured containers

## Contributing

[TO BE FILLED: Contributing guidelines]

## License

[TO BE FILLED: License information]
165 changes: 165 additions & 0 deletions lib/bm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#!/bin/bash

usage() {
echo "Usage: $0 [options]"
echo "Options:"
echo " --mode <normal|tdx> VM mode (default: normal)"
echo " --image PATH Path to VM image (required)"
echo " --ram SIZE RAM size in GB (default: 32)"
echo " --cpus NUMBER Number of CPUs (default: 16)"
echo " --ssh-port PORT SSH port forwarding (default: 10022)"
echo " --ports PORTS Additional ports to open, comma-separated"
echo " --name STRING Process name (default: qemu-vm)"
echo " --log PATH Log file path (default: /tmp/qemu-guest.log)"
echo " --ovmf PATH Path to OVMF firmware (default: /usr/share/ovmf/OVMF.fd)"
echo " --help Show this help message"
exit 1
}

cleanup() {
rm -f /tmp/qemu-guest*.log &> /dev/null
rm -f /tmp/qemu-*-monitor.sock &> /dev/null

PID_QEMU=$(cat /tmp/qemu-pid.pid 2> /dev/null)
[ ! -z "$PID_QEMU" ] && echo "Cleanup, kill VM with PID: ${PID_QEMU}" && kill -TERM ${PID_QEMU} &> /dev/null
sleep 3
}

# Default values
MODE="normal"
RAM_SIZE="32"
CPUS="16"
SSH_PORT="10022"
ADDITIONAL_PORTS=""
PROCESS_NAME="qemu-vm"
LOGFILE="/tmp/qemu-guest.log"
OVMF_PATH="/usr/share/ovmf/OVMF.fd"

# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--mode)
MODE="$2"
shift 2
;;
--image)
VM_IMG="$2"
shift 2
;;
--ram)
RAM_SIZE="$2"
shift 2
;;
--cpus)
CPUS="$2"
shift 2
;;
--ssh-port)
SSH_PORT="$2"
shift 2
;;
--ports)
ADDITIONAL_PORTS="$2"
shift 2
;;
--name)
PROCESS_NAME="$2"
shift 2
;;
--log)
LOGFILE="$2"
shift 2
;;
--ovmf)
OVMF_PATH="$2"
shift 2
;;
--help)
usage
;;
*)
echo "Unknown option: $1"
usage
;;
esac
done

# Check required parameters
if [ -z "$VM_IMG" ]; then
echo "Error: VM image path is required"
usage
fi

# Verify mode
if [ "$MODE" != "normal" ] && [ "$MODE" != "tdx" ]; then
echo "Error: Invalid mode. Must be 'normal' or 'tdx'"
usage
fi

# Check KVM group membership
if ! groups | grep -qw "kvm"; then
echo "Please add user $USER to kvm group to run this script (usermod -aG kvm $USER and then log in again)."
exit 1
fi

# Clean up any existing instances
cleanup
if [ "$1" = "clean" ]; then
exit 0
fi

# Prepare port forwarding string
PORT_FORWARDS="-device virtio-net-pci,netdev=nic0 -netdev user,id=nic0,hostfwd=tcp::${SSH_PORT}-:22"

# Add default flashbox ports
PORT_FORWARDS="${PORT_FORWARDS},hostfwd=tcp::24070-:24070,hostfwd=tcp::24071-:24071"

# Add additional ports if specified
if [ ! -z "$ADDITIONAL_PORTS" ]; then
IFS=',' read -ra PORTS <<< "$ADDITIONAL_PORTS"
for port in "${PORTS[@]}"; do
PORT_FORWARDS="${PORT_FORWARDS},hostfwd=tcp::${port}-:${port}"
done
fi

# Base QEMU command
QEMU_CMD="qemu-system-x86_64 -D $LOGFILE \
-accel kvm \
-m ${RAM_SIZE}G -smp $CPUS \
-name ${PROCESS_NAME},process=${PROCESS_NAME},debug-threads=on \
-cpu host \
-nographic \
-nodefaults \
${PORT_FORWARDS} \
-drive file=${VM_IMG},if=none,id=virtio-disk0 \
-device virtio-blk-pci,drive=virtio-disk0 \
-bios ${OVMF_PATH} \
-chardev stdio,id=char0,mux=on,signal=off \
-mon chardev=char0 \
-serial chardev:char0 \
-pidfile /tmp/qemu-pid.pid"

# Add TDX-specific parameters if mode is tdx
if [ "$MODE" = "tdx" ]; then
QEMU_CMD="$QEMU_CMD \
-object '{\"qom-type\":\"tdx-guest\",\"id\":\"tdx\",\"quote-generation-socket\":{\"type\": \"vsock\", \"cid\":\"2\",\"port\":\"4050\"}}' \
-machine q35,kernel_irqchip=split,confidential-guest-support=tdx,hpet=off \
-device vhost-vsock-pci,guest-cid=4"
else
QEMU_CMD="$QEMU_CMD \
-machine q35"
fi

# Execute QEMU command
eval $QEMU_CMD

ret=$?
if [ $ret -ne 0 ]; then
echo "Error: Failed to create VM. Please check logfile \"$LOGFILE\" for more information."
exit $ret
fi

PID_QEMU=$(cat /tmp/qemu-pid.pid)

echo "VM started in $MODE mode with PID: ${PID_QEMU}"
echo "To login via SSH: ssh -p $SSH_PORT root@localhost"
Loading

0 comments on commit 9f55786

Please sign in to comment.