|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Function to prompt for input with a default value |
| 4 | +prompt() { |
| 5 | + local var_name=$1 |
| 6 | + local prompt_text=$2 |
| 7 | + local default_value=$3 |
| 8 | + read -p "$prompt_text [$default_value]: " input |
| 9 | + export $var_name="${input:-$default_value}" |
| 10 | +} |
| 11 | + |
| 12 | +# Function to prompt for yes/no with a default value |
| 13 | +prompt_yes_no() { |
| 14 | + local var_name=$1 |
| 15 | + local prompt_text=$2 |
| 16 | + local default_value=$3 |
| 17 | + read -p "$prompt_text (y/n) [$default_value]: " input |
| 18 | + case "${input:-$default_value}" in |
| 19 | + y|Y ) export $var_name="true";; |
| 20 | + n|N ) export $var_name="false";; |
| 21 | + * ) export $var_name=$default_value;; |
| 22 | + esac |
| 23 | +} |
| 24 | + |
| 25 | +# Prompt for variables |
| 26 | +prompt NEW_USER "Enter the new username" "youruser" |
| 27 | +prompt NEW_USER_PASSWORD "Enter the new user password" "your-secret-password" |
| 28 | +prompt SSH_PUBLIC_KEY "Enter the SSH public key content" "your-public-key-content" |
| 29 | +prompt_yes_no INSTALL_COOLIFY "Do you want to install Coolify?" "n" |
| 30 | +prompt_yes_no AUTO_REBOOT "Enable automatic reboot for unattended upgrades?" "n" |
| 31 | +prompt_yes_no REMOVE_UNUSED_DEPS "Remove unused dependencies during unattended upgrades?" "n" |
| 32 | + |
| 33 | +# Update system |
| 34 | +prompt_yes_no RUN_UPDATE "Do you want to update the system?" "y" |
| 35 | +if [ "$RUN_UPDATE" = "true" ]; then |
| 36 | + apt update && apt upgrade -y |
| 37 | +fi |
| 38 | + |
| 39 | +# Install required packages |
| 40 | +prompt_yes_no INSTALL_PACKAGES "Do you want to install required packages?" "y" |
| 41 | +if [ "$INSTALL_PACKAGES" = "true" ]; then |
| 42 | + apt install -y sudo ufw fail2ban unattended-upgrades apt-listchanges |
| 43 | +fi |
| 44 | + |
| 45 | +# Configure unattended-upgrades |
| 46 | +prompt_yes_no CONFIGURE_UNATTENDED_UPGRADES "Do you want to configure unattended-upgrades?" "y" |
| 47 | +if [ "$CONFIGURE_UNATTENDED_UPGRADES" = "true" ]; then |
| 48 | + cat > /etc/apt/apt.conf.d/20auto-upgrades << EOF |
| 49 | +APT::Periodic::Update-Package-Lists "1"; |
| 50 | +APT::Periodic::Unattended-Upgrade "1"; |
| 51 | +APT::Periodic::Download-Upgradeable-Packages "1"; |
| 52 | +APT::Periodic::AutocleanInterval "7"; |
| 53 | +EOF |
| 54 | + |
| 55 | + cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF |
| 56 | +Unattended-Upgrade::Origins-Pattern { |
| 57 | + "origin=Debian,codename=\${distro_codename},label=Debian-Security"; |
| 58 | + "origin=Debian,codename=\${distro_codename}-security,label=Debian-Security"; |
| 59 | +}; |
| 60 | +Unattended-Upgrade::AutoFixInterruptedDpkg "true"; |
| 61 | +Unattended-Upgrade::MinimalSteps "true"; |
| 62 | +Unattended-Upgrade::InstallOnShutdown "false"; |
| 63 | +Unattended-Upgrade::Mail "root"; |
| 64 | +Unattended-Upgrade::MailReport "on-change"; |
| 65 | +Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; |
| 66 | +Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; |
| 67 | +Unattended-Upgrade::Remove-Unused-Dependencies "${REMOVE_UNUSED_DEPS}"; |
| 68 | +Unattended-Upgrade::Automatic-Reboot "${AUTO_REBOOT}"; |
| 69 | +Unattended-Upgrade::Automatic-Reboot-Time "02:00"; |
| 70 | +EOF |
| 71 | + |
| 72 | + systemctl enable unattended-upgrades |
| 73 | + systemctl start unattended-upgrades |
| 74 | +fi |
| 75 | + |
| 76 | +# Create new user and add to sudo group |
| 77 | +prompt_yes_no CREATE_USER "Do you want to create a new user?" "y" |
| 78 | +if [ "$CREATE_USER" = "true" ]; then |
| 79 | + useradd -m -s /bin/bash $NEW_USER |
| 80 | + echo "$NEW_USER:$NEW_USER_PASSWORD" | chpasswd |
| 81 | + usermod -aG sudo $NEW_USER |
| 82 | + |
| 83 | + # Setup SSH key for new user |
| 84 | + mkdir -p /home/$NEW_USER/.ssh |
| 85 | + echo "$SSH_PUBLIC_KEY" > /home/$NEW_USER/.ssh/authorized_keys |
| 86 | + chmod 700 /home/$NEW_USER/.ssh |
| 87 | + chmod 600 /home/$NEW_USER/.ssh/authorized_keys |
| 88 | + chown -R $NEW_USER:$NEW_USER /home/$NEW_USER/.ssh |
| 89 | +fi |
| 90 | + |
| 91 | +# Configure SSH |
| 92 | +prompt_yes_no CONFIGURE_SSH "Do you want to configure SSH?" "y" |
| 93 | +if [ "$CONFIGURE_SSH" = "true" ]; then |
| 94 | + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config |
| 95 | + sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config |
| 96 | + sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config |
| 97 | +fi |
| 98 | + |
| 99 | +# Configure fail2ban |
| 100 | +prompt_yes_no CONFIGURE_FAIL2BAN "Do you want to configure fail2ban?" "y" |
| 101 | +if [ "$CONFIGURE_FAIL2BAN" = "true" ]; then |
| 102 | + cat > /etc/fail2ban/jail.local << EOF |
| 103 | +[sshd] |
| 104 | +enabled = true |
| 105 | +port = ssh |
| 106 | +filter = sshd |
| 107 | +logpath = /var/log/auth.log |
| 108 | +maxretry = 3 |
| 109 | +bantime = 3600 |
| 110 | +findtime = 600 |
| 111 | +EOF |
| 112 | +fi |
| 113 | + |
| 114 | +# Configure firewall |
| 115 | +prompt_yes_no CONFIGURE_UFW "Do you want to configure the firewall?" "y" |
| 116 | +if [ "$CONFIGURE_UFW" = "true" ]; then |
| 117 | + ufw default deny incoming |
| 118 | + ufw default allow outgoing |
| 119 | + ufw allow ssh |
| 120 | + ufw allow http |
| 121 | + ufw allow https |
| 122 | + echo "y" | ufw enable |
| 123 | +fi |
| 124 | + |
| 125 | +# Install Docker |
| 126 | +prompt_yes_no INSTALL_DOCKER "Do you want to install Docker?" "y" |
| 127 | +if [ "$INSTALL_DOCKER" = "true" ]; then |
| 128 | + apt install -y ca-certificates curl gnupg |
| 129 | + install -m 0755 -d /etc/apt/keyrings |
| 130 | + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg |
| 131 | + chmod a+r /etc/apt/keyrings/docker.gpg |
| 132 | + |
| 133 | + echo \ |
| 134 | + "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ |
| 135 | + "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ |
| 136 | + tee /etc/apt/sources.list.d/docker.list > /dev/null |
| 137 | + |
| 138 | + apt update |
| 139 | + apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin |
| 140 | + |
| 141 | + # Add user to docker group |
| 142 | + usermod -aG docker $NEW_USER |
| 143 | +fi |
| 144 | + |
| 145 | +# Optionally install and configure Coolify |
| 146 | +if [ "${INSTALL_COOLIFY}" = "true" ]; then |
| 147 | + |
| 148 | + echo "Installing Coolify..." |
| 149 | + |
| 150 | + # Temporary Coolify ports |
| 151 | + echo "⚠️ Adding temporary Coolify ports. Remember to remove them after configuring your domain!" |
| 152 | + ufw allow 8000/tcp comment 'Temporary Coolify Web UI' |
| 153 | + ufw allow 6001/tcp comment 'Temporary Coolify Websocket' |
| 154 | + ufw allow 6002/tcp comment 'Temporary Coolify API' |
| 155 | + |
| 156 | + |
| 157 | + mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance} |
| 158 | + mkdir -p /data/coolify/ssh/{keys,mux} |
| 159 | + mkdir -p /data/coolify/proxy/dynamic |
| 160 | + |
| 161 | + ssh-keygen -f /data/coolify/ssh/keys/ [email protected] -t ed25519 -N '' -C root@coolify |
| 162 | + |
| 163 | + cat /data/coolify/ssh/keys/ [email protected] >>~/.ssh/authorized_keys |
| 164 | + chmod 600 ~/.ssh/authorized_keys |
| 165 | + |
| 166 | + curl -fsSL https://cdn.coollabs.io/coolify/docker-compose.yml -o /data/coolify/source/docker-compose.yml |
| 167 | + curl -fsSL https://cdn.coollabs.io/coolify/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml |
| 168 | + curl -fsSL https://cdn.coollabs.io/coolify/.env.production -o /data/coolify/source/.env |
| 169 | + curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh -o /data/coolify/source/upgrade.sh |
| 170 | + |
| 171 | + chown -R 9999:root /data/coolify |
| 172 | + chmod -R 700 /data/coolify |
| 173 | + |
| 174 | + sed -i "s|APP_ID=.*|APP_ID=$(openssl rand -hex 16)|g" /data/coolify/source/.env |
| 175 | + sed -i "s|APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|g" /data/coolify/source/.env |
| 176 | + sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env |
| 177 | + sed -i "s|REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env |
| 178 | + sed -i "s|PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|g" /data/coolify/source/.env |
| 179 | + sed -i "s|PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|g" /data/coolify/source/.env |
| 180 | + sed -i "s|PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|g" /data/coolify/source/.env |
| 181 | + |
| 182 | + docker network create --attachable coolify |
| 183 | + |
| 184 | + docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --pull always --remove-orphans --force-recreate |
| 185 | + |
| 186 | + echo "⚠️ After configuring your domain in Coolify, remove temporary ports:" |
| 187 | + echo "ssh $VPS_USER@$VPS_HOST 'sudo ufw delete allow 8000/tcp && sudo ufw delete allow 6001/tcp && sudo ufw delete allow 6002/tcp'" |
| 188 | +fi |
| 189 | + |
| 190 | +# Restart services |
| 191 | +prompt_yes_no RESTART_SERVICES "Do you want to restart services?" "y" |
| 192 | +if [ "$RESTART_SERVICES" = "true" ]; then |
| 193 | + systemctl restart sshd |
| 194 | + systemctl restart fail2ban |
| 195 | +fi |
| 196 | + |
| 197 | +# Print access information |
| 198 | +echo "=== IMPORTANT: SAVE THIS INFORMATION ===" |
| 199 | +echo "New user: $NEW_USER" |
| 200 | +echo "Password: $NEW_USER_PASSWORD" |
| 201 | +echo "" |
| 202 | +echo "Test SSH access with: ssh $NEW_USER@<your-vps-ip>" |
| 203 | +echo "" |
| 204 | +echo "After confirming SSH key access works, run:" |
| 205 | +echo "ssh $NEW_USER@<your-vps-ip> 'sudo sed -i \"s/PasswordAuthentication yes/PasswordAuthentication no/\" /etc/ssh/sshd_config && sudo systemctl restart sshd'" |
| 206 | +echo "" |
| 207 | +if [ "${INSTALL_COOLIFY}" = "true" ]; then |
| 208 | + echo "⚠️ After configuring your domain in Coolify, remove temporary ports:" |
| 209 | + echo "ssh $NEW_USER@<your-vps-ip> 'sudo ufw delete allow 8000/tcp && sudo ufw delete allow 6001/tcp && sudo ufw delete allow 6002/tcp'" |
| 210 | +fi |
| 211 | +echo "" |
| 212 | +echo "===================================" |
| 213 | +echo "Setup completed! " |
0 commit comments