Contents
- 1 VPS First-Time Setup
- 2 1. Initial Login
- 3 2. Create Non-Root User
- 4 3. Setup SSH Key (Recommended)
- 5 Disable root SSH login
- 6 4. Configure Firewall (Before Changing SSH Port)
- 7 5. Change SSH Port
- 8 6. Test New SSH Port (Critical Step)
- 9 7. Remove Default Port 22 From Firewall
- 10 8. Install Fail2Ban
- 11 9. Set Timezone
- 12 10. Install Stack (Choose One)
- 13 Final Security Baseline
VPS First-Time Setup
Assume:
- New SSH port = 2222
- Ubuntu VPS
1. Initial Login
ssh root@YOUR_VPS_IP
apt update && apt upgrade -y
reboot
Reconnect after reboot.
2. Create Non-Root User
adduser youruser
usermod -aG sudo youruser
3. Setup SSH Key (Recommended)
From local machine:
ssh-keygen
ssh-copy-id youruser@YOUR_VPS_IP
Test login:
ssh youruser@YOUR_VPS_IP
Disable root SSH login
Disable root SSH login (Ubuntu)
- Edit SSH config:
sudo nano /etc/ssh/sshd_config
- Set:
PermitRootLogin no
- (Optional but recommended)
PasswordAuthentication no
- Restart SSH:
sudo systemctl restart ssh
Important
- Ensure you have a normal user with sudo:
adduser youruser
usermod -aG sudo youruser
- Test login in a new session before closing current one.
4. Configure Firewall (Before Changing SSH Port)
Install UFW:
sudo apt install ufw -y
Allow required ports:
sudo ufw allow 2222/tcp
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
sudo ufw status
Ensure 2222/tcp is allowed.
5. Change SSH Port
Edit config:
sudo nano /etc/ssh/sshd_config
Modify:
Port 2222
PermitRootLogin no # disable root login
PasswordAuthentication no # if login using ssh key
Save and restart:
sudo systemctl restart ssh
6. Test New SSH Port (Critical Step)
Open new terminal window:
ssh -p 2222 youruser@YOUR_VPS_IP
If successful → continue.
If not → fix before closing old session.
7. Remove Default Port 22 From Firewall
List rules:
sudo ufw status numbered
Delete OpenSSH rule (by number):
sudo ufw delete <number>
Verify:
sudo ufw status
Port 22 should no longer be allowed.
8. Install Fail2Ban
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
9. Set Timezone
sudo timedatectl set-timezone Asia/Jakarta
10. Install Stack (Choose One)
Option A – Nginx + PHP
sudo apt install nginx -y
sudo apt install php-fpm php-mysql php-cli php-curl php-mbstring php-xml php-zip -y
sudo systemctl enable nginx
Option B - apache + php (laravel ready)
Install Apache + PHP 8.3 (Ubuntu)
sudo apt update && sudo apt upgrade -y
# install repo for PHP 8.3
sudo apt install -y software-properties-common ca-certificates lsb-release apt-transport-https
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
# install apache + php 8.3 + required extensions
sudo apt install -y apache2 php8.3 php8.3-cli php8.3-common php8.3-mysql php8.3-xml php8.3-curl php8.3-mbstring php8.3-zip php8.3-bcmath php8.3-intl php8.3-gd libapache2-mod-php8.3 unzip curl git
# enable apache rewrite (needed for Laravel)
sudo a2enmod rewrite
# restart apache
sudo systemctl restart apache2
Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Laravel ready notes
- Document root →
/var/www/html/yourproject/public - Set permission:
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 775 /var/www/html
Option C – Docker
curl -fsSL https://get.docker.com | sudo bash
sudo usermod -aG docker youruser
Logout/login again.
Test:
docker run hello-world
if youruser still not added to docker group
newgrp docker
then rerun hello world
Final Security Baseline
- SSH on custom port (2222)
- Root login disabled
- Password login disabled
- Firewall enabled
- Fail2Ban active
- System updated
- Kernel updated + rebooted
This is a clean, secure baseline for production VPS.