Introduction
Learning how to configure SSH in Ubuntu is a fundamental skill for anyone managing servers, developers, or system administrators. Secure Shell (SSH) provides a encrypted channel for remote login and command execution, protecting your data from eavesdropping. This guide walks you through every step—from installing the SSH server to hardening its security—so you can confidently set up a reliable remote access solution on your Ubuntu machine.
Why SSH is Essential
- Security: All traffic is encrypted, preventing password sniffing and man‑in‑the‑middle attacks.
- Flexibility: Manage multiple Ubuntu instances from a single workstation.
- Automation: SSH keys enable password‑less scripts and CI/CD pipelines.
Understanding the underlying principles helps you troubleshoot and optimize the connection later It's one of those things that adds up..
Installing the SSH Server
- Update the package list
sudo apt update - Install the OpenSSH server
sudo apt install openssh-server - Verify the service is running
sudo systemctl status ssh
If the service is not active, start it with:
sudo systemctl start ssh
sudo systemctl enable ssh # to start on boot
Generating SSH Keys
SSH keys provide a more secure alternative to password authentication And that's really what it comes down to..
-
Create a key pair (2048‑bit RSA is a good default)
ssh-keygen -t rsa -b 2048 -C "your_email@example.com"- Press Enter to accept the default file location (
~/.ssh/id_rsa). - Optionally set a passphrase for extra protection.
- Press Enter to accept the default file location (
-
Copy the public key to the remote Ubuntu host
ssh-copy-id user@remote_hostReplace
userwith your Ubuntu username andremote_hostwith the IP or hostname. -
Test password‑less login
ssh user@remote_hostIf you see a shell prompt without entering a password, the key setup succeeded.
Configuring the SSH Daemon (sshd_config)
The main configuration file is /etc/ssh/sshd_config. Editing it allows you to fine‑tune behavior and security Not complicated — just consistent..
Key Settings to Consider
- Port – Change from the default 22 to reduce automated scans.
Port 2222 - Protocol – Use Protocol 2 (the only supported protocol).
Protocol 2 - PasswordAuthentication – Disable to enforce key‑based login.
PasswordAuthentication no - PubkeyAuthentication – Enable (default).
PubkeyAuthentication yes - PermitRootLogin – Restrict root access.
PermitRootLogin prohibit‑password - MaxAuthTries – Limit login attempts.
MaxAuthTries 3 - ClientAliveInterval – Send keep‑alive messages to prevent timeout.
ClientAliveInterval 300
After editing, reload the daemon:
sudo systemctl reload ssh
Setting Up the Firewall (UFW)
If you changed the SSH port, update the firewall accordingly.
- Enable UFW (if not already enabled)
sudo ufw enable - Allow the new SSH port
sudo ufw allow 2222/tcp - Check status
sudo ufw status verbose
Remember to keep the firewall rules restrictive—only allow your IP or a trusted range if possible Simple as that..
Testing the SSH Connection
- Basic connectivity:
ssh user@remote_host -p 2222 - Verbose mode (useful for debugging):
ssh -v user@remote_host -p 2222 - Check authentication logs for details:
sudo journalctl -u ssh -f
A successful login will show your prompt without requesting a password (if key‑based) or after entering the correct password Not complicated — just consistent..
Best Practices for SSH Security
- Use strong keys: 4096‑bit RSA or Ed25519 for better performance and security.
- Rotate keys regularly: Schedule a reminder to regenerate and redistribute keys.
- Limit user access: Use
AllowUsersorDenyUsersto restrict who can log in. - Disable X11 forwarding unless needed:
X11Forwarding no - Implement fail2ban: It automatically bans IPs after repeated failed attempts.
- Audit logs: Regularly review
/var/log/auth.logfor suspicious activity.
These practices help protect your Ubuntu system from brute‑force attacks and unauthorized access That's the part that actually makes a difference..
Troubleshooting Common Issues
| Symptom | Likely Cause | Quick Fix |
|---|---|---|
| Connection timed out | Firewall blocking port, wrong IP, or service not running | Verify UFW rules, check systemctl status ssh, ensure correct port |
| Permission denied (publickey) | Missing or incorrect key, key permissions too open | Ensure ~/.ssh permissions are 700, ~/.In real terms, ssh/authorized_keys is 600 |
| Server refuses to listen on port | Port already in use or Port directive mis‑typed |
Use `ss -tulnph |
| Login takes too long | Slow key exchange or weak cipher | Edit Ciphers to use modern algorithms (e. Which means g. , *chacha20-poly1305@openssh. |
Running ssh -v user@host provides detailed logs to pinpoint the exact failure.
Conclusion
Configuring SSH on Ubuntu is a blend of installation, key management, and security hardening. By following the steps outlined—installing the server, generating and deploying keys, customizing /etc/ssh/sshd_config, securing the firewall, and applying best practices—you’ll have a reliable and protected remote access environment. Regularly review and update your SSH settings to stay ahead of emerging threats, ensuring your Ubuntu system remains both accessible and safe.
Advanced Hardening & Automation
Beyond the baseline configuration, production environments often require stricter controls and automated management to maintain compliance at scale.
Enforce SSH Certificates Instead of Raw Keys
Short‑lived SSH certificates issued by a trusted Certificate Authority (CA) eliminate the need to distribute individual public keys to every host.
- Generate a CA key (keep offline):
ssh-keygen -t ed25519 -f ssh_ca -C "internal-ssh-ca" - Sign user keys with a validity window (e.g., 8 hours):
ssh-keygen -s ssh_ca -I "user@domain" -n "ubuntu-user" -V "+8h" id_ed25519.pub - Configure the server to trust the CA:
# /etc/ssh/sshd_config TrustedUserCAKeys /etc/ssh/ssh_ca.pub AuthenticationMethods publickey
Certificates automatically expire, reducing the blast radius of a compromised key.
Mandate Multi‑Factor Authentication (MFA)
Layer Time‑based One‑Time Passwords (TOTP) on top of public‑key auth:
sudo apt update && sudo apt install libpam-google-authenticator
google-authenticator # run as each user; scan QR code into authenticator app
Update PAM and SSH config:
# /etc/pam.d/sshd
auth required pam_google_authenticator.so nullok
# /etc/ssh/sshd_config
AuthenticationMethods publickey,keyboard-interactive
ChallengeResponseAuthentication yes
UsePAM yes
Restart SSH; users now need both their private key and a TOTP code.
Centralized Configuration with Ansible
Maintain identical sshd_config across fleets using a playbook:
- name: Harden SSH on all Ubuntu hosts
hosts: ubuntu_servers
become: yes
tasks:
- name: Deploy hardened sshd_config
copy:
src: files/sshd_config.hardened
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: '0644'
notify: restart ssh
- name: Ensure UFW allows SSH port
ufw:
rule: allow
port: '2222'
proto: tcp
handlers:
- name: restart ssh
systemd:
name: ssh
state: restarted
Run periodically via CI/CD to drift‑detect and remediate automatically Small thing, real impact..
Continuous Compliance Scanning
Integrate OpenSCAP or Lynis into your pipeline:
sudo apt install lynis
sudo lynis audit system --profile /etc/lynis/custom.prf
Fail the build if critical SSH findings (e.g., PermitRootLogin yes, weak ciphers) appear.
Final Thoughts
SSH is the gateway to your infrastructure; treating it as a static “set‑and‑forget” service invites risk. By progressing from basic key‑based login to certificate‑driven, MFA‑protected, automatically audited access, you transform SSH from a simple remote‑shell tool into a resilient, auditable control plane. Pair these technical controls with operational discipline—regular key rotation, log aggregation, and incident‑response playbooks—and your Ubuntu fleet will remain both accessible to authorized engineers and hostile to attackers.
No fluff here — just what actually works.