You just bought the box. The metal is yours. But that freedom comes with a price: if you don't lock the doors, anyone can walk in. Bare-metal hosting gives you full control, but it also means you are responsible for every open port, every default credential, and every unpatched kernel module. I have seen too many servers compromised because the admin focused on the application but ignored the OS layer. This is not about theoretical best practices. This is about the specific, immediate steps you need to take tonight to stop the automated scanners from finding a way in.
Disable Root Login and Enforce Keys
The first thing a bot does is try root with a weak password. If you allow direct root login over SSH, you are handing them the keys. You need to switch to key-based authentication and disable password authentication entirely.
Configure SSHD
Edit your SSH configuration file. On most systems, this is /etc/ssh/sshd_config. Make sure these lines are set:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
```n
Save the file. Then, restart the service. Do not close your current terminal until you have tested a new login with your key. If you lock yourself out, you need console access via your provider's VNC or IPMI. Test it. Always test it.
If you use cPanel or Plesk, the configuration might be handled differently, but the principle remains the same. Never leave password login enabled for the root user.
## Lock Down the Firewall
An open port is an invitation. You only need a few ports open: 22 for SSH, 80 for HTTP, and 443 for HTTPS. Everything else should be blocked by default. Use `ufw` for simplicity or `iptables`/`nftables` for granular control.
### Basic UFW Setup
If you are using Ubuntu or Debian, `ufw` is the easiest tool. Set the default policy to deny incoming connections. Then allow your necessary services.
```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
```n
Check the status to ensure it is active. If you are running a virtual server, check if the cloud provider has its own security group or firewall. Those rules apply *before* your OS firewall. If the cloud firewall allows 0.0.0.0/0 on port 22, your UFW rules won't stop the initial handshake, but they can still block the connection if you restrict it further. However, for true bare-metal, the OS firewall is your last line of defense. Keep it strict.
So what if you need to access a database port? Do not expose it to the world. Restrict the source IP to your office IP or your application server's IP only.
## Update Everything, Then Set It to Auto
Running an outdated kernel or library is like leaving the front door open. Vulnerabilities are discovered daily. Patches are released quickly. If you are not updating, you are vulnerable.
### Enable Unattended Upgrades
On Debian/Ubuntu, install `unattended-upgrades`. This allows the system to automatically install security updates. You do not need to reboot automatically, but you should be notified when a reboot is required.
```bash
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
For RHEL/CentOS/AlmaLinux, use yum-cron or dnf-automatic. The goal is the same: security patches should be applied without waiting for you to remember to run apt update.
Check your logs regularly. If a reboot is pending, schedule it during a maintenance window. A server that reboots at 3 AM without warning is annoying, but a server that stays up with a known CVE is dangerous.
Harden File Permissions
Default permissions are often too loose. A world-readable private key is a disaster. Check your critical files.
Critical Files
/etc/passwd: Should be readable by all, but writable only by root./etc/shadow: Should be readable only by root./etc/sudoers: Should be readable only by root.- SSH private keys (
/root/.ssh/id_rsa): Should be 600. - SSH public keys (
/root/.ssh/id_rsa.pub): Should be 644.
Run ls -l on these files. If you see 777 permissions, fix it immediately. Use chmod to tighten them. For example, to restrict a private key:
chmod 600 /root/.ssh/id_rsa
Also, check for world-writable files. Run find / -xdev -type f -perm -0002 2>/dev/null. If you find any, investigate why they exist. They are often leftovers from bad installations or malicious scripts.
Monitor and Log Everything
You cannot fix what you do not see. Ensure your logs are being written and that you have a way to alert on suspicious activity.
Enable Auditd
auditd is a system activity monitoring tool. It records events that are related to system security. Install it and configure basic rules to watch for changes in critical files.
sudo apt install auditd
sudo systemctl enable auditd
sudo systemctl start auditd
Add rules to watch for changes to /etc/passwd and /etc/shadow. This will alert you if someone is trying to create a new user or change a password.
Review Logs Daily
Check /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL/CentOS). Look for failed SSH attempts. If you see hundreds of failed attempts from a single IP, block that IP. Use fail2ban to automate this. It reads your logs and bans IPs that show malicious behavior.
sudo apt install fail2ban
Configure fail2ban to protect SSH. The default configuration is usually fine, but adjust the bantime and findtime to suit your needs. A short ban time might not be enough for persistent attackers. A long ban time might lock out a legitimate user who forgot their password. Find a balance.
Protect Against Brute Force
Even with key-based auth, attackers will try to brute-force keys if they can guess them. Use strong, long keys. RSA 4096 or Ed25519 are good choices. Do not use DSA. It is deprecated and weak.
Generate Strong Keys
If you are generating a new key, use this command:
ssh-keygen -t ed25519 -C "[email protected]"
Do not use an empty passphrase. If you do, anyone who gets the key has access. Use a strong passphrase. You can use a password manager to store it. The convenience of no passphrase is not worth the risk.
Also, consider using ssh-agent to load your keys into memory. This way, you do not have to type the passphrase every time you connect. It caches it for a session. This is a good balance between security and convenience.
Final Checks and Maintenance
Security is not a one-time task. It is a habit. Schedule regular audits. Check for new users. Check for new processes. Check for new open ports.
Regular Audit Checklist
- Check for new users in
/etc/passwd. - Check for new SSH keys in
/home/*/.ssh/authorized_keys. - Check for new open ports with
netstat -tulpn. - Check for new cron jobs in
/etc/cron.dand user crontabs. - Check for new services in
/etc/systemd/system.
If you find anything unexpected, investigate it. Do not assume it is harmless. It might be a backdoor.
What to check first
If you are starting from scratch, do not try to do everything at once. Focus on the highest-risk items first:
- SSH: Disable root login, enforce keys.
- Firewall: Deny all incoming, allow only necessary ports.
- Updates: Enable automatic security updates.
- Permissions: Tighten file permissions on critical files.
- Monitoring: Enable
fail2banandauditd.
These five steps will stop the vast majority of automated attacks. The rest is about maintaining the system and staying informed. Security is a journey, not a destination. But these steps are the foundation. Build on them. Do not skip them. Your server will thank you.
FAQ
Do I need a firewall if I am using a cloud provider? Yes. Cloud security groups are the first layer, but your OS firewall is the second. They work together. If the cloud group allows a port, the OS firewall can still block it. Always use both.
Can I use password authentication for convenience? No. The risk is too high. Use keys. If you need to share access, share keys, not passwords. Passwords are weak and easily guessed.
How often should I update? Security updates should be applied as soon as they are available. Use automatic updates for this. Reboots can be scheduled, but patches should not wait.
What if I lock myself out of SSH? Use your provider's console access. This is why you should always have a backup access method. Never rely on a single point of failure for access.
