Initial commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
results/
|
||||
*.deb
|
||||
@@ -0,0 +1,93 @@
|
||||
# Alpine Linux Base Image for Archipelago Bitcoin Node OS
|
||||
# Multi-arch support: ARM64 (Raspberry Pi) and x86_64
|
||||
|
||||
ARG ALPINE_VERSION=3.19
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
|
||||
# Install essential packages
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
curl \
|
||||
wget \
|
||||
ca-certificates \
|
||||
openssl \
|
||||
sudo \
|
||||
shadow \
|
||||
systemd \
|
||||
systemd-openrc \
|
||||
dbus \
|
||||
udev \
|
||||
util-linux \
|
||||
e2fsprogs \
|
||||
dosfstools \
|
||||
parted \
|
||||
gptfdisk \
|
||||
rsync \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
htop \
|
||||
iotop \
|
||||
net-tools \
|
||||
iproute2 \
|
||||
iputils \
|
||||
tcpdump \
|
||||
tzdata \
|
||||
logrotate \
|
||||
fail2ban \
|
||||
ufw \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Install Podman and dependencies
|
||||
RUN apk add --no-cache \
|
||||
podman \
|
||||
podman-compose \
|
||||
crun \
|
||||
fuse-overlayfs \
|
||||
slirp4netns \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Create archipelago user for rootless containers
|
||||
RUN adduser -D -s /bin/bash archipelago && \
|
||||
echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman, /usr/bin/podman-compose" >> /etc/sudoers
|
||||
|
||||
# Configure Podman for rootless operation
|
||||
RUN mkdir -p /home/archipelago/.config/containers && \
|
||||
echo 'driver = "overlay"' > /home/archipelago/.config/containers/storage.conf && \
|
||||
echo 'rootless_storage_path = "/home/archipelago/.local/share/containers/storage"' >> /home/archipelago/.config/containers/storage.conf
|
||||
|
||||
# Set up systemd for container management
|
||||
RUN systemctl enable systemd-resolved && \
|
||||
systemctl enable dbus
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p \
|
||||
/var/lib/archipelago \
|
||||
/var/lib/archipelago/apps \
|
||||
/var/lib/archipelago/secrets \
|
||||
/var/lib/archipelago/logs \
|
||||
/var/lib/archipelago/backups \
|
||||
/etc/archipelago
|
||||
|
||||
# Copy hardening scripts
|
||||
COPY scripts/harden-alpine.sh /usr/local/bin/
|
||||
COPY scripts/install-podman.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/harden-alpine.sh /usr/local/bin/install-podman.sh
|
||||
|
||||
# Run hardening script
|
||||
RUN /usr/local/bin/harden-alpine.sh
|
||||
|
||||
# Set timezone to UTC
|
||||
RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
||||
|
||||
# Configure log rotation
|
||||
COPY configs/logrotate.conf /etc/logrotate.d/archipelago
|
||||
|
||||
# Set up firewall defaults (will be configured on first boot)
|
||||
RUN ufw --force enable || true
|
||||
|
||||
# Expose common ports (will be managed by firewall rules)
|
||||
EXPOSE 22 80 443 8332 8333 9735 10009 8080 8443
|
||||
|
||||
# Default command
|
||||
CMD ["/bin/bash"]
|
||||
@@ -0,0 +1,23 @@
|
||||
# StartOS Image Recipes
|
||||
|
||||
Code and `debos` recipes that are used to create the StartOS live and installer
|
||||
images.
|
||||
|
||||
If you want to build a local image in the exact same environment used to build
|
||||
official StartOS images, you can use the `run-local-build.sh` helper script:
|
||||
|
||||
```bash
|
||||
# Prerequisites
|
||||
sudo apt-get install -y debspawn
|
||||
sudo mkdir -p /etc/debspawn/ && echo "AllowUnsafePermissions=true" | sudo tee /etc/debspawn/global.toml
|
||||
|
||||
# Get dpkg
|
||||
mkdir -p overlays/startos/root
|
||||
wget -O overlays/startos/root/startos_0.3.x-1_amd64.deb <dpkg_url>
|
||||
|
||||
# Build image
|
||||
./run-local-build.sh
|
||||
```
|
||||
|
||||
In order for the build to work properly, you will need debspawn >= 0.5.1, the
|
||||
build may fail with prior versions.
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Build script for Alpine Linux base image
|
||||
# Supports multi-arch: ARM64 (aarch64) and x86_64
|
||||
|
||||
set -e
|
||||
|
||||
ARCH="${ARCH:-$(uname -m)}"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
IMAGE_NAME="archipelago/alpine-base"
|
||||
TAG="${ALPINE_VERSION}-${ARCH}"
|
||||
|
||||
echo "🔨 Building Alpine Linux base image for ${ARCH}..."
|
||||
|
||||
# Map architecture names
|
||||
case "$ARCH" in
|
||||
aarch64|arm64)
|
||||
BUILD_ARCH="arm64"
|
||||
PLATFORM="linux/arm64"
|
||||
;;
|
||||
x86_64|amd64)
|
||||
BUILD_ARCH="amd64"
|
||||
PLATFORM="linux/amd64"
|
||||
;;
|
||||
*)
|
||||
echo "❌ Unsupported architecture: $ARCH"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build the image
|
||||
docker buildx build \
|
||||
--platform "$PLATFORM" \
|
||||
--file image-recipe/Dockerfile.alpine-base \
|
||||
--tag "${IMAGE_NAME}:${TAG}" \
|
||||
--tag "${IMAGE_NAME}:latest-${BUILD_ARCH}" \
|
||||
--load \
|
||||
.
|
||||
|
||||
echo "✅ Alpine base image built successfully!"
|
||||
echo " Image: ${IMAGE_NAME}:${TAG}"
|
||||
echo " Platform: ${PLATFORM}"
|
||||
Executable
+355
@@ -0,0 +1,355 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
MAX_IMG_SECTORS=7217792 # 4GB
|
||||
|
||||
echo "==== StartOS Image Build ===="
|
||||
|
||||
echo "Building for architecture: $IB_TARGET_ARCH"
|
||||
|
||||
base_dir="$(dirname "$(readlink -f "$0")")"
|
||||
prep_results_dir="$base_dir/images-prep"
|
||||
if systemd-detect-virt -qc; then
|
||||
RESULTS_DIR="/srv/artifacts"
|
||||
else
|
||||
RESULTS_DIR="$base_dir/results"
|
||||
fi
|
||||
echo "Saving results in: $RESULTS_DIR"
|
||||
|
||||
IMAGE_BASENAME=startos-${VERSION_FULL}_${IB_TARGET_PLATFORM}
|
||||
|
||||
mkdir -p $prep_results_dir
|
||||
|
||||
cd $prep_results_dir
|
||||
|
||||
QEMU_ARCH=${IB_TARGET_ARCH}
|
||||
BOOTLOADERS=grub-efi,syslinux
|
||||
if [ "$QEMU_ARCH" = 'amd64' ]; then
|
||||
QEMU_ARCH=x86_64
|
||||
elif [ "$QEMU_ARCH" = 'arm64' ]; then
|
||||
QEMU_ARCH=aarch64
|
||||
BOOTLOADERS=grub-efi
|
||||
fi
|
||||
NON_FREE=
|
||||
if [[ "${IB_TARGET_PLATFORM}" =~ -nonfree$ ]] || [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
NON_FREE=1
|
||||
fi
|
||||
IMAGE_TYPE=iso
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ] || [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then
|
||||
IMAGE_TYPE=img
|
||||
fi
|
||||
|
||||
ARCHIVE_AREAS="main contrib"
|
||||
if [ "$NON_FREE" = 1 ]; then
|
||||
if [ "$IB_SUITE" = "bullseye" ]; then
|
||||
ARCHIVE_AREAS="$ARCHIVE_AREAS non-free"
|
||||
elif [ "$IB_SUITE" = "bookworm" ]; then
|
||||
ARCHIVE_AREAS="$ARCHIVE_AREAS non-free-firmware"
|
||||
fi
|
||||
fi
|
||||
|
||||
PLATFORM_CONFIG_EXTRAS=
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --firmware-binary false"
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --firmware-chroot false"
|
||||
# BEGIN stupid ugly hack
|
||||
# The actual name of the package is `raspberrypi-kernel`
|
||||
# live-build determines thte name of the package for the kernel by combining the `linux-packages` flag, with the `linux-flavours` flag
|
||||
# the `linux-flavours` flag defaults to the architecture, so there's no way to remove the suffix.
|
||||
# So we're doing this, cause thank the gods our package name contains a hypen. Cause if it didn't we'd be SOL
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --linux-packages raspberrypi"
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --linux-flavours kernel"
|
||||
# END stupid ugly hack
|
||||
elif [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then
|
||||
PLATFORM_CONFIG_EXTRAS="$PLATFORM_CONFIG_EXTRAS --linux-flavours rockchip64"
|
||||
fi
|
||||
|
||||
cat > /etc/wgetrc << EOF
|
||||
retry_connrefused = on
|
||||
tries = 100
|
||||
EOF
|
||||
lb config \
|
||||
--iso-application "StartOS v${VERSION_FULL} ${IB_TARGET_ARCH}" \
|
||||
--iso-volume "StartOS v${VERSION} ${IB_TARGET_ARCH}" \
|
||||
--iso-preparer "START9 LABS; HTTPS://START9.COM" \
|
||||
--iso-publisher "START9 LABS; HTTPS://START9.COM" \
|
||||
--backports true \
|
||||
--bootappend-live "boot=live noautologin" \
|
||||
--bootloaders $BOOTLOADERS \
|
||||
--mirror-bootstrap "https://deb.debian.org/debian/" \
|
||||
--mirror-chroot "https://deb.debian.org/debian/" \
|
||||
--mirror-chroot-security "https://security.debian.org/debian-security" \
|
||||
-d ${IB_SUITE} \
|
||||
-a ${IB_TARGET_ARCH} \
|
||||
--bootstrap-qemu-arch ${IB_TARGET_ARCH} \
|
||||
--bootstrap-qemu-static /usr/bin/qemu-${QEMU_ARCH}-static \
|
||||
--archive-areas "${ARCHIVE_AREAS}" \
|
||||
$PLATFORM_CONFIG_EXTRAS
|
||||
|
||||
# Overlays
|
||||
|
||||
mkdir -p config/includes.chroot/deb
|
||||
cp $base_dir/deb/${IMAGE_BASENAME}.deb config/includes.chroot/deb/
|
||||
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
cp -r $base_dir/raspberrypi/squashfs/* config/includes.chroot/
|
||||
fi
|
||||
|
||||
mkdir -p config/includes.chroot/etc
|
||||
echo start > config/includes.chroot/etc/hostname
|
||||
cat > config/includes.chroot/etc/hosts << EOT
|
||||
127.0.0.1 localhost start
|
||||
::1 localhost start ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
EOT
|
||||
|
||||
# Bootloaders
|
||||
|
||||
rm -rf config/bootloaders
|
||||
cp -r /usr/share/live/build/bootloaders config/bootloaders
|
||||
|
||||
cat > config/bootloaders/syslinux/syslinux.cfg << EOF
|
||||
include menu.cfg
|
||||
default vesamenu.c32
|
||||
prompt 0
|
||||
timeout 50
|
||||
EOF
|
||||
|
||||
cat > config/bootloaders/isolinux/isolinux.cfg << EOF
|
||||
include menu.cfg
|
||||
default vesamenu.c32
|
||||
prompt 0
|
||||
timeout 50
|
||||
EOF
|
||||
|
||||
rm config/bootloaders/syslinux_common/splash.svg
|
||||
cp $base_dir/splash.png config/bootloaders/syslinux_common/splash.png
|
||||
cp $base_dir/splash.png config/bootloaders/isolinux/splash.png
|
||||
cp $base_dir/splash.png config/bootloaders/grub-pc/splash.png
|
||||
|
||||
sed -i -e '2i set timeout=5' config/bootloaders/grub-pc/config.cfg
|
||||
|
||||
# Archives
|
||||
|
||||
mkdir -p config/archives
|
||||
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
curl -fsSL https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o config/archives/raspi.key
|
||||
echo "deb https://archive.raspberrypi.org/debian/ bullseye main" > config/archives/raspi.list
|
||||
fi
|
||||
|
||||
if [ "${IB_SUITE}" = "bullseye" ]; then
|
||||
cat > config/archives/backports.pref <<- EOF
|
||||
Package: *
|
||||
Pin: release a=bullseye-backports
|
||||
Pin-Priority: 500
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "${IB_TARGET_PLATFORM}" = "rockchip64" ]; then
|
||||
curl -fsSL https://apt.armbian.com/armbian.key | gpg --dearmor -o config/archives/armbian.key
|
||||
echo "deb https://apt.armbian.com/ ${IB_SUITE} main" > config/archives/armbian.list
|
||||
fi
|
||||
|
||||
curl -fsSL https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc > config/archives/tor.key
|
||||
echo "deb [arch=${IB_TARGET_ARCH} signed-by=/etc/apt/trusted.gpg.d/tor.key.gpg] https://deb.torproject.org/torproject.org ${IB_SUITE} main" > config/archives/tor.list
|
||||
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o config/archives/docker.key
|
||||
echo "deb [arch=${IB_TARGET_ARCH} signed-by=/etc/apt/trusted.gpg.d/docker.key.gpg] https://download.docker.com/linux/debian ${IB_SUITE} stable" > config/archives/docker.list
|
||||
|
||||
echo "deb http://deb.debian.org/debian/ trixie main contrib" > config/archives/trixie.list
|
||||
cat > config/archives/trixie.pref <<- EOF
|
||||
Package: *
|
||||
Pin: release n=trixie
|
||||
Pin-Priority: 100
|
||||
|
||||
Package: podman
|
||||
Pin: release n=trixie
|
||||
Pin-Priority: 600
|
||||
EOF
|
||||
|
||||
# Dependencies
|
||||
|
||||
## Base dependencies
|
||||
dpkg-deb --fsys-tarfile $base_dir/deb/${IMAGE_BASENAME}.deb | tar --to-stdout -xvf - ./usr/lib/startos/depends > config/package-lists/embassy-depends.list.chroot
|
||||
|
||||
## Firmware
|
||||
if [ "$NON_FREE" = 1 ]; then
|
||||
echo 'firmware-iwlwifi firmware-misc-nonfree firmware-brcm80211 firmware-realtek firmware-atheros firmware-libertas firmware-amd-graphics' > config/package-lists/nonfree.list.chroot
|
||||
fi
|
||||
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
echo 'raspberrypi-bootloader rpi-update parted' > config/package-lists/bootloader.list.chroot
|
||||
else
|
||||
echo 'grub-efi grub2-common' > config/package-lists/bootloader.list.chroot
|
||||
fi
|
||||
if [ "${IB_TARGET_ARCH}" = "amd64" ] || [ "${IB_TARGET_ARCH}" = "i386" ]; then
|
||||
echo 'grub-pc-bin' >> config/package-lists/bootloader.list.chroot
|
||||
fi
|
||||
|
||||
cat > config/hooks/normal/9000-install-startos.hook.chroot << EOF
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
apt-get install -y /deb/${IMAGE_BASENAME}.deb
|
||||
rm -rf /deb
|
||||
|
||||
if [ "${IB_SUITE}" = bookworm ]; then
|
||||
echo 'deb https://deb.debian.org/debian/ bullseye main' > /etc/apt/sources.list.d/bullseye.list
|
||||
apt-get update
|
||||
apt-get install -y postgresql-13
|
||||
rm /etc/apt/sources.list.d/bullseye.list
|
||||
apt-get update
|
||||
fi
|
||||
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
for f in /usr/lib/modules/*; do
|
||||
v=\${f#/usr/lib/modules/}
|
||||
echo "Configuring raspi kernel '\$v'"
|
||||
extract-ikconfig "/usr/lib/modules/\$v/kernel/kernel/configs.ko.xz" > /boot/config-\$v
|
||||
update-initramfs -c -k \$v
|
||||
done
|
||||
ln -sf /usr/bin/pi-beep /usr/local/bin/beep
|
||||
fi
|
||||
|
||||
useradd --shell /bin/bash -G embassy -m start9
|
||||
echo start9:embassy | chpasswd
|
||||
usermod -aG sudo start9
|
||||
|
||||
echo "start9 ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee "/etc/sudoers.d/010_start9-nopasswd"
|
||||
|
||||
if [ "${IB_TARGET_PLATFORM}" != "raspberrypi" ]; then
|
||||
/usr/lib/startos/scripts/enable-kiosk
|
||||
fi
|
||||
|
||||
if ! [[ "${IB_OS_ENV}" =~ (^|-)dev($|-) ]]; then
|
||||
passwd -l start9
|
||||
fi
|
||||
|
||||
EOF
|
||||
|
||||
SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(date '+%s')}"
|
||||
|
||||
lb bootstrap
|
||||
lb chroot
|
||||
lb installer
|
||||
lb binary_chroot
|
||||
lb chroot_prep install all mode-apt-install-binary mode-archives-chroot
|
||||
ln -sf /run/systemd/resolve/stub-resolv.conf chroot/chroot/etc/resolv.conf
|
||||
lb binary_rootfs
|
||||
|
||||
cp $prep_results_dir/binary/live/filesystem.squashfs $RESULTS_DIR/$IMAGE_BASENAME.squashfs
|
||||
|
||||
if [ "${IMAGE_TYPE}" = iso ]; then
|
||||
|
||||
lb binary_manifest
|
||||
lb binary_package-lists
|
||||
lb binary_linux-image
|
||||
lb binary_memtest
|
||||
lb binary_grub-legacy
|
||||
lb binary_grub-pc
|
||||
lb binary_grub_cfg
|
||||
lb binary_syslinux
|
||||
lb binary_disk
|
||||
lb binary_loadlin
|
||||
lb binary_win32-loader
|
||||
lb binary_includes
|
||||
lb binary_grub-efi
|
||||
lb binary_hooks
|
||||
lb binary_checksums
|
||||
find binary -newermt "$(date -d@${SOURCE_DATE_EPOCH} '+%Y-%m-%d %H:%M:%S')" -printf "%y %p\n" -exec touch '{}' -d@${SOURCE_DATE_EPOCH} --no-dereference ';' > binary.modified_timestamps
|
||||
lb binary_iso
|
||||
lb binary_onie
|
||||
lb binary_netboot
|
||||
lb binary_tar
|
||||
lb binary_hdd
|
||||
lb binary_zsync
|
||||
lb chroot_prep remove all mode-archives-chroot
|
||||
lb source
|
||||
|
||||
mv $prep_results_dir/live-image-${IB_TARGET_ARCH}.hybrid.iso $RESULTS_DIR/$IMAGE_BASENAME.iso
|
||||
|
||||
elif [ "${IMAGE_TYPE}" = img ]; then
|
||||
|
||||
function partition_for () {
|
||||
if [[ "$1" =~ [0-9]+$ ]]; then
|
||||
echo "$1p$2"
|
||||
else
|
||||
echo "$1$2"
|
||||
fi
|
||||
}
|
||||
|
||||
ROOT_PART_END=$MAX_IMG_SECTORS
|
||||
TARGET_NAME=$prep_results_dir/${IMAGE_BASENAME}.img
|
||||
TARGET_SIZE=$[($ROOT_PART_END+1)*512]
|
||||
truncate -s $TARGET_SIZE $TARGET_NAME
|
||||
(
|
||||
echo o
|
||||
echo x
|
||||
echo i
|
||||
echo "0xcb15ae4d"
|
||||
echo r
|
||||
echo n
|
||||
echo p
|
||||
echo 1
|
||||
echo 2048
|
||||
echo 526335
|
||||
echo t
|
||||
echo c
|
||||
echo n
|
||||
echo p
|
||||
echo 2
|
||||
echo 526336
|
||||
echo $ROOT_PART_END
|
||||
echo a
|
||||
echo 1
|
||||
echo w
|
||||
) | fdisk $TARGET_NAME
|
||||
OUTPUT_DEVICE=$(losetup --show -fP $TARGET_NAME)
|
||||
mkfs.ext4 `partition_for ${OUTPUT_DEVICE} 2`
|
||||
mkfs.vfat `partition_for ${OUTPUT_DEVICE} 1`
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
|
||||
mount `partition_for ${OUTPUT_DEVICE} 2` $TMPDIR
|
||||
mkdir $TMPDIR/boot
|
||||
mount `partition_for ${OUTPUT_DEVICE} 1` $TMPDIR/boot
|
||||
unsquashfs -f -d $TMPDIR $prep_results_dir/binary/live/filesystem.squashfs
|
||||
|
||||
if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then
|
||||
sed -i 's| boot=embassy| init=/usr/lib/startos/scripts/init_resize\.sh|' $TMPDIR/boot/cmdline.txt
|
||||
rsync -a $base_dir/raspberrypi/img/ $TMPDIR/
|
||||
fi
|
||||
|
||||
umount $TMPDIR/boot
|
||||
umount $TMPDIR
|
||||
|
||||
e2fsck -fy `partition_for ${OUTPUT_DEVICE} 2`
|
||||
resize2fs -M `partition_for ${OUTPUT_DEVICE} 2`
|
||||
|
||||
BLOCK_COUNT=$(dumpe2fs -h `partition_for ${OUTPUT_DEVICE} 2` | awk '/^Block count:/ { print $3 }')
|
||||
BLOCK_SIZE=$(dumpe2fs -h `partition_for ${OUTPUT_DEVICE} 2` | awk '/^Block size:/ { print $3 }')
|
||||
SECTOR_LEN=$[$BLOCK_COUNT*$BLOCK_SIZE/512]
|
||||
|
||||
losetup -d $OUTPUT_DEVICE
|
||||
|
||||
(
|
||||
echo d
|
||||
echo 2
|
||||
echo n
|
||||
echo p
|
||||
echo 2
|
||||
echo 526336
|
||||
echo +$SECTOR_LEN
|
||||
echo w
|
||||
) | fdisk $TARGET_NAME
|
||||
|
||||
ROOT_PART_END=$[526336+$SECTOR_LEN]
|
||||
TARGET_SIZE=$[($ROOT_PART_END+1)*512]
|
||||
truncate -s $TARGET_SIZE $TARGET_NAME
|
||||
|
||||
mv $TARGET_NAME $RESULTS_DIR/$IMAGE_BASENAME.img
|
||||
|
||||
fi
|
||||
@@ -0,0 +1,24 @@
|
||||
# Log rotation configuration for Archipelago
|
||||
/var/log/archipelago/*.log {
|
||||
daily
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0644 root root
|
||||
sharedscripts
|
||||
postrotate
|
||||
/usr/bin/systemctl reload archipelago > /dev/null 2>&1 || true
|
||||
endscript
|
||||
}
|
||||
|
||||
/var/lib/archipelago/logs/*.log {
|
||||
daily
|
||||
rotate 14
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0644 archipelago archipelago
|
||||
}
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get install -yq \
|
||||
live-build \
|
||||
procps \
|
||||
systemd \
|
||||
binfmt-support \
|
||||
qemu-utils \
|
||||
qemu-user-static \
|
||||
qemu-system-x86 \
|
||||
qemu-system-aarch64 \
|
||||
xorriso \
|
||||
isolinux \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gpg \
|
||||
fdisk \
|
||||
dosfstools \
|
||||
e2fsprogs \
|
||||
squashfs-tools \
|
||||
rsync
|
||||
@@ -0,0 +1,2 @@
|
||||
/dev/mmcblk0p1 /boot vfat umask=0077 0 2
|
||||
/dev/mmcblk0p2 / ext4 defaults 0 1
|
||||
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
|
||||
get_variables () {
|
||||
ROOT_PART_DEV=$(findmnt / -o source -n)
|
||||
ROOT_PART_NAME=$(echo "$ROOT_PART_DEV" | cut -d "/" -f 3)
|
||||
ROOT_DEV_NAME=$(echo /sys/block/*/"${ROOT_PART_NAME}" | cut -d "/" -f 4)
|
||||
ROOT_DEV="/dev/${ROOT_DEV_NAME}"
|
||||
ROOT_PART_NUM=$(cat "/sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition")
|
||||
|
||||
BOOT_PART_DEV=$(findmnt /boot -o source -n)
|
||||
BOOT_PART_NAME=$(echo "$BOOT_PART_DEV" | cut -d "/" -f 3)
|
||||
BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4)
|
||||
BOOT_PART_NUM=$(cat "/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition")
|
||||
|
||||
OLD_DISKID=$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')
|
||||
|
||||
ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size")
|
||||
if [ "$ROOT_DEV_SIZE" -le 67108864 ]; then
|
||||
TARGET_END=$((ROOT_DEV_SIZE - 1))
|
||||
else
|
||||
TARGET_END=$((33554432 - 1))
|
||||
DATA_PART_START=33554432
|
||||
DATA_PART_END=$((ROOT_DEV_SIZE - 1))
|
||||
fi
|
||||
|
||||
PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's')
|
||||
|
||||
LAST_PART_NUM=$(echo "$PARTITION_TABLE" | tail -n 1 | cut -d ":" -f 1)
|
||||
|
||||
ROOT_PART_LINE=$(echo "$PARTITION_TABLE" | grep -e "^${ROOT_PART_NUM}:")
|
||||
ROOT_PART_START=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 2)
|
||||
ROOT_PART_END=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 3)
|
||||
}
|
||||
|
||||
check_variables () {
|
||||
if [ "$BOOT_DEV_NAME" != "$ROOT_DEV_NAME" ]; then
|
||||
FAIL_REASON="Boot and root partitions are on different devices"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$ROOT_PART_NUM" -ne "$LAST_PART_NUM" ]; then
|
||||
FAIL_REASON="Root partition should be last partition"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$ROOT_PART_END" -gt "$TARGET_END" ]; then
|
||||
FAIL_REASON="Root partition runs past the end of device"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -b "$ROOT_DEV" ] || [ ! -b "$ROOT_PART_DEV" ] || [ ! -b "$BOOT_PART_DEV" ] ; then
|
||||
FAIL_REASON="Could not determine partitions"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
main () {
|
||||
get_variables
|
||||
|
||||
if ! check_variables; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# if [ "$ROOT_PART_END" -eq "$TARGET_END" ]; then
|
||||
# reboot_pi
|
||||
# fi
|
||||
|
||||
if ! echo Yes | parted -m --align=optimal "$ROOT_DEV" ---pretend-input-tty u s resizepart "$ROOT_PART_NUM" "$TARGET_END" ; then
|
||||
FAIL_REASON="Root partition resize failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$DATA_PART_START" ]; then
|
||||
if ! parted -ms --align=optimal "$ROOT_DEV" u s mkpart primary "$DATA_PART_START" "$DATA_PART_END"; then
|
||||
FAIL_REASON="Data partition creation failed"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
(
|
||||
echo x
|
||||
echo i
|
||||
echo "0xcb15ae4d"
|
||||
echo r
|
||||
echo w
|
||||
) | fdisk $ROOT_DEV
|
||||
|
||||
mount / -o remount,rw
|
||||
|
||||
resize2fs $ROOT_PART_DEV
|
||||
|
||||
if ! systemd-machine-id-setup; then
|
||||
FAIL_REASON="systemd-machine-id-setup failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! ssh-keygen -A; then
|
||||
FAIL_REASON="ssh host key generation failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo start > /etc/hostname
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
mount -t proc proc /proc
|
||||
mount -t sysfs sys /sys
|
||||
mount -t tmpfs tmp /run
|
||||
mkdir -p /run/systemd
|
||||
mount /boot
|
||||
mount / -o remount,ro
|
||||
|
||||
beep
|
||||
|
||||
if main; then
|
||||
sed -i 's| init=/usr/lib/startos/scripts/init_resize\.sh| boot=embassy|' /boot/cmdline.txt
|
||||
echo "Resized root filesystem. Rebooting in 5 seconds..."
|
||||
sleep 5
|
||||
else
|
||||
echo -e "Could not expand filesystem.\n${FAIL_REASON}"
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
sync
|
||||
|
||||
umount /boot
|
||||
|
||||
reboot -f
|
||||
@@ -0,0 +1 @@
|
||||
usb-storage.quirks=152d:0562:u,14cd:121c:u,0781:cfcb:u console=serial0,115200 console=tty1 root=PARTUUID=cb15ae4d-02 rootfstype=ext4 fsck.repair=yes rootwait cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory quiet boot=embassy
|
||||
@@ -0,0 +1,86 @@
|
||||
# For more options and information see
|
||||
# http://rpf.io/configtxt
|
||||
# Some settings may impact device functionality. See link above for details
|
||||
|
||||
# uncomment if you get no picture on HDMI for a default "safe" mode
|
||||
#hdmi_safe=1
|
||||
|
||||
# uncomment the following to adjust overscan. Use positive numbers if console
|
||||
# goes off screen, and negative if there is too much border
|
||||
#overscan_left=16
|
||||
#overscan_right=16
|
||||
#overscan_top=16
|
||||
#overscan_bottom=16
|
||||
|
||||
# uncomment to force a console size. By default it will be display's size minus
|
||||
# overscan.
|
||||
#framebuffer_width=1280
|
||||
#framebuffer_height=720
|
||||
|
||||
# uncomment if hdmi display is not detected and composite is being output
|
||||
#hdmi_force_hotplug=1
|
||||
|
||||
# uncomment to force a specific HDMI mode (this will force VGA)
|
||||
#hdmi_group=1
|
||||
#hdmi_mode=1
|
||||
|
||||
# uncomment to force a HDMI mode rather than DVI. This can make audio work in
|
||||
# DMT (computer monitor) modes
|
||||
#hdmi_drive=2
|
||||
|
||||
# uncomment to increase signal to HDMI, if you have interference, blanking, or
|
||||
# no display
|
||||
#config_hdmi_boost=4
|
||||
|
||||
# uncomment for composite PAL
|
||||
#sdtv_mode=2
|
||||
|
||||
#uncomment to overclock the arm. 700 MHz is the default.
|
||||
#arm_freq=800
|
||||
|
||||
# Uncomment some or all of these to enable the optional hardware interfaces
|
||||
#dtparam=i2c_arm=on
|
||||
#dtparam=i2s=on
|
||||
#dtparam=spi=on
|
||||
|
||||
# Uncomment this to enable infrared communication.
|
||||
#dtoverlay=gpio-ir,gpio_pin=17
|
||||
#dtoverlay=gpio-ir-tx,gpio_pin=18
|
||||
|
||||
# Additional overlays and parameters are documented /boot/overlays/README
|
||||
|
||||
# Enable audio (loads snd_bcm2835)
|
||||
dtparam=audio=on
|
||||
|
||||
# Automatically load overlays for detected cameras
|
||||
camera_auto_detect=1
|
||||
|
||||
# Automatically load overlays for detected DSI displays
|
||||
display_auto_detect=1
|
||||
|
||||
# Enable DRM VC4 V3D driver
|
||||
dtoverlay=vc4-kms-v3d
|
||||
max_framebuffers=2
|
||||
|
||||
# Run in 64-bit mode
|
||||
arm_64bit=1
|
||||
|
||||
# Disable compensation for displays with overscan
|
||||
disable_overscan=1
|
||||
|
||||
[cm4]
|
||||
# Enable host mode on the 2711 built-in XHCI USB controller.
|
||||
# This line should be removed if the legacy DWC2 controller is required
|
||||
# (e.g. for USB device mode) or if USB support is not required.
|
||||
otg_mode=1
|
||||
|
||||
[all]
|
||||
|
||||
[pi4]
|
||||
# Run as fast as firmware / board allows
|
||||
arm_boost=1
|
||||
|
||||
[all]
|
||||
gpu_mem=16
|
||||
dtoverlay=pwm-2chan,disable-bt
|
||||
initramfs initrd.img-6.1.21-v8+
|
||||
@@ -0,0 +1,6 @@
|
||||
os-partitions:
|
||||
boot: /dev/mmcblk0p1
|
||||
root: /dev/mmcblk0p2
|
||||
ethernet-interface: end0
|
||||
wifi-interface: wlan0
|
||||
disable-encryption: true
|
||||
@@ -0,0 +1 @@
|
||||
options cfg80211 ieee80211_regdom=US
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------
|
||||
# extract-ikconfig - Extract the .config file from a kernel image
|
||||
#
|
||||
# This will only work when the kernel was compiled with CONFIG_IKCONFIG.
|
||||
#
|
||||
# The obscure use of the "tr" filter is to work around older versions of
|
||||
# "grep" that report the byte offset of the line instead of the pattern.
|
||||
#
|
||||
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
|
||||
# Licensed under the terms of the GNU General Public License.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
cf1='IKCFG_ST\037\213\010'
|
||||
cf2='0123456789'
|
||||
|
||||
dump_config()
|
||||
{
|
||||
if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"`
|
||||
then
|
||||
pos=${pos%%:*}
|
||||
tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null
|
||||
if [ $? != 1 ]
|
||||
then # exit status must be 0 or 2 (trailing garbage warning)
|
||||
cat $tmp1
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
try_decompress()
|
||||
{
|
||||
for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
|
||||
do
|
||||
pos=${pos%%:*}
|
||||
tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null
|
||||
dump_config $tmp2
|
||||
done
|
||||
}
|
||||
|
||||
# Check invocation:
|
||||
me=${0##*/}
|
||||
img=$1
|
||||
if [ $# -ne 1 -o ! -s "$img" ]
|
||||
then
|
||||
echo "Usage: $me <kernel-image>" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Prepare temp files:
|
||||
tmp1=/tmp/ikconfig$$.1
|
||||
tmp2=/tmp/ikconfig$$.2
|
||||
trap "rm -f $tmp1 $tmp2" 0
|
||||
|
||||
# Initial attempt for uncompressed images or objects:
|
||||
dump_config "$img"
|
||||
|
||||
# That didn't work, so retry after decompression.
|
||||
try_decompress '\037\213\010' xy gunzip
|
||||
try_decompress '\3757zXZ\000' abcde unxz
|
||||
try_decompress 'BZh' xy bunzip2
|
||||
try_decompress '\135\0\0\0' xxx unlzma
|
||||
try_decompress '\211\114\132' xy 'lzop -d'
|
||||
try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
|
||||
try_decompress '\050\265\057\375' xxx unzstd
|
||||
|
||||
# Bail out:
|
||||
echo "$me: Cannot find kernel config." >&2
|
||||
exit 1
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
DEB_PATH="$(realpath $1)"
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"/..
|
||||
|
||||
BASEDIR="$(pwd -P)"
|
||||
|
||||
VERSION="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/VERSION.txt)"
|
||||
GIT_HASH="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/GIT_HASH.txt)"
|
||||
if [[ "$GIT_HASH" =~ ^@ ]]; then
|
||||
GIT_HASH="unknown"
|
||||
else
|
||||
GIT_HASH="$(echo -n "$GIT_HASH" | head -c 7)"
|
||||
fi
|
||||
STARTOS_ENV="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/ENVIRONMENT.txt)"
|
||||
PLATFORM="$(dpkg-deb --fsys-tarfile $DEB_PATH | tar --to-stdout -xvf - ./usr/lib/startos/PLATFORM.txt)"
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
PLATFORM="$(uname -m)"
|
||||
fi
|
||||
if [ "$PLATFORM" = "x86_64" ] || [ "$PLATFORM" = "x86_64-nonfree" ]; then
|
||||
ARCH=amd64
|
||||
QEMU_ARCH=x86_64
|
||||
elif [ "$PLATFORM" = "aarch64" ] || [ "$PLATFORM" = "aarch64-nonfree" ] || [ "$PLATFORM" = "raspberrypi" ] || [ "$PLATFORM" = "rockchip64" ]; then
|
||||
ARCH=arm64
|
||||
QEMU_ARCH=aarch64
|
||||
else
|
||||
ARCH="$PLATFORM"
|
||||
QEMU_ARCH="$PLATFORM"
|
||||
fi
|
||||
|
||||
SUITE=bookworm
|
||||
|
||||
debspawn list | grep $SUITE || debspawn create $SUITE
|
||||
|
||||
VERSION_FULL="${VERSION}-${GIT_HASH}"
|
||||
if [ -n "$STARTOS_ENV" ]; then
|
||||
VERSION_FULL="$VERSION_FULL~${STARTOS_ENV}"
|
||||
fi
|
||||
|
||||
if [ -z "$DSNAME" ]; then
|
||||
DSNAME="$SUITE"
|
||||
fi
|
||||
|
||||
if [ "$QEMU_ARCH" != "$(uname -m)" ]; then
|
||||
sudo update-binfmts --import qemu-$QEMU_ARCH
|
||||
fi
|
||||
|
||||
imgbuild_fname="$(mktemp /tmp/exec-mkimage.XXXXXX)"
|
||||
cat > $imgbuild_fname <<END
|
||||
#!/bin/sh
|
||||
|
||||
export IB_SUITE=${SUITE}
|
||||
export IB_TARGET_ARCH=${ARCH}
|
||||
export IB_TARGET_PLATFORM=${PLATFORM}
|
||||
export IB_OS_ENV=${STARTOS_ENV}
|
||||
export VERSION=${VERSION}
|
||||
export VERSION_FULL=${VERSION_FULL}
|
||||
exec ./build.sh
|
||||
END
|
||||
|
||||
prepare_hash=$(sha1sum ${BASEDIR}/image-recipe/prepare.sh | head -c 7)
|
||||
|
||||
mkdir -p ${BASEDIR}/image-recipe/deb
|
||||
cp $DEB_PATH ${BASEDIR}/image-recipe/deb/
|
||||
|
||||
mkdir -p ${BASEDIR}/results
|
||||
set +e
|
||||
debspawn run \
|
||||
-x \
|
||||
--allow=read-kmods,kvm,full-dev \
|
||||
--cachekey="${SUITE}-${prepare_hash}-mkimage" \
|
||||
--init-command="${BASEDIR}/image-recipe/prepare.sh" \
|
||||
--build-dir="${BASEDIR}/image-recipe" \
|
||||
--artifacts-out="${BASEDIR}/results" \
|
||||
--header="StartOS Image Build" \
|
||||
--suite=${SUITE} \
|
||||
${DSNAME} \
|
||||
${imgbuild_fname}
|
||||
|
||||
retval=$?
|
||||
rm $imgbuild_fname
|
||||
if [ $retval -ne 0 ]; then
|
||||
exit $retval
|
||||
fi
|
||||
exit 0
|
||||
Executable
+118
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
# Alpine Linux Hardening Script for Archipelago Bitcoin Node OS
|
||||
# This script applies security hardening to the Alpine base image
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔒 Starting Alpine Linux hardening..."
|
||||
|
||||
# Disable unnecessary services
|
||||
systemctl disable bluetooth || true
|
||||
systemctl disable avahi-daemon || true
|
||||
|
||||
# Configure kernel parameters for security
|
||||
cat >> /etc/sysctl.conf <<EOF
|
||||
|
||||
# Archipelago Security Hardening
|
||||
# Disable IP forwarding
|
||||
net.ipv4.ip_forward = 0
|
||||
net.ipv6.conf.all.forwarding = 0
|
||||
|
||||
# Enable SYN flood protection
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
|
||||
# Disable source routing
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.conf.default.accept_source_route = 0
|
||||
net.ipv6.conf.all.accept_source_route = 0
|
||||
net.ipv6.conf.default.accept_source_route = 0
|
||||
|
||||
# Disable ICMP redirects
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
|
||||
# Disable send redirects
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
# Log martian packets
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
net.ipv4.conf.default.log_martians = 1
|
||||
|
||||
# Ignore ICMP ping requests (can be enabled if needed)
|
||||
# net.ipv4.icmp_echo_ignore_all = 1
|
||||
|
||||
# Ignore ICMP ping broadcasts
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
|
||||
# Ignore bogus ICMP errors
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
|
||||
# Enable RFC-recommended source validation
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
|
||||
# Disable IPv6 if not needed (uncomment if IPv6 not required)
|
||||
# net.ipv6.conf.all.disable_ipv6 = 1
|
||||
# net.ipv6.conf.default.disable_ipv6 = 1
|
||||
EOF
|
||||
|
||||
# Configure SSH (if installed)
|
||||
if [ -f /etc/ssh/sshd_config ]; then
|
||||
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config || true
|
||||
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config || true
|
||||
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config || true
|
||||
fi
|
||||
|
||||
# Set up fail2ban basic configuration
|
||||
if [ -f /etc/fail2ban/jail.conf ]; then
|
||||
cat > /etc/fail2ban/jail.local <<EOF
|
||||
[DEFAULT]
|
||||
bantime = 3600
|
||||
findtime = 600
|
||||
maxretry = 5
|
||||
destemail = root@localhost
|
||||
sendername = Fail2Ban
|
||||
action = %(action_)s
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Configure automatic security updates
|
||||
cat > /etc/periodic/daily/archipelago-security-updates <<'EOF'
|
||||
#!/bin/sh
|
||||
# Automatic security updates for Archipelago
|
||||
apk update && apk upgrade -u || true
|
||||
EOF
|
||||
chmod +x /etc/periodic/daily/archipelago-security-updates
|
||||
|
||||
# Set restrictive file permissions
|
||||
chmod 700 /var/lib/archipelago/secrets
|
||||
chmod 755 /var/lib/archipelago/apps
|
||||
chmod 755 /var/lib/archipelago/logs
|
||||
|
||||
# Create log directory with proper permissions
|
||||
mkdir -p /var/log/archipelago
|
||||
chmod 755 /var/log/archipelago
|
||||
|
||||
# Configure log rotation for archipelago logs
|
||||
cat > /etc/logrotate.d/archipelago <<EOF
|
||||
/var/log/archipelago/*.log {
|
||||
daily
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0644 root root
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Alpine Linux hardening complete!"
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
# Podman Installation and Configuration Script for Archipelago
|
||||
# Configures Podman for rootless operation
|
||||
|
||||
set -e
|
||||
|
||||
echo "🐳 Configuring Podman for rootless operation..."
|
||||
|
||||
# Ensure archipelago user exists
|
||||
if ! id "archipelago" &>/dev/null; then
|
||||
echo "Creating archipelago user..."
|
||||
adduser -D -s /bin/bash archipelago
|
||||
fi
|
||||
|
||||
# Create Podman configuration directories
|
||||
mkdir -p /home/archipelago/.config/containers
|
||||
mkdir -p /home/archipelago/.local/share/containers/storage
|
||||
|
||||
# Configure storage
|
||||
cat > /home/archipelago/.config/containers/storage.conf <<EOF
|
||||
[storage]
|
||||
driver = "overlay"
|
||||
runroot = "/run/user/$(id -u archipelago)/containers"
|
||||
graphroot = "/home/archipelago/.local/share/containers/storage"
|
||||
EOF
|
||||
|
||||
# Configure registries (use Docker Hub and quay.io)
|
||||
mkdir -p /home/archipelago/.config/containers/registries.conf.d
|
||||
cat > /home/archipelago/.config/containers/registries.conf.d/000-shortnames.conf <<EOF
|
||||
[registries.search]
|
||||
registries = ['docker.io', 'quay.io', 'ghcr.io']
|
||||
|
||||
[registries.insecure]
|
||||
registries = []
|
||||
|
||||
[registries.block]
|
||||
registries = []
|
||||
EOF
|
||||
|
||||
# Set up subuid and subgid for rootless containers
|
||||
if ! grep -q "^archipelago:" /etc/subuid; then
|
||||
echo "archipelago:100000:65536" >> /etc/subuid
|
||||
fi
|
||||
|
||||
if ! grep -q "^archipelago:" /etc/subgid; then
|
||||
echo "archipelago:100000:65536" >> /etc/subgid
|
||||
fi
|
||||
|
||||
# Create systemd user service directory
|
||||
mkdir -p /home/archipelago/.config/systemd/user
|
||||
|
||||
# Enable lingering for archipelago user (allows user services to run without login)
|
||||
loginctl enable-linger archipelago || true
|
||||
|
||||
# Set proper permissions
|
||||
chown -R archipelago:archipelago /home/archipelago/.config
|
||||
chown -R archipelago:archipelago /home/archipelago/.local
|
||||
|
||||
echo "✅ Podman configuration complete!"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
Reference in New Issue
Block a user