mirror of
https://github.com/fscotto/infra.git
synced 2026-09-27 19:03:47 +00:00
Feature/aegis coreos (#7)
* feat(aegis): add ARM image bootstrap workflow * feat(aegis): manage firewall and SSH hardening * feat(aegis): harden Fedora IoT services * chore(aegis): remove local TLS configuration * fix(aegis): restore supported Fedora IoT bootstrap
This commit is contained in:
committed by
GitHub
parent
295f1a62ad
commit
ae1ca44aa7
@@ -1,32 +1,55 @@
|
||||
# Bootstrap monouso per Fedora CoreOS su Aegis.
|
||||
# Sostituire le chiavi SSH prima di generare Ignition con butane --strict.
|
||||
variant: fcos
|
||||
version: 1.6.0
|
||||
# One-time bootstrap for Fedora IoT on Aegis (Raspberry Pi 4).
|
||||
# Generate only: ./generate-aegis-ign.sh
|
||||
# Generate and write an SD card: ./generate-aegis-ign.sh --write IMAGE DEVICE
|
||||
# The write mode uses arm-image-installer with the RPi4 target and embeds
|
||||
# config.ign; it prompts for Wi-Fi credentials unless supplied through its
|
||||
# WIFI_SSID and WIFI_PASS environment variables.
|
||||
# For WiFi, the UEFI 'System Table Selection' must be DeviceTree (Esc at boot).
|
||||
variant: fiot
|
||||
version: 1.0.0
|
||||
passwd:
|
||||
users:
|
||||
- name: pi
|
||||
password_hash: "$6$bNDsU0XC5BxNJS5U$ENDGpdOUPJM3wcXBgNESCQkOqqQ9gN72/xEQoJsAI6QdsaY6mD4G5DBVIv7nHwHQOP35IH1oGRl.Uy3R2iUYQ1"
|
||||
groups:
|
||||
- wheel
|
||||
ssh_authorized_keys:
|
||||
- "ssh-ed25519 CHANGEME_AEGIS_SSH_PUBLIC_KEY"
|
||||
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINrIxXjA3ffPwziKGR5gzc4gAoBehQPlnEMcXF4Wl0ZS ikaros"
|
||||
systemd:
|
||||
units:
|
||||
- name: sshd.service
|
||||
enabled: true
|
||||
- name: rpm-ostree-install-wifi.service
|
||||
enabled: true
|
||||
contents: |
|
||||
[Unit]
|
||||
Description=Layer WiFi packages (driver, firmware, NetworkManager-wifi)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
Before=zincati.service
|
||||
ConditionPathExists=!/var/lib/%N.stamp
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/rpm-ostree install -y --allow-inactive NetworkManager-wifi NetworkManager-wwan wpa_supplicant wireless-regdb iw brcmfmac-firmware
|
||||
ExecStart=/bin/touch /var/lib/%N.stamp
|
||||
ExecStart=/bin/systemctl --no-block reboot
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
storage:
|
||||
disks:
|
||||
- device: /dev/mmcblk0
|
||||
wipe_table: false
|
||||
partitions:
|
||||
- label: aegis-data
|
||||
number: 5
|
||||
size_mib: 0
|
||||
filesystems:
|
||||
- device: /dev/disk/by-partlabel/aegis-data
|
||||
format: btrfs
|
||||
label: aegis-data
|
||||
wipe_filesystem: false
|
||||
mount:
|
||||
path: /
|
||||
options:
|
||||
- compress=zstd
|
||||
files:
|
||||
- path: /etc/hostname
|
||||
mode: 0644
|
||||
contents:
|
||||
inline: |
|
||||
aegis
|
||||
- path: /etc/sysctl.d/99-ip-forward.conf
|
||||
mode: 0644
|
||||
contents:
|
||||
inline: |
|
||||
net.ipv4.ip_forward = 1
|
||||
links:
|
||||
- path: /etc/localtime
|
||||
target: ../usr/share/zoneinfo/Europe/Rome
|
||||
|
||||
147
ansible/bootstrap/generate-aegis-ign.sh
Executable file
147
ansible/bootstrap/generate-aegis-ign.sh
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
BUTANE_IMAGE=${BUTANE_IMAGE:-quay.io/coreos/butane:release}
|
||||
BUTANE_SOURCE=${BUTANE_SOURCE:-"$SCRIPT_DIR/aegis.bu"}
|
||||
IGNITION_OUTPUT=${IGNITION_OUTPUT:-"$SCRIPT_DIR/config.ign"}
|
||||
SSH_PUBLIC_KEY=${SSH_PUBLIC_KEY:-"$HOME/.ssh/id_ed25519.pub"}
|
||||
WIFI_SECURITY=${WIFI_SECURITY:-wpa-psk}
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
generate-aegis-ign.sh
|
||||
generate-aegis-ign.sh --write IMAGE DEVICE
|
||||
|
||||
Environment overrides:
|
||||
BUTANE_IMAGE Butane container image (default: quay.io/coreos/butane:release)
|
||||
BUTANE_SOURCE Butane source path (default: aegis.bu beside this script)
|
||||
IGNITION_OUTPUT Ignition output path (default: config.ign beside this script)
|
||||
SSH_PUBLIC_KEY SSH public key passed to arm-image-installer
|
||||
WIFI_SSID Wi-Fi SSID; prompted if unset in --write mode
|
||||
WIFI_PASS Wi-Fi password; prompted if unset in --write mode
|
||||
WIFI_SECURITY Wi-Fi security type (default: wpa-psk)
|
||||
USAGE
|
||||
}
|
||||
|
||||
require_command() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
printf 'Error: required command not found: %s\n' "$1" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
read_required() {
|
||||
prompt=$1
|
||||
value=$2
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
printf '%s' "$prompt" >&2
|
||||
IFS= read -r value
|
||||
fi
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
printf '%s\n' 'Error: a value is required.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
read_secret() {
|
||||
value=$1
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
printf '%s' 'Wi-Fi password: ' >&2
|
||||
stty -echo
|
||||
IFS= read -r value
|
||||
stty echo
|
||||
printf '\n' >&2
|
||||
fi
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
printf '%s\n' 'Error: a value is required.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
write_image=false
|
||||
case $# in
|
||||
0)
|
||||
;;
|
||||
3)
|
||||
if [ "$1" != '--write' ]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
write_image=true
|
||||
IMAGE=$2
|
||||
DEVICE=$3
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
require_command podman
|
||||
|
||||
if [ ! -f "$BUTANE_SOURCE" ]; then
|
||||
printf 'Error: Butane source not found: %s\n' "$BUTANE_SOURCE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTPUT_DIR=$(dirname "$IGNITION_OUTPUT")
|
||||
if [ ! -d "$OUTPUT_DIR" ]; then
|
||||
printf 'Error: output directory not found: %s\n' "$OUTPUT_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
umask 077
|
||||
TEMP_OUTPUT=$(mktemp "$OUTPUT_DIR/.config.ign.XXXXXX")
|
||||
trap 'rm -f "$TEMP_OUTPUT"' EXIT HUP INT TERM
|
||||
|
||||
podman run --rm -i "$BUTANE_IMAGE" --strict < "$BUTANE_SOURCE" > "$TEMP_OUTPUT"
|
||||
mv "$TEMP_OUTPUT" "$IGNITION_OUTPUT"
|
||||
trap - EXIT HUP INT TERM
|
||||
|
||||
printf 'Generated Ignition config: %s\n' "$IGNITION_OUTPUT"
|
||||
|
||||
if [ "$write_image" = false ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f "$IMAGE" ]; then
|
||||
printf 'Error: image not found: %s\n' "$IMAGE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -b "$DEVICE" ]; then
|
||||
printf 'Error: target is not a block device: %s\n' "$DEVICE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$SSH_PUBLIC_KEY" ]; then
|
||||
printf 'Error: SSH public key not found: %s\n' "$SSH_PUBLIC_KEY" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_command arm-image-installer
|
||||
WIFI_SSID=$(read_required 'Wi-Fi SSID: ' "${WIFI_SSID:-}")
|
||||
WIFI_PASS=$(read_secret "${WIFI_PASS:-}")
|
||||
|
||||
printf 'Writing %s to %s.\n' "$IMAGE" "$DEVICE" >&2
|
||||
sudo arm-image-installer \
|
||||
--image="$IMAGE" \
|
||||
--target=rpi4 \
|
||||
--media="$DEVICE" \
|
||||
--ignition="$IGNITION_OUTPUT" \
|
||||
--addkey="$SSH_PUBLIC_KEY" \
|
||||
--resizefs \
|
||||
--wifi-ssid="$WIFI_SSID" \
|
||||
--wifi-pass="$WIFI_PASS" \
|
||||
--wifi-security="$WIFI_SECURITY"
|
||||
Reference in New Issue
Block a user