├── .github └── workflows │ └── deploy.yml ├── README.md ├── old ├── setup_cli.sh └── setup_without_coolify.sh ├── setup-interactive.sh └── setup.sh /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to VPS 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - name: Deploy to VPS 15 | uses: appleboy/ssh-action@master 16 | env: 17 | NEW_USER: ${{ secrets.VPS_USER }} 18 | NEW_USER_PASSWORD: ${{ secrets.VPS_USER_PASSWORD }} 19 | SSH_PUBLIC_KEY: ${{ secrets.SSH_PUBLIC_KEY }} 20 | INSTALL_COOLIFY: ${{ secrets.INSTALL_COOLIFY }} 21 | AUTO_REBOOT: ${{ secrets.AUTO_REBOOT }} 22 | REMOVE_UNUSED_DEPS: ${{ secrets.REMOVE_UNUSED_DEPS }} 23 | with: 24 | host: ${{ secrets.VPS_HOST }} 25 | username: root 26 | password: ${{ secrets.VPS_ROOT_PASSWORD }} 27 | envs: NEW_USER,NEW_USER_PASSWORD,SSH_PUBLIC_KEY,INSTALL_COOLIFY,AUTO_REBOOT,REMOVE_UNUSED_DEPS 28 | script: | 29 | TEMP_DIR=$(mktemp -d) 30 | cd $TEMP_DIR 31 | cat > setup.sh << 'EOL' 32 | ${{ github.workspace }}/setup.sh 33 | EOL 34 | chmod +x setup.sh 35 | ./setup.sh 36 | cd / 37 | rm -rf $TEMP_DIR 38 | 39 | - name: Post-setup instructions 40 | run: | 41 | echo "🎉 Setup completed!" 42 | echo "⚠️ IMPORTANT: After verifying SSH key access works, disable password authentication:" 43 | echo "ssh ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} 'sudo sed -i \"s/PasswordAuthentication yes/PasswordAuthentication no/\" /etc/ssh/sshd_config && sudo systemctl restart sshd'" 44 | if [ "${INSTALL_COOLIFY}" = "true" ]; then 45 | echo "⚠️ After configuring your domain in Coolify, remove temporary ports:" 46 | echo "ssh $NEW_USER@ 'sudo ufw delete allow 8000/tcp && sudo ufw delete allow 6001/tcp && sudo ufw delete allow 6002/tcp'" 47 | fi 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Secure VPS Setup Automation 2 | 3 | This repository contains automation scripts to set up a secure Debian-based VPS with essential security features and Docker installation. The setup is completely automated using GitHub Actions and can be easily forked and customized for your own use. 4 | 5 | ## 🔑 Features 6 | 7 | - **User Management** 8 | - Creates a non-root user with sudo privileges 9 | - Configures SSH key-based authentication 10 | - Disables root login and password authentication 11 | 12 | - **Security** 13 | - Sets up UFW firewall (allows only SSH, HTTP, HTTPS) 14 | - Installs and configures fail2ban to prevent brute-force attacks 15 | - Configures unattended-upgrades for automatic security updates 16 | - Implements secure SSH configuration 17 | 18 | - **Docker** 19 | - Installs Docker and Docker Compose 20 | - Adds user to docker group 21 | 22 | - **System Updates** 23 | - Configures automatic security updates 24 | - Sets up unattended-upgrades with email notifications 25 | - Automatic system cleanup 26 | 27 | - **Coolify Installation (Optional)** 28 | - Install Coolify 29 | - Open temporary ports (8000, 6001, 6002) 30 | - Provide instructions for securing after domain setup 31 | 32 | ## 🚀 Usage 33 | 34 | There are two options on how to use this script: 35 | 36 | 1. Run the (interactive) setup script (`setup-interactive.sh`) on your local machine or vps. 37 | 38 | 2. Duplicate this repository, configure the variables as Secrets and use the included github action (`.github/workflows/deploy.yml`) to automatically run this script on your VPS when you push your updates. 39 | 40 | ### Option 1. Run the script 41 | 42 | 43 | You can run this script on your local machine or vps. It is necessary, that you have root ssh access to your remote VPS. 44 | 45 | `VPS_HOST` ist your vps hostname or ip adress. 46 | 47 | a) On your local machine 48 | ```bash 49 | ssh root@VPS_HOST "bash <(curl -s https://raw.githubusercontent.com/legout/vps-setup/refs/heads/main/setup-interactive.sh)" 50 | ``` 51 | b) On your VPS 52 | ```bash 53 | ssh root@VPS_HOST 54 | 55 | # you are on your remote VPS now 56 | bash <(curl -s https://raw.githubusercontent.com/legout/vps-setup/refs/heads/main/setup-interactive.sh) 57 | ``` 58 | 59 | ### Option 2: GitHub Action 60 | #### 1. Duplicate this Repository 61 | Duplicate this repository and make it private to safely store your configurations. 62 | 63 | 1. 64 | ```bash 65 | git clone --bare https://github.com/legout/vps-setup.git 66 | ``` 67 | 2. 68 | ```bash 69 | cd vps-setup 70 | git push --mirror https://github.com//vps-setup.git 71 | ``` 72 | 3. 73 | ```bash 74 | cd .. 75 | rm -r vps-setup 76 | git clone https://github.com//vps-setup.git 77 | ``` 78 | 79 | 80 | #### 2. Configure GitHub Secrets 81 | In your forked repository, go to Settings > Secrets and variables > Actions and add the following secrets: 82 | 83 | - `VPS_HOST`: Your VPS IP address or hostname 84 | - `VPS_ROOT_PASSWORD`: Initial root password 85 | - `VPS_USER`: Desired username for the non-root user 86 | - `VPS_USER_PASSWORD`: Password for the new user 87 | - `SSH_PUBLIC_KEY`: Your SSH public key content (from `~/.ssh/id_rsa.pub`) 88 | - `INSTALL_COOLIFY`: Set to "true" to install Coolify, "false" to skip (defaults to "false") 89 | - `AUTO_REBOOT`: Set to "true" for automatic reboot after system updates, "false" to skip (defaults to "false") 90 | - `REMOVE_UNUSED_DEPS`: Set to "true" to remove unused dependencies, "false" to skip (defaults to "false") 91 | 92 | ⚠️ Security Note: 93 | - Never commit these values directly to the repository 94 | - Always use GitHub Secrets for sensitive information 95 | - Use strong passwords for both root and user accounts 96 | - Keep your SSH private key secure 97 | 98 | #### 3. Deploy 99 | The setup will automatically deploy when you push to the main branch, or you can manually trigger it from the Actions tab. 100 | 101 | #### 4. Post-Setup Security Steps 102 | 103 | After the GitHub Action completes successfully: 104 | 105 | 1. Test SSH key-based login: 106 | ```bash 107 | ssh your-user@your-vps-host 108 | ``` 109 | 110 | 2. If SSH key access works, disable password authentication: 111 | ```bash 112 | ssh your-user@your-vps-host 'sudo sed -i "s/PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config && sudo systemctl restart sshd' 113 | ``` 114 | 115 | ⚠️ Important: 116 | - Only disable password authentication after confirming SSH key access works 117 | - Keep a backup of your SSH private key 118 | - Store your VPS root password securely (in case of emergencies) 119 | - Monitor the GitHub Actions logs for the setup result 120 | 121 | ##### Coolify Configuration 122 | 123 | The setup includes an optional Coolify installation with temporary open ports: 124 | - 8000/tcp: Coolify Web UI 125 | - 6001/tcp: Coolify Websocket 126 | - 6002/tcp: Coolify Terminal 127 | 128 | ⚠️ Important: After configuring your domain in Coolify and setting up SSL, remove these temporary ports: 129 | ```bash 130 | ssh your-user@your-vps-host 'sudo ufw delete allow 8000/tcp && sudo ufw delete allow 6001/tcp && sudo ufw delete allow 6002/tcp' 131 | ``` 132 | 133 | These ports should only be open during initial setup. Once you've configured your domain and SSL in Coolify, all traffic should go through ports 80/443. 134 | 135 | ### 📋 What Gets Installed 136 | 137 | - UFW (Uncomplicated Firewall) 138 | - fail2ban 139 | - unattended-upgrades 140 | - Docker & Docker Compose 141 | - Essential system utilities 142 | - Coolify (optinal) 143 | 144 | ## ⚙️ Configuration Details 145 | 146 | ### Firewall Rules 147 | - Default: deny incoming, allow outgoing 148 | - Allowed incoming ports: 149 | - 22 (SSH) 150 | - 80 (HTTP) 151 | - 443 (HTTPS) 152 | 153 | ### fail2ban Configuration 154 | - Monitors SSH authentication 155 | - Bans IP after 3 failed attempts 156 | - Ban duration: 1 hour 157 | - Monitor window: 10 minutes 158 | 159 | ### Automatic Updates 160 | - Daily security updates 161 | - Automatic removal of unused packages 162 | - Configured reboot at 2 AM if necessary 163 | - Email notifications for important updates 164 | 165 | ### SSH Security 166 | - Key-based authentication only 167 | - Root login disabled 168 | - Password authentication enabled. For security reasons you should disable it after successfull setup (see [Post-Setup Security Steps](#4-post-setup-security-steps) below) 169 | 170 | 171 | ## 🛠️ Customization 172 | 173 | 1. Fork this repository 174 | 2. Modify `setup.sh` according to your needs 175 | 3. Update the GitHub Actions workflow in `.github/workflows/deploy.yml` if necessary 176 | 4. Set up your secrets 177 | 5. Deploy! 178 | 179 | ## 📈 Security Recommendations 180 | 181 | - Always keep your SSH private key secure 182 | - Regularly update your SSH keys 183 | - Monitor system logs regularly 184 | - Keep Docker and system packages updated 185 | - Review automatic update logs periodically 186 | 187 | ## 🔍 Monitoring 188 | 189 | After deployment, you can monitor various aspects: 190 | 191 | - Fail2ban logs: `/var/log/fail2ban.log` 192 | - UFW logs: `/var/log/ufw.log` 193 | - Unattended upgrades: `/var/log/unattended-upgrades/` 194 | - System logs: `/var/log/syslog` 195 | 196 | ## ⚠️ Important Notes 197 | 198 | - This script is designed for Debian-based systems (tested on Debian 12) 199 | - Ensure you have root access to your VPS before running 200 | - Make sure to test the setup in a development environment first 201 | - Keep your forked repository private to protect sensitive information 202 | - Regularly update your SSH keys and monitor system logs 203 | 204 | ## 🤝 Contributing 205 | 206 | Contributions are welcome! Please feel free to submit a Pull Request. 207 | 208 | ## 📝 License 209 | 210 | This project is licensed under the MIT License - see the LICENSE file for details. 211 | 212 | ## 💪 Support This Project 213 | 214 | Please give it a ⭐! 215 | 216 | If you find this project useful and are looking for a VPS provider, consider using my affiliate link: 217 | 218 | - [Get a Netcup VPS](https://www.netcup.com/en/?ref=223843) - Starting from €3.99/month 219 | - Excellent performance and reliability 220 | - Perfect for running this setup 221 | 222 | > 🙏 Using this link supports the maintenance and development of this project at no extra cost to you. 223 | 224 | ## 🔐 Security 225 | 226 | If you discover any security issues, please send an email to ligno.blades@gmail.com instead of using the issue tracker. 227 | -------------------------------------------------------------------------------- /old/setup_cli.sh: -------------------------------------------------------------------------------- 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/id.root@host.docker.internal -t ed25519 -N '' -C root@coolify 162 | 163 | cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >>~/.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@" 203 | echo "" 204 | echo "After confirming SSH key access works, run:" 205 | echo "ssh $NEW_USER@ '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@ '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! " 214 | -------------------------------------------------------------------------------- /old/setup_without_coolify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Variables 4 | NEW_USER="youruser" 5 | NEW_USER_PASSWORD="your-secret-password" 6 | SSH_PUBLIC_KEY="your-public-key-content" 7 | 8 | # Update system 9 | apt update && apt upgrade -y 10 | 11 | # Install required packages 12 | apt install -y sudo ufw fail2ban unattended-upgrades apt-listchanges 13 | 14 | # Configure unattended-upgrades 15 | cat > /etc/apt/apt.conf.d/20auto-upgrades << EOF 16 | APT::Periodic::Update-Package-Lists "1"; 17 | APT::Periodic::Unattended-Upgrade "1"; 18 | APT::Periodic::Download-Upgradeable-Packages "1"; 19 | APT::Periodic::AutocleanInterval "7"; 20 | EOF 21 | 22 | cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF 23 | Unattended-Upgrade::Origins-Pattern { 24 | "origin=Debian,codename=\${distro_codename},label=Debian-Security"; 25 | "origin=Debian,codename=\${distro_codename}-security,label=Debian-Security"; 26 | }; 27 | Unattended-Upgrade::AutoFixInterruptedDpkg "true"; 28 | Unattended-Upgrade::MinimalSteps "true"; 29 | Unattended-Upgrade::InstallOnShutdown "false"; 30 | Unattended-Upgrade::Mail "root"; 31 | Unattended-Upgrade::MailReport "on-change"; 32 | Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; 33 | Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; 34 | Unattended-Upgrade::Remove-Unused-Dependencies "false"; 35 | Unattended-Upgrade::Automatic-Reboot "true"; 36 | Unattended-Upgrade::Automatic-Reboot-Time "02:00"; 37 | EOF 38 | 39 | # Enable unattended-upgrades 40 | systemctl enable unattended-upgrades 41 | systemctl start unattended-upgrades 42 | 43 | # Create new user and add to sudo group 44 | useradd -m -s /bin/bash $NEW_USER 45 | echo "$NEW_USER:$NEW_USER_PASSWORD" | chpasswd 46 | usermod -aG sudo $NEW_USER 47 | 48 | # Setup SSH key for new user 49 | mkdir -p /home/$NEW_USER/.ssh 50 | echo "$SSH_PUBLIC_KEY" > /home/$NEW_USER/.ssh/authorized_keys 51 | chmod 700 /home/$NEW_USER/.ssh 52 | chmod 600 /home/$NEW_USER/.ssh/authorized_keys 53 | chown -R $NEW_USER:$NEW_USER /home/$NEW_USER/.ssh 54 | 55 | # Configure SSH 56 | sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config 57 | sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config 58 | sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config 59 | 60 | # Configure fail2ban 61 | cat > /etc/fail2ban/jail.local << EOF 62 | [sshd] 63 | enabled = true 64 | port = ssh 65 | filter = sshd 66 | logpath = /var/log/auth.log 67 | maxretry = 3 68 | bantime = 3600 69 | findtime = 600 70 | EOF 71 | 72 | # Configure firewall 73 | ufw default deny incoming 74 | ufw default allow outgoing 75 | ufw allow ssh 76 | ufw allow http 77 | ufw allow https 78 | echo "y" | ufw enable 79 | 80 | # Install Docker 81 | apt install -y ca-certificates curl gnupg 82 | install -m 0755 -d /etc/apt/keyrings 83 | curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 84 | chmod a+r /etc/apt/keyrings/docker.gpg 85 | 86 | echo \ 87 | "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ 88 | "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ 89 | tee /etc/apt/sources.list.d/docker.list > /dev/null 90 | 91 | apt update 92 | apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 93 | 94 | # Add user to docker group 95 | usermod -aG docker $NEW_USER 96 | 97 | # Restart services 98 | systemctl restart sshd 99 | systemctl restart fail2ban 100 | 101 | # Print access information 102 | echo "=== IMPORTANT: SAVE THIS INFORMATION ===" 103 | echo "New user: $NEW_USER" 104 | echo "Password: $NEW_USER_PASSWORD" 105 | echo "" 106 | echo "Test SSH access with: ssh $NEW_USER@" 107 | echo "" 108 | echo "After confirming SSH key access works, run:" 109 | echo "ssh $NEW_USER@ 'sudo sed -i \"s/PasswordAuthentication yes/PasswordAuthentication no/\" /etc/ssh/sshd_config && sudo systemctl restart sshd'" 110 | echo "===================================" 111 | 112 | echo "Setup completed!" 113 | -------------------------------------------------------------------------------- /setup-interactive.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Helper function for yes/no prompts 4 | confirm() { 5 | while true; do 6 | read -p "$1 [y/N] " yn 7 | case $yn in 8 | [Yy]* ) echo "yes"; return 0;; 9 | [Nn]* | "" ) echo "no"; return 1;; 10 | * ) echo "Please answer yes or no.";; 11 | esac 12 | done 13 | } 14 | 15 | # Helper function for required input 16 | prompt_required() { 17 | local value="" 18 | while [ -z "$value" ]; do 19 | read -p "$1: " value 20 | if [ -z "$value" ]; then 21 | echo "This field is required." 22 | fi 23 | done 24 | echo "$value" 25 | } 26 | 27 | # Helper function for optional input with default 28 | prompt_with_default() { 29 | local default=$2 30 | read -p "$1 [$default]: " value 31 | echo "${value:-$default}" 32 | } 33 | 34 | echo "=== VPS Setup Interactive Configuration ===" 35 | echo 36 | 37 | # Gather basic information 38 | NEW_USER=$(prompt_required "Enter new username") 39 | NEW_USER_PASSWORD=$(prompt_required "Enter password for new user") 40 | SSH_PUBLIC_KEY=$(prompt_required "Enter your SSH public key (content of id_rsa.pub)") 41 | 42 | # Configuration options 43 | echo 44 | echo "=== Configuration Options ===" 45 | AUTO_UPDATE=$(confirm "Enable automatic system updates?") 46 | AUTO_REBOOT=$(confirm "Enable automatic system reboots?") 47 | REMOVE_UNUSED_DEPS=$(confirm "Remove unused dependencies?") 48 | INSTALL_DOCKER=$(confirm "Install Docker?") 49 | INSTALL_COOLIFY=$(confirm "Install Coolify?") 50 | 51 | # Security configuration 52 | echo 53 | echo "=== Security Configuration ===" 54 | SETUP_UFW=$(confirm "Configure UFW firewall?") 55 | SETUP_FAIL2BAN=$(confirm "Configure fail2ban?") 56 | 57 | # Confirmation 58 | echo 59 | echo "=== Configuration Summary ===" 60 | echo "New User: $NEW_USER" 61 | echo "Auto Updates: $AUTO_UPDATE" 62 | echo "Auto Reboot: $AUTO_REBOOT" 63 | echo "Remove Unused Deps: $REMOVE_UNUSED_DEPS" 64 | echo "Install Docker: $INSTALL_DOCKER" 65 | echo "Install Coolify: $INSTALL_COOLIFY" 66 | echo "Setup UFW: $SETUP_UFW" 67 | echo "Setup fail2ban: $SETUP_FAIL2BAN" 68 | echo 69 | 70 | if ! confirm "Proceed with installation?"; then 71 | echo "Setup cancelled." 72 | exit 1 73 | fi 74 | 75 | # Update system 76 | echo "Updating system..." 77 | apt update && apt upgrade -y 78 | 79 | # Install required packages 80 | apt install -y sudo 81 | 82 | if [ "$AUTO_UPDATE" = "yes" ]; then 83 | echo "Configuring automatic updates..." 84 | apt install -y unattended-upgrades apt-listchanges 85 | 86 | cat > /etc/apt/apt.conf.d/20auto-upgrades << EOF 87 | APT::Periodic::Update-Package-Lists "1"; 88 | APT::Periodic::Unattended-Upgrade "1"; 89 | APT::Periodic::Download-Upgradeable-Packages "1"; 90 | APT::Periodic::AutocleanInterval "7"; 91 | EOF 92 | 93 | cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF 94 | Unattended-Upgrade::Origins-Pattern { 95 | "origin=Debian,codename=\${distro_codename},label=Debian-Security"; 96 | "origin=Debian,codename=\${distro_codename}-security,label=Debian-Security"; 97 | }; 98 | Unattended-Upgrade::AutoFixInterruptedDpkg "true"; 99 | Unattended-Upgrade::MinimalSteps "true"; 100 | Unattended-Upgrade::InstallOnShutdown "false"; 101 | Unattended-Upgrade::Mail "root"; 102 | Unattended-Upgrade::MailReport "on-change"; 103 | Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; 104 | Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; 105 | Unattended-Upgrade::Remove-Unused-Dependencies "${REMOVE_UNUSED_DEPS}"; 106 | Unattended-Upgrade::Automatic-Reboot "${AUTO_REBOOT}"; 107 | Unattended-Upgrade::Automatic-Reboot-Time "02:00"; 108 | EOF 109 | 110 | systemctl enable unattended-upgrades 111 | systemctl start unattended-upgrades 112 | fi 113 | 114 | # Create new user 115 | echo "Creating new user..." 116 | useradd -m -s /bin/bash $NEW_USER 117 | echo "$NEW_USER:$NEW_USER_PASSWORD" | chpasswd 118 | usermod -aG sudo $NEW_USER 119 | 120 | # Setup SSH 121 | echo "Configuring SSH..." 122 | mkdir -p /home/$NEW_USER/.ssh 123 | echo "$SSH_PUBLIC_KEY" > /home/$NEW_USER/.ssh/authorized_keys 124 | chmod 700 /home/$NEW_USER/.ssh 125 | chmod 600 /home/$NEW_USER/.ssh/authorized_keys 126 | chown -R $NEW_USER:$NEW_USER /home/$NEW_USER/.ssh 127 | 128 | sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config 129 | sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config 130 | sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config 131 | 132 | if [ "$SETUP_FAIL2BAN" = "yes" ]; then 133 | echo "Configuring fail2ban..." 134 | apt install -y fail2ban 135 | cat > /etc/fail2ban/jail.local << EOF 136 | [sshd] 137 | enabled = true 138 | port = ssh 139 | filter = sshd 140 | logpath = /var/log/auth.log 141 | maxretry = 3 142 | bantime = 3600 143 | findtime = 600 144 | EOF 145 | fi 146 | 147 | if [ "$SETUP_UFW" = "yes" ]; then 148 | echo "Configuring UFW..." 149 | apt install -y ufw 150 | ufw default deny incoming 151 | ufw default allow outgoing 152 | ufw allow ssh 153 | ufw allow http 154 | ufw allow https 155 | echo "y" | ufw enable 156 | fi 157 | 158 | if [ "$INSTALL_DOCKER" = "yes" ]; then 159 | echo "Installing Docker..." 160 | apt install -y ca-certificates curl gnupg 161 | install -m 0755 -d /etc/apt/keyrings 162 | curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 163 | chmod a+r /etc/apt/keyrings/docker.gpg 164 | 165 | echo \ 166 | "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ 167 | "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ 168 | tee /etc/apt/sources.list.d/docker.list > /dev/null 169 | 170 | apt update 171 | apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 172 | usermod -aG docker $NEW_USER 173 | fi 174 | 175 | if [ "$INSTALL_COOLIFY" = "yes" ]; then 176 | echo "Installing Coolify..." 177 | 178 | echo "⚠️ Adding temporary Coolify ports. Remember to remove them after configuring your domain!" 179 | ufw allow 8000/tcp comment 'Temporary Coolify Web UI' 180 | ufw allow 6001/tcp comment 'Temporary Coolify Websocket' 181 | ufw allow 6002/tcp comment 'Temporary Coolify API' 182 | 183 | mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance} 184 | mkdir -p /data/coolify/ssh/{keys,mux} 185 | mkdir -p /data/coolify/proxy/dynamic 186 | 187 | ssh-keygen -f /data/coolify/ssh/keys/id.root@host.docker.internal -t ed25519 -N '' -C root@coolify 188 | 189 | cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >>~/.ssh/authorized_keys 190 | chmod 600 ~/.ssh/authorized_keys 191 | 192 | curl -fsSL https://cdn.coollabs.io/coolify/docker-compose.yml -o /data/coolify/source/docker-compose.yml 193 | curl -fsSL https://cdn.coollabs.io/coolify/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml 194 | curl -fsSL https://cdn.coollabs.io/coolify/.env.production -o /data/coolify/source/.env 195 | curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh -o /data/coolify/source/upgrade.sh 196 | 197 | chown -R 9999:root /data/coolify 198 | chmod -R 700 /data/coolify 199 | 200 | sed -i "s|APP_ID=.*|APP_ID=$(openssl rand -hex 16)|g" /data/coolify/source/.env 201 | sed -i "s|APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|g" /data/coolify/source/.env 202 | sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env 203 | sed -i "s|REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env 204 | sed -i "s|PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|g" /data/coolify/source/.env 205 | sed -i "s|PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|g" /data/coolify/source/.env 206 | sed -i "s|PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|g" /data/coolify/source/.env 207 | 208 | docker network create --attachable coolify 209 | 210 | 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 211 | fi 212 | 213 | # Restart services 214 | systemctl restart sshd 215 | [ "$SETUP_FAIL2BAN" = "yes" ] && systemctl restart fail2ban 216 | 217 | # Print access information 218 | echo 219 | echo "=== IMPORTANT: SAVE THIS INFORMATION ===" 220 | echo "New user: $NEW_USER" 221 | echo "Password: $NEW_USER_PASSWORD" 222 | echo 223 | echo "Test SSH access with: ssh $NEW_USER@" 224 | echo 225 | echo "After confirming SSH key access works, run:" 226 | echo "ssh $NEW_USER@ 'sudo sed -i \"s/PasswordAuthentication yes/PasswordAuthentication no/\" /etc/ssh/sshd_config && sudo systemctl restart sshd'" 227 | echo 228 | if [ "$INSTALL_COOLIFY" = "yes" ]; then 229 | echo "⚠️ After configuring your domain in Coolify, remove temporary ports:" 230 | echo "ssh $NEW_USER@ 'sudo ufw delete allow 8000/tcp && sudo ufw delete allow 6001/tcp && sudo ufw delete allow 6002/tcp'" 231 | fi 232 | echo 233 | echo "===================================" 234 | echo "Setup completed!" 235 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Variables 4 | NEW_USER="${NEW_USER:-youruser}" 5 | NEW_USER_PASSWORD="${NEW_USER_PASSWORD:-your-secret-password}" 6 | SSH_PUBLIC_KEY="${SSH_PUBLIC_KEY:-your-public-key-content}" 7 | INSTALL_COOLIFY="${INSTALL_COOLIFY:-false}" 8 | AUTO_REBOOT="${AUTO_REBOOT:-false}" 9 | REMOVE_UNUSED_DEPS="${REMOVE_UNUSED_DEPS:-false}" 10 | 11 | # Update system 12 | apt update && apt upgrade -y 13 | 14 | # Install required packages 15 | apt install -y sudo ufw fail2ban unattended-upgrades apt-listchanges 16 | 17 | # Configure unattended-upgrades 18 | cat > /etc/apt/apt.conf.d/20auto-upgrades << EOF 19 | APT::Periodic::Update-Package-Lists "1"; 20 | APT::Periodic::Unattended-Upgrade "1"; 21 | APT::Periodic::Download-Upgradeable-Packages "1"; 22 | APT::Periodic::AutocleanInterval "7"; 23 | EOF 24 | 25 | cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF 26 | Unattended-Upgrade::Origins-Pattern { 27 | "origin=Debian,codename=\${distro_codename},label=Debian-Security"; 28 | "origin=Debian,codename=\${distro_codename}-security,label=Debian-Security"; 29 | }; 30 | Unattended-Upgrade::AutoFixInterruptedDpkg "true"; 31 | Unattended-Upgrade::MinimalSteps "true"; 32 | Unattended-Upgrade::InstallOnShutdown "false"; 33 | Unattended-Upgrade::Mail "root"; 34 | Unattended-Upgrade::MailReport "on-change"; 35 | Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; 36 | Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; 37 | Unattended-Upgrade::Remove-Unused-Dependencies "${REMOVE_UNUSED_DEPS}"; 38 | Unattended-Upgrade::Automatic-Reboot "${AUTO_REBOOT}"; 39 | Unattended-Upgrade::Automatic-Reboot-Time "02:00"; 40 | EOF 41 | 42 | # Enable unattended-upgrades 43 | systemctl enable unattended-upgrades 44 | systemctl start unattended-upgrades 45 | 46 | # Create new user and add to sudo group 47 | useradd -m -s /bin/bash $NEW_USER 48 | echo "$NEW_USER:$NEW_USER_PASSWORD" | chpasswd 49 | usermod -aG sudo $NEW_USER 50 | 51 | # Setup SSH key for new user 52 | mkdir -p /home/$NEW_USER/.ssh 53 | echo "$SSH_PUBLIC_KEY" > /home/$NEW_USER/.ssh/authorized_keys 54 | chmod 700 /home/$NEW_USER/.ssh 55 | chmod 600 /home/$NEW_USER/.ssh/authorized_keys 56 | chown -R $NEW_USER:$NEW_USER /home/$NEW_USER/.ssh 57 | 58 | # Configure SSH 59 | sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config 60 | sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config 61 | sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config 62 | 63 | # Configure fail2ban 64 | cat > /etc/fail2ban/jail.local << EOF 65 | [sshd] 66 | enabled = true 67 | port = ssh 68 | filter = sshd 69 | logpath = /var/log/auth.log 70 | maxretry = 3 71 | bantime = 3600 72 | findtime = 600 73 | EOF 74 | 75 | # Configure firewall 76 | ufw default deny incoming 77 | ufw default allow outgoing 78 | ufw allow ssh 79 | ufw allow http 80 | ufw allow https 81 | 82 | # Install Docker 83 | apt install -y ca-certificates curl gnupg 84 | install -m 0755 -d /etc/apt/keyrings 85 | curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 86 | chmod a+r /etc/apt/keyrings/docker.gpg 87 | 88 | echo \ 89 | "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ 90 | "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ 91 | tee /etc/apt/sources.list.d/docker.list > /dev/null 92 | 93 | apt update 94 | apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 95 | 96 | # Optionally install and configure coolify 97 | if [ "${INSTALL_COOLIFY}" = "true" ]; then 98 | 99 | echo "Installing Coolify..." 100 | 101 | # Temporary Coolify ports 102 | echo "⚠️ Adding temporary Coolify ports. Remember to remove them after configuring your domain!" 103 | ufw allow 8000/tcp comment 'Temporary Coolify Web UI' 104 | ufw allow 6001/tcp comment 'Temporary Coolify Websocket' 105 | ufw allow 6002/tcp comment 'Temporary Coolify API' 106 | 107 | 108 | mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance} 109 | mkdir -p /data/coolify/ssh/{keys,mux} 110 | mkdir -p /data/coolify/proxy/dynamic 111 | 112 | ssh-keygen -f /data/coolify/ssh/keys/id.root@host.docker.internal -t ed25519 -N '' -C root@coolify 113 | 114 | cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >>~/.ssh/authorized_keys 115 | chmod 600 ~/.ssh/authorized_keys 116 | 117 | curl -fsSL https://cdn.coollabs.io/coolify/docker-compose.yml -o /data/coolify/source/docker-compose.yml 118 | curl -fsSL https://cdn.coollabs.io/coolify/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml 119 | curl -fsSL https://cdn.coollabs.io/coolify/.env.production -o /data/coolify/source/.env 120 | curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh -o /data/coolify/source/upgrade.sh 121 | 122 | chown -R 9999:root /data/coolify 123 | chmod -R 700 /data/coolify 124 | 125 | sed -i "s|APP_ID=.*|APP_ID=$(openssl rand -hex 16)|g" /data/coolify/source/.env 126 | sed -i "s|APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|g" /data/coolify/source/.env 127 | sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env 128 | sed -i "s|REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|g" /data/coolify/source/.env 129 | sed -i "s|PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|g" /data/coolify/source/.env 130 | sed -i "s|PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|g" /data/coolify/source/.env 131 | sed -i "s|PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|g" /data/coolify/source/.env 132 | 133 | docker network create --attachable coolify 134 | 135 | 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 136 | 137 | echo "⚠️ After configuring your domain in Coolify, remove temporary ports:" 138 | echo "ssh $VPS_USER@$VPS_HOST 'sudo ufw delete allow 8000/tcp && sudo ufw delete allow 6001/tcp && sudo ufw delete allow 6002/tcp'" 139 | fi 140 | 141 | # enable ufw 142 | echo "y" | ufw enable 143 | 144 | # Add user to docker group 145 | usermod -aG docker $NEW_USER 146 | 147 | # Restart services 148 | systemctl restart sshd 149 | systemctl restart fail2ban 150 | 151 | # Print access information 152 | echo "=== IMPORTANT: SAVE THIS INFORMATION ===" 153 | echo "New user: $NEW_USER" 154 | echo "Password: $NEW_USER_PASSWORD" 155 | echo "" 156 | echo "Test SSH access with: ssh $NEW_USER@" 157 | echo "" 158 | echo "After confirming SSH key access works, run:" 159 | echo "ssh $NEW_USER@ 'sudo sed -i \"s/PasswordAuthentication yes/PasswordAuthentication no/\" /etc/ssh/sshd_config && sudo systemctl restart sshd'" 160 | echo "" 161 | if [ "${INSTALL_COOLIFY}" = "true" ]; then 162 | echo "⚠️ After configuring your domain in Coolify, remove temporary ports:" 163 | echo "ssh $NEW_USER@ 'sudo ufw delete allow 8000/tcp && sudo ufw delete allow 6001/tcp && sudo ufw delete allow 6002/tcp'" 164 | fi 165 | echo "" 166 | echo "===================================" 167 | echo "Setup completed! " 168 | --------------------------------------------------------------------------------