How to Install SSH on Debian 13, 12 and 11

Install SSH on Debian 13, 12 and 11 with firewall rules, key authentication, Includes hardening tips and Fail2Ban protection, hardening steps.

Last updatedAuthorJoshua JamesRead time8 minGuide typeDebian

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 releaseOpenSSH seriesNormal unit to enableRelease-specific note
Debian 13 (Trixie)10.0 seriesssh.servicessh.socket exists but is disabled in the standard service workflow; DSA keys are no longer supported.
Debian 12 (Bookworm)9.2 seriesssh.servicessh.socket exists but is disabled in the standard service workflow.
Debian 11 (Bullseye)8.4 seriesssh.servicessh.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, run sudo /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-server from 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.

Share this guide

Help another Linux user troubleshoot faster

Share this guide with someone troubleshooting Linux systems or saving it for later.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show more of our fresh Linux tutorials in Top Stories and From your sources when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<blockquote>quote</blockquote> quote block

Got a Question or Feedback?

We read and reply to every comment - let us know how we can help or improve this guide.

Verify before posting: