Add files via upload
This commit is contained in:
@@ -0,0 +1,879 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ubuntu 24.04 Post-Installation Script
|
||||
# Run with: sudo bash post-install.sh
|
||||
|
||||
echo "=== Ubuntu 24.04 Post-Installation Script ==="
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the actual user (not root)
|
||||
ACTUAL_USER="${SUDO_USER:-$USER}"
|
||||
ACTUAL_HOME=$(getent passwd "$ACTUAL_USER" | cut -d: -f6)
|
||||
|
||||
echo "Note: Script will continue even if individual packages fail to install"
|
||||
echo ""
|
||||
|
||||
# Update package list
|
||||
echo "Updating package lists..."
|
||||
apt update
|
||||
|
||||
# Install basic utilities
|
||||
echo ""
|
||||
echo "Installing basic utilities..."
|
||||
echo " - net-tools: Network configuration tools (ifconfig, netstat, etc.)"
|
||||
echo " - ncdu: Disk usage analyzer with ncurses interface"
|
||||
echo " - git: Version control system"
|
||||
echo " - curl: Command-line tool for transferring data with URLs"
|
||||
echo " - wget: Network downloader"
|
||||
echo " - vim: Advanced text editor"
|
||||
echo " - htop: Interactive process viewer"
|
||||
echo " - tree: Display directory structure in tree format"
|
||||
echo " - zip/unzip: Archive compression utilities"
|
||||
echo " - rclone: Rsync for cloud storage and local drives (backup tool)"
|
||||
echo ""
|
||||
|
||||
apt install -y \
|
||||
net-tools \
|
||||
ncdu \
|
||||
git \
|
||||
curl \
|
||||
wget \
|
||||
vim \
|
||||
htop \
|
||||
tree \
|
||||
zip \
|
||||
unzip \
|
||||
rclone || echo "Warning: Some utilities failed to install, continuing..."
|
||||
|
||||
# Install OpenSSH Server
|
||||
echo ""
|
||||
echo "Installing OpenSSH Server..."
|
||||
echo " - openssh-server: SSH server for remote access"
|
||||
echo ""
|
||||
|
||||
apt install -y openssh-server || echo "Warning: OpenSSH server installation failed, continuing..."
|
||||
|
||||
# Start and enable SSH service
|
||||
systemctl start ssh || echo "Warning: Failed to start SSH"
|
||||
systemctl enable ssh || echo "Warning: Failed to enable SSH"
|
||||
|
||||
# Generate SSH key for this computer
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "SSH KEY GENERATION"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
read -p "Generate a new SSH key for this computer? (y/n): " GENERATE_KEY
|
||||
|
||||
if [ "$GENERATE_KEY" = "y" ] || [ "$GENERATE_KEY" = "Y" ]; then
|
||||
echo ""
|
||||
read -p "Enter a label/comment for the key (e.g., email or hostname) [default: $ACTUAL_USER@$(hostname)]: " KEY_COMMENT
|
||||
|
||||
if [ -z "$KEY_COMMENT" ]; then
|
||||
KEY_COMMENT="$ACTUAL_USER@$(hostname)"
|
||||
fi
|
||||
|
||||
# Check if key already exists
|
||||
if [ -f "$ACTUAL_HOME/.ssh/id_rsa" ]; then
|
||||
echo ""
|
||||
echo "⚠️ WARNING: SSH key already exists at $ACTUAL_HOME/.ssh/id_rsa"
|
||||
read -p "Overwrite existing key? This cannot be undone! (y/n): " OVERWRITE_KEY
|
||||
|
||||
if [ "$OVERWRITE_KEY" != "y" ] && [ "$OVERWRITE_KEY" != "Y" ]; then
|
||||
echo "Skipping key generation."
|
||||
GENERATE_KEY="n"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$GENERATE_KEY" = "y" ] || [ "$GENERATE_KEY" = "Y" ]; then
|
||||
echo ""
|
||||
echo "Generating 4096-bit RSA key pair..."
|
||||
echo "This may take a moment..."
|
||||
|
||||
# Generate key as the actual user, not root
|
||||
sudo -u "$ACTUAL_USER" ssh-keygen -t rsa -b 4096 -C "$KEY_COMMENT" -f "$ACTUAL_HOME/.ssh/id_rsa" -N ""
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "✓ SSH key generated successfully!"
|
||||
echo ""
|
||||
echo "Private key: $ACTUAL_HOME/.ssh/id_rsa (keep this secret!)"
|
||||
echo "Public key: $ACTUAL_HOME/.ssh/id_rsa.pub"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Your PUBLIC key (safe to share):"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
cat "$ACTUAL_HOME/.ssh/id_rsa.pub"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "To use this key:"
|
||||
echo " • Add to GitHub: Settings → SSH and GPG keys → New SSH key"
|
||||
echo " • Add to servers: Copy above key to remote ~/.ssh/authorized_keys"
|
||||
echo " • View anytime: cat ~/.ssh/id_rsa.pub"
|
||||
echo ""
|
||||
else
|
||||
echo "✗ Failed to generate SSH key"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Skipping SSH key generation."
|
||||
fi
|
||||
|
||||
# Import SSH keys from GitHub/Launchpad
|
||||
echo ""
|
||||
read -p "Import SSH keys from GitHub? (enter username or leave blank to skip): " GITHUB_USER
|
||||
read -p "Import SSH keys from Launchpad? (enter username or leave blank to skip): " LAUNCHPAD_USER
|
||||
|
||||
KEYS_IMPORTED=false
|
||||
|
||||
# Create .ssh directory if it doesn't exist
|
||||
mkdir -p "$ACTUAL_HOME/.ssh"
|
||||
touch "$ACTUAL_HOME/.ssh/authorized_keys"
|
||||
chmod 700 "$ACTUAL_HOME/.ssh"
|
||||
chmod 600 "$ACTUAL_HOME/.ssh/authorized_keys"
|
||||
|
||||
if [ -n "$GITHUB_USER" ]; then
|
||||
echo "Importing SSH keys from GitHub user: $GITHUB_USER"
|
||||
if curl -fsSL "https://github.com/$GITHUB_USER.keys" >> "$ACTUAL_HOME/.ssh/authorized_keys" 2>/dev/null; then
|
||||
echo "✓ GitHub keys imported successfully"
|
||||
KEYS_IMPORTED=true
|
||||
else
|
||||
echo "✗ Failed to import GitHub keys"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$LAUNCHPAD_USER" ]; then
|
||||
echo "Importing SSH keys from Launchpad user: $LAUNCHPAD_USER"
|
||||
if curl -fsSL "https://launchpad.net/~$LAUNCHPAD_USER/+sshkeys" >> "$ACTUAL_HOME/.ssh/authorized_keys" 2>/dev/null; then
|
||||
echo "✓ Launchpad keys imported successfully"
|
||||
KEYS_IMPORTED=true
|
||||
else
|
||||
echo "✗ Failed to import Launchpad keys"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix ownership
|
||||
chown -R "$ACTUAL_USER:$ACTUAL_USER" "$ACTUAL_HOME/.ssh"
|
||||
|
||||
# Disable password authentication if keys were imported
|
||||
if [ "$KEYS_IMPORTED" = true ]; then
|
||||
echo ""
|
||||
echo "SSH keys imported. Disabling password authentication..."
|
||||
|
||||
# Backup sshd_config
|
||||
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
|
||||
|
||||
# Disable password authentication
|
||||
sed -i 's/^#*PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
sed -i 's/^#*PasswordAuthentication no/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
|
||||
# Ensure these settings are also set
|
||||
grep -q "^PasswordAuthentication" /etc/ssh/sshd_config || echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
|
||||
|
||||
# Restart SSH service to apply changes
|
||||
systemctl restart ssh
|
||||
|
||||
echo "✓ Password authentication disabled. SSH key authentication required."
|
||||
echo "✓ Backup saved to /etc/ssh/sshd_config.backup"
|
||||
else
|
||||
echo ""
|
||||
echo "No SSH keys imported. Password authentication remains enabled."
|
||||
fi
|
||||
|
||||
|
||||
# Install Docker prerequisites
|
||||
echo ""
|
||||
echo "Installing Docker prerequisites..."
|
||||
echo " - ca-certificates: SSL/TLS certificates for secure connections"
|
||||
echo " - gnupg: GNU Privacy Guard for package verification"
|
||||
echo " - lsb-release: Provides Ubuntu version information"
|
||||
echo ""
|
||||
|
||||
apt install -y \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
lsb-release || echo "Warning: Some prerequisites failed to install, continuing..."
|
||||
|
||||
# Install Docker
|
||||
echo ""
|
||||
echo "Installing Docker..."
|
||||
echo " - Docker Engine: Container runtime platform"
|
||||
echo " - Docker Compose: Multi-container application orchestration"
|
||||
echo ""
|
||||
|
||||
# Remove old Docker packages if they exist
|
||||
apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
|
||||
|
||||
# Add Docker's official GPG key
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
chmod a+r /etc/apt/keyrings/docker.asc
|
||||
|
||||
# Add Docker repository
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# Update package list with Docker repo
|
||||
apt update
|
||||
|
||||
# Install Docker Engine, CLI, containerd, and Docker Compose plugin
|
||||
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin || echo "Warning: Docker installation failed, continuing..."
|
||||
|
||||
# Start and enable Docker service
|
||||
systemctl start docker || echo "Warning: Failed to start Docker"
|
||||
systemctl enable docker || echo "Warning: Failed to enable Docker"
|
||||
|
||||
# Add current user to docker group (if not root)
|
||||
if [ -n "$SUDO_USER" ]; then
|
||||
usermod -aG docker "$SUDO_USER"
|
||||
echo "User $SUDO_USER added to docker group"
|
||||
fi
|
||||
|
||||
# Verify Docker installation
|
||||
echo ""
|
||||
echo "Verifying Docker installation..."
|
||||
docker --version || echo "Warning: Docker verification failed"
|
||||
docker compose version || echo "Warning: Docker Compose verification failed"
|
||||
|
||||
# Install NetBird
|
||||
echo ""
|
||||
echo "Installing NetBird..."
|
||||
echo " - NetBird: Secure mesh VPN for connecting devices"
|
||||
echo ""
|
||||
|
||||
curl -fsSL https://pkgs.netbird.io/install.sh | sh || echo "Warning: NetBird installation failed, continuing..."
|
||||
|
||||
echo ""
|
||||
echo "NetBird installed. Setup instructions:"
|
||||
echo " 1. Create account at https://app.netbird.io (or self-host)"
|
||||
echo " 2. Run 'netbird up' and authenticate via browser"
|
||||
echo ""
|
||||
echo "For NetBird SSH functionality:"
|
||||
echo " • Enable SSH in NetBird dashboard settings"
|
||||
echo " • Use 'netbird ssh <peer-name>' to connect to peers"
|
||||
echo " • NetBird manages SSH keys automatically when using 'netbird ssh'"
|
||||
echo " • Traditional SSH also works using peer IPs from 'netbird status'"
|
||||
echo " • Configure ACL rules in dashboard for SSH access (port 22)"
|
||||
echo ""
|
||||
|
||||
# Install RustDesk
|
||||
echo ""
|
||||
echo "Installing RustDesk..."
|
||||
echo " - RustDesk: Open-source remote desktop software"
|
||||
echo ""
|
||||
|
||||
# Download latest RustDesk .deb package
|
||||
RUSTDESK_VERSION=$(curl -s https://api.github.com/repos/rustdesk/rustdesk/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')
|
||||
RUSTDESK_URL="https://github.com/rustdesk/rustdesk/releases/download/${RUSTDESK_VERSION}/rustdesk-${RUSTDESK_VERSION}-x86_64.deb"
|
||||
|
||||
wget -O /tmp/rustdesk.deb "$RUSTDESK_URL" || echo "Warning: RustDesk download failed, continuing..."
|
||||
|
||||
if [ -f /tmp/rustdesk.deb ]; then
|
||||
apt install -y /tmp/rustdesk.deb || echo "Warning: RustDesk installation failed, continuing..."
|
||||
rm /tmp/rustdesk.deb
|
||||
fi
|
||||
|
||||
# Create rclone backup script and instructions
|
||||
echo ""
|
||||
echo "Setting up rclone backup configuration..."
|
||||
echo ""
|
||||
|
||||
# Create backup script directory
|
||||
mkdir -p /usr/local/bin/backup-scripts
|
||||
|
||||
# Create mount point directories
|
||||
echo ""
|
||||
echo "Creating mount point directories in $ACTUAL_HOME/drives/..."
|
||||
mkdir -p "$ACTUAL_HOME/drives/primary"
|
||||
mkdir -p "$ACTUAL_HOME/drives/backup1"
|
||||
mkdir -p "$ACTUAL_HOME/drives/backup2"
|
||||
chown -R "$ACTUAL_USER:$ACTUAL_USER" "$ACTUAL_HOME/drives"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "DRIVE SETUP - Mount your drives"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Available block devices:"
|
||||
echo ""
|
||||
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,LABEL
|
||||
echo ""
|
||||
|
||||
read -p "Do you want to mount drives now? (y/n): " MOUNT_NOW
|
||||
|
||||
if [ "$MOUNT_NOW" = "y" ] || [ "$MOUNT_NOW" = "Y" ]; then
|
||||
echo ""
|
||||
echo "Enter device paths (e.g., /dev/sdb1) or leave blank to skip"
|
||||
echo ""
|
||||
|
||||
read -p "Primary drive device (e.g., /dev/sdb1): " PRIMARY_DEV
|
||||
read -p "Backup1 drive device (e.g., /dev/sdc1): " BACKUP1_DEV
|
||||
read -p "Backup2 drive device (e.g., /dev/sdd1): " BACKUP2_DEV
|
||||
|
||||
# Mount primary
|
||||
if [ -n "$PRIMARY_DEV" ] && [ -b "$PRIMARY_DEV" ]; then
|
||||
echo "Mounting $PRIMARY_DEV to $ACTUAL_HOME/drives/primary..."
|
||||
mount "$PRIMARY_DEV" "$ACTUAL_HOME/drives/primary" && echo "✓ Primary mounted" || echo "✗ Failed to mount primary"
|
||||
fi
|
||||
|
||||
# Mount backup1
|
||||
if [ -n "$BACKUP1_DEV" ] && [ -b "$BACKUP1_DEV" ]; then
|
||||
echo "Mounting $BACKUP1_DEV to $ACTUAL_HOME/drives/backup1..."
|
||||
mount "$BACKUP1_DEV" "$ACTUAL_HOME/drives/backup1" && echo "✓ Backup1 mounted" || echo "✗ Failed to mount backup1"
|
||||
fi
|
||||
|
||||
# Mount backup2
|
||||
if [ -n "$BACKUP2_DEV" ] && [ -b "$BACKUP2_DEV" ]; then
|
||||
echo "Mounting $BACKUP2_DEV to $ACTUAL_HOME/drives/backup2..."
|
||||
mount "$BACKUP2_DEV" "$ACTUAL_HOME/drives/backup2" && echo "✓ Backup2 mounted" || echo "✗ Failed to mount backup2"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Current mounts:"
|
||||
df -h | grep "$ACTUAL_HOME/drives"
|
||||
|
||||
echo ""
|
||||
read -p "Add these mounts to /etc/fstab for automatic mounting at boot? (y/n): " ADD_FSTAB
|
||||
|
||||
if [ "$ADD_FSTAB" = "y" ] || [ "$ADD_FSTAB" = "Y" ]; then
|
||||
echo ""
|
||||
echo "Adding entries to /etc/fstab..."
|
||||
cp /etc/fstab /etc/fstab.backup-$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
if [ -n "$PRIMARY_DEV" ] && [ -b "$PRIMARY_DEV" ]; then
|
||||
PRIMARY_UUID=$(blkid -s UUID -o value "$PRIMARY_DEV")
|
||||
if [ -n "$PRIMARY_UUID" ]; then
|
||||
echo "UUID=$PRIMARY_UUID $ACTUAL_HOME/drives/primary auto defaults 0 2" >> /etc/fstab
|
||||
echo "✓ Added primary to fstab"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$BACKUP1_DEV" ] && [ -b "$BACKUP1_DEV" ]; then
|
||||
BACKUP1_UUID=$(blkid -s UUID -o value "$BACKUP1_DEV")
|
||||
if [ -n "$BACKUP1_UUID" ]; then
|
||||
echo "UUID=$BACKUP1_UUID $ACTUAL_HOME/drives/backup1 auto defaults 0 2" >> /etc/fstab
|
||||
echo "✓ Added backup1 to fstab"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$BACKUP2_DEV" ] && [ -b "$BACKUP2_DEV" ]; then
|
||||
BACKUP2_UUID=$(blkid -s UUID -o value "$BACKUP2_DEV")
|
||||
if [ -n "$BACKUP2_UUID" ]; then
|
||||
echo "UUID=$BACKUP2_UUID $ACTUAL_HOME/drives/backup2 auto defaults 0 2" >> /etc/fstab
|
||||
echo "✓ Added backup2 to fstab"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✓ Backup of original fstab saved with timestamp"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "Skipping drive mounting. You can mount manually later."
|
||||
echo "Mount points created at:"
|
||||
echo " $ACTUAL_HOME/drives/primary"
|
||||
echo " $ACTUAL_HOME/drives/backup1"
|
||||
echo " $ACTUAL_HOME/drives/backup2"
|
||||
fi
|
||||
|
||||
# Create example backup script with correct paths
|
||||
cat > /usr/local/bin/backup-scripts/rclone-backup.sh << BACKUP_SCRIPT
|
||||
#!/bin/bash
|
||||
|
||||
################################################################################
|
||||
# Rclone SPLIT Backup Script - Divide data between multiple backup drives
|
||||
################################################################################
|
||||
#
|
||||
# RCLONE TERMINOLOGY:
|
||||
# SOURCE (PRIMARY) = Where your data currently lives
|
||||
# DESTINATION (BACKUP) = Where you want exact copies stored
|
||||
#
|
||||
# SPLIT BACKUP STRATEGY:
|
||||
# This script splits your primary data between backup1 and backup2
|
||||
# Perfect for when: Primary is 4TB, Backup1 is 2TB, Backup2 is 2TB
|
||||
#
|
||||
# Example:
|
||||
# primary/work/ → backup1/work/ (backup1 only)
|
||||
# primary/photos/ → backup1/photos/ (backup1 only)
|
||||
# primary/videos/ → backup2/videos/ (backup2 only)
|
||||
# primary/music/ → backup2/music/ (backup2 only)
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# ┌────────────────────────────────────────────────────────────────────┐
|
||||
# │ CONFIGURE THESE PATHS │
|
||||
# └────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
# SOURCE: Primary drive (where your data lives)
|
||||
PRIMARY="$ACTUAL_HOME/drives/primary"
|
||||
|
||||
# DESTINATIONS: Backup drives (where copies will be stored)
|
||||
BACKUP1="$ACTUAL_HOME/drives/backup1"
|
||||
BACKUP2="$ACTUAL_HOME/drives/backup2"
|
||||
|
||||
# ┌────────────────────────────────────────────────────────────────────┐
|
||||
# │ ⚠️ CRITICAL: CONFIGURE WHICH FOLDERS GO TO WHICH BACKUP DRIVE! ⚠️ │
|
||||
# └────────────────────────────────────────────────────────────────────┘
|
||||
#
|
||||
# List folder names that exist in PRIMARY and assign them to backup drives.
|
||||
# Balance the data so each backup drive has roughly equal capacity used.
|
||||
#
|
||||
# Example setup (adjust to match YOUR actual folders):
|
||||
|
||||
# Folders to backup to BACKUP1 only
|
||||
BACKUP1_DIRS=(
|
||||
"documents"
|
||||
"work"
|
||||
"photos"
|
||||
)
|
||||
|
||||
# Folders to backup to BACKUP2 only
|
||||
BACKUP2_DIRS=(
|
||||
"videos"
|
||||
"music"
|
||||
"downloads"
|
||||
)
|
||||
|
||||
# ┌────────────────────────────────────────────────────────────────────┐
|
||||
# │ HOW TO BALANCE YOUR DATA: │
|
||||
# └────────────────────────────────────────────────────────────────────┘
|
||||
#
|
||||
# 1. Check size of each folder on PRIMARY:
|
||||
# du -sh $ACTUAL_HOME/drives/primary/*
|
||||
#
|
||||
# 2. Divide folders between BACKUP1_DIRS and BACKUP2_DIRS so the total
|
||||
# size in each list fits on the respective backup drive
|
||||
#
|
||||
# Example output from du -sh:
|
||||
# 500G primary/work
|
||||
# 800G primary/photos
|
||||
# 1.2T primary/videos
|
||||
# 500G primary/music
|
||||
#
|
||||
# Split strategy (for 2TB backup drives):
|
||||
# BACKUP1_DIRS: work (500G) + photos (800G) = 1.3TB → fits on 2TB drive
|
||||
# BACKUP2_DIRS: videos (1.2T) + music (500G) = 1.7TB → fits on 2TB drive
|
||||
#
|
||||
|
||||
################################################################################
|
||||
# Script logic below - you shouldn't need to edit anything below this line
|
||||
################################################################################
|
||||
|
||||
# Log file
|
||||
LOG="/var/log/rclone-backup.log"
|
||||
|
||||
echo "=== Rclone SPLIT Backup Started: \$(date) ===" | tee -a "\$LOG"
|
||||
echo "SOURCE (Primary): \$PRIMARY" | tee -a "\$LOG"
|
||||
echo "Strategy: Split data between backup drives" | tee -a "\$LOG"
|
||||
echo "" | tee -a "\$LOG"
|
||||
|
||||
# Function to backup specific directories to a destination
|
||||
backup_to_drive() {
|
||||
local dest=\$1
|
||||
local drive_name=\$2
|
||||
shift 2
|
||||
local dirs_array=("\$@")
|
||||
|
||||
if [ ! -d "\$dest" ]; then
|
||||
echo "⚠️ WARNING: \$drive_name (\$dest) not mounted, skipping" | tee -a "\$LOG"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ \${#dirs_array[@]} -eq 0 ]; then
|
||||
echo "⚠️ WARNING: No directories assigned to \$drive_name, skipping" | tee -a "\$LOG"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | tee -a "\$LOG"
|
||||
echo "DESTINATION: \$drive_name (\$dest)" | tee -a "\$LOG"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | tee -a "\$LOG"
|
||||
|
||||
for dir in "\${dirs_array[@]}"; do
|
||||
if [ ! -d "\$PRIMARY/\$dir" ]; then
|
||||
echo " ⚠️ WARNING: \$PRIMARY/\$dir does not exist, skipping" | tee -a "\$LOG"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "" | tee -a "\$LOG"
|
||||
echo " Syncing: \$dir" | tee -a "\$LOG"
|
||||
echo " FROM: \$PRIMARY/\$dir" | tee -a "\$LOG"
|
||||
echo " TO: \$dest/\$dir" | tee -a "\$LOG"
|
||||
|
||||
# Use rclone sync for exact mirroring
|
||||
# SOURCE -> DESTINATION (one-way)
|
||||
# --checksum: verify with checksums (slower but accurate)
|
||||
# --verbose: show what's being copied
|
||||
# --progress: show progress
|
||||
# --delete-during: delete files from dest that don't exist in source
|
||||
|
||||
rclone sync "\$PRIMARY/\$dir" "\$dest/\$dir" \\
|
||||
--checksum \\
|
||||
--verbose \\
|
||||
--progress \\
|
||||
--log-file="\$LOG" \\
|
||||
--stats=30s
|
||||
|
||||
if [ \$? -eq 0 ]; then
|
||||
echo " ✓ \$dir synced successfully to \$drive_name" | tee -a "\$LOG"
|
||||
else
|
||||
echo " ✗ \$dir sync to \$drive_name FAILED" | tee -a "\$LOG"
|
||||
fi
|
||||
done
|
||||
echo "" | tee -a "\$LOG"
|
||||
}
|
||||
|
||||
# Sync to backup drives with their assigned directories
|
||||
backup_to_drive "\$BACKUP1" "Backup Drive 1" "\${BACKUP1_DIRS[@]}"
|
||||
backup_to_drive "\$BACKUP2" "Backup Drive 2" "\${BACKUP2_DIRS[@]}"
|
||||
|
||||
echo "=== Backup Completed: \$(date) ===" | tee -a "\$LOG"
|
||||
BACKUP_SCRIPT
|
||||
|
||||
chmod +x /usr/local/bin/backup-scripts/rclone-backup.sh
|
||||
|
||||
# Create systemd service for automatic backups (optional)
|
||||
cat > /etc/systemd/system/rclone-backup.service << 'SERVICE'
|
||||
[Unit]
|
||||
Description=Rclone Backup Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/backup-scripts/rclone-backup.sh
|
||||
User=root
|
||||
SERVICE
|
||||
|
||||
# Create systemd timer for daily backups at 2 AM (optional)
|
||||
cat > /etc/systemd/system/rclone-backup.timer << 'TIMER'
|
||||
[Unit]
|
||||
Description=Daily Rclone Backup Timer
|
||||
Requires=rclone-backup.service
|
||||
|
||||
[Timer]
|
||||
OnCalendar=daily
|
||||
OnCalendar=02:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
TIMER
|
||||
|
||||
echo "✓ Rclone backup script created at /usr/local/bin/backup-scripts/rclone-backup.sh"
|
||||
echo "✓ Systemd service/timer created (disabled by default)"
|
||||
|
||||
|
||||
# Full system upgrade
|
||||
echo ""
|
||||
echo "Performing full system upgrade..."
|
||||
apt upgrade -y
|
||||
|
||||
# Clean up
|
||||
echo ""
|
||||
echo "Cleaning up..."
|
||||
apt autoremove -y
|
||||
apt autoclean
|
||||
|
||||
echo ""
|
||||
echo "=== Installation Complete! ==="
|
||||
echo ""
|
||||
echo "Installed Software:"
|
||||
echo " ✓ net-tools, ncdu, git, curl, wget, vim, htop, tree, zip/unzip"
|
||||
echo " ✓ rclone - Backup/sync tool"
|
||||
echo " ✓ OpenSSH Server - SSH remote access"
|
||||
echo " ✓ Samba - File sharing (Primary drive shared)"
|
||||
echo " ✓ Docker Engine + Docker Compose"
|
||||
echo " ✓ NetBird - Mesh VPN"
|
||||
echo " ✓ RustDesk - Remote desktop"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "SSH AUTHENTICATION SETUP"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo " SSH Key for This Computer:"
|
||||
if [ "$GENERATE_KEY" = "y" ] || [ "$GENERATE_KEY" = "Y" ]; then
|
||||
if [ -f "$ACTUAL_HOME/.ssh/id_rsa.pub" ]; then
|
||||
echo " ✓ 4096-bit RSA key generated"
|
||||
echo " Public key: $ACTUAL_HOME/.ssh/id_rsa.pub"
|
||||
echo " View with: cat ~/.ssh/id_rsa.pub"
|
||||
else
|
||||
echo " ✗ Key generation was attempted but may have failed"
|
||||
fi
|
||||
else
|
||||
echo " Not generated (skipped during install)"
|
||||
echo " Generate later: ssh-keygen -t rsa -b 4096 -C \"your@email.com\""
|
||||
fi
|
||||
echo ""
|
||||
echo " SSH Server Status:"
|
||||
if [ "$KEYS_IMPORTED" = true ]; then
|
||||
echo " Password authentication: DISABLED (key-only access)"
|
||||
echo " Imported SSH keys: ~/.ssh/authorized_keys"
|
||||
else
|
||||
echo " Password authentication: ENABLED"
|
||||
fi
|
||||
echo ""
|
||||
echo " Traditional SSH Access:"
|
||||
echo " - Uses keys from GitHub/Launchpad (if imported)"
|
||||
echo " - Connect with: ssh user@hostname"
|
||||
if [ "$KEYS_IMPORTED" = true ]; then
|
||||
echo " - Password login: DISABLED (keys required)"
|
||||
else
|
||||
echo " - Password login: ENABLED"
|
||||
fi
|
||||
echo ""
|
||||
echo " NetBird SSH Access (independent of traditional SSH):"
|
||||
echo " - NetBird manages its own keys automatically"
|
||||
echo " - Works even with password auth disabled"
|
||||
echo " - Connect with: netbird ssh <peer-name>"
|
||||
echo " - Enable in NetBird dashboard first"
|
||||
echo ""
|
||||
echo " You can use ANY combination:"
|
||||
echo " ✓ GitHub + Launchpad + NetBird SSH"
|
||||
echo " ✓ GitHub + NetBird SSH"
|
||||
echo " ✓ Launchpad + NetBird SSH"
|
||||
echo " ✓ GitHub + Launchpad (no NetBird)"
|
||||
echo " ✓ Just GitHub or just Launchpad"
|
||||
echo " ✓ Just NetBird SSH"
|
||||
echo " ✓ None (password auth only - if no keys imported)"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "RCLONE BACKUP SETUP - Exact Drive Mirroring"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo " Mount points created at:"
|
||||
echo " $ACTUAL_HOME/drives/primary"
|
||||
echo " $ACTUAL_HOME/drives/backup1"
|
||||
echo " $ACTUAL_HOME/drives/backup2"
|
||||
echo ""
|
||||
if [ "$MOUNT_NOW" = "y" ] || [ "$MOUNT_NOW" = "Y" ]; then
|
||||
echo " ✓ Drives have been mounted (if you provided valid device paths)"
|
||||
echo ""
|
||||
else
|
||||
echo " → Drives NOT mounted yet. To mount manually:"
|
||||
echo " See available drives: lsblk -f"
|
||||
echo " Mount: sudo mount /dev/sdX1 $ACTUAL_HOME/drives/primary"
|
||||
echo " Make permanent: Add to /etc/fstab (see instructions below)"
|
||||
echo ""
|
||||
fi
|
||||
echo " ⚠️ CRITICAL: CONFIGURE BEFORE RUNNING ⚠️"
|
||||
echo " The backup script uses SPLIT BACKUP strategy"
|
||||
echo " You decide which folders go to which backup drive"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ STEP 1: CONFIGURE THE SPLIT BACKUP SCRIPT │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " Edit the backup script:"
|
||||
echo " sudo nano /usr/local/bin/backup-scripts/rclone-backup.sh"
|
||||
echo ""
|
||||
echo " ╔═══════════════════════════════════════════════════════════════╗"
|
||||
echo " ║ SPLIT BACKUP EXPLAINED: ║"
|
||||
echo " ║ ║"
|
||||
echo " ║ Your PRIMARY drive is bigger than either backup drive ║"
|
||||
echo " ║ Example: Primary=4TB, Backup1=2TB, Backup2=2TB ║"
|
||||
echo " ║ ║"
|
||||
echo " ║ Solution: DIVIDE your folders between the two backups ║"
|
||||
echo " ║ • Some folders → backup1 only ║"
|
||||
echo " ║ • Other folders → backup2 only ║"
|
||||
echo " ║ ║"
|
||||
echo " ║ Each folder is backed up to ONE drive, NOT both ║"
|
||||
echo " ╚═══════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " Step 1a: Check how much space your folders use"
|
||||
echo " du -sh $ACTUAL_HOME/drives/primary/*"
|
||||
echo ""
|
||||
echo " Example output:"
|
||||
echo " 500G primary/work"
|
||||
echo " 800G primary/photos"
|
||||
echo " 1.2T primary/videos"
|
||||
echo " 500G primary/music"
|
||||
echo ""
|
||||
echo " Step 1b: Divide folders so each backup drive has enough space"
|
||||
echo ""
|
||||
echo " In the script, find these two lists:"
|
||||
echo ""
|
||||
echo " # Folders to backup to BACKUP1 only (example: 1.3TB total)"
|
||||
echo " BACKUP1_DIRS=("
|
||||
echo " \"work\" # 500G"
|
||||
echo " \"photos\" # 800G"
|
||||
echo " )"
|
||||
echo ""
|
||||
echo " # Folders to backup to BACKUP2 only (example: 1.7TB total)"
|
||||
echo " BACKUP2_DIRS=("
|
||||
echo " \"videos\" # 1.2T"
|
||||
echo " \"music\" # 500G"
|
||||
echo " )"
|
||||
echo ""
|
||||
echo " ⚠️ What this means:"
|
||||
echo " primary/work/ → backup1/work/ (backup1 ONLY)"
|
||||
echo " primary/photos/ → backup1/photos/ (backup1 ONLY)"
|
||||
echo " primary/videos/ → backup2/videos/ (backup2 ONLY)"
|
||||
echo " primary/music/ → backup2/music/ (backup2 ONLY)"
|
||||
echo ""
|
||||
echo " ✓ Benefit: Your 4TB primary fits across two 2TB backups"
|
||||
echo " ⚠️ Risk: If backup1 fails, you lose work/ and photos/ backups"
|
||||
echo " (but original data on primary is still safe!)"
|
||||
echo ""
|
||||
echo " Save with: Ctrl+O, then Enter, then Ctrl+X to exit"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ STEP 2: TEST WITH DRY-RUN (DO THIS FIRST!) │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " Test what would sync to BACKUP1 (without actually copying):"
|
||||
echo ""
|
||||
echo " rclone sync $ACTUAL_HOME/drives/primary/work \\"
|
||||
echo " $ACTUAL_HOME/drives/backup1/work \\"
|
||||
echo " --checksum --dry-run -v"
|
||||
echo ""
|
||||
echo " Test what would sync to BACKUP2:"
|
||||
echo ""
|
||||
echo " rclone sync $ACTUAL_HOME/drives/primary/videos \\"
|
||||
echo " $ACTUAL_HOME/drives/backup2/videos \\"
|
||||
echo " --checksum --dry-run -v"
|
||||
echo ""
|
||||
echo " The dry-run shows:"
|
||||
echo " • Files that would copy FROM primary TO backup"
|
||||
echo " • Files that would be DELETED from backup (not on primary)"
|
||||
echo " • Total data that would transfer"
|
||||
echo ""
|
||||
echo " ⚠️ Read carefully! Make sure the right folders go to the right drives!"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ STEP 3: RUN FIRST BACKUP MANUALLY │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " Only after dry-run looks correct:"
|
||||
echo " sudo /usr/local/bin/backup-scripts/rclone-backup.sh"
|
||||
echo ""
|
||||
echo " The script will sync:"
|
||||
echo " FROM: $ACTUAL_HOME/drives/primary/[BACKUP1_DIRS]"
|
||||
echo " TO: $ACTUAL_HOME/drives/backup1/[same folders]"
|
||||
echo ""
|
||||
echo " FROM: $ACTUAL_HOME/drives/primary/[BACKUP2_DIRS]"
|
||||
echo " TO: $ACTUAL_HOME/drives/backup2/[same folders]"
|
||||
echo ""
|
||||
echo " Each folder goes to its assigned backup drive only!"
|
||||
echo ""
|
||||
echo " Monitor live progress:"
|
||||
echo " tail -f /var/log/rclone-backup.log"
|
||||
echo ""
|
||||
echo " The log shows which folders sync to which backup drives"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ STEP 4: ENABLE AUTOMATIC DAILY BACKUPS (Optional) │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " Only enable after successful manual backup:"
|
||||
echo " sudo systemctl enable rclone-backup.timer"
|
||||
echo " sudo systemctl start rclone-backup.timer"
|
||||
echo ""
|
||||
echo " This will automatically run the split backup daily at 2 AM"
|
||||
echo " (Each folder syncs to its assigned backup drive)"
|
||||
echo ""
|
||||
echo " Check status:"
|
||||
echo " sudo systemctl status rclone-backup.timer"
|
||||
echo " sudo systemctl list-timers"
|
||||
echo ""
|
||||
echo " Change schedule (default: 2 AM daily):"
|
||||
echo " sudo systemctl edit rclone-backup.timer"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ STEP 5: MANUAL MOUNT INSTRUCTIONS (if you skipped earlier) │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " Find drive UUIDs:"
|
||||
echo " sudo blkid"
|
||||
echo ""
|
||||
echo " Edit /etc/fstab for permanent mounts:"
|
||||
echo " sudo nano /etc/fstab"
|
||||
echo ""
|
||||
echo " Add lines like (replace UUID with actual values from blkid):"
|
||||
echo " UUID=xxxx-xxxx $ACTUAL_HOME/drives/primary auto defaults 0 2"
|
||||
echo " UUID=yyyy-yyyy $ACTUAL_HOME/drives/backup1 auto defaults 0 2"
|
||||
echo " UUID=zzzz-zzzz $ACTUAL_HOME/drives/backup2 auto defaults 0 2"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ STEP 6: DRIVE FAILURE & RECOVERY (Split Backup Strategy) │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " If SOURCE (primary) drive fails - CRITICAL SITUATION:"
|
||||
echo " ⚠️ With split backup, you need BOTH backup drives to restore!"
|
||||
echo ""
|
||||
echo " 1. Get a new drive (same size or larger than primary)"
|
||||
echo " 2. Format it: sudo mkfs.ext4 /dev/sdX1"
|
||||
echo " 3. Mount as primary: sudo mount /dev/sdX1 $ACTUAL_HOME/drives/primary"
|
||||
echo " 4. Restore from BOTH backups:"
|
||||
echo " rclone sync $ACTUAL_HOME/drives/backup1/ $ACTUAL_HOME/drives/primary/ --checksum"
|
||||
echo " rclone sync $ACTUAL_HOME/drives/backup2/ $ACTUAL_HOME/drives/primary/ --checksum"
|
||||
echo " 5. Update /etc/fstab with new UUID"
|
||||
echo ""
|
||||
echo " If DESTINATION (backup1 or backup2) drive fails:"
|
||||
echo " ⚠️ You lose backup of those specific folders until drive is replaced!"
|
||||
echo ""
|
||||
echo " Example: backup1 fails (had work/ and photos/ backups)"
|
||||
echo " • Your PRIMARY still has work/ and photos/ (original data is safe)"
|
||||
echo " • backup2 still works (videos/ and music/ are still backed up)"
|
||||
echo " • But work/ and photos/ have NO backup until you fix backup1"
|
||||
echo ""
|
||||
echo " Recovery:"
|
||||
echo " 1. Replace the failed drive"
|
||||
echo " 2. Format: sudo mkfs.ext4 /dev/sdX1"
|
||||
echo " 3. Mount: sudo mount /dev/sdX1 $ACTUAL_HOME/drives/backup1"
|
||||
echo " 4. Update /etc/fstab if needed"
|
||||
echo " 5. Run backup script - rclone will sync the assigned folders back"
|
||||
echo ""
|
||||
echo " ⚠️ IMPORTANT: Replace failed backup drives quickly!"
|
||||
echo " While a backup drive is down, those folders have no redundancy."
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ STEP 7: VERIFY BACKUPS - Check Sync Status │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ VERIFY BACKUPS - Check if PRIMARY and BACKUP match │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " Compare SOURCE (primary) vs DESTINATION (backup):"
|
||||
echo " rclone check $ACTUAL_HOME/drives/primary/documents \\"
|
||||
echo " $ACTUAL_HOME/drives/backup1/documents"
|
||||
echo ""
|
||||
echo " This shows any differences between the two locations."
|
||||
echo " If they match perfectly, you'll see: \"0 differences found\""
|
||||
echo ""
|
||||
echo " One-way check (files that exist on primary but not backup):"
|
||||
echo " rclone check $ACTUAL_HOME/drives/primary/documents \\"
|
||||
echo " $ACTUAL_HOME/drives/backup1/documents \\"
|
||||
echo " --checksum --one-way"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "OTHER IMPORTANT NOTES"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo " Samba File Sharing:"
|
||||
if command -v smbd &> /dev/null && grep -q "\[Primary\]" /etc/samba/smb.conf 2>/dev/null; then
|
||||
echo " ✓ Share 'Primary' is accessible at:"
|
||||
echo " Windows: \\\\$(hostname)\\Primary"
|
||||
echo " Mac/Linux: smb://$(hostname)/Primary"
|
||||
echo " • Username: $ACTUAL_USER"
|
||||
echo " • Use the Samba password you just set"
|
||||
echo ""
|
||||
else
|
||||
echo " Not configured (Samba installation may have failed)"
|
||||
echo ""
|
||||
fi
|
||||
echo " Docker: Log out and back in for group membership to take effect"
|
||||
echo ""
|
||||
echo " NetBird:"
|
||||
echo " 1. Run 'netbird up' (opens browser for authentication)"
|
||||
echo " 2. View connected peers: netbird status"
|
||||
echo " 3. Configure ACLs in dashboard: https://app.netbird.io"
|
||||
echo ""
|
||||
echo " RustDesk: Launch from applications menu or run 'rustdesk'"
|
||||
echo ""
|
||||
@@ -0,0 +1,637 @@
|
||||
# Ubuntu 24.04 Desktop Post-Installation Script
|
||||
|
||||
Automated setup script for Ubuntu 24.04 Desktop that installs essential tools, configures SSH, sets up Docker, configures remote access, and creates a split-backup system using rclone.
|
||||
|
||||
## What This Script Does
|
||||
|
||||
### Core Utilities Installed
|
||||
- **net-tools** - Network utilities (ifconfig, netstat)
|
||||
- **ncdu** - Disk usage analyzer with ncurses interface
|
||||
- **git** - Version control system
|
||||
- **curl & wget** - Download tools
|
||||
- **vim** - Text editor (instructions use nano)
|
||||
- **htop** - Interactive process viewer
|
||||
- **tree** - Directory structure visualizer
|
||||
- **zip/unzip** - Archive utilities
|
||||
- **rclone** - Sync tool for split backup strategy
|
||||
|
||||
### SSH Configuration
|
||||
- **OpenSSH Server** - Enables remote SSH access
|
||||
- **SSH Key Generation** - Creates 4096-bit RSA key pair for this computer
|
||||
- **Key Import** - Optionally imports public keys from GitHub and/or Launchpad
|
||||
- **Security** - Automatically disables password authentication if keys are imported
|
||||
|
||||
### Docker Installation
|
||||
- **Docker Engine** - Latest version from official Docker repository (not snap)
|
||||
- **Docker Compose** - Installed as a plugin (modern method)
|
||||
- **User Configuration** - Adds your user to docker group (run docker without sudo)
|
||||
|
||||
### Samba File Sharing
|
||||
- **Samba Server** - SMB/CIFS file server for network file sharing
|
||||
- **Primary Drive Share** - Entire primary drive shared as "Primary"
|
||||
- **User Configuration** - Creates Samba user matching your system username
|
||||
- **Cross-Platform Access** - Works with Windows, Mac, and Linux
|
||||
|
||||
### Remote Access Tools
|
||||
- **NetBird** - Mesh VPN for secure device connections
|
||||
- Supports both NetBird SSH and traditional SSH
|
||||
- Enables remote access across networks
|
||||
- **RustDesk** - Open-source remote desktop software
|
||||
|
||||
### Backup System - Split Backup Strategy
|
||||
- **Automated rclone backup script** using split-backup approach
|
||||
- **Mount point management** at `~/drives/primary`, `~/drives/backup1`, `~/drives/backup2`
|
||||
- **Interactive drive mounting** with automatic fstab configuration
|
||||
- **Systemd timer** for scheduled daily backups (optional)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Fresh Ubuntu 24.04 Desktop installation
|
||||
- Sudo/root access
|
||||
- Internet connection
|
||||
- (Optional) External drives for backup configuration
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Download the Script
|
||||
|
||||
```bash
|
||||
# Download (replace URL with actual location)
|
||||
wget https://your-domain.com/post-install.sh
|
||||
|
||||
# Or create manually
|
||||
nano post-install.sh
|
||||
# Paste the script content and save (Ctrl+O, Enter, Ctrl+X)
|
||||
```
|
||||
|
||||
### 2. Make Executable
|
||||
|
||||
```bash
|
||||
chmod +x post-install.sh
|
||||
```
|
||||
|
||||
### 3. Run the Script
|
||||
|
||||
```bash
|
||||
sudo ./post-install.sh
|
||||
```
|
||||
|
||||
### 4. Follow Interactive Prompts
|
||||
|
||||
The script will ask you:
|
||||
- **SSH Key Generation**: Generate new 4096-bit RSA key? (y/n)
|
||||
- **Import SSH Keys**: GitHub username, Launchpad username (or leave blank)
|
||||
- **Mount Drives**: Mount backup drives now? (y/n)
|
||||
- **Drive Selection**: Device paths for primary, backup1, backup2 (e.g., /dev/sdb1)
|
||||
- **fstab Configuration**: Add mounts to /etc/fstab for auto-mount? (y/n)
|
||||
- **Samba Password**: Set password for Samba user (suggested: use same as system password)
|
||||
|
||||
### 5. Post-Installation Steps
|
||||
|
||||
**Required:**
|
||||
```bash
|
||||
# Log out and back in for docker group to take effect
|
||||
logout
|
||||
```
|
||||
|
||||
**Recommended:**
|
||||
```bash
|
||||
# Configure rclone backup (see Backup Configuration section)
|
||||
sudo nano /usr/local/bin/backup-scripts/rclone-backup.sh
|
||||
```
|
||||
|
||||
## SSH Configuration
|
||||
|
||||
### SSH Key Combinations Supported
|
||||
|
||||
You can use **any combination** of:
|
||||
- ✓ GitHub keys + Launchpad keys + NetBird SSH
|
||||
- ✓ GitHub keys only
|
||||
- ✓ Launchpad keys only
|
||||
- ✓ NetBird SSH only
|
||||
- ✓ Your generated key + any of the above
|
||||
- ✓ Password authentication only (if no keys imported)
|
||||
|
||||
### Traditional SSH vs NetBird SSH
|
||||
|
||||
**Traditional SSH** (uses imported keys):
|
||||
```bash
|
||||
ssh user@hostname
|
||||
ssh user@192.168.1.100
|
||||
```
|
||||
|
||||
**NetBird SSH** (manages keys automatically):
|
||||
```bash
|
||||
netbird ssh peer-name
|
||||
```
|
||||
|
||||
These work independently - NetBird SSH works even if password auth is disabled.
|
||||
|
||||
### Your Generated SSH Key
|
||||
|
||||
After installation, find your public key:
|
||||
```bash
|
||||
cat ~/.ssh/id_rsa.pub
|
||||
```
|
||||
|
||||
Use it to:
|
||||
- Add to GitHub: Settings → SSH and GPG keys → New SSH key
|
||||
- Add to other servers: Append to remote `~/.ssh/authorized_keys`
|
||||
- Connect from this computer to other servers
|
||||
|
||||
## Backup Configuration
|
||||
|
||||
### Understanding Split Backup Strategy
|
||||
|
||||
**The Problem:**
|
||||
- Your primary drive: 4TB
|
||||
- Your backup drives: 2TB each
|
||||
- Can't fit full primary on one backup drive
|
||||
|
||||
**The Solution:**
|
||||
Divide your data between backup1 and backup2:
|
||||
```
|
||||
primary/work/ (500G) → backup1/work/ ┐
|
||||
primary/photos/ (800G) → backup1/photos/ ├─ 1.3TB on backup1
|
||||
┘
|
||||
primary/videos/ (1.2T) → backup2/videos/ ┐
|
||||
primary/music/ (500G) → backup2/music/ ├─ 1.7TB on backup2
|
||||
┘
|
||||
```
|
||||
|
||||
### Step-by-Step Backup Setup
|
||||
|
||||
#### 1. Check Your Folder Sizes
|
||||
|
||||
```bash
|
||||
du -sh ~/drives/primary/*
|
||||
```
|
||||
|
||||
Example output:
|
||||
```
|
||||
500G primary/work
|
||||
800G primary/photos
|
||||
1.2T primary/videos
|
||||
500G primary/music
|
||||
```
|
||||
|
||||
#### 2. Edit the Backup Script
|
||||
|
||||
```bash
|
||||
sudo nano /usr/local/bin/backup-scripts/rclone-backup.sh
|
||||
```
|
||||
|
||||
Find and edit these sections:
|
||||
|
||||
```bash
|
||||
# Folders to backup to BACKUP1 only
|
||||
BACKUP1_DIRS=(
|
||||
"work" # 500G
|
||||
"photos" # 800G
|
||||
)
|
||||
# Total: ~1.3TB
|
||||
|
||||
# Folders to backup to BACKUP2 only
|
||||
BACKUP2_DIRS=(
|
||||
"videos" # 1.2T
|
||||
"music" # 500G
|
||||
)
|
||||
# Total: ~1.7TB
|
||||
```
|
||||
|
||||
**Balance the data** so each backup drive has enough space.
|
||||
|
||||
#### 3. Test with Dry-Run (CRITICAL!)
|
||||
|
||||
```bash
|
||||
# Test backup1 sync (shows what WOULD happen)
|
||||
rclone sync ~/drives/primary/work ~/drives/backup1/work --checksum --dry-run -v
|
||||
|
||||
# Test backup2 sync
|
||||
rclone sync ~/drives/primary/videos ~/drives/backup2/videos --checksum --dry-run -v
|
||||
```
|
||||
|
||||
Review the output carefully!
|
||||
|
||||
#### 4. Run First Backup
|
||||
|
||||
```bash
|
||||
sudo /usr/local/bin/backup-scripts/rclone-backup.sh
|
||||
```
|
||||
|
||||
Monitor progress:
|
||||
```bash
|
||||
tail -f /var/log/rclone-backup.log
|
||||
```
|
||||
|
||||
#### 5. Enable Automatic Backups (Optional)
|
||||
|
||||
After successful manual backup:
|
||||
```bash
|
||||
sudo systemctl enable rclone-backup.timer
|
||||
sudo systemctl start rclone-backup.timer
|
||||
```
|
||||
|
||||
Check status:
|
||||
```bash
|
||||
sudo systemctl status rclone-backup.timer
|
||||
sudo systemctl list-timers
|
||||
```
|
||||
|
||||
Change schedule (default: 2 AM daily):
|
||||
```bash
|
||||
sudo systemctl edit rclone-backup.timer
|
||||
```
|
||||
|
||||
### Manual Drive Mounting
|
||||
|
||||
If you skipped auto-mounting during installation:
|
||||
|
||||
```bash
|
||||
# Create mount points (already done by script)
|
||||
mkdir -p ~/drives/primary ~/drives/backup1 ~/drives/backup2
|
||||
|
||||
# Find your drives
|
||||
lsblk -f
|
||||
sudo blkid
|
||||
|
||||
# Mount drives
|
||||
sudo mount /dev/sdb1 ~/drives/primary
|
||||
sudo mount /dev/sdc1 ~/drives/backup1
|
||||
sudo mount /dev/sdd1 ~/drives/backup2
|
||||
|
||||
# Make permanent (add to /etc/fstab)
|
||||
sudo nano /etc/fstab
|
||||
```
|
||||
|
||||
Add lines like:
|
||||
```
|
||||
UUID=xxxx-xxxx /home/username/drives/primary auto defaults 0 2
|
||||
UUID=yyyy-yyyy /home/username/drives/backup1 auto defaults 0 2
|
||||
UUID=zzzz-zzzz /home/username/drives/backup2 auto defaults 0 2
|
||||
```
|
||||
|
||||
## Drive Failure Recovery
|
||||
|
||||
### If PRIMARY Drive Fails ⚠️ CRITICAL
|
||||
|
||||
You need **BOTH** backup drives to restore (data is split between them):
|
||||
|
||||
```bash
|
||||
# 1. Get new drive (same size or larger)
|
||||
# 2. Format it
|
||||
sudo mkfs.ext4 /dev/sdX1
|
||||
|
||||
# 3. Mount as primary
|
||||
sudo mount /dev/sdX1 ~/drives/primary
|
||||
|
||||
# 4. Restore from BOTH backups
|
||||
rclone sync ~/drives/backup1/ ~/drives/primary/ --checksum
|
||||
rclone sync ~/drives/backup2/ ~/drives/primary/ --checksum
|
||||
|
||||
# 5. Update /etc/fstab with new UUID
|
||||
sudo blkid /dev/sdX1
|
||||
sudo nano /etc/fstab
|
||||
```
|
||||
|
||||
### If BACKUP Drive Fails
|
||||
|
||||
Example: backup1 fails (contained work/ and photos/ backups)
|
||||
|
||||
**Status:**
|
||||
- ✓ Primary still has work/ and photos/ (original data is safe)
|
||||
- ✓ backup2 still works (videos/ and music/ still backed up)
|
||||
- ⚠️ work/ and photos/ have NO backup until backup1 is replaced
|
||||
|
||||
**Recovery:**
|
||||
```bash
|
||||
# 1. Replace the drive
|
||||
# 2. Format it
|
||||
sudo mkfs.ext4 /dev/sdX1
|
||||
|
||||
# 3. Mount it
|
||||
sudo mount /dev/sdX1 ~/drives/backup1
|
||||
|
||||
# 4. Update /etc/fstab if needed
|
||||
sudo nano /etc/fstab
|
||||
|
||||
# 5. Run backup script - syncs assigned folders back
|
||||
sudo /usr/local/bin/backup-scripts/rclone-backup.sh
|
||||
```
|
||||
|
||||
**⚠️ Replace failed backup drives quickly!** While a backup is down, those folders have no redundancy.
|
||||
|
||||
## Verification Commands
|
||||
|
||||
### Check Backups Match Primary
|
||||
|
||||
```bash
|
||||
# Verify backup1 folders
|
||||
rclone check ~/drives/primary/work ~/drives/backup1/work
|
||||
rclone check ~/drives/primary/photos ~/drives/backup1/photos
|
||||
|
||||
# Verify backup2 folders
|
||||
rclone check ~/drives/primary/videos ~/drives/backup2/videos
|
||||
rclone check ~/drives/primary/music ~/drives/backup2/music
|
||||
```
|
||||
|
||||
If perfect: "0 differences found"
|
||||
|
||||
### Check Space Usage
|
||||
|
||||
```bash
|
||||
# See what's on each drive
|
||||
du -sh ~/drives/primary/*
|
||||
du -sh ~/drives/backup1/*
|
||||
du -sh ~/drives/backup2/*
|
||||
|
||||
# Check free space
|
||||
df -h ~/drives/primary
|
||||
df -h ~/drives/backup1
|
||||
df -h ~/drives/backup2
|
||||
```
|
||||
|
||||
## NetBird Setup
|
||||
|
||||
```bash
|
||||
# 1. Connect to NetBird (opens browser for auth)
|
||||
netbird up
|
||||
|
||||
# 2. View connected peers
|
||||
netbird status
|
||||
|
||||
# 3. SSH via NetBird (if enabled in dashboard)
|
||||
netbird ssh peer-name
|
||||
|
||||
# 4. Configure ACLs and settings
|
||||
# Visit: https://app.netbird.io
|
||||
```
|
||||
|
||||
## Samba File Sharing
|
||||
|
||||
The script automatically shares your **entire primary drive** via Samba.
|
||||
|
||||
### Share Details
|
||||
|
||||
- **Share name**: Primary
|
||||
- **Path**: `~/drives/primary`
|
||||
- **Username**: Your system username
|
||||
- **Password**: The Samba password you set during installation (suggested to match your system password)
|
||||
- **Permissions**: Read/Write access for the configured user
|
||||
|
||||
### Accessing the Share
|
||||
|
||||
**From Windows:**
|
||||
```
|
||||
1. Open File Explorer
|
||||
2. In the address bar, type:
|
||||
\\hostname\Primary
|
||||
Or use IP: \\192.168.1.100\Primary
|
||||
|
||||
3. Enter credentials when prompted:
|
||||
Username: your_username
|
||||
Password: your_samba_password
|
||||
```
|
||||
|
||||
**From macOS:**
|
||||
```
|
||||
1. Open Finder
|
||||
2. Press Cmd+K (or Go → Connect to Server)
|
||||
3. Enter:
|
||||
smb://hostname/Primary
|
||||
Or: smb://192.168.1.100/Primary
|
||||
|
||||
4. Click Connect and enter credentials
|
||||
```
|
||||
|
||||
**From Linux:**
|
||||
```bash
|
||||
# Browse in file manager
|
||||
smb://hostname/Primary
|
||||
|
||||
# Or mount manually
|
||||
sudo mkdir /mnt/primary-share
|
||||
sudo mount -t cifs //hostname/Primary /mnt/primary-share -o username=your_username
|
||||
```
|
||||
|
||||
### Find Your Hostname/IP
|
||||
|
||||
```bash
|
||||
# Show hostname
|
||||
hostname
|
||||
|
||||
# Show IP address
|
||||
hostname -I
|
||||
ip addr show
|
||||
```
|
||||
|
||||
### Managing Samba
|
||||
|
||||
```bash
|
||||
# Restart Samba
|
||||
sudo systemctl restart smbd nmbd
|
||||
|
||||
# Check status
|
||||
sudo systemctl status smbd
|
||||
|
||||
# View share configuration
|
||||
sudo nano /etc/samba/smb.conf
|
||||
|
||||
# Change Samba password
|
||||
sudo smbpasswd your_username
|
||||
|
||||
# Add additional users
|
||||
sudo smbpasswd -a new_username
|
||||
```
|
||||
|
||||
### Add Additional Shares
|
||||
|
||||
Edit `/etc/samba/smb.conf`:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/samba/smb.conf
|
||||
```
|
||||
|
||||
Add new share:
|
||||
```ini
|
||||
[ShareName]
|
||||
comment = Description of share
|
||||
path = /path/to/share
|
||||
browseable = yes
|
||||
read only = no
|
||||
writable = yes
|
||||
valid users = username
|
||||
create mask = 0775
|
||||
directory mask = 0775
|
||||
```
|
||||
|
||||
Restart Samba:
|
||||
```bash
|
||||
sudo systemctl restart smbd nmbd
|
||||
```
|
||||
|
||||
### Troubleshooting Samba
|
||||
|
||||
**Can't connect to share:**
|
||||
```bash
|
||||
# Check if Samba is running
|
||||
sudo systemctl status smbd
|
||||
|
||||
# Check firewall (if enabled)
|
||||
sudo ufw allow samba
|
||||
|
||||
# Test configuration
|
||||
testparm
|
||||
|
||||
# View active connections
|
||||
sudo smbstatus
|
||||
```
|
||||
|
||||
**Permission denied:**
|
||||
```bash
|
||||
# Check share permissions
|
||||
ls -la ~/drives/primary
|
||||
|
||||
# Ensure Samba user exists
|
||||
sudo pdbedit -L
|
||||
|
||||
# Reset Samba password
|
||||
sudo smbpasswd your_username
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Docker Permission Denied
|
||||
|
||||
```bash
|
||||
# If you get "permission denied" after install
|
||||
# Log out and back in for group membership to take effect
|
||||
logout
|
||||
```
|
||||
|
||||
### SSH Key Already Exists
|
||||
|
||||
If you see "key already exists" warning:
|
||||
- Choose 'n' to keep existing key
|
||||
- Or choose 'y' to overwrite (cannot be undone!)
|
||||
|
||||
### Drive Won't Mount
|
||||
|
||||
```bash
|
||||
# Check if drive is recognized
|
||||
lsblk -f
|
||||
|
||||
# Check filesystem
|
||||
sudo fsck /dev/sdX1
|
||||
|
||||
# Try manual mount
|
||||
sudo mount -t auto /dev/sdX1 ~/drives/primary
|
||||
```
|
||||
|
||||
### Backup Script Fails
|
||||
|
||||
```bash
|
||||
# Check if drives are mounted
|
||||
df -h | grep drives
|
||||
|
||||
# Check log for errors
|
||||
tail -50 /var/log/rclone-backup.log
|
||||
|
||||
# Verify directories exist on primary
|
||||
ls -la ~/drives/primary/
|
||||
```
|
||||
|
||||
### NetBird Won't Connect
|
||||
|
||||
```bash
|
||||
# Check service status
|
||||
sudo systemctl status netbird
|
||||
|
||||
# Restart service
|
||||
sudo systemctl restart netbird
|
||||
|
||||
# Check logs
|
||||
sudo journalctl -u netbird -f
|
||||
```
|
||||
|
||||
### Samba Share Not Accessible
|
||||
|
||||
```bash
|
||||
# Verify Samba is running
|
||||
sudo systemctl status smbd
|
||||
|
||||
# Check share configuration
|
||||
testparm
|
||||
|
||||
# View Samba users
|
||||
sudo pdbedit -L
|
||||
|
||||
# Check if firewall is blocking
|
||||
sudo ufw status
|
||||
sudo ufw allow samba
|
||||
|
||||
# Restart Samba
|
||||
sudo systemctl restart smbd nmbd
|
||||
```
|
||||
|
||||
## Split Backup Advantages & Disadvantages
|
||||
|
||||
### ✓ Advantages
|
||||
- **Budget-friendly**: 4TB primary = 2TB backup1 + 2TB backup2 (saves money)
|
||||
- **Simpler than RAID**: No complex RAID setup or rebuild process
|
||||
- **Easy recovery**: Mount points stay the same, just swap drives
|
||||
- **No downtime**: Replace drives one at a time
|
||||
- **Flexible**: Easily rebalance folders between drives
|
||||
|
||||
### ⚠️ Disadvantages
|
||||
- **Split redundancy**: Each folder backed up to ONE drive only (not both)
|
||||
- **Two-drive restore**: Need BOTH backups to fully restore primary
|
||||
- **Urgent replacement**: Failed backup leaves some folders without redundancy
|
||||
- **Manual balancing**: You must divide folders between drives yourself
|
||||
|
||||
## Files Created by This Script
|
||||
|
||||
```
|
||||
/usr/local/bin/backup-scripts/rclone-backup.sh # Backup script
|
||||
/etc/systemd/system/rclone-backup.service # Systemd service
|
||||
/etc/systemd/system/rclone-backup.timer # Systemd timer
|
||||
/var/log/rclone-backup.log # Backup log
|
||||
/etc/fstab.backup-TIMESTAMP # fstab backup (if modified)
|
||||
/etc/ssh/sshd_config.backup # SSH config backup (if modified)
|
||||
/etc/samba/smb.conf.backup-TIMESTAMP # Samba config backup
|
||||
~/drives/primary/ # Primary mount point (shared via Samba)
|
||||
~/drives/backup1/ # Backup1 mount point
|
||||
~/drives/backup2/ # Backup2 mount point
|
||||
~/.ssh/id_rsa # Private SSH key (if generated)
|
||||
~/.ssh/id_rsa.pub # Public SSH key (if generated)
|
||||
~/.ssh/authorized_keys # Imported SSH keys (if any)
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- **Private SSH key** (`~/.ssh/id_rsa`): Keep secret! Never share!
|
||||
- **Public SSH key** (`~/.ssh/id_rsa.pub`): Safe to share
|
||||
- **Password authentication**: Disabled if keys imported (more secure)
|
||||
- **Docker group**: Equivalent to root access - only add trusted users
|
||||
- **Samba password**: Stored separately from system password; change with `sudo smbpasswd username`
|
||||
- **Samba shares**: Only accessible to configured users; ensure strong passwords
|
||||
- **Network security**: Samba shares are accessible to anyone on your local network who has credentials
|
||||
- **Backup drives**: Consider encrypting sensitive data
|
||||
|
||||
## Support & Feedback
|
||||
|
||||
This script continues even if individual packages fail. Check the output for warnings or errors.
|
||||
|
||||
To report issues or improve the script:
|
||||
- Review log files in `/var/log/`
|
||||
- Check systemd service status
|
||||
- Verify drive mounts with `df -h`
|
||||
|
||||
## License
|
||||
|
||||
This script is provided as-is for Ubuntu 24.04 Desktop installations.
|
||||
|
||||
## Changelog
|
||||
|
||||
- Initial version: Ubuntu 24.04 Desktop post-installation automation
|
||||
- Features: SSH (with key generation and import), Docker, Samba file sharing, NetBird, RustDesk, split-backup with rclone
|
||||
Reference in New Issue
Block a user