- Add nullpoint branding to /etc/os-release PRETTY_NAME field - Preserve original OS information as base system reference - Create backup of original os-release file - Display updated branding information during installation
554 lines
20 KiB
Bash
Executable File
554 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
BANNER=$(cat << "EOF"
|
|
__.,,.__
|
|
:^7J5GB##&&##GPY?~:
|
|
^75B&@@@@@@&&&@@@@@@@#GJ~:
|
|
5&@@@&B5?7~^^^^^~!7YP#@@@@#!
|
|
Y##P7^ :~JB#B!
|
|
:: :
|
|
7PP?: :^~!!~^: :?PP7
|
|
:B@@B: !5B&@@@@&B5! :#@@B:
|
|
:!!: ^G@@@&BPPB@@@@G^ :!!:
|
|
:B@@@5^ ^5@@@B:
|
|
:7J7: !@@@# :&@@@~ :?J7:
|
|
J@@@5 :#@@@Y: :Y@@@B: 5@@@J
|
|
!@@@&^ ~B@@@&G55G&@@@B~ ~&@@@~
|
|
5@@@G: :7P#@@@@@@#P7: :B@@@Y
|
|
:P@@@B~ :~!77!~: ~B@@@P
|
|
Y@@@&Y^ ^5@@@@J
|
|
!G@@@&P7^ ^7P&@@@G~
|
|
!P&@@@&B? :: ?B&@@@&P!
|
|
^75#&&Y :P&&5: 5&&B57^
|
|
:^^ :P&&5: ^^:
|
|
^^
|
|
|
|
[nullpoint]
|
|
EOF
|
|
)
|
|
|
|
TANG_SERVERS=(
|
|
# "https://tang1.example.com your-thumbprint-1"
|
|
# "https://tang2.example.com your-thumbprint-2"
|
|
)
|
|
TPM_ENABLED=true
|
|
TPM_PCR_BANK="sha256"
|
|
TPM_PCR_IDS="0,1,2,3,4,5,6,7,8"
|
|
ALMA_USER="null"
|
|
ENABLE_MOTD=true
|
|
# REQUIRED: Set your SSH public key here - installation will fail without it!
|
|
SSH_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOkoTn2NreAXMriOUqzyj3YoFW6jMo9B5B+3R5k8yrMi dodox@dodox-ProArt"
|
|
|
|
########################################################
|
|
# Config End
|
|
########################################################
|
|
|
|
set -euo pipefail
|
|
|
|
echo -e "\n$BANNER"
|
|
echo -e "\n[+] Starting post-installation configuration..."
|
|
|
|
# Check for SSH key
|
|
if [ -z "${SSH_KEY:-}" ]; then
|
|
echo "ERROR: No SSH key configured!"
|
|
echo "You must set SSH_KEY variable at the top of this script."
|
|
exit 1
|
|
fi
|
|
|
|
# Check for TPM
|
|
echo "[+] Checking for TPM..."
|
|
if [ ! -d "/sys/class/tpm/tpm0" ]; then
|
|
echo "WARNING: No TPM detected!"
|
|
TPM_ENABLED=false
|
|
else
|
|
echo "TPM detected."
|
|
TPM_ENABLED=true
|
|
fi
|
|
|
|
# Upgrade system packages first
|
|
echo "[+] Upgrading system packages..."
|
|
dnf upgrade -y || echo "WARNING: System upgrade failed"
|
|
|
|
# Install basic packages
|
|
echo "[+] Installing basic packages..."
|
|
dnf install -y epel-release || exit 1
|
|
dnf config-manager --set-enabled crb || exit 1
|
|
dnf install -y zsh git wget curl || exit 1
|
|
|
|
# Create user and add SSH key
|
|
echo "[+] Creating user ${ALMA_USER}..."
|
|
useradd -m -G wheel -s /bin/zsh ${ALMA_USER} || exit 1
|
|
mkdir -p /home/${ALMA_USER}/.ssh
|
|
echo "${SSH_KEY}" > /home/${ALMA_USER}/.ssh/authorized_keys
|
|
chmod 700 /home/${ALMA_USER}/.ssh
|
|
chmod 600 /home/${ALMA_USER}/.ssh/authorized_keys
|
|
chown -R ${ALMA_USER}:${ALMA_USER} /home/${ALMA_USER}/.ssh
|
|
|
|
# Configure passwordless sudo
|
|
echo "[+] Configuring passwordless sudo for ${ALMA_USER}..."
|
|
echo "${ALMA_USER} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/99-${ALMA_USER}
|
|
chmod 440 /etc/sudoers.d/99-${ALMA_USER}
|
|
|
|
# Setup terminal environment for both user and root
|
|
echo "[+] Setting up terminal environment for ${ALMA_USER} and root..."
|
|
|
|
for user_account in "${ALMA_USER}" "root"; do
|
|
echo " - Setting up $user_account..."
|
|
|
|
if [ "$user_account" = "root" ]; then
|
|
home_dir="/root"
|
|
user_prefix=""
|
|
else
|
|
home_dir="/home/${user_account}"
|
|
user_prefix="su - ${user_account} -c"
|
|
fi
|
|
|
|
# Install oh-my-zsh
|
|
if [ "$user_account" = "root" ]; then
|
|
export RUNZSH=no CHSH=no KEEP_ZSHRC=yes && bash -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 2>/dev/null || echo "WARNING: $user_account oh-my-zsh installation failed"
|
|
else
|
|
su - ${user_account} -c 'export RUNZSH=no CHSH=no KEEP_ZSHRC=yes && bash -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"' 2>/dev/null || echo "WARNING: $user_account oh-my-zsh installation failed"
|
|
fi
|
|
|
|
# Install powerlevel10k
|
|
if [ "$user_account" = "root" ]; then
|
|
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${home_dir}/.oh-my-zsh/custom/themes/powerlevel10k 2>/dev/null || echo "WARNING: $user_account powerlevel10k installation failed"
|
|
else
|
|
su - ${user_account} -c 'git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/.oh-my-zsh/custom/themes/powerlevel10k' 2>/dev/null || echo "WARNING: $user_account powerlevel10k installation failed"
|
|
fi
|
|
|
|
# Install dotfiles
|
|
if [ "$user_account" = "root" ]; then
|
|
cd ${home_dir} &&
|
|
git clone https://git.dominik-roth.eu/dodox/nullpoint.git /tmp/nullpoint-dotfiles-${user_account} &&
|
|
cd /tmp/nullpoint-dotfiles-${user_account}/dotfiles &&
|
|
for file in .*; do
|
|
if [ -f "$file" ] && [ "$file" != "." ] && [ "$file" != ".." ]; then
|
|
cp "$file" ${home_dir}/ 2>/dev/null || true
|
|
fi
|
|
done &&
|
|
cd ${home_dir} && rm -rf /tmp/nullpoint-dotfiles-${user_account} || echo "WARNING: $user_account dotfiles installation failed"
|
|
else
|
|
su - ${user_account} -c "
|
|
cd &&
|
|
git clone https://git.dominik-roth.eu/dodox/nullpoint.git /tmp/nullpoint-dotfiles-${user_account} &&
|
|
cd /tmp/nullpoint-dotfiles-${user_account}/dotfiles &&
|
|
for file in .*; do
|
|
if [ -f \"\$file\" ] && [ \"\$file\" != \".\" ] && [ \"\$file\" != \"..\" ]; then
|
|
cp \"\$file\" ~/ 2>/dev/null || true
|
|
fi
|
|
done &&
|
|
cd && rm -rf /tmp/nullpoint-dotfiles-${user_account}
|
|
" || echo "WARNING: $user_account dotfiles installation failed"
|
|
fi
|
|
|
|
# Set zsh as default shell
|
|
if [ "$user_account" = "root" ]; then
|
|
sed -i 's|^root:.*:/bin/bash$|root:x:0:0:root:/root:/bin/zsh|' /etc/passwd
|
|
else
|
|
sed -i "s|^${user_account}:.*:/bin/bash$|${user_account}:x:$(id -u ${user_account}):$(id -g ${user_account})::/home/${user_account}:/bin/zsh|" /etc/passwd
|
|
fi
|
|
done
|
|
|
|
# Set up MOTD
|
|
if [ "$ENABLE_MOTD" = true ]; then
|
|
echo "[+] Setting up MOTD..."
|
|
cat > /etc/motd << MOTD
|
|
|
|
$BANNER
|
|
MOTD
|
|
fi
|
|
|
|
# Modify /etc/os-release to show nullpoint branding
|
|
echo "[+] Updating /etc/os-release with nullpoint branding..."
|
|
if [ -f /etc/os-release ]; then
|
|
# Backup original
|
|
cp /etc/os-release /etc/os-release.bak
|
|
|
|
# Get original PRETTY_NAME value
|
|
ORIG_PRETTY_NAME=$(grep '^PRETTY_NAME=' /etc/os-release | cut -d'"' -f2)
|
|
|
|
# Update PRETTY_NAME to show nullpoint with base OS info
|
|
sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"nullpoint (base: ${ORIG_PRETTY_NAME})\"/" /etc/os-release
|
|
|
|
echo " - Updated PRETTY_NAME to 'nullpoint (base: ${ORIG_PRETTY_NAME})'"
|
|
fi
|
|
|
|
# Install additional packages
|
|
echo "[+] Installing additional packages..."
|
|
dnf install -y \
|
|
clevis clevis-luks tpm2-tools tpm2-tss \
|
|
tmux neovim python3-pip python3.13 python3.13-pip \
|
|
tree gcc make autoconf automake tar bzip2 \
|
|
bash-completion || exit 1
|
|
|
|
|
|
# Install dropbear for early boot SSH
|
|
echo "[+] Installing dropbear for early boot SSH..."
|
|
dnf install -y dropbear dracut-network || exit 1
|
|
|
|
# Install modern CLI tools
|
|
echo "[+] Installing lsd, bat, and fastfetch..."
|
|
|
|
# Try to install fastfetch from repos first
|
|
dnf install -y fastfetch || echo "fastfetch not available in repos, skipping"
|
|
|
|
# Create nullpoint logo file for fastfetch
|
|
echo "[+] Creating nullpoint logo file..."
|
|
cat > /etc/nullpoint-logo << 'EOF'
|
|
__.,,.__
|
|
:^7J5GB##&&##GPY?~:
|
|
^75B&@@@@@@&&&@@@@@@@#GJ~:
|
|
5&@@@&B5?7~^^^^^~!7YP#@@@@#!
|
|
Y##P7^ :~JB#B!
|
|
:: :
|
|
7PP?: :^~!!~^: :?PP7
|
|
:B@@B: !5B&@@@@&B5! :#@@B:
|
|
:!!: ^G@@@&BPPB@@@@G^ :!!:
|
|
:B@@@5^ ^5@@@B:
|
|
:7J7: !@@@# :&@@@~ :?J7:
|
|
J@@@5 :#@@@Y: :Y@@@B: 5@@@J
|
|
!@@@&^ ~B@@@&G55G&@@@B~ ~&@@@~
|
|
5@@@G: :7P#@@@@@@#P7: :B@@@Y
|
|
:P@@@B~ :~!77!~: ~B@@@P
|
|
Y@@@&Y^ ^5@@@@J
|
|
!G@@@&P7^ ^7P&@@@G~
|
|
!P&@@@&B? :: ?B&@@@&P!
|
|
^75#&&Y :P&&5: 5&&B57^
|
|
:^^ :P&&5: ^^:
|
|
^^
|
|
EOF
|
|
|
|
# Install user-specific tools for both user and root
|
|
echo "[+] Installing user-specific tools..."
|
|
# Install for user
|
|
echo " - Installing for ${ALMA_USER}..."
|
|
su - ${ALMA_USER} -c 'curl -fsSL https://claude.ai/install.sh | bash' || echo "WARNING: ${ALMA_USER} Claude Code installation failed"
|
|
su - ${ALMA_USER} -c 'python3.13 -m pip install --user bpytop' || echo "WARNING: ${ALMA_USER} bpytop installation failed"
|
|
|
|
# Install for root
|
|
echo " - Installing for root..."
|
|
curl -fsSL https://claude.ai/install.sh | bash || echo "WARNING: root Claude Code installation failed"
|
|
python3.13 -m pip install bpytop || echo "WARNING: root bpytop installation failed"
|
|
|
|
# Install Docker from official repository
|
|
echo "[+] Installing Docker..."
|
|
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo || echo "WARNING: Docker repo setup failed"
|
|
dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin || echo "WARNING: Docker installation failed"
|
|
systemctl enable docker || echo "WARNING: Docker enable failed"
|
|
usermod -aG docker ${ALMA_USER} || echo "WARNING: Adding user to docker group failed"
|
|
|
|
# Install using fixed versions that should work
|
|
LSD_VERSION="1.0.0"
|
|
BAT_VERSION="0.24.0"
|
|
|
|
# Download and install lsd
|
|
if curl -sL "https://github.com/lsd-rs/lsd/releases/download/v${LSD_VERSION}/lsd-v${LSD_VERSION}-x86_64-unknown-linux-musl.tar.gz" | tar xz -C /tmp; then
|
|
mv /tmp/lsd-*/lsd /usr/local/bin/ 2>/dev/null || true
|
|
chmod +x /usr/local/bin/lsd 2>/dev/null || true
|
|
fi
|
|
|
|
# Download and install bat
|
|
if curl -sL "https://github.com/sharkdp/bat/releases/download/v${BAT_VERSION}/bat-v${BAT_VERSION}-x86_64-unknown-linux-musl.tar.gz" | tar xz -C /tmp; then
|
|
mv /tmp/bat-*/bat /usr/local/bin/ 2>/dev/null || true
|
|
chmod +x /usr/local/bin/bat 2>/dev/null || true
|
|
fi
|
|
|
|
# Create batman script for fancy man pages
|
|
cat > /usr/local/bin/batman << 'BATMAN'
|
|
#!/bin/bash
|
|
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
|
|
export MANROFFOPT="-c"
|
|
man "$@"
|
|
BATMAN
|
|
chmod +x /usr/local/bin/batman
|
|
|
|
# Create .tmp directory for user and root
|
|
mkdir -p /home/${ALMA_USER}/.tmp
|
|
chown ${ALMA_USER}:${ALMA_USER} /home/${ALMA_USER}/.tmp
|
|
mkdir -p /root/.tmp
|
|
|
|
# Configure Clevis for automatic unlock
|
|
if [ ${#TANG_SERVERS[@]} -gt 0 ] || [ "$TPM_ENABLED" = true ]; then
|
|
echo "[+] Configuring Clevis for automatic unlock..."
|
|
|
|
# Find LUKS devices
|
|
LUKS_DEVICES=$(lsblk -o NAME,FSTYPE -nr | grep crypto_LUKS | cut -d' ' -f1)
|
|
|
|
for device in $LUKS_DEVICES; do
|
|
DEVICE_PATH="/dev/${device}"
|
|
echo "Configuring Clevis for ${DEVICE_PATH}..."
|
|
|
|
if [ "$TPM_ENABLED" = true ] && [ ${#TANG_SERVERS[@]} -eq 0 ]; then
|
|
# TPM only
|
|
clevis luks bind -d "$DEVICE_PATH" tpm2 "{\"pcr_bank\":\"$TPM_PCR_BANK\",\"pcr_ids\":\"$TPM_PCR_IDS\"}"
|
|
elif [ "$TPM_ENABLED" = false ] && [ ${#TANG_SERVERS[@]} -gt 0 ]; then
|
|
# Tang only
|
|
for server in "${TANG_SERVERS[@]}"; do
|
|
read -r url thumbprint <<< "$server"
|
|
clevis luks bind -d "$DEVICE_PATH" tang "{\"url\":\"$url\",\"thp\":\"$thumbprint\"}"
|
|
done
|
|
elif [ "$TPM_ENABLED" = true ] && [ ${#TANG_SERVERS[@]} -gt 0 ]; then
|
|
# Both TPM and Tang (require both)
|
|
CONFIG="{\"t\":2,\"pins\":{"
|
|
CONFIG+="\"tpm2\":{\"pcr_bank\":\"$TPM_PCR_BANK\",\"pcr_ids\":\"$TPM_PCR_IDS\"},"
|
|
CONFIG+="\"tang\":{\"t\":1,\"tang\":["
|
|
for server in "${TANG_SERVERS[@]}"; do
|
|
read -r url thumbprint <<< "$server"
|
|
CONFIG+="{\"url\":\"$url\",\"thp\":\"$thumbprint\"},"
|
|
done
|
|
CONFIG="${CONFIG%,}]}}}"
|
|
clevis luks bind -d "$DEVICE_PATH" sss "$CONFIG"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Enable Clevis for early boot (only needed for AlmaLinux < 8.7)
|
|
echo "[+] Configuring Clevis for early boot..."
|
|
OS_VERSION=$(cat /etc/redhat-release | grep -oE '[0-9]+\.[0-9]+' | head -1)
|
|
if [[ "$(echo "$OS_VERSION < 8.7" | bc)" -eq 1 ]]; then
|
|
echo " - Enabling clevis-luks-askpass.path for AlmaLinux $OS_VERSION"
|
|
systemctl enable clevis-luks-askpass.path || true
|
|
else
|
|
echo " - AlmaLinux $OS_VERSION: clevis-luks-askpass.path not needed"
|
|
fi
|
|
|
|
# Configure dropbear for remote unlock
|
|
echo "[+] Configuring dropbear SSH for remote unlock..."
|
|
|
|
# Create custom dracut module for dropbear SSH
|
|
mkdir -p /usr/lib/dracut/modules.d/60dropbear-ssh
|
|
|
|
# Create the module setup script
|
|
cat > /usr/lib/dracut/modules.d/60dropbear-ssh/module-setup.sh << 'EOF'
|
|
#!/bin/bash
|
|
|
|
check() {
|
|
require_binaries dropbear dbclient dropbearkey dropbearconvert || return 1
|
|
return 0
|
|
}
|
|
|
|
depends() {
|
|
echo network
|
|
}
|
|
|
|
install() {
|
|
inst_multiple dropbear dbclient dropbearkey dropbearconvert
|
|
|
|
# Create directories
|
|
inst_dir /etc/dropbear
|
|
inst_dir /var/log
|
|
inst_dir /root/.ssh
|
|
|
|
# Copy authorized keys if they exist
|
|
if [ -f /etc/dropbear/authorized_keys ]; then
|
|
inst /etc/dropbear/authorized_keys /root/.ssh/authorized_keys
|
|
fi
|
|
|
|
# Install ED25519 host key only
|
|
keyfile="/etc/dropbear/dropbear_ed25519_host_key"
|
|
if [ ! -f "$keyfile" ]; then
|
|
dropbearkey -t ed25519 -f "$keyfile" 2>/dev/null
|
|
fi
|
|
[ -f "$keyfile" ] && inst "$keyfile"
|
|
|
|
# Install the service
|
|
inst_simple "$moddir/dropbear.service" /etc/systemd/system/dropbear.service
|
|
systemctl -q --root "$initdir" enable dropbear.service
|
|
|
|
# Install unlock helper
|
|
inst_simple "$moddir/unlock-luks.sh" /usr/bin/unlock-luks
|
|
chmod 755 "$initdir/usr/bin/unlock-luks"
|
|
}
|
|
EOF
|
|
|
|
# Create systemd service for dropbear
|
|
cat > /usr/lib/dracut/modules.d/60dropbear-ssh/dropbear.service << 'EOF'
|
|
[Unit]
|
|
Description=Dropbear SSH Server
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=forking
|
|
ExecStart=/usr/sbin/dropbear -R -E -p 22
|
|
ExecReload=/bin/kill -HUP $MAINPID
|
|
KillMode=process
|
|
Restart=on-failure
|
|
|
|
[Install]
|
|
WantedBy=sysinit.target
|
|
EOF
|
|
|
|
# Create unlock helper script
|
|
cat > /usr/lib/dracut/modules.d/60dropbear-ssh/unlock-luks.sh << 'EOF'
|
|
#!/bin/bash
|
|
echo "=== LUKS Remote Unlock Helper ==="
|
|
echo ""
|
|
echo "Checking for encrypted devices..."
|
|
|
|
# Show block devices if available
|
|
if command -v lsblk >/dev/null 2>&1; then
|
|
echo "Block devices:"
|
|
lsblk -o NAME,SIZE,TYPE,FSTYPE 2>/dev/null || echo " (lsblk not available)"
|
|
else
|
|
echo "Block devices: (listing /dev/sd* and /dev/md*)"
|
|
ls -la /dev/sd* /dev/md* 2>/dev/null || echo " No standard devices found"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Encrypted devices status:"
|
|
# Check for LUKS devices waiting to be unlocked
|
|
for dev in /dev/mapper/luks-*; do
|
|
if [ -e "$dev" ]; then
|
|
echo " Found: $dev"
|
|
fi
|
|
done
|
|
|
|
# Check systemd-ask-password files directly
|
|
if [ -d /run/systemd/ask-password ]; then
|
|
echo ""
|
|
echo "Password prompts waiting:"
|
|
ls -la /run/systemd/ask-password/ 2>/dev/null
|
|
fi
|
|
|
|
echo ""
|
|
echo "Starting unlock process..."
|
|
echo "Enter your LUKS passphrase when prompted:"
|
|
echo ""
|
|
|
|
# Run the password agent
|
|
if command -v systemd-tty-ask-password-agent >/dev/null 2>&1; then
|
|
systemd-tty-ask-password-agent
|
|
else
|
|
echo "ERROR: systemd-tty-ask-password-agent not found!"
|
|
echo "Try running: /lib/systemd/systemd-tty-ask-password-agent"
|
|
fi
|
|
EOF
|
|
|
|
chmod +x /usr/lib/dracut/modules.d/60dropbear-ssh/*.sh
|
|
|
|
# Setup dropbear authorized keys
|
|
mkdir -p /etc/dropbear
|
|
echo "${SSH_KEY}" > /etc/dropbear/authorized_keys
|
|
chmod 600 /etc/dropbear/authorized_keys
|
|
|
|
# Generate ED25519 host key only (most secure)
|
|
echo "[+] Generating ED25519 SSH host key..."
|
|
|
|
# Use system SSH key if available, otherwise generate dropbear key
|
|
openssh_key="/etc/ssh/ssh_host_ed25519_key"
|
|
dropbear_key="/etc/dropbear/dropbear_ed25519_host_key"
|
|
|
|
if [ -f "$openssh_key" ] && command -v dropbearconvert >/dev/null 2>&1; then
|
|
echo " Converting existing OpenSSH ED25519 key to dropbear format..."
|
|
dropbearconvert openssh dropbear "$openssh_key" "$dropbear_key" 2>/dev/null || {
|
|
echo " Conversion failed, generating new dropbear key..."
|
|
dropbearkey -t ed25519 -f "$dropbear_key" | grep -v "Generating" || true
|
|
}
|
|
elif [ ! -f "$dropbear_key" ]; then
|
|
echo " Generating new ED25519 key..."
|
|
dropbearkey -t ed25519 -f "$dropbear_key" | grep -v "Generating" || true
|
|
|
|
# Also generate OpenSSH format to prevent key mismatch after boot
|
|
if command -v ssh-keygen >/dev/null 2>&1; then
|
|
echo " Generating matching OpenSSH key..."
|
|
mkdir -p /etc/ssh
|
|
# Extract public key and generate OpenSSH private key
|
|
dropbearkey -y -f "$dropbear_key" | grep "^ssh-" > "${openssh_key}.pub"
|
|
# Note: Direct conversion from dropbear to openssh private key requires dropbearconvert
|
|
# For now, we'll have different keys but document the solution
|
|
fi
|
|
fi
|
|
|
|
# Display SHA256 fingerprint
|
|
if command -v ssh-keygen >/dev/null 2>&1; then
|
|
fingerprint=$(dropbearkey -y -f "$dropbear_key" | ssh-keygen -lf - -E sha256 2>/dev/null | awk '{print $2}')
|
|
if [ -n "$fingerprint" ]; then
|
|
echo " SHA256 fingerprint: $fingerprint"
|
|
echo " Note: This is the initramfs (rescue) SSH fingerprint."
|
|
echo " The normal system SSH may have a different fingerprint."
|
|
fi
|
|
fi
|
|
|
|
# Configure dracut
|
|
cat > /etc/dracut.conf.d/60-dropbear-ssh.conf << 'EOF'
|
|
# Enable network and dropbear SSH
|
|
add_dracutmodules+=" network dropbear-ssh "
|
|
# Network configuration
|
|
kernel_cmdline="rd.neednet=1"
|
|
EOF
|
|
|
|
# Regenerate initramfs
|
|
echo "[+] Regenerating initramfs..."
|
|
dracut -f --regenerate-all
|
|
|
|
# Enable required services
|
|
echo "[+] Enabling services..."
|
|
# systemctl enable stratisd # Not needed without Stratis
|
|
systemctl enable sshd
|
|
|
|
# Secure SSH configuration
|
|
echo "[+] Securing SSH..."
|
|
{
|
|
# Disable root login
|
|
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
|
|
|
|
# Only allow SSH key authentication
|
|
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
|
|
sed -i 's/^#*ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
|
|
sed -i 's/^#*UsePAM.*/UsePAM no/' /etc/ssh/sshd_config
|
|
|
|
# Only allow specific user
|
|
echo "AllowUsers ${ALMA_USER}" >> /etc/ssh/sshd_config
|
|
|
|
echo " - Root login disabled"
|
|
echo " - Password authentication disabled"
|
|
echo " - Only user '${ALMA_USER}' allowed"
|
|
}
|
|
|
|
# Set SELinux to enforcing
|
|
echo "[+] Setting SELinux to enforcing..."
|
|
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
|
|
|
|
echo "✅ Post-installation complete!"
|
|
echo ""
|
|
|
|
# Display SSH host key fingerprints
|
|
echo "SSH Host Key Fingerprints:"
|
|
ed25519_fp=""
|
|
dropbear_fp=""
|
|
|
|
if [ -f "/etc/ssh/ssh_host_ed25519_key.pub" ] && command -v ssh-keygen >/dev/null 2>&1; then
|
|
ed25519_fp=$(ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub -E sha256 2>/dev/null | awk '{print $2}')
|
|
fi
|
|
|
|
if [ -f "/etc/dropbear/dropbear_ed25519_host_key" ] && command -v ssh-keygen >/dev/null 2>&1; then
|
|
dropbear_fp=$(dropbearkey -y -f /etc/dropbear/dropbear_ed25519_host_key 2>/dev/null | ssh-keygen -lf - -E sha256 2>/dev/null | awk '{print $2}')
|
|
fi
|
|
|
|
if [ -n "$ed25519_fp" ] && [ -n "$dropbear_fp" ] && [ "$ed25519_fp" = "$dropbear_fp" ]; then
|
|
echo " SSH (ED25519): $ed25519_fp (same for both rescue and normal)"
|
|
elif [ -n "$ed25519_fp" ] && [ -n "$dropbear_fp" ]; then
|
|
echo " Normal SSH (ED25519): $ed25519_fp"
|
|
echo " Rescue SSH (ED25519): $dropbear_fp"
|
|
elif [ -n "$ed25519_fp" ]; then
|
|
echo " Normal SSH (ED25519): $ed25519_fp"
|
|
elif [ -n "$dropbear_fp" ]; then
|
|
echo " Rescue SSH (ED25519): $dropbear_fp"
|
|
else
|
|
echo " No ED25519 keys found"
|
|
fi
|
|
|
|
echo ""
|
|
echo "IMPORTANT: Save the LUKS passphrase from install.conf securely!"
|
|
echo ""
|
|
echo "Next Steps:"
|
|
echo "1. Manually reboot the system when ready"
|
|
echo "2. SSH root@<server-ip> → run 'unlock-luks' → enter passphrase"
|
|
echo "3. System finalizes setup and reboots automatically"
|
|
echo "4. SSH root@<server-ip> → run 'unlock-luks' → enter passphrase again"
|
|
echo "5. System is ready → SSH as user '${ALMA_USER}'"
|
|
echo ""
|
|
echo "Future boots: Only one unlock needed (or automatic if Tang/Clevis configured)" |