Install and Enable the OpenSSH Server on Linux
# Ubuntu, Debian, Linux Mint
sudo apt install openssh-server
sudo systemctl enable --now ssh
sudo ufw allow OpenSSH # only if ufw is active
# Fedora
sudo dnf install openssh-server
sudo systemctl enable --now sshd
# Arch
sudo pacman -S openssh
sudo systemctl enable --now sshd
# openSUSE
sudo zypper install openssh
sudo systemctl enable --now sshd
sudo firewall-cmd --permanent --add-service=ssh && sudo firewall-cmd --reload
Then connect from another machine with ssh user@server-ip. Find the IP with ip -br addr. Next, set up SSH keys and turn off password login.
Check whether SSH is already running
systemctl status ssh ssh.socket sshd 2>/dev/null | grep -E '●|Active'
sudo ss -tlnp | grep -E ':22\b'
Example output on Ubuntu 26.04 after installing:
● ssh.socket - OpenBSD Secure Shell server socket
Active: active (listening) since ...
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("systemd",pid=1,fd=...))
The listener is owned by systemd, not sshd. That's socket activation (below). Fedora Server, openSUSE and most cloud images ship with sshd enabled already; desktop editions usually don't.
Ubuntu, Debian and Linux Mint
sudo apt update
sudo apt install openssh-server
sudo systemctl enable --now ssh
The package starts the server and enables it at boot automatically, so the last command mostly confirms that. The unit is ssh; sshd also works as an alias on most releases.
Ubuntu 22.10 and later: ssh.socket
Since Ubuntu 22.10 (so on 24.04 LTS and 26.04 LTS), SSH is socket-activated. systemd listens on port 22 through ssh.socket and starts ssh.service when the first connection arrives, which saves memory on idle machines. This matters in two situations:
- Changing the port or ListenAddress. The socket, not sshd, opens the port. On Ubuntu 23.04 and later a generator reads
PortandListenAddressfromsshd_configand rewrites the socket, but only after a reload:
On 22.10 itself you had to overridesudo systemctl daemon-reload sudo systemctl restart ssh.socketssh.socketwithsudo systemctl edit ssh.socket(an emptyListenStream=line, thenListenStream=2222). - Checking status.
systemctl status sshcan show "inactive" while SSH works perfectly, because the service hasn't been triggered yet. Checkssh.socket.
To go back to a classic always-running daemon:
sudo systemctl disable --now ssh.socket
sudo rm -f /etc/systemd/system/ssh.service.d/00-socket.conf /etc/systemd/system/ssh.socket.d/addresses.conf
sudo systemctl daemon-reload
sudo systemctl enable --now ssh.service
The removed drop-ins exist only on some upgraded systems; rm -f is harmless if they don't. Debian doesn't use socket activation by default: ssh.service runs normally and Port changes apply after sudo systemctl restart ssh.
Fedora
sudo dnf install openssh-server
sudo systemctl enable --now sshd
Fedora Workstation's firewalld zone already allows SSH. On Fedora Server, check with sudo firewall-cmd --list-services and add it if missing. SELinux allows sshd on port 22 only; for another port, label it first:
sudo semanage port -a -t ssh_port_t -p tcp 2222
Don't disable SELinux to make a custom port work. The semanage line is the correct fix.
Arch Linux
sudo pacman -S openssh
sudo systemctl enable --now sshd
Arch has no firewall enabled by default, so nothing else is needed unless you've set one up. Arch ships upstream defaults: root login with a password is refused (PermitRootLogin prohibit-password), and password login for normal users is allowed. See the Arch Wiki OpenSSH page.
openSUSE
sudo zypper install openssh
sudo systemctl enable --now sshd
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
openSUSE keeps vendor defaults in /usr/etc/ssh/sshd_config on Tumbleweed and Leap 16. Put your own settings in /etc/ssh/sshd_config.d/ rather than editing the vendor file. YaST's firewall and services modules do the same as the commands above.
Open the firewall
| Firewall | Allow SSH | Custom port 2222 |
|---|---|---|
| ufw (Ubuntu, Mint) | sudo ufw allow OpenSSH | sudo ufw allow 2222/tcp |
| firewalld (Fedora, openSUSE) | sudo firewall-cmd --permanent --add-service=ssh | sudo firewall-cmd --permanent --add-port=2222/tcp |
| Cloud provider | Open TCP 22 (or your port) in the security group / network firewall as well. | |
Run sudo firewall-cmd --reload after firewalld changes. Allow SSH before enabling ufw on a remote machine, or you'll lock yourself out. The firewall setup guide covers both tools properly.
Hardening basics
Put changes in a drop-in file instead of editing /etc/ssh/sshd_config. sshd_config includes /etc/ssh/sshd_config.d/*.conf at the top, and the first value sshd reads for a setting wins. Files are read in alphabetical order, so name yours with a low number. Ubuntu cloud images ship 50-cloud-init.conf, which may set PasswordAuthentication yes, and a 60- file would lose to it.
sudo tee /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
# optional: only these users may log in
# AllowUsers anna deploy
EOF
sudo sshd -t && echo "config OK"
Copy your key first (ssh-copy-id user@server, see SSH keys), log in with it in a second terminal, and keep your current session open while you reload. If key login fails, you still have a way back in.
# Ubuntu/Debian
sudo systemctl reload ssh
# Fedora/Arch/openSUSE
sudo systemctl reload sshd
# confirm the effective values
sudo sshd -T | grep -Ei 'passwordauthentication|permitrootlogin|^port'
Further steps worth considering: fail2ban or sshguard against brute-force attempts, limiting the source address in the firewall, and keeping openssh-server updated. Moving to a non-standard port cuts log noise but isn't a security control on its own.
Listen only on certain addresses
By default sshd listens on every interface. On a machine with a public and a private interface, or one you only reach over a VPN, restrict it:
# /etc/ssh/sshd_config.d/10-listen.conf
ListenAddress 192.168.1.50
ListenAddress 10.8.0.1
On Debian, Fedora, Arch and openSUSE, test with sudo sshd -t and restart the service. On Ubuntu with socket activation, run sudo systemctl daemon-reload and sudo systemctl restart ssh.socket so the generated socket picks up the addresses. If the address belongs to an interface that comes up late (a VPN), the bind can fail at boot; firewall rules restricting the source address are more robust than ListenAddress in that case.
Verify from another machine
ssh -v [email protected]
# custom port
ssh -p 2222 [email protected]
# on the server: watch logins live
sudo journalctl -u ssh -u sshd -f
The first connection asks you to confirm the host key fingerprint. Compare it with ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub on the server. If the server sits behind a router, use its LAN IP from inside the network; reaching it from outside needs port forwarding or a VPN.
Common problems
| Symptom | Cause and fix |
|---|---|
| Connection refused | Nothing listening: server not installed or not started, or listening on another port. Check ss -tlnp. |
| Connection timed out | Firewall, cloud security group or wrong IP. Packets are being dropped before reaching sshd. |
| New port ignored on Ubuntu | ssh.socket still on 22. Run daemon-reload and restart ssh.socket. |
| sshd fails to start on Fedora with a custom port | SELinux. Add the port with semanage port -a -t ssh_port_t. |
| Permission denied (publickey) | Key not in ~/.ssh/authorized_keys, or wrong permissions on ~/.ssh. |
| Password login still works after hardening | An earlier drop-in (e.g. 50-cloud-init.conf) sets it first. Check sshd -T and rename your file to a lower number. |
sshd -t: "no hostkeys available" | Host keys missing (cloned image). Run sudo ssh-keygen -A. |
For client-side options and everyday commands, see the SSH cheat sheet. To manage the service with systemctl in general, see systemd basics.
Frequently asked questions
Why does Ubuntu ignore the Port setting in sshd_config?
Ubuntu 22.10 and later start SSH through ssh.socket. After changing Port, run sudo systemctl daemon-reload and sudo systemctl restart ssh.socket so the socket listens on the new port.
Is the SSH service called ssh or sshd?
On Debian and Ubuntu the unit is ssh.service (with sshd as an alias on many releases). On Fedora, Arch and openSUSE it is sshd.service.
Is it safe to expose SSH to the internet?
It is common and reasonably safe if you use key authentication, disable password login and root login, and keep OpenSSH updated. Restricting access by firewall or VPN is safer still.
How do I check that SSH is listening?
Run sudo ss -tlnp | grep ssh. You should see port 22 (or your custom port) in LISTEN state, owned by sshd or systemd.
Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.