Debian does not always install an SSH server by default, especially on minimal, server, and custom images. To install SSH on Debian, use the openssh-server package, enable the packaged ssh.service unit, then confirm the daemon is listening before you depend on remote access.
For inbound logins, openssh-server provides the sshd daemon that accepts connections to this Debian system. APT also installs openssh-sftp-server for inbound SFTP support. The separate openssh-client package provides outbound tools such as ssh, scp, sftp, ssh-keygen, and ssh-copy-id.
Install SSH on Debian with APT
Refresh APT metadata first so Debian installs the current package revision from the enabled repositories:
sudo apt update
These commands use sudo for package and service changes that require root privileges. If your account cannot run sudo yet, add the account with the Debian sudoers setup guide before continuing.
Install the OpenSSH server package:
sudo apt install openssh-server
Enable and start the Debian SSH service:
sudo systemctl enable --now ssh
Debian’s canonical OpenSSH server unit is ssh.service. Current packages also expose sshd.service as a compatibility alias, but use ssh in Debian commands and troubleshooting so the unit name matches the packaged service file.
Check the OpenSSH Package State and Version
Confirm the server, client, and SFTP helper packages are installed:
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' openssh-server openssh-client openssh-sftp-server
Expected output after installing openssh-server is:
ii openssh-client ii openssh-server ii openssh-sftp-server
The ii status means the package is installed and configured. If openssh-server is missing from the output, install it before trying to enable inbound SSH logins.
Check the installed server package version with dpkg-query:
dpkg-query -W -f='${binary:Package} ${Version}\n' openssh-server
Check the client version reported by the ssh command:
ssh -V
Debian security updates can change the exact package revision, so local command output is more reliable than a frozen version string. In the default Debian repositories, Debian 13 uses the OpenSSH 10.0 series, Debian 12 uses the 9.2 series, and Debian 11 uses the 8.4 series.
Debian Release Differences for SSH Services
Debian 13, Debian 12, and Debian 11 use the same normal management path after a standard openssh-server setup: enable ssh.service, check ssh.service, and verify a listener on port 22. This differs from Ubuntu 26.04 and 24.04, where OpenSSH socket activation is the default listener path.
| Debian release | OpenSSH series | Normal unit to enable | Release-specific note |
|---|---|---|---|
| Debian 13 (Trixie) | 10.0 series | ssh.service | ssh.socket exists but is disabled in the standard service workflow; DSA keys are no longer supported. |
| Debian 12 (Bookworm) | 9.2 series | ssh.service | ssh.socket exists but is disabled in the standard service workflow. |
| Debian 11 (Bullseye) | 8.4 series | ssh.service | ssh.socket exists but is disabled; its packaged socket behavior differs internally from Debian 13 and 12. |
If you intentionally build a custom socket-activated SSH setup, test that design separately. For a standard Debian OpenSSH server, do not treat an inactive ssh.socket as a failure when ssh.service is active and port 22 is listening.
Verify SSH is Enabled and Running
Confirm the service is enabled for boot and active right now:
systemctl is-enabled ssh
systemctl is-active ssh
Expected output for a ready SSH server is:
enabled active
If you are comparing Debian with Ubuntu socket-activation instructions, check the Debian socket state separately:
systemctl is-enabled ssh.socket
systemctl is-active ssh.socket
In the standard Debian service workflow, expected output is:
disabled inactive
The socket state commands can return a nonzero shell status when they print disabled or inactive. That is expected for this diagnostic check; the important point is that ssh.service is active and the port listener exists.
For more detail, inspect the full unit status:
systemctl status ssh --no-pager
Look for Loaded: loaded with enabled and Active: active (running). Debian 13 may show the service file under /usr/lib/systemd/system/ssh.service, while Debian 12 and Debian 11 may show /lib/systemd/system/ssh.service; that path difference is normal, so manage SSH by the unit name instead of hard-coding the file path.
Confirm SSH is Listening on Port 22
Use ss to confirm Debian is accepting TCP connections on the default SSH port:
ss -H -ltn 'sport = :22' | awk '{print $1, $4}'
A normal listener shows LISTEN entries for IPv4 and IPv6:
LISTEN 0.0.0.0:22 LISTEN [::]:22
If you need to confirm which process owns the port, run the root-level listener check:
sudo ss -tlnp 'sport = :22'
If you later change the SSH port, replace 22 in the listener check with the new port.
Connect to Debian Over SSH
Find the Debian system’s IPv4 address from the server console or an existing local session:
ip -4 -brief address show scope global
Example output looks like this:
ens33 UP 192.168.1.100/24
Use the address before the slash when connecting, such as 192.168.1.100. If the system has multiple network interfaces, choose the address reachable from the client machine.
Then connect from the client machine:
ssh username@ip_address
Replace username with the Debian account name and ip_address with the server address. For example:
ssh joshua@192.168.1.100
The first connection asks you to verify the host key fingerprint. Accept it only when the fingerprint matches the server you intended to reach; this protects you from connecting to an impostor host. For more client-side examples, use the ssh command guide. If you prefer a graphical SSH client, install and configure PuTTY on Debian.
Set Up SSH Key Authentication
SSH keys are safer than reusable account passwords because the private key stays on the client and the Debian server stores only the public key. Set up keys before disabling password authentication, and keep the current SSH session open while testing the new login path.
Generate an Ed25519 SSH Key
Run ssh-keygen on the client machine, not on the server, unless the server is also the machine you will connect from:
ssh-keygen -t ed25519 -C "your_email@example.com"
Press Enter to accept the default key path, usually ~/.ssh/id_ed25519, and set a passphrase when the key protects an important account. Ed25519 is the preferred default for new OpenSSH keys because it is compact, fast, and widely supported on current Debian releases.
Copy the Public Key to Debian
Copy the public key to the Debian account:
ssh-copy-id username@ip_address
The command appends the public key to ~/.ssh/authorized_keys on the server and sets the account’s SSH directory permissions. Connect again from a new terminal before changing authentication policy:
ssh username@ip_address
Harden SSH After Installation
Hardening SSH is safest when you make one access change at a time, test syntax, reload the service, and prove a second login works before closing your current session. This order matters more than any single setting because an untested SSH change can lock you out of a remote server.
Allow SSH Through Your Firewall First
If the server uses UFW, firewalld, nftables, a cloud security group, or another firewall, allow the SSH port before enabling or tightening firewall rules. The default OpenSSH port is 22/tcp. If UFW is your firewall manager, follow the UFW guide for Debian so the SSH allow rule exists before the firewall is enabled.
Disable Root and Password Logins After Key Access Works
Create a local SSH drop-in after key-based login has been tested from another terminal. This example disables direct root login and password-style authentication while keeping public-key login enabled:
sudo install -m 0755 -d /etc/ssh/sshd_config.d
printf '%s\n' \
'PermitRootLogin no' \
'PubkeyAuthentication yes' \
'PasswordAuthentication no' \
'KbdInteractiveAuthentication no' | sudo tee /etc/ssh/sshd_config.d/99-local-hardening.conf >/dev/null
The first command makes sure the drop-in directory exists. The sudo tee command writes the settings to a root-owned file without changing ownership of your current shell.
Validate the SSH daemon configuration before applying it:
sudo /usr/sbin/sshd -t
If the syntax check prints no errors, reload the service:
sudo systemctl reload ssh
Do not close your existing SSH session until a second terminal can log in with a key. If key login fails after disabling passwords, keep the first session open, remove or edit
/etc/ssh/sshd_config.d/99-local-hardening.conf, runsudo /usr/sbin/sshd -t, and reload SSH again.
Changing the SSH port can reduce background scan noise, but it is not a replacement for keys, firewall rules, and update discipline. If you change Port, allow the new port in every firewall layer before reloading SSH, then connect with ssh -p new_port username@ip_address.
Add Brute-Force Protection with Fail2Ban
Fail2Ban is a useful next step for internet-facing SSH servers because it watches failed login attempts and bans repeat offenders through firewall actions. Use the dedicated Fail2Ban guide for Debian for the full install, jail verification, backend checks, unban commands, and removal path.
Debian 13 OpenSSH Notes
Debian 13 (Trixie) includes OpenSSH changes that can affect upgraded systems. The Debian 13 release notes document the full upgrade caveats, including two SSH-related changes that matter for remote access.
SSH No Longer Reads ~/.pam_environment by Default
OpenSSH on Debian 13 no longer reads ~/.pam_environment by default. If an older setup used that file for SSH session variables, move the variables into the user’s shell startup files, such as ~/.bash_profile or ~/.bashrc, and test a new login before relying on the changed environment.
DSA Keys Are No Longer Supported
OpenSSH in Debian 13 no longer supports DSA keys, even with compatibility options that worked in older releases. Check verbose SSH output before an upgrade if you still connect to very old systems:
ssh -v username@server 2>&1 | grep "Server accepts key"
If the accepted key is ssh-dss, generate and deploy an Ed25519 key before upgrading or changing authentication settings.
Rare legacy devices that only support DSA may require a separate legacy client path such as Debian’s openssh-client-ssh1 package. Keep that exception separate from the normal OpenSSH server setup because it is for connecting from a client to old devices, not for enabling modern inbound SSH on Debian.
Troubleshoot SSH on Debian
ssh.service or sshd.service Unit Name
Use ssh.service for Debian OpenSSH service commands. If a copied command uses sshd.service, check the canonical unit directly:
systemctl status ssh --no-pager
Current Debian packages can expose sshd.service as an alias, but the service file installed by openssh-server is named ssh.service.
Connection Refused or Timed Out
Connection refused usually means the service is stopped or not listening on the port you tried. Check the service and listener:
systemctl is-active ssh
ss -H -ltn 'sport = :22' | awk '{print $1, $4}'
Connection timed out more often points to a firewall, router, cloud security group, wrong IP address, or custom port. If you changed the port, connect with the matching -p option:
ssh -p 2222 username@ip_address
Permission Denied with SSH Keys
Permission denied (publickey) means the server did not accept a usable key for that account. Check that the public key, not the private key, is in authorized_keys:
head -n 1 ~/.ssh/authorized_keys
A public key normally starts with ssh-ed25519, ecdsa-sha2-, or ssh-rsa. A file that starts with -----BEGIN OPENSSH PRIVATE KEY----- is the private key and must not be pasted into authorized_keys.
Check the SSH directory and file permissions on the server:
ls -ld ~/.ssh
ls -l ~/.ssh/authorized_keys
If permissions are too open, fix them with chmod:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Use the chmod command guide if you need more context on permission modes.
Configuration Errors After Editing SSH
Always test the daemon configuration before reloading or restarting SSH:
sudo /usr/sbin/sshd -t
If the command reports an error, review the named file and line before reloading the service. Check recent service logs with journalctl:
sudo journalctl -u ssh -n 30 --no-pager
Update SSH on Debian
OpenSSH updates come through Debian’s normal APT repositories. To update only the OpenSSH server and client packages when newer revisions are available, refresh package metadata and run an upgrade-limited install:
sudo apt update
sudo apt install --only-upgrade openssh-server openssh-client openssh-sftp-server
After an SSH update, confirm the daemon is still active before closing any remote session:
systemctl is-active ssh
ssh -V
Remove SSH Server from Debian
Do not remove
openssh-serverfrom a remote-only system unless you have another tested access path, such as a hosting console, local console, hypervisor console, serial console, or an already working alternate remote tool.
Remove only the SSH server package when the Debian system no longer needs inbound SSH logins:
sudo apt remove openssh-server
Use purge only when you also want to remove package-managed server configuration files:
sudo apt purge openssh-server
After removal, clean dependencies that APT marks as no longer required:
sudo apt autoremove
If you created the local hardening drop-in and want to remove that custom policy as well, delete the drop-in file separately:
sudo rm -f /etc/ssh/sshd_config.d/99-local-hardening.conf
Verify the package state after removal:
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' openssh-server 2>/dev/null || echo "openssh-server is not installed"
A line that starts with ii means the server package is still installed. A line that starts with rc means the package was removed but residual configuration remains, which is expected after apt remove and cleared by apt purge.
Removing openssh-server does not remove the normal client tools provided by openssh-client. You can still use ssh, scp, sftp, ssh-keygen, and ssh-copy-id for outbound connections unless you remove the client package separately.
Conclusion
SSH is installed on Debian with the OpenSSH server enabled, the listener verified, and a safer key-based access path ready for hardening. Keep a tested fallback session open before changing authentication, pair internet-facing SSH with firewall rules and Fail2Ban, and use Debian’s ssh.service unit for normal service management.


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>