nullpoint/install.sh
2025-08-25 11:07:39 +02:00

252 lines
7.8 KiB
Bash

#!/bin/bash
# nullpoint installer - run this from Hetzner rescue mode
# Use get.sh for wget piping: wget -qO- https://git.dominik-roth.eu/dodox/nullpoint/raw/branch/master/get.sh | 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
)
clear
echo -e "\n$BANNER"
echo -e "\n[+] nullpoint installer starting..."
# Check if we're in Hetzner rescue mode
if [ ! -f /etc/hetzner-build ]; then
echo "ERROR: This script must be run from Hetzner rescue mode!"
exit 1
fi
# Get SSH key from current session
echo "[+] Detecting SSH key from current session..."
SSH_KEY=$(grep "^ssh-" ~/.ssh/authorized_keys | head -1)
if [ -z "$SSH_KEY" ]; then
echo "ERROR: No SSH key found in authorized_keys!"
echo "Please enter your SSH public key:"
read -r SSH_KEY
if [ -z "$SSH_KEY" ]; then
echo "SSH key is required!"
exit 1
fi
fi
echo "Found SSH key: ${SSH_KEY:0:50}..."
# Ask for hostname
echo -e "\n[+] Server configuration"
read -r -p "Enter hostname [nullpoint]: " HOSTNAME < /dev/tty
HOSTNAME=${HOSTNAME:-nullpoint}
# Ask for username
read -r -p "Enter username for admin account [null]: " USERNAME < /dev/tty
USERNAME=${USERNAME:-null}
# Generate secure LUKS passphrase
echo -e "\n[+] Generating secure LUKS passphrase..."
LUKS_PASS=$(openssl rand -base64 30)
echo -e "\n================================================"
echo "LUKS PASSPHRASE (SAVE THIS!):"
echo "$LUKS_PASS"
echo "================================================"
echo -e "\nPress Enter when you've saved the passphrase..."
read -r < /dev/tty
# Check if we're already in the nullpoint directory or need to use it
if [ -f "install.conf" ] && [ -f "post-install.sh" ]; then
echo "[+] Using local nullpoint files..."
else
# Clean up any existing directory
if [ -d "/tmp/nullpoint" ]; then
rm -rf /tmp/nullpoint
fi
echo "[+] Downloading nullpoint configuration..."
git clone https://git.dominik-roth.eu/dodox/nullpoint.git /tmp/nullpoint
cd /tmp/nullpoint
fi
echo "[+] Configuring installation..."
# Auto-detect drives
echo "[+] Detecting drives..."
DRIVES=($(lsblk -dno NAME,TYPE | grep disk | awk '{print "/dev/"$1}' | sort))
if [ ${#DRIVES[@]} -lt 2 ]; then
echo "ERROR: Need at least 2 drives for RAID1, found ${#DRIVES[@]}"
exit 1
fi
DRIVE1="${DRIVES[0]}"
DRIVE2="${DRIVES[1]}"
echo " Found drives: $DRIVE1 and $DRIVE2"
# Update install.conf with detected drives
if ! sed -i "s|^DRIVE1 .*|DRIVE1 $DRIVE1|" install.conf; then
echo "ERROR: Failed to update DRIVE1 in install.conf"
exit 1
fi
if ! sed -i "s|^DRIVE2 .*|DRIVE2 $DRIVE2|" install.conf; then
echo "ERROR: Failed to update DRIVE2 in install.conf"
exit 1
fi
# Update hostname
if ! sed -i "s/^HOSTNAME .*/HOSTNAME $HOSTNAME/" install.conf; then
echo "ERROR: Failed to update HOSTNAME in install.conf"
exit 1
fi
# Use awk for CRYPTPASSWORD to handle special characters
if ! awk -v pass="$LUKS_PASS" '
/^CRYPTPASSWORD / { print "CRYPTPASSWORD " pass; next }
{ print }
' install.conf > install.conf.tmp; then
echo "ERROR: Failed to update CRYPTPASSWORD in install.conf"
exit 1
fi
mv install.conf.tmp install.conf
# Update post-install.sh
if ! sed -i "s/^ALMA_USER=.*/ALMA_USER=\"$USERNAME\"/" post-install.sh; then
echo "ERROR: Failed to update ALMA_USER in post-install.sh"
exit 1
fi
# Use awk to replace SSH_KEY line to avoid sed issues with special characters
if ! awk -v key="$SSH_KEY" '
/^SSH_KEY=/ { print "SSH_KEY=\"" key "\""; next }
{ print }
' post-install.sh > post-install.sh.tmp; then
echo "ERROR: Failed to update SSH_KEY in post-install.sh"
exit 1
fi
mv post-install.sh.tmp post-install.sh
# Copy to root directory where installimage expects them
if ! cp install.conf /root/; then
echo "ERROR: Failed to copy install.conf to /root/"
exit 1
fi
if ! cp post-install.sh /root/; then
echo "ERROR: Failed to copy post-install.sh to /root/"
exit 1
fi
chmod +x /root/post-install.sh
# Ask for optional features
echo -e "\n[+] Optional features:"
read -r -p "Do you have a TPM and want to use it? [y/N]: " USE_TPM < /dev/tty
if [[ "$USE_TPM" =~ ^[Yy]$ ]]; then
echo "TPM will be configured if available."
else
sed -i 's/^TPM_ENABLED=.*/TPM_ENABLED=false/' /root/post-install.sh
fi
read -r -p "Do you want to configure remote unlock Tang servers? [y/N]: " USE_TANG < /dev/tty
if [[ "$USE_TANG" =~ ^[Yy]$ ]]; then
echo "Configuring Tang servers..."
TANG_CONFIG=""
while true; do
read -r -p "Enter Tang server URL (or press Enter to finish): " TANG_URL < /dev/tty
if [ -z "$TANG_URL" ]; then
break
fi
read -r -p "Enter thumbprint for $TANG_URL: " TANG_THUMBPRINT < /dev/tty
if [ -n "$TANG_THUMBPRINT" ]; then
TANG_CONFIG+=" \"$TANG_URL $TANG_THUMBPRINT\"\n"
echo "Added Tang server: $TANG_URL"
else
echo "Skipping server (no thumbprint provided)"
fi
done
if [ -n "$TANG_CONFIG" ]; then
# Update the TANG_SERVERS array in post-install.sh
sed -i '/^TANG_SERVERS=(/,/^)/ {
/^TANG_SERVERS=(/ {
r /dev/stdin
d
}
/^)/ !d
}' /root/post-install.sh << EOF
TANG_SERVERS=(
$TANG_CONFIG)
EOF
echo "Configured Tang servers in post-install script."
else
echo "No Tang servers configured."
fi
fi
# Final confirmation
echo -e "\n[+] Ready to install with these settings:"
echo " Hostname: $HOSTNAME"
echo " Username: $USERNAME"
echo " SSH Key: ${SSH_KEY:0:50}..."
echo " LUKS Passphrase: $LUKS_PASS"
echo ""
read -r -p "Proceed with installation? [Y/n]: " CONFIRM < /dev/tty
if [[ "$CONFIRM" =~ ^[Nn]$ ]]; then
echo "Installation cancelled."
exit 1
fi
# Check if installimage exists
if ! command -v installimage &> /dev/null; then
echo "ERROR: installimage command not found!"
echo "This might not be a Hetzner rescue system, or installimage is not in PATH."
echo "On Hetzner rescue, installimage is usually at /root/.oldroot/nfs/install/installimage"
# Try common locations
if [ -x "/root/.oldroot/nfs/install/installimage" ]; then
echo "Found installimage at /root/.oldroot/nfs/install/installimage"
INSTALLIMAGE_CMD="/root/.oldroot/nfs/install/installimage"
else
echo "Could not find installimage. Please check your Hetzner rescue environment."
exit 1
fi
else
INSTALLIMAGE_CMD="installimage"
fi
# Run the installer
echo -e "\n[+] Starting Hetzner installimage..."
echo "The installer will now run. Follow any prompts if needed."
echo ""
if ! $INSTALLIMAGE_CMD -a -c /root/install.conf -x /root/post-install.sh; then
echo -e "\nERROR: Installation failed!"
exit 1
fi
echo -e "\n[+] Installation complete!"
echo ""
echo "IMPORTANT REMINDERS:"
echo "1. Save your LUKS passphrase securely!"
echo "2. After reboot, you'll need to enter it twice (once per disk)"
echo "3. SSH to the server as user '$USERNAME'"
echo ""
echo "The system is ready for use!"