Complete Security Implementation for Non-Root Users
This comprehensive guide covers essential server hardening techniques for Ubuntu Server, focusing on security measures that should be implemented as a non-root user. Server hardening is the process of securing a server by reducing its attack surface and implementing security best practices to protect against potential threats and unauthorized access.
Sudo (Superuser Do) is a powerful command that allows permitted users to execute commands with elevated privileges without switching to the root user account. This approach provides an additional layer of security and accountability by making administrators more conscious of their actions and creating an audit trail of privileged operations.
The root user is all-powerful and any mistakes made as root can be devastating and often irreversible. A single command executed incorrectly as root can destroy an entire server. Sudo forces you to think before executing privileged commands.
When performing administrative tasks such as installing packages, updating the system, restarting services, or editing configuration files, you must always use sudo before the command.
| Task Type | Requires Sudo? | Example |
|---|---|---|
| Installing packages | ✓ Yes | sudo apt install nginx |
| Updating packages | ✓ Yes | sudo apt update |
| Restarting services | ✓ Yes | sudo systemctl restart ssh |
| Editing system config files | ✓ Yes | sudo nano /etc/ssh/sshd_config |
| Viewing directories | ✗ No | ls -la |
| Changing your own files | ✗ No | nano myfile.txt |
SSH key authentication is a more secure alternative to password-based authentication. It uses a public-private key pair where the private key remains on your local machine (encrypted with a passphrase) and the public key is stored on the server. This method is significantly more secure because it eliminates the risk of password brute-force attacks and provides stronger cryptographic security.
DO NOT log into your server to generate the SSH key pair! The key pair must be generated locally on your PC or Mac, not on the server. This is a fundamental security principle.
Before proceeding, ensure you're working on your local machine, not logged into the server. Check your terminal prompt.
If you see your server hostname (e.g., "2404"), you're logged into the server. Type 'exit' to log out.
Create a 4096-bit RSA key pair on your local machine. This command works identically on Linux, Mac, and Windows (Git Bash).
The passphrase encrypts your private key on your local machine. It is NOT the password you use to log into your server. You'll need this passphrase each time you use the private key to connect to your server.
Check that both keys were created with correct permissions.
Use ssh-copy-id to securely transfer and configure your public key on the server.
The ssh-copy-id command connected to your server using SSH, created the necessary directories and files, added your public key to ~/.ssh/authorized_keys, and set the correct permissions automatically.
Verify that you can log in using your private key instead of a password.
Now that SSH key authentication works, disable password-based login for enhanced security.
Find and modify the following line:
Apply the configuration changes by restarting the SSH service.
Log out and test that password authentication no longer works.
Regular system updates are crucial for maintaining server security. Updates include security patches, bug fixes, and performance improvements that protect your server from known vulnerabilities and exploits.
After creating a new server instance, many hosting providers (like Vultr, DigitalOcean, AWS) automatically run package updates. If kernel updates are applied, you'll see a "System restart required" message. Here's how to handle it:
| Command | Purpose | When to Use |
|---|---|---|
sudo apt update |
Updates package lists from repositories | Before installing or upgrading packages |
sudo apt upgrade |
Upgrades installed packages to newer versions | Weekly or when security updates available |
sudo apt dist-upgrade |
Upgrades packages and handles dependencies | For major system upgrades |
sudo apt autoremove |
Removes unnecessary packages | After upgrades to clean up |
Implementing a firewall policy is one of the most crucial steps in server hardening. A properly configured firewall acts as a barrier between your server and potential threats, allowing only necessary traffic while blocking everything else.
Deny all incoming traffic by default, then explicitly allow only the services and ports you need. This "default deny" approach minimizes your attack surface.
| Port | Service | Protocol | Should Allow? |
|---|---|---|---|
| 22 | SSH | TCP | ✓ Yes (for remote access) |
| 80 | HTTP | TCP | ✓ If running web server |
| 443 | HTTPS | TCP | ✓ If running web server |
| 3306 | MySQL | TCP | ✗ Block (internal only) |
| 5432 | PostgreSQL | TCP | ✗ Block (internal only) |
Fail2Ban is an intrusion prevention framework that protects your server from brute-force attacks by monitoring log files and automatically blocking IP addresses that show malicious behavior, such as too many failed login attempts.
Fail2Ban uses two main configuration directories:
/etc/fail2ban/jail.conf - Default configuration (DO NOT edit directly)/etc/fail2ban/jail.local - Your custom configuration (overrides defaults)Never edit jail.conf directly. Always create a jail.local file for your custom settings, as jail.conf will be overwritten during updates.
Find the [sshd] section in jail.local and configure it:
At the top of jail.local, find the [DEFAULT] section and adjust:
Save and exit: Ctrl+X, then Y, then Enter
Or using iptables:
If you're running a web server, add protection for Nginx or Apache:
Add these sections:
To prevent accidentally banning yourself:
In the [DEFAULT] section, add:
Replace 192.168.1.50 with your actual IP address.
Create a recidive jail that bans repeat offenders for longer:
From another machine (or use a VM), attempt multiple failed SSH logins:
On your server:
You should see the attacker's IP banned.
From the server console (not SSH):
Or disable Fail2Ban temporarily:
| Security Measure | Status | Priority |
|---|---|---|
| Created non-root user with sudo privileges | ✓ Complete | Critical |
| Implemented SSH key authentication | ✓ Complete | Critical |
| Disabled password authentication | ✓ Complete | Critical |
| Applied system updates | ✓ Complete | High |
| Configure firewall (UFW) | Pending | Critical |
| Install and configure Fail2Ban | ✓ Complete | High |
With SSH key authentication successfully implemented, password authentication disabled, and Fail2Ban configured, your server is significantly more secure. The next phase of hardening will focus on configuring the firewall (UFW) to create a comprehensive security posture for your Ubuntu server.
Security is not a one-time setup but an ongoing process. Regularly review logs, update systems, and stay informed about security best practices and emerging threats.