feat: add security hardening, AppArmor, and ARM64 Raspberry Pi support (Phase 6)
Security hardening: bind kubeconfig server to localhost, mount hardening (noexec/nosuid/nodev on tmpfs), sysctl network hardening, kernel module loading lock after boot, SHA256 checksum verification for downloads, kernel AppArmor + Audit support, complain-mode AppArmor profiles for containerd and kubelet, and security integration test. ARM64 Raspberry Pi support: piCore64 base extraction, RPi kernel build from raspberrypi/linux fork, RPi firmware fetch, SD card image with 4- partition GPT and tryboot A/B mechanism, BootEnv Go interface abstracting GRUB vs RPi boot environments, architecture-aware build scripts, QEMU aarch64 dev VM and boot test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,16 @@ CACHE_DIR="${CACHE_DIR:-$PROJECT_ROOT/build/cache}"
|
||||
ROOTFS_DIR="${ROOTFS_DIR:-$PROJECT_ROOT/build/rootfs-work}"
|
||||
ROOTFS="$ROOTFS_DIR/rootfs"
|
||||
VERSION="$(cat "$PROJECT_ROOT/VERSION")"
|
||||
INJECT_ARCH="${TARGET_ARCH:-amd64}"
|
||||
|
||||
# Architecture-specific paths
|
||||
if [ "$INJECT_ARCH" = "arm64" ]; then
|
||||
LIB_ARCH="aarch64-linux-gnu"
|
||||
LD_SO="/lib/ld-linux-aarch64.so.1"
|
||||
else
|
||||
LIB_ARCH="x86_64-linux-gnu"
|
||||
LD_SO="/lib64/ld-linux-x86-64.so.2"
|
||||
fi
|
||||
|
||||
if [ ! -d "$ROOTFS" ]; then
|
||||
echo "ERROR: Rootfs not found: $ROOTFS"
|
||||
@@ -90,8 +100,13 @@ fi
|
||||
# --- 3. Custom kernel or TCZ kernel modules ---
|
||||
# If a custom kernel was built (with CONFIG_CGROUP_BPF=y), use it.
|
||||
# Otherwise fall back to TCZ-extracted modules with manual modules.dep.
|
||||
CUSTOM_KERNEL_DIR="$CACHE_DIR/custom-kernel"
|
||||
CUSTOM_VMLINUZ="$CUSTOM_KERNEL_DIR/vmlinuz"
|
||||
if [ "$INJECT_ARCH" = "arm64" ]; then
|
||||
CUSTOM_KERNEL_DIR="$CACHE_DIR/custom-kernel-arm64"
|
||||
CUSTOM_VMLINUZ="$CUSTOM_KERNEL_DIR/Image"
|
||||
else
|
||||
CUSTOM_KERNEL_DIR="$CACHE_DIR/custom-kernel"
|
||||
CUSTOM_VMLINUZ="$CUSTOM_KERNEL_DIR/vmlinuz"
|
||||
fi
|
||||
CUSTOM_MODULES="$CUSTOM_KERNEL_DIR/modules"
|
||||
|
||||
# Detect kernel version from rootfs
|
||||
@@ -131,7 +146,11 @@ if [ -f "$CUSTOM_VMLINUZ" ] && [ -d "$CUSTOM_MODULES/lib/modules/$KVER" ]; then
|
||||
done
|
||||
|
||||
# Use modprobe --show-depends to resolve each module + its transitive deps
|
||||
MODULES_LIST="$PROJECT_ROOT/build/config/modules.list"
|
||||
if [ "$INJECT_ARCH" = "arm64" ]; then
|
||||
MODULES_LIST="$PROJECT_ROOT/build/config/modules-arm64.list"
|
||||
else
|
||||
MODULES_LIST="$PROJECT_ROOT/build/config/modules.list"
|
||||
fi
|
||||
NEEDED_MODS=$(mktemp)
|
||||
while IFS= read -r mod; do
|
||||
# Skip comments and blank lines
|
||||
@@ -291,21 +310,22 @@ if [ -f /usr/sbin/xtables-nft-multi ]; then
|
||||
ln -sf xtables-nft-multi "$ROOTFS/usr/sbin/$cmd"
|
||||
done
|
||||
|
||||
# Copy required shared libraries
|
||||
mkdir -p "$ROOTFS/usr/lib/x86_64-linux-gnu" "$ROOTFS/lib/x86_64-linux-gnu" "$ROOTFS/lib64"
|
||||
# Copy required shared libraries (architecture-aware paths)
|
||||
mkdir -p "$ROOTFS/usr/lib/$LIB_ARCH" "$ROOTFS/lib/$LIB_ARCH"
|
||||
[ "$INJECT_ARCH" != "arm64" ] && mkdir -p "$ROOTFS/lib64"
|
||||
for lib in \
|
||||
/lib/x86_64-linux-gnu/libxtables.so.12* \
|
||||
/lib/x86_64-linux-gnu/libmnl.so.0* \
|
||||
/lib/x86_64-linux-gnu/libnftnl.so.11* \
|
||||
/lib/x86_64-linux-gnu/libc.so.6 \
|
||||
/lib64/ld-linux-x86-64.so.2; do
|
||||
"/lib/$LIB_ARCH/libxtables.so.12"* \
|
||||
"/lib/$LIB_ARCH/libmnl.so.0"* \
|
||||
"/lib/$LIB_ARCH/libnftnl.so.11"* \
|
||||
"/lib/$LIB_ARCH/libc.so.6" \
|
||||
"$LD_SO"; do
|
||||
[ -e "$lib" ] && cp -aL "$lib" "$ROOTFS${lib}" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# Copy xtables modules directory (match extensions)
|
||||
if [ -d /usr/lib/x86_64-linux-gnu/xtables ]; then
|
||||
mkdir -p "$ROOTFS/usr/lib/x86_64-linux-gnu/xtables"
|
||||
cp -a /usr/lib/x86_64-linux-gnu/xtables/*.so "$ROOTFS/usr/lib/x86_64-linux-gnu/xtables/" 2>/dev/null || true
|
||||
if [ -d "/usr/lib/$LIB_ARCH/xtables" ]; then
|
||||
mkdir -p "$ROOTFS/usr/lib/$LIB_ARCH/xtables"
|
||||
cp -a "/usr/lib/$LIB_ARCH/xtables/"*.so "$ROOTFS/usr/lib/$LIB_ARCH/xtables/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo " Installed iptables-nft (xtables-nft-multi) + shared libs"
|
||||
@@ -314,11 +334,16 @@ else
|
||||
fi
|
||||
|
||||
# Kernel modules list (for init to load at boot)
|
||||
cp "$PROJECT_ROOT/build/config/modules.list" "$ROOTFS/usr/lib/kubesolo-os/modules.list"
|
||||
if [ "$INJECT_ARCH" = "arm64" ]; then
|
||||
cp "$PROJECT_ROOT/build/config/modules-arm64.list" "$ROOTFS/usr/lib/kubesolo-os/modules.list"
|
||||
else
|
||||
cp "$PROJECT_ROOT/build/config/modules.list" "$ROOTFS/usr/lib/kubesolo-os/modules.list"
|
||||
fi
|
||||
|
||||
# --- 4. Sysctl config ---
|
||||
mkdir -p "$ROOTFS/etc/sysctl.d"
|
||||
cp "$PROJECT_ROOT/build/rootfs/etc/sysctl.d/k8s.conf" "$ROOTFS/etc/sysctl.d/k8s.conf"
|
||||
cp "$PROJECT_ROOT/build/rootfs/etc/sysctl.d/security.conf" "$ROOTFS/etc/sysctl.d/security.conf"
|
||||
|
||||
# --- 5. OS metadata ---
|
||||
echo "$VERSION" > "$ROOTFS/etc/kubesolo-os-version"
|
||||
@@ -362,7 +387,35 @@ else
|
||||
echo " WARN: No CA certificates found in builder — TLS verification will fail"
|
||||
fi
|
||||
|
||||
# --- 9. Ensure /etc/hosts and /etc/resolv.conf exist ---
|
||||
# --- 9. AppArmor parser + profiles ---
|
||||
echo " Installing AppArmor..."
|
||||
if [ -f /usr/sbin/apparmor_parser ]; then
|
||||
mkdir -p "$ROOTFS/usr/sbin"
|
||||
cp /usr/sbin/apparmor_parser "$ROOTFS/usr/sbin/apparmor_parser"
|
||||
chmod +x "$ROOTFS/usr/sbin/apparmor_parser"
|
||||
|
||||
# Copy shared libraries required by apparmor_parser
|
||||
for lib in "/lib/$LIB_ARCH/libapparmor.so.1"*; do
|
||||
[ -e "$lib" ] && cp -aL "$lib" "$ROOTFS${lib}" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo " Installed apparmor_parser + shared libs"
|
||||
else
|
||||
echo " WARN: apparmor_parser not found in builder (install apparmor package)"
|
||||
fi
|
||||
|
||||
# Copy AppArmor profiles
|
||||
APPARMOR_PROFILES="$PROJECT_ROOT/build/rootfs/etc/apparmor.d"
|
||||
if [ -d "$APPARMOR_PROFILES" ]; then
|
||||
mkdir -p "$ROOTFS/etc/apparmor.d"
|
||||
cp "$APPARMOR_PROFILES"/* "$ROOTFS/etc/apparmor.d/" 2>/dev/null || true
|
||||
PROFILE_COUNT=$(ls "$ROOTFS/etc/apparmor.d/" 2>/dev/null | wc -l)
|
||||
echo " Installed $PROFILE_COUNT AppArmor profiles"
|
||||
else
|
||||
echo " WARN: No AppArmor profiles found at $APPARMOR_PROFILES"
|
||||
fi
|
||||
|
||||
# --- 10. Ensure /etc/hosts and /etc/resolv.conf exist ---
|
||||
if [ ! -f "$ROOTFS/etc/hosts" ]; then
|
||||
cat > "$ROOTFS/etc/hosts" << EOF
|
||||
127.0.0.1 localhost
|
||||
|
||||
Reference in New Issue
Block a user