Remote administration on Ubuntu is much safer once OpenSSH is installed, listening, and protected before you need emergency access. To install SSH server on Ubuntu, use the openssh-server package for inbound logins and keep openssh-client available for outbound SSH, SCP, and SFTP connections.
Ubuntu 26.04 LTS (Resolute Raccoon), 24.04 LTS (Noble Numbat), and 22.04 LTS (Jammy Jellyfish) all ship OpenSSH from the default repositories. You do not need a separate OpenSSH download on a normal Ubuntu system; APT retrieves the maintained packages directly. The install command is the same across those releases, but service management differs because 26.04 and 24.04 use ssh.socket for socket activation while 22.04 uses the traditional ssh.service listener.
Ubuntu Server installs may already include the SSH server, while Ubuntu Desktop and minimal systems commonly need
openssh-serveradded before they can accept inbound connections. The client package only lets the machine connect out to other SSH servers.
Install and Enable OpenSSH on Ubuntu
Install and enable SSH on Ubuntu by adding the OpenSSH server package, then confirming the socket or service is listening on port 22. The same package name handles common query variants such as openssh-server, OpenSSH server, and sshd.
Check Existing SSH Packages
Start by checking whether the SSH client is already present:
ssh -V
Relevant output on Ubuntu 26.04 currently looks like this:
OpenSSH_10.2p1 Ubuntu-2ubuntu3, OpenSSL 3.5.5 27 Jan 2026
Check the server and client packages with dpkg-query. The ii status means the package is installed and configured:
dpkg-query -W -f='${binary:Package} ${Version} ${db:Status-Abbrev}\n' openssh-server openssh-client
Relevant output on Ubuntu 26.04:
openssh-client 1:10.2p1-2ubuntu3 ii openssh-server 1:10.2p1-2ubuntu3 ii
If openssh-server is missing, continue with the update and install steps below. If only openssh-client is installed, the machine can connect to remote SSH hosts but cannot accept SSH logins itself.
Update Ubuntu Before Installation
Refresh package metadata before installing or upgrading OpenSSH:
sudo apt update && sudo apt upgrade
These commands use
sudofor package-management tasks that need root privileges. If your account is not allowed to usesudoyet, use a root session or follow the guide on adding a sudo user on Ubuntu before continuing.
Install OpenSSH Server and Client
Install OpenSSH server on Ubuntu with sudo apt install openssh-server openssh-client. The server package provides sshd for inbound logins, while the client package provides commands such as ssh, scp, and sftp.
sudo apt install openssh-server openssh-client
APT enables the packaged SSH service path during installation. On Ubuntu 26.04 and 24.04, ssh.socket handles the listening socket. On Ubuntu 22.04, ssh.service runs the persistent daemon directly.
Compare Ubuntu OpenSSH Versions
The package revisions below were verified from Ubuntu repositories for the supported LTS releases. Exact revisions change with security updates, but the activation model is the important release difference for service commands.
| Ubuntu release | OpenSSH package revision | Service model |
|---|---|---|
| Ubuntu 26.04 LTS (Resolute Raccoon) | 1:10.2p1-2ubuntu3 | ssh.socket socket activation |
| Ubuntu 24.04 LTS (Noble Numbat) | 1:9.6p1-3ubuntu13.15 | ssh.socket socket activation |
| Ubuntu 22.04 LTS (Jammy Jellyfish) | 1:8.9p1-3ubuntu0.14 | ssh.service persistent daemon |
Verify SSH Is Listening
On Ubuntu 26.04 and 24.04, check the socket because it owns the listening port:
sudo systemctl status ssh.socket --no-pager
Relevant output includes:
ssh.socket - OpenBSD Secure Shell server socket
Loaded: loaded (/usr/lib/systemd/system/ssh.socket; enabled; preset: enabled)
Active: active (running)
Listen: 0.0.0.0:22 (Stream)
[::]:22 (Stream)
On Ubuntu 22.04, check the service directly:
sudo systemctl status ssh --no-pager
Relevant output includes:
ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) Active: active (running) Main PID: 818 (sshd)
Confirm the listener from the networking side as well:
sudo ss -tlnp | grep -E ':22[[:space:]]'
On socket-activated Ubuntu releases, the listener can show both systemd and sshd after an SSH session has connected. On Ubuntu 22.04, the listener normally shows sshd only.
Test SSH Access on Ubuntu
Before changing security settings, confirm the server accepts a local SSH connection. This test catches missing packages, disabled services, and firewall mistakes before remote access depends on the new setup.
ssh localhost
The first connection asks you to trust the local host key:
The authenticity of host 'localhost (127.0.0.1)' can't be established. ED25519 key fingerprint is SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz1234567890. Are you sure you want to continue connecting (yes/no/[fingerprint])?
Type yes, authenticate with your local account password or SSH key, then run exit to close the test session. If the login fails, leave the terminal open and use the troubleshooting section before attempting remote changes.
Configure SSH Security Settings
OpenSSH works immediately after installation, but internet-facing servers need stricter authentication and firewall rules. Keep one existing SSH session open while making changes so you can undo a bad setting without losing access.
Use SSH Configuration Snippets
Ubuntu’s current OpenSSH configuration includes /etc/ssh/sshd_config.d/*.conf, so a small drop-in file is easier to review than editing the main package file. The Ubuntu OpenSSH server documentation and the OpenSSH manual pages describe the available directives.
Create a local hardening file for the settings you want to manage:
sudo nano /etc/ssh/sshd_config.d/99-local-hardening.conf
After each edit, test the full SSH configuration before restarting anything:
sudo sshd -t
A valid configuration returns no output. If the command prints an error, fix the named file or directive before restarting the socket or service.
Change the SSH Port Safely
A custom SSH port reduces background scanner noise, but it does not replace strong authentication. Add the new firewall rule first, keep port 22 open until the new port works, and test from a second terminal before closing your active session.
Add the port directive to your local hardening file:
Port 2222
Allow the new port through UFW before restarting SSH:
sudo ufw allow 2222/tcp
Check the rule list:
sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 2222/tcp ALLOW IN Anywhere
[ 3] 22/tcp (v6) ALLOW IN Anywhere (v6)
[ 4] 2222/tcp (v6) ALLOW IN Anywhere (v6)
Apply the port change on Ubuntu 26.04 and 24.04 with a daemon reload and socket restart. The reload lets systemd regenerate the socket from the OpenSSH configuration:
sudo sshd -t
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
On Ubuntu 22.04, restart the service instead:
sudo sshd -t
sudo systemctl restart ssh
Verify the new listener before removing the old firewall rule:
sudo ss -tlnp | grep -E ':2222[[:space:]]'
Test the new port locally or from another trusted machine:
ssh -p 2222 localhost
After the new port works, remove the default UFW service rule if you no longer want port 22 exposed:
sudo ufw delete allow ssh
Limit SSH Login Attempts
Limit failed authentication attempts per connection with MaxAuthTries. A value of 3 is stricter than the OpenSSH default, but users with several keys loaded in an SSH agent may need a higher value.
MaxAuthTries 3
For authentication-only changes, test the config and restart the service:
sudo sshd -t
sudo systemctl restart ssh
On Ubuntu 26.04 and 24.04, restarting
sshapplies authentication settings after the socket has started the service. Usessh.socketrestart only when you change listener settings such asPortorListenAddress.
Disable Direct Root Login
Confirm a normal account can sign in and use
sudobefore disabling root login. If you need another administrator account first, add one through the Ubuntu sudoers workflow.
Add this directive to block direct root SSH logins:
PermitRootLogin no
Apply and test the setting:
sudo sshd -t
sudo systemctl restart ssh
ssh root@localhost
Expected result after root login is disabled:
root@localhost: Permission denied (publickey).
Require SSH Key Authentication
Key authentication avoids reusable password prompts and is the safer default for exposed servers. Do not disable passwords until at least one sudo-capable account can log in with a working key.
PasswordAuthentication no
KbdInteractiveAuthentication no
Optionally restrict logins to named users or named groups. Pick the form that matches how you manage access instead of adding both by habit:
AllowUsers alice deploy
Or use a group-based rule:
AllowGroups sshusers
Restart SSH after testing syntax:
sudo sshd -t
sudo systemctl restart ssh
Then test password authentication from a second terminal:
ssh -o PreferredAuthentications=password localhost
user@localhost: Permission denied (publickey).
Configure UFW for SSH
UFW controls which remote systems can reach the SSH listener. If UFW is not installed, add it from Ubuntu’s default repositories:
sudo apt install ufw
Allow the default SSH service:
sudo ufw allow ssh
For a custom port, match the port configured in OpenSSH:
sudo ufw allow 2222/tcp
To allow SSH only from one trusted client IP, use a source-limited rule:
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
Enable UFW only after the SSH rule is in place:
sudo ufw enable
Verify the firewall state:
sudo ufw status
Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6)
For deeper firewall management, see the Ubuntu guides for installing and configuring UFW on Ubuntu and enabling or disabling UFW on Ubuntu. Servers exposed to the internet also pair well with Fail2ban on Ubuntu for repeated authentication failures.
Use SSH Client Commands
The SSH client can connect to remote shells, copy files, and run one-off commands after the server side is ready. For a broader command reference, use the SSH command guide for Linux.
Connect to a Remote Server
ssh username@remote_server
Replace username with the remote account name and remote_server with a hostname or IP address. For a custom port, add -p:
ssh -p 2222 username@remote_server
Create and Copy SSH Keys
Create an Ed25519 key pair unless your environment requires another key type:
ssh-keygen -t ed25519
Copy the public key to the remote account:
ssh-copy-id username@remote_server
If you keep the private key outside the default path, specify it during login:
ssh -i /path/to/private_key username@remote_server
Private keys should be readable only by your account:
ls -l ~/.ssh/id_ed25519
-rw------- 1 user user 419 Jan 15 10:00 /home/user/.ssh/id_ed25519
If the mode is too open, tighten it with chmod:
chmod 600 ~/.ssh/id_ed25519
Transfer Files with SCP
Use SCP when you need a simple encrypted file transfer over SSH:
scp /path/to/local/file username@remote_server:/path/to/remote/directory
Copy a directory recursively with -r:
scp -r /path/to/local/directory username@remote_server:/path/to/remote/directory
For custom SSH ports, SCP uses uppercase -P, not lowercase -p:
scp -P 2222 /path/to/local/file username@remote_server:/path/to/remote/directory
Run Remote Commands
Run a single remote command without opening an interactive shell:
ssh username@remote_server 'df -h'
The command output prints in your local terminal, then SSH closes the connection automatically.
Troubleshoot SSH on Ubuntu
Most SSH failures fall into three groups: the server is not listening, the firewall blocks the port, or authentication rejects the user or key. Work through those layers in order.
Check the Socket or Service
On Ubuntu 26.04 and 24.04, start the socket if it is inactive:
sudo systemctl start ssh.socket
sudo systemctl status ssh.socket --no-pager
On Ubuntu 22.04, start the service:
sudo systemctl start ssh
sudo systemctl status ssh --no-pager
If ssh.service appears inactive on a socket-activated release, check ssh.socket before treating that as a failure. The service may be inactive before any connection starts it, or active while current SSH sessions are connected.
Ubuntu packages the unit as ssh.service. The name sshd.service can appear as an alias on current LTS releases, but examples should still use ssh, ssh.service, or ssh.socket. If a command reports sshd.service was not found, confirm openssh-server is installed before restarting the Ubuntu service name.
Fix Connection Refused
A refused connection usually means nothing is listening on that address and port:
ssh: connect to host 192.168.1.100 port 22: Connection refused
Check the local listener on the server:
sudo ss -tlnp | grep -E ':22[[:space:]]'
If no output appears, start the socket or service for your Ubuntu release. If SSH is listening, check the firewall:
sudo ufw status
sudo ufw allow ssh
Fix Permission Denied Publickey
The Permission denied (publickey) error means the server did not accept the key offered by the client. Check client-side key permissions first:
ls -la ~/.ssh/
drwx------ 2 user user 4096 Jan 15 10:00 .ssh -rw------- 1 user user 419 Jan 15 10:00 id_ed25519 -rw-r--r-- 1 user user 105 Jan 15 10:00 id_ed25519.pub
Fix incorrect modes with chmod:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
On the server account, confirm the public key exists in ~/.ssh/authorized_keys and lock down that file:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
cat ~/.ssh/authorized_keys
Each authorized key should be on one line and usually starts with ssh-ed25519 or ssh-rsa.
Fix Connection Timeout
A timeout usually points to routing, firewall, cloud security group, or wrong-port problems:
ssh: connect to host 192.168.1.100 port 22: Connection timed out
Confirm the host is reachable:
ping 192.168.1.100
If ICMP is allowed and the host responds, test the SSH TCP port with Telnet as a simple probe. Install Telnet first if your system does not have it; the Ubuntu Telnet guide covers that package.
telnet 192.168.1.100 22
Trying 192.168.1.100... Connected to 192.168.1.100. Escape character is '^]'. SSH-2.0-OpenSSH_10.2p1 Ubuntu-2ubuntu3
If the TCP probe times out, inspect local UFW rules, upstream firewalls, cloud security groups, NAT rules, and the port number configured in sshd_config.
Review SSH Authentication Logs
Use grep to filter SSH log lines while troubleshooting authentication failures:
sudo tail -50 /var/log/auth.log | grep sshd
Failed password for user from 192.168.1.50 port 54321 ssh2
Repeated failed logins from unknown IP addresses are a good reason to add rate limiting with Fail2ban on Ubuntu after SSH is working.
Connection closed by authenticating user root 192.168.1.50 port 54321 [preauth]
That line commonly appears after direct root login is disabled and someone attempts to authenticate as root.
Test SSH Configuration Syntax
When SSH refuses to restart after an edit, run the syntax check again:
sudo sshd -t
An invalid directive produces output like this:
/etc/ssh/sshd_config.d/99-local-hardening.conf line 4: Bad configuration option: InvalidDirective /etc/ssh/sshd_config.d/99-local-hardening.conf: terminating, 1 bad configuration options
Fix the named directive, rerun sudo sshd -t, and restart SSH only after the command returns no output.
Remove OpenSSH from Ubuntu
Remove the SSH server only when you have console access or another confirmed remote-access path. Removing openssh-server from a remote machine can end the only management channel you have.
Remove the Server Package
Remove the inbound SSH server while keeping the client available for outbound connections:
sudo apt remove openssh-server
Use purge only when you also want package-managed server configuration removed:
sudo apt purge openssh-server
If you truly want to remove the outbound client too, purge it separately after confirming nothing on the system depends on it:
sudo apt purge openssh-client
Run
sudo apt autoremoveonly after reviewing the package list APT proposes. Autoremove can include packages unrelated to this SSH article on reused systems, especially desktops and long-lived servers.
Remove Host Keys and Local Configuration
Deleting host keys changes the server identity. Clients that connected before will warn about a changed host key after OpenSSH is reinstalled and new keys are generated.
Remove only the server host keys while preserving the rest of /etc/ssh:
sudo rm /etc/ssh/ssh_host_*
For a full system-wide SSH reset, remove the whole directory only after backing up anything you need:
sudo rm -rf /etc/ssh
Remove Personal SSH Keys
Your personal ~/.ssh directory can contain keys for GitHub, GitLab, other servers, and automation. Back it up before deleting anything:
cp -r ~/.ssh ~/.ssh.backup
Remove the directory only when you want to reset all personal SSH state:
rm -rf ~/.ssh
If you only need to clear remembered host fingerprints, remove known_hosts instead:
rm ~/.ssh/known_hosts
Remove UFW SSH Rules
Remove firewall rules that were created for SSH:
sudo ufw delete allow ssh
sudo ufw delete allow 2222/tcp
Then verify the remaining rules:
sudo ufw status numbered
Verify OpenSSH Removal
Check whether package records remain:
dpkg -l 'openssh-*'
An rc status means the package was removed but configuration files remain:
rc openssh-server 1:9.6p1-3ubuntu13.15 amd64 secure shell (SSH) server
Confirm nothing is still listening for SSH:
sudo ss -tlnp | grep -E 'ssh|:22[[:space:]]'
No output means the system is not exposing a local SSH listener on the checked port.
OpenSSH References
The OpenSSH project site publishes upstream release information, and the OpenSSH Portable repository tracks the portable source tree used by Linux distributions. Ubuntu-specific packaging and configuration guidance belongs in the Ubuntu OpenSSH server documentation.
Conclusion
OpenSSH is installed and listening on Ubuntu with the correct socket or service path for your LTS release. From here, keep key-based authentication working, confirm firewall access before changing ports, and add Fail2ban or tighter UFW source rules when the server is reachable from untrusted networks.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>