<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>SSH Essentials on Linuxize</title><link>https://linuxize.com/series/ssh-essentials/</link><description>Recent content in SSH Essentials on Linuxize</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><managingEditor>hello@linuxize.com (Linuxize)</managingEditor><webMaster>hello@linuxize.com (Linuxize)</webMaster><lastBuildDate>Fri, 30 Jan 2026 18:00:00 +0100</lastBuildDate><atom:link href="https://linuxize.com/series/ssh-essentials/index.xml" rel="self" type="application/rss+xml"/><image><url>https://linuxize.com/icons/icon-512x512.png</url><title>Linuxize</title><link>https://linuxize.com/</link></image><item><title>ssh Command in Linux: Connect to Remote Servers</title><link>https://linuxize.com/post/ssh-command-in-linux/</link><pubDate>Tue, 17 Dec 2019 19:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ssh-command-in-linux/</guid><category>ssh</category><category>linux commands</category><description>The ssh command connects you to a remote Linux server. This guide covers its syntax, the most useful options, key-based login, and port forwarding.</description><content:encoded>&lt;p&gt;Sooner or later, every Linux user has to work on a machine that is not in front of them. Secure Shell (SSH) makes that safe: it is a cryptographic network protocol used for an encrypted connection between a client and a server, so passwords and commands never travel in the clear.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ssh&lt;/code&gt; client creates that secure connection to the SSH server on a remote machine. Once it is open, you can execute commands on the server, tunnel X11 sessions, forward ports, and more.&lt;/p&gt;
&lt;p&gt;There are a number of SSH clients available, both free and commercial, with OpenSSH being the most widely used. It is available on all major platforms, including Linux, OpenBSD, Windows, and macOS.&lt;/p&gt;
&lt;p&gt;This guide explains how to use the OpenSSH command-line client (&lt;code&gt;ssh&lt;/code&gt;) to log in to a remote machine, run commands, and perform other operations.&lt;/p&gt;
&lt;h2 id="installing-openssh-client"&gt;Installing OpenSSH Client &lt;a class="headline-link" href="#installing-openssh-client" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The OpenSSH client program is called &lt;code&gt;ssh&lt;/code&gt; and can be invoked from the terminal. The OpenSSH client package also provides other SSH utilities such as &lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;&lt;code&gt;scp&lt;/code&gt;&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;&lt;code&gt;sftp&lt;/code&gt;&lt;/a&gt;
that are installed alongside the &lt;code&gt;ssh&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;OpenSSH client is preinstalled on most Linux distributions. If your system does not have the &lt;code&gt;ssh&lt;/code&gt; client installed, you can install it using your distribution&amp;rsquo;s package manager.&lt;/p&gt;
&lt;h3 id="install-openssh-on-ubuntu-debian-and-derivatives"&gt;Install OpenSSH on Ubuntu, Debian, and Derivatives &lt;a class="headline-link" href="#install-openssh-on-ubuntu-debian-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install openssh-client&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="install-openssh-on-fedora-rhel-and-derivatives"&gt;Install OpenSSH on Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#install-openssh-on-fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install openssh-clients&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="install-openssh-on-windows-10-and-11"&gt;Install OpenSSH on Windows 10 and 11 &lt;a class="headline-link" href="#install-openssh-on-windows-10-and-11" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Windows 10 and Windows 11 include a built-in OpenSSH client that can be installed via PowerShell. To find the exact package name, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="powershell"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;powershell&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Where-Object&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;-like&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;OpenSSH*&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Name : OpenSSH.Client~~~~0.0.1.0
State : NotPresent
Name : OpenSSH.Server~~~~0.0.1.0
State : NotPresent&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once you know the package name, install it by running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="powershell"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;powershell&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Add-WindowsCapability&lt;/span&gt; &lt;span class="n"&gt;-Online&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="n"&gt;OpenSSH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;~~~~&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Path :
Online : True
RestartNeeded : False&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="install-openssh-on-macos"&gt;Install OpenSSH on macOS &lt;a class="headline-link" href="#install-openssh-on-macos" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;macOS ships with the OpenSSH client installed by default.&lt;/p&gt;
&lt;h2 id="ssh-command-syntax"&gt;ssh Command Syntax &lt;a class="headline-link" href="#ssh-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The basic syntax of the &lt;code&gt;ssh&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh [OPTIONS] [USER@]HOST&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The following requirements must be met to log in to a remote machine via SSH:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An SSH server must be running on the remote machine.&lt;/li&gt;
&lt;li&gt;The SSH port must be open in the remote machine&amp;rsquo;s firewall.&lt;/li&gt;
&lt;li&gt;You must know the username and password of the remote account, or have a valid SSH key pair configured.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="connecting-to-a-remote-server"&gt;Connecting to a Remote Server &lt;a class="headline-link" href="#connecting-to-a-remote-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To connect to a remote server, type &lt;code&gt;ssh&lt;/code&gt; followed by the remote hostname or IP address:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh ssh.linuxize.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you connect to a remote machine for the first time, you will see a message like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;The authenticity of host &amp;#39;ssh.linuxize.com (192.168.121.111)&amp;#39; can&amp;#39;t be established.
ECDSA key fingerprint is SHA256:Vybt22mVXuNuB5unE++yowF7lgA/9/2bLSiO3qmYWBY.
Are you sure you want to continue connecting (yes/no/[fingerprint])?&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each host has a unique fingerprint that is stored in the &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt; file. Before accepting it, compare the displayed fingerprint with the value provided by the server administrator or shown in the server console. Once you have verified that they match, type &lt;code&gt;yes&lt;/code&gt; to store the fingerprint and continue. You will then be prompted to enter your password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Warning: Permanently added &amp;#39;ssh.linuxize.com&amp;#39; (ECDSA) to the list of known hosts.
dev@ssh.linuxize.com&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once you enter the password, you will be logged in to the remote machine.&lt;/p&gt;
&lt;p&gt;When no username is given, &lt;code&gt;ssh&lt;/code&gt; uses the current system login name. To log in as a different user, specify the username and host in the following format:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The username can also be specified with the &lt;code&gt;-l&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -l username hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;By default, &lt;code&gt;ssh&lt;/code&gt; connects to port 22. On some servers, administrators &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;change the default SSH port&lt;/a&gt;
to reduce the risk of automated attacks. To connect to a non-default port, use the &lt;code&gt;-p&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -p &lt;span class="m"&gt;5522&lt;/span&gt; username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are experiencing authentication or connection issues, use the &lt;code&gt;-v&lt;/code&gt; option to print debugging messages:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -v username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For more verbosity, use &lt;code&gt;-vv&lt;/code&gt; or &lt;code&gt;-vvv&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="running-remote-commands"&gt;Running Remote Commands &lt;a class="headline-link" href="#running-remote-commands" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can execute a command on a remote machine without starting an interactive shell session by appending the command after the host:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@hostname &lt;span class="s1"&gt;&amp;#39;command&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For example, to check the disk usage on a remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@hostname &lt;span class="s1"&gt;&amp;#39;df -h&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To run multiple commands in one session, separate them with a semicolon or use &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@hostname &lt;span class="s1"&gt;&amp;#39;uname -a &amp;amp;&amp;amp; df -h&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To run a command that requires a pseudo-terminal (for example, &lt;code&gt;top&lt;/code&gt; or &lt;code&gt;sudo&lt;/code&gt;), pass the &lt;code&gt;-t&lt;/code&gt; flag to force TTY allocation:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -t username@hostname &lt;span class="s1"&gt;&amp;#39;sudo journalctl -f&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="ssh-command-options"&gt;ssh Command Options &lt;a class="headline-link" href="#ssh-command-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;ssh&lt;/code&gt; command accepts a long list of options, but a small group covers almost everything you will do day to day. The ones you have already seen control the connection itself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; - Remote port to connect to (default is 22)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; - Login name to use on the remote host&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; - Path to the private key file (identity file)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt; - Verbose output for debugging (&lt;code&gt;-vv&lt;/code&gt; and &lt;code&gt;-vvv&lt;/code&gt; add more detail)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-q&lt;/code&gt; - Quiet mode, which suppresses warnings and diagnostic messages&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt; - Force pseudo-terminal allocation&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-T&lt;/code&gt; - Disable pseudo-terminal allocation&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt; - Compress all data sent over the connection&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-F&lt;/code&gt; - Use an alternative configuration file instead of &lt;code&gt;~/.ssh/config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-4&lt;/code&gt; and &lt;code&gt;-6&lt;/code&gt; - Force IPv4 or IPv6 only&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rest deal with forwarding and tunneling:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-L&lt;/code&gt; - Local port forwarding&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-R&lt;/code&gt; - Remote port forwarding&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-D&lt;/code&gt; - Dynamic port forwarding (SOCKS proxy)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-N&lt;/code&gt; - Do not execute a remote command, which is useful when you only want a tunnel&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; - Send &lt;code&gt;ssh&lt;/code&gt; to the background just before the command runs&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-g&lt;/code&gt; - Allow remote hosts to connect to locally forwarded ports&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-A&lt;/code&gt; - Forward your local authentication agent (enable it only for hosts you trust)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-w&lt;/code&gt; - Request tun device forwarding for a layer 3 VPN&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A few of these are worth a closer look.&lt;/p&gt;
&lt;h3 id="passing-configuration-options-with--o"&gt;Passing Configuration Options with -o &lt;a class="headline-link" href="#passing-configuration-options-with--o" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Not every setting has a dedicated command-line flag. The &lt;code&gt;-o&lt;/code&gt; option lets you pass any &lt;code&gt;ssh_config&lt;/code&gt; directive on the command line, using the same &lt;code&gt;Keyword=value&lt;/code&gt; form you would write in the config file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -o &lt;span class="s2"&gt;&amp;#34;ServerAliveInterval=60&amp;#34;&lt;/span&gt; username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Repeat &lt;code&gt;-o&lt;/code&gt; to pass more than one directive:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -o &lt;span class="s2"&gt;&amp;#34;User=root&amp;#34;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;#34;Port=5522&amp;#34;&lt;/span&gt; hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Options given on the command line take precedence over the same options in &lt;code&gt;~/.ssh/config&lt;/code&gt;, so &lt;code&gt;-o&lt;/code&gt; is a convenient way to override a host entry once without editing the file. Run &lt;code&gt;man ssh_config&lt;/code&gt; for the full list of directives it accepts.&lt;/p&gt;
&lt;h3 id="connecting-through-a-jump-host-with--j"&gt;Connecting Through a Jump Host with -J &lt;a class="headline-link" href="#connecting-through-a-jump-host-with--j" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Servers on a private network are often reachable only through a bastion host. The &lt;code&gt;-J&lt;/code&gt; option tells &lt;code&gt;ssh&lt;/code&gt; to connect to the jump host first, then open the connection to the final destination through it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -J username@jumphost username@internal-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Authentication to the final server happens from your local machine, so the jump host never sees your password or private key. To chain more than one jump host, separate them with commas:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -J user@first,user@second user@destination&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="forwarding-x11-with--x"&gt;Forwarding X11 with -X &lt;a class="headline-link" href="#forwarding-x11-with--x" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;X11 forwarding lets you start a graphical program on the remote server and have its window appear on your local desktop. Pass the &lt;code&gt;-X&lt;/code&gt; option to enable it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -X username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once connected, launching an application such as &lt;code&gt;firefox&lt;/code&gt; opens the window locally while the program itself runs on the server. Your local system needs a running X server, and the remote host typically needs the &lt;code&gt;xauth&lt;/code&gt; package and &lt;code&gt;X11Forwarding yes&lt;/code&gt; in its effective SSH server configuration.&lt;/p&gt;
&lt;p&gt;Enable X11 forwarding only when you trust the remote server. Although &lt;code&gt;-X&lt;/code&gt; applies X11 security restrictions, a compromised or privileged remote host may still be able to access your local display or monitor input. Use &lt;code&gt;-x&lt;/code&gt; (lowercase) to disable X11 forwarding for a single connection when your config file enables it by default.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;-Y&lt;/code&gt; option enables trusted forwarding and skips the X11 security extension controls. Prefer &lt;code&gt;-X&lt;/code&gt;, and use &lt;code&gt;-Y&lt;/code&gt; only when an application requires it, because trusted forwarding gives the remote program full access to your local display.&lt;/p&gt;
&lt;h2 id="ssh-config-file"&gt;SSH Config File &lt;a class="headline-link" href="#ssh-config-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you connect to multiple remote systems over SSH regularly, remembering all IP addresses, usernames, non-standard ports, and command-line options becomes difficult.&lt;/p&gt;
&lt;p&gt;The OpenSSH client reads options from the per-user configuration file (&lt;code&gt;~/.ssh/config&lt;/code&gt;). You can store different SSH options for each remote host in this file.&lt;/p&gt;
&lt;p&gt;A sample SSH config entry looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host dev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName dev.linuxize.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User mike&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;Port 4422&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With this entry, typing &lt;code&gt;ssh dev&lt;/code&gt; is equivalent to:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -p &lt;span class="m"&gt;4422&lt;/span&gt; mike@dev.linuxize.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For more information, see the article on the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="public-key-authentication"&gt;Public Key Authentication &lt;a class="headline-link" href="#public-key-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The SSH protocol supports various authentication mechanisms. Public key authentication lets you &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;log in to a remote server without entering a password&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;This method uses a pair of cryptographic keys. The private key stays on your local machine and the public key is placed on each remote server you want to access.&lt;/p&gt;
&lt;p&gt;If you do not already have an SSH key pair on your local machine, &lt;a href="https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/"&gt;generate one&lt;/a&gt;
with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519 -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Ed25519 is the recommended key type for new keys because it provides strong security with smaller keys and faster signing than RSA. If you need RSA for compatibility with older systems, use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be asked to enter a passphrase. Using a passphrase is optional but strongly recommended for security.&lt;/p&gt;
&lt;p&gt;Once you have your key pair, copy the public key to the remote server with &lt;a href="https://linuxize.com/post/ssh-copy-id-command/"&gt;&lt;code&gt;ssh-copy-id&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Enter the remote user&amp;rsquo;s password when prompted. The public key will be appended to the &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file on the remote server.&lt;/p&gt;
&lt;p&gt;After the key is in place, you can log in without being prompted for a password.&lt;/p&gt;
&lt;h2 id="port-forwarding"&gt;Port Forwarding &lt;a class="headline-link" href="#port-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SSH tunneling (port forwarding) creates an encrypted SSH connection through which traffic for other services can be relayed. It is useful for securing unencrypted protocols such as VNC or FTP, accessing geo-restricted services, or bypassing intermediate firewalls.&lt;/p&gt;
&lt;p&gt;There are three types of SSH port forwarding:&lt;/p&gt;
&lt;h3 id="local-port-forwarding"&gt;Local Port Forwarding &lt;a class="headline-link" href="#local-port-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Local port forwarding forwards a connection from the client host through the SSH server to a destination host and port. Pass the &lt;code&gt;-L&lt;/code&gt; option to create a local forward:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -L &lt;span class="o"&gt;[&lt;/span&gt;LOCAL_IP:&lt;span class="o"&gt;]&lt;/span&gt;LOCAL_PORT:DESTINATION_HOST:DESTINATION_PORT -N -f username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="remote-port-forwarding"&gt;Remote Port Forwarding &lt;a class="headline-link" href="#remote-port-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Remote port forwarding forwards a port from the server host back to the client host. Pass the &lt;code&gt;-R&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -R &lt;span class="o"&gt;[&lt;/span&gt;REMOTE:&lt;span class="o"&gt;]&lt;/span&gt;REMOTE_PORT:DESTINATION:DESTINATION_PORT -N -f username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="dynamic-port-forwarding"&gt;Dynamic Port Forwarding &lt;a class="headline-link" href="#dynamic-port-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Dynamic port forwarding creates a &lt;a href="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/"&gt;SOCKS proxy server&lt;/a&gt;
that allows communication across a range of ports. Pass the &lt;code&gt;-D&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -D &lt;span class="o"&gt;[&lt;/span&gt;LOCAL_IP:&lt;span class="o"&gt;]&lt;/span&gt;LOCAL_PORT -N -f username@hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-f&lt;/code&gt; option tells &lt;code&gt;ssh&lt;/code&gt; to run in the background and &lt;code&gt;-N&lt;/code&gt; tells it not to execute a remote command.&lt;/p&gt;
&lt;p&gt;For detailed step-by-step instructions, see &lt;a href="https://linuxize.com/post/how-to-setup-ssh-tunneling/"&gt;How to Set Up SSH Tunneling (Port Forwarding)&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Connection refused&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The SSH server is not running on the remote host, or the SSH port is blocked by a firewall. Verify the server is running (&lt;code&gt;sudo systemctl status ssh&lt;/code&gt; or &lt;code&gt;sudo systemctl status sshd&lt;/code&gt;) and that the port is open. If both check out, work through the remaining &lt;a href="https://linuxize.com/post/fix-ssh-connection-refused/"&gt;causes of an SSH connection refused error&lt;/a&gt;
, such as a listener bound to the wrong address.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Host key verification failed&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The remote host&amp;rsquo;s key has changed since you last connected, which may indicate a server rebuild or a &lt;a href="https://linuxize.com/post/fix-ssh-host-key-verification-failed/"&gt;man-in-the-middle attack&lt;/a&gt;
. If you are sure the host is legitimate, remove the old key with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -R hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then reconnect to store the new fingerprint.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Permission denied (publickey)&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The server does not accept your key. Verify that your public key is in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; on the remote host, that file permissions are correct (&lt;code&gt;chmod 600 ~/.ssh/authorized_keys&lt;/code&gt;), and that the correct private key is being used. Run &lt;code&gt;ssh -v&lt;/code&gt; for details, or see &lt;a href="https://linuxize.com/post/fix-ssh-permission-denied-publickey/"&gt;Fix SSH Permission Denied (publickey)&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Permission denied (password)&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The password is wrong, or the server has password authentication disabled. Check &lt;code&gt;PasswordAuthentication&lt;/code&gt; in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; on the remote host.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ssh_exchange_identification: read: Connection reset by peer&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The SSH server rejected the connection before authentication. This can be caused by &lt;code&gt;MaxStartups&lt;/code&gt; or &lt;code&gt;AllowUsers&lt;/code&gt;/&lt;code&gt;DenyUsers&lt;/code&gt; restrictions in &lt;code&gt;sshd_config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connection is slow to establish&lt;/strong&gt;&lt;br&gt;
Add &lt;code&gt;GSSAPIAuthentication no&lt;/code&gt; to your &lt;code&gt;~/.ssh/config&lt;/code&gt; for the affected host to skip Kerberos authentication, which can cause delays when it times out.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect using current username&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect as a specific user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -p PORT user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect on a non-default port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -i ~/.ssh/id_ed25519 user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect with a specific key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -o &amp;quot;User=root&amp;quot; hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass an ssh_config directive inline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -J user@jump user@target&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect through a jump host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -X user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable X11 forwarding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -C user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable compression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -q user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quiet mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh user@hostname 'command'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a remote command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -t user@hostname 'sudo command'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a command requiring a TTY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -L 8080:localhost:80 user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Local port forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -R 9090:localhost:3000 user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remote port forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -D 1080 user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dynamic SOCKS proxy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh -v user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Debug connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-keygen -t ed25519&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate an Ed25519 key pair&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id user@hostname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy public key to remote host&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;ssh&lt;/code&gt; and &lt;code&gt;scp&lt;/code&gt;/&lt;code&gt;sftp&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;ssh&lt;/code&gt; opens an interactive shell session or runs a single remote command. &lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;&lt;code&gt;scp&lt;/code&gt;&lt;/a&gt;
copies files between hosts over SSH, and &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;&lt;code&gt;sftp&lt;/code&gt;&lt;/a&gt;
provides an interactive file transfer session. All three use the same SSH protocol and authentication.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Should I use Ed25519 or RSA keys?&lt;/strong&gt;&lt;br&gt;
Use Ed25519 for new keys. It provides strong security with short keys and fast operations. RSA with a sufficient key size, such as 4096 bits, also remains secure and is useful when connecting to older systems that do not support Ed25519.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I keep an SSH session alive?&lt;/strong&gt;&lt;br&gt;
Add the following to your &lt;code&gt;~/.ssh/config&lt;/code&gt; to send keepalive packets and prevent idle disconnection:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host *&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ServerAliveInterval 60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ServerAliveCountMax 3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;How do I run &lt;code&gt;ssh&lt;/code&gt; without typing a password every time?&lt;/strong&gt;&lt;br&gt;
Use public key authentication and copy your public key to the server with &lt;code&gt;ssh-copy-id&lt;/code&gt;. See &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;How to Set Up Passwordless SSH Login&lt;/a&gt;
for a step-by-step guide.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;ssh&lt;/code&gt; command is the primary tool for securely connecting to remote Linux servers. Use key-based authentication with Ed25519 keys, reach for &lt;code&gt;-v&lt;/code&gt; whenever a connection misbehaves, and move your regular hosts into the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
once you are managing more than a couple of them.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ssh-command-in-linux/featured_hu_372913d6c2594dd9.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Enable SSH on Ubuntu 18.04</title><link>https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/</link><pubDate>Sun, 09 Sep 2018 19:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/</guid><category>ssh</category><category>ubuntu</category><description>In this tutorial, we'll show you how to enable SSH on an Ubuntu Desktop machine. Enabling SSH will allow you to remotely connect to your Ubuntu machine and securely transfer files or perform administrative tasks.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol used for a secure connection between a client and a server.&lt;/p&gt;
&lt;p&gt;In this tutorial, we&amp;rsquo;ll show you how to enable SSH on an Ubuntu Desktop machine. Enabling SSH will allow you to remotely connect to your Ubuntu machine and securely transfer files or perform administrative tasks.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before continuing with this tutorial, make sure you are logged in as a &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-ubuntu/"&gt;user with sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="enabling-ssh-on-ubuntu"&gt;Enabling SSH on Ubuntu &lt;a class="headline-link" href="#enabling-ssh-on-ubuntu" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The SSH server is not installed by default on Ubuntu desktop systems but it can be easily installed from the standard Ubuntu repositories.&lt;/p&gt;
&lt;p&gt;To install and enable SSH on your Ubuntu system complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open your terminal either by using the &lt;code&gt;Ctrl+Alt+T&lt;/code&gt; keyboard shortcut or by clicking on the terminal icon and install the &lt;code&gt;openssh-server&lt;/code&gt; package by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install openssh-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Enter the password when prompted and enter &lt;code&gt;Y&lt;/code&gt; to continue with the installation.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 1024 / 768"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh_hu_5702606c6bb2dde6.webp 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh_hu_b673de5ad0d77f0b.webp 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh_hu_26e6cef8b8000922.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover cursor-zoom-in" loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh_hu_38365b49f4bdafb3.jpg"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh_hu_5b50535b86d76a92.jpg 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh_hu_38365b49f4bdafb3.jpg 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh_hu_bad73c709b37b57.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="576"
alt="ubuntu install ssh" data-zoomable="true" data-zoom-src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-install-ssh.jpg" tabindex="0"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once the installation is completed, the SSH service will start automatically. To verify that the installation was successful and SSH service is running type the following command which will print the SSH server status:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You should see something like &lt;code&gt;Active: active (running)&lt;/code&gt; :&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 1024 / 768"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status_hu_4340163c78ba555e.webp 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status_hu_b09d21208e22b962.webp 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status_hu_f40be2791cd31659.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover cursor-zoom-in" loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status_hu_c4516faa33648bf2.jpg"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status_hu_c0a40761fce0729f.jpg 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status_hu_c4516faa33648bf2.jpg 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status_hu_d8687b934cf30b5c.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="576"
alt="ubuntu ssh status" data-zoomable="true" data-zoom-src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-ssh-status.jpg" tabindex="0"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;Press &lt;code&gt;q&lt;/code&gt; to get back to the command line prompt.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ubuntu comes with a firewall configuration tool called UFW. If the firewall is enabled on your system, make sure to open the SSH port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now that SSH is installed and running on your Ubuntu system you can connect to it via SSH from any remote machine. Linux and macOS systems have SSH clients installed by default. If you want to connect from a Windows machine then you can use an SSH client such as &lt;a href="https://www.putty.org/" target="_blank" rel="noopener noreferrer"&gt;PuTTY&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="connecting-to-ssh-over-lan"&gt;Connecting to SSH Over LAN &lt;a class="headline-link" href="#connecting-to-ssh-over-lan" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To connect to your Ubuntu machine over LAN you only need to enter the following command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Change the &lt;code&gt;username&lt;/code&gt; with the actual user name and &lt;code&gt;ip_address&lt;/code&gt; with the IP Address of the Ubuntu machine where you installed SSH.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you don&amp;rsquo;t know your IP address you can easily find it using the &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;ip command&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 1024 / 768"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address_hu_26341c8730ff36c.webp 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address_hu_4f24eb5747cb1e9a.webp 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address_hu_30a85572df49e9ae.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover cursor-zoom-in" loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address_hu_d5704774eb5984a2.jpg"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address_hu_9d683f696dc3ce8e.jpg 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address_hu_d5704774eb5984a2.jpg 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address_hu_6643a2afc4ec0309.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="576"
alt="ubuntu find ip address" data-zoomable="true" data-zoom-src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/ubuntu-find-ip-address.jpg" tabindex="0"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;As you can see from the output, the system IP address is &lt;code&gt;192.168.121.111&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once you’ve found the IP address, login to remote machine by running the following &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;ssh&lt;/code&gt;&lt;/a&gt;
command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh linuxize@192.168.121.111&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you connect through SSH for the first time, you will see a message looking something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;The authenticity of host &amp;#39;192.168.121.111 (192.168.121.111)&amp;#39; can&amp;#39;t be established.
ECDSA key fingerprint is SHA256:Vybt22mVXuNuB5unE++yowF7lgA/9/2bLSiO3qmYWBY.
Are you sure you want to continue connecting (yes/no)?&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Type &lt;code&gt;yes&lt;/code&gt; and you’ll be prompted to enter your password.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Warning: Permanently added &amp;#39;192.168.121.111&amp;#39; (ECDSA) to the list of known hosts.
linuxize@192.168.121.111&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once you enter the password you will be greeted with a message similar to the one below.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-33-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You are now logged in to your Ubuntu machine.&lt;/p&gt;
&lt;h2 id="connecting-to-ssh-over-internet"&gt;Connecting to SSH Over Internet &lt;a class="headline-link" href="#connecting-to-ssh-over-internet" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To connect to your Ubuntu machine over the Internet you will need to know your public IP Address and to configure your router to accept data on port 22 and send it to the Ubuntu machine where the SSH is running.&lt;/p&gt;
&lt;p&gt;To determine the public IP address of the machine you’re trying to SSH to, simply visit the following URL: &lt;a href="https://api.ipify.org" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;https://api.ipify.org&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;When it comes to setting up &lt;a href="https://linuxize.com/post/how-to-setup-ssh-tunneling/"&gt;port forwarding&lt;/a&gt;
each router has a different way to setup port forwarding. You should consult your router documentation about how to set up port forwarding. In short, you need to enter the port number where requests will be made (Default SSH port is 22) and the private IP address you found earlier (using the &lt;code&gt;ip a&lt;/code&gt; command) of the machine where the SSH is running.&lt;/p&gt;
&lt;p&gt;Once you’ve found the IP address, and configured your router you can log in by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@public_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are exposing your machine to the Internet it is a good idea to implement some security measures. The most basic one is to configure your router to accept SSH traffic on a non-standard port and to forward it to port 22 on the machine running the SSH service.&lt;/p&gt;
&lt;p&gt;You can also &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;set up an SSH key-based authentication&lt;/a&gt;
and connect to your Ubuntu machine without entering a password.&lt;/p&gt;
&lt;h2 id="disabling-ssh-on-ubuntu"&gt;Disabling SSH on Ubuntu &lt;a class="headline-link" href="#disabling-ssh-on-ubuntu" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If for some reason you want to disable SSH on your Ubuntu machine you can simply stop the SSH service by running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl stop ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To start it again run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To disable the SSH service to start during system boot run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl disable ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To enable it again type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You have learned how to install and enable SSH on your Ubuntu 18.04. You can now login to your machine and perform common sysadmin tasks through the command prompt.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
adds an extra layer of security to your server by reducing the risk of automated attacks.&lt;/p&gt;
&lt;p&gt;If you are managing multiple systems, you can simplify your workflow by defining all of your connections in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;For more information, about how to configure your SSH server read the Ubuntu&amp;rsquo;s &lt;a href="https://help.ubuntu.com/community/SSH/OpenSSH/Configuring" target="_blank" rel="noopener noreferrer"&gt;SSH/OpenSSH/Configuring&lt;/a&gt;
guide and the &lt;a href="https://www.openssh.com/manual.html" target="_blank" rel="noopener noreferrer"&gt;official SSH manual&lt;/a&gt;
page.&lt;/p&gt;
&lt;p&gt;If you have any questions, please leave a comment below.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-18-04/featured_hu_717d9276a5fc555c.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Enable SSH on Ubuntu</title><link>https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/</link><pubDate>Mon, 01 Jun 2020 19:51:27 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/</guid><category>ssh</category><category>ubuntu</category><description>Enable SSH on Ubuntu by installing OpenSSH Server, checking the correct systemd unit, allowing it through UFW, and connecting from Linux, macOS, or Windows.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a network protocol that allows you to securely connect to a remote server or computer over an encrypted connection. With SSH enabled, you can remotely manage your Ubuntu system, run administrative commands, and transfer files securely using tools like &lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;&lt;code&gt;scp&lt;/code&gt;&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;&lt;code&gt;sftp&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;This guide explains how to enable SSH on Ubuntu 20.04, 22.04, 24.04, and 26.04, connect to it remotely, and manage the SSH service.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install OpenSSH server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo apt install openssh-server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check SSH service status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl status ssh.service ssh.socket&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start SSH on Ubuntu 20.04/22.04&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl start ssh.service&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start SSH on Ubuntu 24.04/26.04&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl start ssh.socket&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stop SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl stop ssh.service ssh.socket&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable SSH on boot (Ubuntu 20.04/22.04)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl enable ssh.service&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable SSH on boot (Ubuntu 24.04/26.04)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl enable ssh.socket&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disable SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl disable --now ssh.service ssh.socket&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow SSH through UFW&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow ssh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connect to remote host&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh username@ip_address&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="enabling-ssh-on-ubuntu"&gt;Enabling SSH on Ubuntu &lt;a class="headline-link" href="#enabling-ssh-on-ubuntu" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, on fresh installs, Ubuntu does not allow SSH connections. You must enable it manually.&lt;/p&gt;
&lt;p&gt;Follow the steps below as root or a &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-ubuntu/"&gt;user with sudo privileges&lt;/a&gt;
to install and enable SSH on your Ubuntu system:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open the terminal using &lt;code&gt;Ctrl+Alt+T&lt;/code&gt; and install the &lt;code&gt;openssh-server&lt;/code&gt; package:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install openssh-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When prompted, enter your password, then press &lt;code&gt;Enter&lt;/code&gt; to continue the installation.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 756 / 259"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-install-ssh_hu_8d606e57dcb4ec11.webp 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-install-ssh_hu_51542e4d4bd0d1f2.webp 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-install-ssh_hu_55ca83ca1f469fef.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-install-ssh_hu_9ac6311966dd6181.jpg"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-install-ssh_hu_6bc76bd8d28f0b4a.jpg 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-install-ssh_hu_9ac6311966dd6181.jpg 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-install-ssh_hu_d4d8bb35173954bf.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="263"
alt="ubuntu install ssh"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After installation, Ubuntu enables OpenSSH automatically. Ubuntu 20.04 and 22.04 run &lt;code&gt;ssh.service&lt;/code&gt; at boot. Verify that the service is running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status ssh.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should show the service as &lt;code&gt;active (running)&lt;/code&gt; and enabled to start on system boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2026-09-01 12:34:00 CEST; 9h ago
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;q&lt;/code&gt; to exit the status screen and get back to the command line prompt.&lt;/p&gt;
&lt;p&gt;Ubuntu 24.04 and 26.04 use &lt;code&gt;ssh.socket&lt;/code&gt; by default, a behavior introduced in Ubuntu 22.10. The socket listens for incoming connections and starts &lt;code&gt;ssh.service&lt;/code&gt; when a client connects. Check the socket unit instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Look for &lt;code&gt;Active: active (listening)&lt;/code&gt; in the output. Before the first connection, &lt;code&gt;ssh.service&lt;/code&gt; may be inactive, which is expected and does not mean that SSH is broken.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ubuntu ships with a firewall configuration tool called UFW. If the &lt;a href="https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-20-04/"&gt;firewall is enabled&lt;/a&gt;
on your system, make sure to open the SSH port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That is it. You can now connect to your Ubuntu system via SSH from any remote machine. Linux and macOS systems include an SSH client by default. On Windows 10 and 11, you can use the built-in &lt;code&gt;ssh&lt;/code&gt; client from PowerShell or Command Prompt, or use &lt;a href="https://www.putty.org/" target="_blank" rel="noopener noreferrer"&gt;PuTTY&lt;/a&gt;
if you prefer a graphical SSH client.&lt;/p&gt;
&lt;h2 id="connecting-to-the-ssh-server"&gt;Connecting to the SSH Server &lt;a class="headline-link" href="#connecting-to-the-ssh-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To connect to your Ubuntu machine over LAN, invoke the &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;ssh&lt;/code&gt; command&lt;/a&gt;
followed by the username and the IP address in the following format:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Make sure you change &lt;strong&gt;username&lt;/strong&gt; to the actual username and &lt;strong&gt;ip_address&lt;/strong&gt; to the IP Address of the Ubuntu machine where you installed SSH.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you do not know the IP address, you can easily find it using the &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;&lt;code&gt;ip&lt;/code&gt; command&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 753 / 274"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-find-ip-address_hu_8a306d539117bde5.webp 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-find-ip-address_hu_628bb76827bfbfc7.webp 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-find-ip-address_hu_b0848f9a9c2796ea.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-find-ip-address_hu_3a6c76a3afcb668d.jpg"
srcset="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-find-ip-address_hu_32657c25e9243f69.jpg 480w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-find-ip-address_hu_3a6c76a3afcb668d.jpg 768w, https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/ubuntu-find-ip-address_hu_17352adae5ee3229.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="279"
alt="ubuntu find ip address"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;As you can see from the output, the system IP address is &lt;code&gt;10.0.2.15&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once you have found the IP address, log in to the remote machine by running the following &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;SSH&lt;/code&gt;&lt;/a&gt;
command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh linuxize@10.0.2.15&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you connect the first time, you will see a security warning like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;The authenticity of host &amp;#39;10.0.2.15 (10.0.2.15)&amp;#39; can&amp;#39;t be established.
ED25519 key fingerprint is SHA256:Vybt22mVXuNuB5unE++yowF7lgA/9/2bLSiO3qmYWBY.
Are you sure you want to continue connecting (yes/no/[fingerprint])?&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Type &lt;code&gt;yes&lt;/code&gt;, and you will be prompted to enter your password.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Warning: Permanently added &amp;#39;10.0.2.15&amp;#39; (ED25519) to the list of known hosts.
linuxize@10.0.2.15&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once you enter the password, you will be logged into your system and greeted with the default Ubuntu message:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.0-45-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You are now logged in to your Ubuntu machine.&lt;/p&gt;
&lt;h2 id="connecting-to-ssh-behind-nat"&gt;Connecting to SSH behind NAT &lt;a class="headline-link" href="#connecting-to-ssh-behind-nat" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To connect to your home Ubuntu machine over the Internet, you will need to know your public IP address and configure your router to accept incoming traffic on port 22 and forward it to the Ubuntu system where SSH is running.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Find Your Public IP Address&lt;/strong&gt;
To determine the public IP address of the machine you are trying to SSH to, visit the following URL: &lt;a href="https://api.ipify.org" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;https://api.ipify.org&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Port Forwarding&lt;/strong&gt;
When it comes to setting up port forwarding on your router, each device has its own interface and terminology. You should consult your router&amp;rsquo;s documentation for instructions on setting up port forwarding.
In short, you need to enter the port number where requests will be made (the default SSH port is 22) and the private IP address you found earlier (using the &lt;code&gt;ip a&lt;/code&gt; command) of the machine where SSH is running.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Connect Using Public IP&lt;/strong&gt;
Once you have found the IP address, and configured your router, you can log in by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@public_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are exposing your home machine to the Internet, it is a good idea to implement some security measures. The most basic one is to configure your router to accept SSH traffic on a non-standard port and to forward it to port 22 on the machine running the SSH service.&lt;/p&gt;
&lt;p&gt;You can also &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;set up an SSH key-based authentication&lt;/a&gt;
and connect to your Ubuntu machine without entering a password.&lt;/p&gt;
&lt;h2 id="disabling-ssh-on-ubuntu"&gt;Disabling SSH on Ubuntu &lt;a class="headline-link" href="#disabling-ssh-on-ubuntu" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To turn off the SSH server on any of the supported Ubuntu releases, disable and stop both systemd units at once:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl disable --now ssh.service ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Only one of these units is normally enabled. Specifying both prevents &lt;code&gt;ssh.socket&lt;/code&gt; from continuing to listen on port 22 and starting the service when a client connects.&lt;/p&gt;
&lt;p&gt;Later, to re-enable SSH on Ubuntu 24.04 or 26.04, enable and start the socket:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Ubuntu 20.04 or 22.04, enable and start the service instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now ssh.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SSH service fails to start&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo journalctl -u ssh.service -u ssh.socket&lt;/code&gt; to see the error. A common cause is a misconfigured &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;. Test the config with &lt;code&gt;sudo sshd -t&lt;/code&gt; before restarting the service or socket.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connection refused on port 22&lt;/strong&gt;&lt;br&gt;
Confirm that SSH is running with &lt;code&gt;sudo systemctl status ssh.service ssh.socket&lt;/code&gt;. If UFW is active, verify the rule is in place with &lt;code&gt;sudo ufw status&lt;/code&gt; and re-run &lt;code&gt;sudo ufw allow ssh&lt;/code&gt; if it is missing. Our guide on the &lt;a href="https://linuxize.com/post/fix-ssh-connection-refused/"&gt;SSH connection refused error&lt;/a&gt;
covers the rest of the checks, from the listening address to the network path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Host key verification failed&lt;/strong&gt;&lt;br&gt;
This happens when the remote host&amp;rsquo;s key has changed (for example, after a reinstall). Remove the old entry with &lt;code&gt;ssh-keygen -R ip_address&lt;/code&gt; and reconnect.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied (publickey)&lt;/strong&gt;&lt;br&gt;
If you use key-based auth, ensure the correct private key is available (&lt;code&gt;~/.ssh/id_rsa&lt;/code&gt; or &lt;code&gt;~/.ssh/id_ed25519&lt;/code&gt;) and that &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; on the server contains the matching public key with permissions &lt;code&gt;600&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does this work on Ubuntu 20.04, 22.04, 24.04, and 26.04?&lt;/strong&gt;&lt;br&gt;
Yes. All four releases use the &lt;code&gt;openssh-server&lt;/code&gt; package. Ubuntu 20.04 and 22.04 run &lt;code&gt;ssh.service&lt;/code&gt; at boot, while Ubuntu 24.04 and 26.04 listen through &lt;code&gt;ssh.socket&lt;/code&gt; and start the service when a client connects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What port does SSH use by default?&lt;/strong&gt;&lt;br&gt;
SSH uses port 22 by default. You can &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;change the default SSH port&lt;/a&gt;
to reduce automated login attempts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I connect without a password?&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;Set up SSH key-based authentication&lt;/a&gt;
to log in using a key pair instead of a password.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I connect to multiple servers more easily?&lt;/strong&gt;&lt;br&gt;
Define your hosts in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
so you can connect with a short alias instead of typing the full address each time.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We have shown you how to install and enable SSH on Ubuntu systems. With SSH enabled, you can manage your system remotely, securely transfer files, and perform everyday administrative tasks without physical access.&lt;/p&gt;
&lt;p&gt;If you manage multiple systems, you can simplify your workflow by defining all your connections in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
adds an extra layer of security to your system by reducing the risk of automated attacks.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-enable-ssh-on-ubuntu-20-04/featured_hu_64e03e1a84811a2a.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Enable SSH on Raspberry Pi</title><link>https://linuxize.com/post/how-to-enable-ssh-on-raspberry-pi/</link><pubDate>Tue, 14 May 2019 19:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-enable-ssh-on-raspberry-pi/</guid><category>ssh</category><category>raspberry pi</category><description>Enable SSH on Raspberry Pi with Raspberry Pi Imager, the headless ssh file method, raspi-config, or systemctl. Updated for current Raspberry Pi OS releases.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a network protocol that lets you securely connect to your Raspberry Pi over an encrypted connection without needing a monitor or keyboard attached. With SSH enabled, you can run commands remotely, transfer files using tools like &lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;&lt;code&gt;scp&lt;/code&gt;&lt;/a&gt;
, and manage your Pi from any machine on the network.&lt;/p&gt;
&lt;p&gt;Raspberry Pi OS ships with SSH disabled by default. This guide covers three ways to enable it: during OS installation with Raspberry Pi Imager, on a pre-imaged SD card without a screen, and from the desktop or terminal on a running system.&lt;/p&gt;
&lt;h2 id="enabling-ssh-during-os-installation"&gt;Enabling SSH During OS Installation &lt;a class="headline-link" href="#enabling-ssh-during-os-installation" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The cleanest approach is to configure SSH before you write the SD card. Raspberry Pi Imager handles this through its Customisation settings, so SSH is ready the moment the Pi boots.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download and install &lt;a href="https://www.raspberrypi.com/software/" target="_blank" rel="noopener noreferrer"&gt;Raspberry Pi Imager&lt;/a&gt;
for your operating system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open Imager, select your Raspberry Pi device, choose &lt;strong&gt;Raspberry Pi OS&lt;/strong&gt;, and select your storage device.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click &lt;strong&gt;Next&lt;/strong&gt;. If the image supports customisation, Imager opens the Customisation tab.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On the &lt;strong&gt;Hostname&lt;/strong&gt; and &lt;strong&gt;User&lt;/strong&gt; subtabs, set a hostname, username, and password. Current Raspberry Pi OS images no longer include a default account, so these credentials are required.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;strong&gt;Remote Access&lt;/strong&gt; subtab. Turn on &lt;strong&gt;Enable SSH&lt;/strong&gt; and choose password authentication or public key authentication.&lt;/p&gt;
&lt;p&gt;To use public key authentication, paste the contents of your &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt; or &lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt; file into the field. If you do not have a key pair yet, &lt;a href="https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/"&gt;generate one first&lt;/a&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Continue through any remaining subtabs, save the customisation settings, and write the image to the card.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When the Pi boots from this card, SSH will be active and you can connect immediately using the credentials you configured.&lt;/p&gt;
&lt;h2 id="enabling-ssh-on-a-pre-imaged-sd-card-headless"&gt;Enabling SSH on a Pre-Imaged SD Card (Headless) &lt;a class="headline-link" href="#enabling-ssh-on-a-pre-imaged-sd-card-headless" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you already have an SD card with Raspberry Pi OS installed and no monitor available, you can enable SSH by placing an empty file named &lt;code&gt;ssh&lt;/code&gt; in the boot partition. The OS checks for this file on startup and enables SSH automatically if it finds it.&lt;/p&gt;
&lt;p&gt;This method only enables the SSH service. You still need a configured user account and, for Wi-Fi-only setups, working network settings. For a new headless install, Raspberry Pi Imager is usually safer because it sets the user, network, and SSH options together.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Power off your Raspberry Pi and remove the SD card.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Insert the SD card into your computer. It mounts automatically.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Navigate to the boot partition. On current Raspberry Pi OS images it is usually labeled &lt;code&gt;bootfs&lt;/code&gt;; on older images it may be labeled &lt;code&gt;boot&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new empty file named exactly &lt;code&gt;ssh&lt;/code&gt; with no extension.&lt;/p&gt;
&lt;p&gt;On Linux or macOS, open a terminal and run the following command, replacing the path with your actual mount point:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;touch /media/&lt;span class="nv"&gt;$USER&lt;/span&gt;/bootfs/ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Windows, right-click inside the partition in File Explorer, create a new text file, and rename it to &lt;code&gt;ssh&lt;/code&gt; removing the &lt;code&gt;.txt&lt;/code&gt; extension.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Eject the SD card, insert it back into the Pi, and power it on. The Pi detects the file on boot, enables SSH, and removes the file automatically.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="enabling-ssh-with-a-monitor-attached"&gt;Enabling SSH With a Monitor Attached &lt;a class="headline-link" href="#enabling-ssh-with-a-monitor-attached" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you have a monitor and keyboard connected, you can enable SSH through the graphical configuration tool, through &lt;code&gt;raspi-config&lt;/code&gt; in the terminal, or by starting the service directly with &lt;code&gt;systemctl&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="from-the-raspberry-pi-configuration-tool"&gt;From the Raspberry Pi Configuration Tool &lt;a class="headline-link" href="#from-the-raspberry-pi-configuration-tool" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Open the Raspberry Pi menu and go to &lt;strong&gt;Preferences&lt;/strong&gt; &amp;gt; &lt;strong&gt;Control Centre&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Interfaces&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Turn on the toggle next to &lt;strong&gt;SSH&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Close&lt;/strong&gt; and reboot if prompted.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="from-raspi-config-in-the-terminal"&gt;From raspi-config in the Terminal &lt;a class="headline-link" href="#from-raspi-config-in-the-terminal" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Open a terminal and launch the configuration tool:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo raspi-config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use the arrow keys to select &lt;strong&gt;3 Interface Options&lt;/strong&gt; &amp;gt; &lt;strong&gt;I1 SSH&lt;/strong&gt;. Confirm that you want to enable the SSH server, then select &lt;strong&gt;OK&lt;/strong&gt; and &lt;strong&gt;Finish&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Alternatively, you can enable and start the SSH service in one step with &lt;code&gt;systemctl&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="connecting-to-raspberry-pi-via-ssh"&gt;Connecting to Raspberry Pi via SSH &lt;a class="headline-link" href="#connecting-to-raspberry-pi-via-ssh" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once SSH is running, you need the Pi&amp;rsquo;s IP address. On the Pi itself, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hostname -I&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;192.168.1.42&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are setting up headlessly, check your router&amp;rsquo;s DHCP client list instead.&lt;/p&gt;
&lt;p&gt;From your computer, connect using the &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;ssh&lt;/code&gt; command&lt;/a&gt;
with the username and IP address you configured:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh username@192.168.1.42&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The first time you connect, SSH displays a fingerprint warning. Type &lt;code&gt;yes&lt;/code&gt; to accept it and add the host to your known hosts file.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;The authenticity of host &amp;#39;192.168.1.42 (192.168.1.42)&amp;#39; can&amp;#39;t be established.
ED25519 key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no/[fingerprint])?&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Windows users can use the built-in &lt;code&gt;ssh&lt;/code&gt; client from PowerShell or Command Prompt, or a graphical client like &lt;a href="https://www.putty.org/" target="_blank" rel="noopener noreferrer"&gt;PuTTY&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If you are exposing the Pi to the internet, &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;changing the default SSH port&lt;/a&gt;
reduces automated login attempts. &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;Setting up key-based authentication&lt;/a&gt;
removes the need to type a password on every connection.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Connection refused&lt;/strong&gt;&lt;br&gt;
SSH is not running or was not enabled on boot. If you have local access, run &lt;code&gt;sudo systemctl status ssh&lt;/code&gt; and start it with &lt;code&gt;sudo systemctl enable --now ssh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No route to host or connection timed out&lt;/strong&gt;&lt;br&gt;
The Pi is not reachable on the network. Check that it is powered on, connected to Ethernet or Wi-Fi, and using the IP address shown by your router or &lt;code&gt;hostname -I&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied&lt;/strong&gt;&lt;br&gt;
The username, password, or SSH key does not match the account configured on the Pi. Recheck the username you set in Raspberry Pi Imager and make sure the public key was copied correctly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The hostname does not resolve&lt;/strong&gt;&lt;br&gt;
If &lt;code&gt;raspberrypi.local&lt;/code&gt; or your custom hostname does not work, connect with the Pi&amp;rsquo;s IP address instead.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You now have SSH enabled on your Raspberry Pi and can connect remotely from any machine on the network. To manage connections more easily, define your Pi in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
so you can connect with a short alias instead of typing the full address each time.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-enable-ssh-on-raspberry-pi/featured_hu_48505af4923c5687.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Using the SSH Config File</title><link>https://linuxize.com/post/using-the-ssh-config-file/</link><pubDate>Sun, 06 Jan 2019 19:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/using-the-ssh-config-file/</guid><category>ssh</category><description>Set up the SSH client config file to manage multiple remote connections with custom hostnames, users, ports, keys, and jump hosts — all without long command-line flags.</description><content:encoded>&lt;p&gt;If you are regularly connecting to multiple remote systems via SSH, remembering various IP addresses, usernames, non-standard ports, and command-line options can be challenging or even impossible.&lt;/p&gt;
&lt;p&gt;One approach is to &lt;a href="https://linuxize.com/post/how-to-create-bash-aliases/"&gt;create a bash alias&lt;/a&gt;
for each remote server connection. However, there is a better, more straightforward solution. OpenSSH allows you to set up a per-user configuration file where you can store different SSH options for each remote machine you connect to.&lt;/p&gt;
&lt;p&gt;This guide covers the basics of the SSH client configuration file and highlights some of the most common options.&lt;/p&gt;
&lt;h2 id="ssh-config-file-location"&gt;SSH Config File Location &lt;a class="headline-link" href="#ssh-config-file-location" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The OpenSSH client-side configuration file is named &lt;code&gt;config&lt;/code&gt;, and resides in the &lt;code&gt;.ssh&lt;/code&gt; directory under the user&amp;rsquo;s home directory. The examples in this guide assume you are using Linux or macOS with an OpenSSH client installed.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;~/.ssh&lt;/code&gt; directory is created automatically when the user runs the &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;ssh&lt;/code&gt;&lt;/a&gt;
command for the first time. If the directory does not exist on your system, create it with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/.ssh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; chmod &lt;span class="m"&gt;700&lt;/span&gt; ~/.ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;By default, the SSH configuration file may not exist, so you may need to create it using the &lt;a href="https://linuxize.com/post/linux-touch-command/"&gt;&lt;code&gt;touch&lt;/code&gt; command&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;touch ~/.ssh/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For security, the file must be readable and writable only by the user and not accessible by others:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;600&lt;/span&gt; ~/.ssh/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="ssh-config-file-structure-and-patterns"&gt;SSH Config File Structure and Patterns &lt;a class="headline-link" href="#ssh-config-file-structure-and-patterns" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The SSH config file takes the following structure:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host hostname1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;SSH_OPTION value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;SSH_OPTION value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host hostname2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;SSH_OPTION value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host *&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;SSH_OPTION value&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The contents of the SSH client config file are organised into stanzas (sections).&lt;/p&gt;
&lt;p&gt;Each stanza begins with the &lt;code&gt;Host&lt;/code&gt; directive and contains specific SSH options that apply when connecting to matching hosts.&lt;/p&gt;
&lt;p&gt;Indentation is not required, but it is recommended because it makes the file easier to read.&lt;/p&gt;
&lt;p&gt;Lines beginning with &lt;code&gt;#&lt;/code&gt; are treated as comments and ignored by SSH, which makes them useful for documenting aliases or temporarily disabling options.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Host&lt;/code&gt; value can be a single hostname, IP address, or pattern, or a space-separated list of patterns. Each pattern can contain zero or more non-whitespace characters or one of the following pattern specifiers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; - Matches zero or more characters. (e.g, &lt;code&gt;Host *&lt;/code&gt; matches all hosts, while &lt;code&gt;192.168.0.*&lt;/code&gt; matches hosts in the &lt;code&gt;192.168.0.0/24&lt;/code&gt; subnet.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;?&lt;/code&gt; - Matches exactly one character. (e.g The pattern, &lt;code&gt;Host 10.10.0.?&lt;/code&gt; matches all hosts in &lt;code&gt;10.10.0.[0-9]&lt;/code&gt; range.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!&lt;/code&gt; - When used at the start of a pattern, it negates the match. (e.g &lt;code&gt;Host 10.10.0.* !10.10.0.5&lt;/code&gt; matches any host in the &lt;code&gt;10.10.0.0/24&lt;/code&gt; subnet except &lt;code&gt;10.10.0.5&lt;/code&gt;.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The SSH client processes the file from top to bottom. If more than one pattern matches, the options from the first matching stanza take precedence. Therefore, more host-specific declarations should be given at the beginning of the file, and more general overrides (like &lt;code&gt;Host *&lt;/code&gt;) at the end of the file.&lt;/p&gt;
&lt;p&gt;You can find a full list of available SSH options by typing &lt;code&gt;man ssh_config&lt;/code&gt; in your terminal or by visiting the &lt;a href="https://man.openbsd.org/OpenBSD-current/man5/ssh_config.5" target="_blank" rel="noopener noreferrer"&gt;ssh_config man page&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;The SSH config file is also read by other programs such as &lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;&lt;code&gt;scp&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;&lt;code&gt;sftp&lt;/code&gt;&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/"&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="basic-example"&gt;Basic Example &lt;a class="headline-link" href="#basic-example" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we have covered the basics of the SSH configuration file, let us look at the following example.&lt;/p&gt;
&lt;p&gt;Normally, when connecting to a remote server via SSH, you would specify the remote user name, hostname, and port. For example, to log in as a user named &lt;code&gt;john&lt;/code&gt; to a host called &lt;code&gt;dev.example.com&lt;/code&gt; on port &lt;code&gt;2322&lt;/code&gt; from the command line, you would type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh john@dev.example.com -p &lt;span class="m"&gt;2322&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To connect to the server using the same options as provided in the command above by typing &lt;code&gt;ssh dev&lt;/code&gt;, add the following lines in your &lt;code&gt;~/.ssh/config&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host dev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName dev.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User john&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;Port 2322&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now, when you type &lt;code&gt;ssh dev&lt;/code&gt;, the ssh client will read the configuration file and use the connection details that are specified for the &lt;code&gt;dev&lt;/code&gt; host:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="advanced-example-patterns-and-precedence"&gt;Advanced Example: Patterns and Precedence &lt;a class="headline-link" href="#advanced-example-patterns-and-precedence" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This example gives more detail about host patterns and option precedence.&lt;/p&gt;
&lt;p&gt;Consider the following example file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host targaryen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName 192.168.1.10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User daenerys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;Port 7654&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;IdentityFile ~/.ssh/targaryen.key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host tyrell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName 192.168.10.20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host martell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName 192.168.10.50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host *ell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;user oberyn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host * !martell&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;LogLevel INFO&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host *&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User root&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;Compression yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When you type &lt;code&gt;ssh targaryen&lt;/code&gt;, the SSH client reads the file and applies the options from the first match, which is &lt;code&gt;Host targaryen&lt;/code&gt;. Then it checks the next stanzas one by one for a matching pattern. The next matching one is &lt;code&gt;Host * !martell&lt;/code&gt; (meaning all hosts except &lt;code&gt;martell&lt;/code&gt;), and it will apply the connection option from this stanza. The last definition &lt;code&gt;Host *&lt;/code&gt; also matches, but the SSH client will take only the &lt;code&gt;Compression&lt;/code&gt; option because the &lt;code&gt;User&lt;/code&gt; option is already defined in the &lt;code&gt;Host targaryen&lt;/code&gt; stanza.&lt;/p&gt;
&lt;p&gt;The full list of options used when you type &lt;code&gt;ssh targaryen&lt;/code&gt; is as follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;HostName 192.168.1.10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;User daenerys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Port 7654&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;IdentityFile ~/.ssh/targaryen.key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;LogLevel INFO&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Compression yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When running &lt;code&gt;ssh tyrell&lt;/code&gt;, the matching host patterns are: &lt;code&gt;Host tyrell&lt;/code&gt;, &lt;code&gt;Host *ell&lt;/code&gt;, &lt;code&gt;Host * !martell&lt;/code&gt;, and &lt;code&gt;Host *&lt;/code&gt;. The options used in this case are:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;HostName 192.168.10.20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;User oberyn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;LogLevel INFO&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Compression yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you run &lt;code&gt;ssh martell&lt;/code&gt;, the matching host patterns are: &lt;code&gt;Host martell&lt;/code&gt;, &lt;code&gt;Host *ell&lt;/code&gt; and &lt;code&gt;Host *&lt;/code&gt;. The options used in this case are:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;HostName 192.168.10.50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;User oberyn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Compression yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For all other connections, the SSH client will use the options specified in the &lt;code&gt;Host * !martell&lt;/code&gt; and &lt;code&gt;Host *&lt;/code&gt; sections.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="overriding-options"&gt;Overriding Options &lt;a class="headline-link" href="#overriding-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The SSH client reads its configuration in the following precedence order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Options specified from the command line.&lt;/li&gt;
&lt;li&gt;Options defined in the &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Options defined in the system-wide &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To override a single option, specify it on the command line. For example, if you have the following definition:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host dev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName dev.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User john&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;Port 2322&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;and you want to use all other options but connect as user &lt;code&gt;root&lt;/code&gt; instead of &lt;code&gt;john&lt;/code&gt;, simply specify the user on the command line:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -o &lt;span class="s2"&gt;&amp;#34;User=root&amp;#34;&lt;/span&gt; dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-F&lt;/code&gt; (&lt;code&gt;configfile&lt;/code&gt;) option allows you to specify an alternative per-user configuration file.&lt;/p&gt;
&lt;p&gt;To tell the SSH client to ignore all of the options specified in the SSH configuration file, use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -F /dev/null user@example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="common-ssh-config-options"&gt;Common SSH Config Options &lt;a class="headline-link" href="#common-ssh-config-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here are some of the most useful directives you will reach for regularly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keep connections alive&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SSH connections drop when there is no traffic for a period of time. To prevent this, configure keepalive packets in a &lt;code&gt;Host *&lt;/code&gt; block at the end of your config:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host *&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ServerAliveInterval 60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ServerAliveCountMax 3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ServerAliveInterval&lt;/code&gt; sends a keepalive packet every 60 seconds. &lt;code&gt;ServerAliveCountMax&lt;/code&gt; closes the connection after 3 unanswered packets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Specify a private key&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you use different keys for different servers, set &lt;code&gt;IdentityFile&lt;/code&gt; per host:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host github.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User git&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;IdentityFile ~/.ssh/github_key&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Connect through a jump host&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ProxyJump&lt;/code&gt; routes your connection through an intermediate server. This replaces the older &lt;code&gt;ProxyCommand&lt;/code&gt; approach:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host internal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName 10.0.0.50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User admin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ProxyJump jumphost.example.com&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now &lt;code&gt;ssh internal&lt;/code&gt; connects through &lt;code&gt;jumphost.example.com&lt;/code&gt; automatically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enable SSH agent forwarding&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you need to authenticate to a second server from within an SSH session, enable agent forwarding selectively — only for hosts that require it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host bastion&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName bastion.example.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ForwardAgent yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Avoid setting &lt;code&gt;ForwardAgent yes&lt;/code&gt; in a &lt;code&gt;Host *&lt;/code&gt; block, as it exposes your SSH agent to every server you connect to.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Directive&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Host&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pattern to match one or more hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HostName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The actual hostname or IP address to connect to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;User&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SSH username&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Port&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remote port (default: 22)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IdentityFile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Path to the private key file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ServerAliveInterval&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Seconds between keepalive packets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ServerAliveCountMax&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unanswered keepalives before disconnect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ProxyJump&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect through a jump host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ForwardAgent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable SSH agent forwarding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Compression&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable compression (&lt;code&gt;yes&lt;/code&gt;/&lt;code&gt;no&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LogLevel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verbosity level (&lt;code&gt;QUIET&lt;/code&gt;, &lt;code&gt;INFO&lt;/code&gt;, &lt;code&gt;DEBUG&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;StrictHostKeyChecking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Control known_hosts checking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Options are not being applied&lt;/strong&gt;&lt;br&gt;
The file permissions must be exactly &lt;code&gt;600&lt;/code&gt; (&lt;code&gt;-rw-------&lt;/code&gt;). If the file is readable by others, OpenSSH ignores it entirely. Fix with &lt;code&gt;chmod 600 ~/.ssh/config&lt;/code&gt;. Also check that your &lt;code&gt;Host&lt;/code&gt; pattern actually matches the alias you are using.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Bad configuration option&amp;rdquo; error&lt;/strong&gt;&lt;br&gt;
There is a typo in a directive name. SSH config directives are case-insensitive but must be spelled correctly. Check the directive against &lt;code&gt;man ssh_config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Permission denied (publickey)&amp;rdquo; despite setting &lt;code&gt;IdentityFile&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Verify the path in &lt;code&gt;IdentityFile&lt;/code&gt; is correct and the key file permissions are &lt;code&gt;600&lt;/code&gt;. You can test which key is being offered with &lt;code&gt;ssh -v alias&lt;/code&gt; and look for lines starting with &lt;code&gt;Offering public key&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Config works with &lt;code&gt;ssh&lt;/code&gt; but not &lt;code&gt;scp&lt;/code&gt; or &lt;code&gt;rsync&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Both &lt;code&gt;scp&lt;/code&gt; and &lt;code&gt;rsync&lt;/code&gt; (over SSH) read &lt;code&gt;~/.ssh/config&lt;/code&gt;. Check that the &lt;code&gt;Host&lt;/code&gt; pattern matches the hostname or alias you pass to those commands, not just the alias you use with &lt;code&gt;ssh&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Where is the SSH config file located?&lt;/strong&gt;&lt;br&gt;
The per-user SSH config file is at &lt;code&gt;~/.ssh/config&lt;/code&gt;. A system-wide config for all users is at &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt;. Settings in &lt;code&gt;~/.ssh/config&lt;/code&gt; override &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt; for your user.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;~/.ssh/config&lt;/code&gt; and &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;~/.ssh/config&lt;/code&gt; is your personal config — only your user account reads it. &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt; applies to all users on the system and is managed by the system administrator. Your personal config takes precedence for any options it defines.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I have multiple &lt;code&gt;Host&lt;/code&gt; entries pointing to the same server?&lt;/strong&gt;&lt;br&gt;
Yes. You can define multiple stanzas with different aliases that connect to the same &lt;code&gt;HostName&lt;/code&gt;, each with different options — for example, one for a regular user and one for root access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I apply an option to all hosts?&lt;/strong&gt;&lt;br&gt;
Add a &lt;code&gt;Host *&lt;/code&gt; stanza at the end of your config file. Options in &lt;code&gt;Host *&lt;/code&gt; apply to every connection but have the lowest precedence — any host-specific option defined earlier in the file takes priority.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does the SSH config file work with &lt;code&gt;scp&lt;/code&gt; and &lt;code&gt;sftp&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
Yes. &lt;code&gt;scp&lt;/code&gt;, &lt;code&gt;sftp&lt;/code&gt;, and &lt;code&gt;rsync&lt;/code&gt; (when using SSH transport) all read &lt;code&gt;~/.ssh/config&lt;/code&gt; and respect the same host aliases and options.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The SSH config file is the most practical way to manage connections to multiple remote servers. Once your aliases are in place, tools like &lt;code&gt;scp&lt;/code&gt;, &lt;code&gt;sftp&lt;/code&gt;, and &lt;code&gt;rsync&lt;/code&gt; pick them up automatically. To further simplify logins, set up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
so you can connect without entering a password each time.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/using-the-ssh-config-file/featured_hu_8f11cfa7f4e8a54e.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Change the SSH Port in Linux</title><link>https://linuxize.com/post/how-to-change-ssh-port-in-linux/</link><pubDate>Sat, 16 Mar 2019 03:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-change-ssh-port-in-linux/</guid><category>ssh</category><category>security</category><description>Change the default SSH port 22 by editing sshd_config, adjusting the firewall, and reloading the SSH service on Linux.</description><content:encoded>&lt;p&gt;By default, SSH listens on port 22. Changing the default SSH port adds an extra layer of security to your server by reducing the risk of automated attacks.&lt;/p&gt;
&lt;p&gt;This tutorial explains how to change the default SSH port in Linux. We will also show you how to configure your firewall to allow access to the new SSH port.&lt;/p&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;The best way to protect your server from attacks is to configure your firewall to allow access to port 22 only from trusted hosts and set up an &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/" target="_blank" rel="noopener noreferrer"&gt;SSH key-based authentication&lt;/a&gt;
.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Open firewall port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow 5522/tcp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit SSH config&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo vim /etc/ssh/sshd_config&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set new port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Port 5522&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restart SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl restart ssh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verify listening&lt;/td&gt;
&lt;td&gt;`ss -tlnp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connect to new port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -p 5522 user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="changing-the-ssh-port"&gt;Changing the SSH Port &lt;a class="headline-link" href="#changing-the-ssh-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Changing the SSH port of a Linux server is a simple task. All you need to do is to edit the SSH configuration file and restart the service.&lt;/p&gt;
&lt;p&gt;The following sections explain how to change the SSH Port on a Linux system.&lt;/p&gt;
&lt;h3 id="1-choosing-a-new-port-number"&gt;1. Choosing a New Port Number &lt;a class="headline-link" href="#1-choosing-a-new-port-number" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In Linux, port numbers below 1024 are reserved for well-known services and can only be bound to by root. Although you can use a port within a 1-1024 range for the SSH service to avoid issues with port allocation in the future, it is recommended to choose a port above 1024.&lt;/p&gt;
&lt;p&gt;In this example we will change the SSH port to 5522, you can choose any port you want.&lt;/p&gt;
&lt;h3 id="2-adjusting-firewall"&gt;2. Adjusting Firewall &lt;a class="headline-link" href="#2-adjusting-firewall" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before changing the SSH port, you will need to adjust your firewall to allow traffic on the new SSH port.&lt;/p&gt;
&lt;p&gt;If you are using &lt;a href="https://linuxize.com/post/ufw-command-in-linux/"&gt;UFW&lt;/a&gt;
, the default firewall configuration tool for Ubuntu, run the following command to open the new SSH port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 5522/tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In CentOS, the default firewall management tool is FirewallD. To open the new port run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --permanent --zone&lt;span class="o"&gt;=&lt;/span&gt;public --add-port&lt;span class="o"&gt;=&lt;/span&gt;5522/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;CentOS users also need to adjust the SELinux rules:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo semanage port -a -t ssh_port_t -p tcp &lt;span class="m"&gt;5522&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On RHEL, Fedora, and derivatives where &lt;code&gt;semanage&lt;/code&gt; is not available, install it with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install policycoreutils-python-utils&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are using nftables, add a rule to accept the new port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nft add rule inet filter input tcp dport &lt;span class="m"&gt;5522&lt;/span&gt; accept&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are using iptables as your firewall, to open the new port, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -p tcp --dport &lt;span class="m"&gt;5522&lt;/span&gt; -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="3-configuring-ssh"&gt;3. Configuring SSH &lt;a class="headline-link" href="#3-configuring-ssh" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Open the SSH configuration file &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; with your text editor:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo vim /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="https://linuxize.com/post/vim-search/"&gt;Search&lt;/a&gt;
for the line starting with &lt;code&gt;Port 22&lt;/code&gt;. In most cases, this line starts with a hash (&lt;code&gt;#&lt;/code&gt;) character. Remove the hash &lt;code&gt;#&lt;/code&gt; and enter the new SSH port number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Port 5522&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Be extra careful when modifying the SSH configuration file. The incorrect configuration may cause the SSH service to fail to start.&lt;/p&gt;
&lt;p&gt;On Ubuntu 22.10 and later, including 24.04, OpenSSH may be started through &lt;code&gt;ssh.socket&lt;/code&gt;. In that case, changing &lt;code&gt;Port&lt;/code&gt; in &lt;code&gt;sshd_config&lt;/code&gt; is not enough because the socket can still listen on port 22. Check whether socket activation is enabled:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl is-active ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the output is &lt;code&gt;active&lt;/code&gt;, create a drop-in to override the listening port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl edit ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add the following, clearing the existing listeners with an empty &lt;code&gt;ListenStream=&lt;/code&gt; before setting the new one:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/systemd/system/ssh.socket.d/override.conf&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Socket]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ListenStream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ListenStream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5522&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Reload systemd and restart the socket:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once done, apply the changes. If &lt;code&gt;ssh.socket&lt;/code&gt; is not active, restart the SSH service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In CentOS the ssh service is named &lt;code&gt;sshd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To verify that SSH daemon is &lt;a href="https://linuxize.com/post/check-listening-ports-linux/"&gt;listening&lt;/a&gt;
on the new port 5522, use &lt;a href="https://linuxize.com/post/ss-command-in-linux/"&gt;&lt;code&gt;ss&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -an &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;5522&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;tcp LISTEN 0 128 0.0.0.0:5522 0.0.0.0:*
tcp ESTAB 0 0 192.168.121.108:5522 192.168.121.1:57638
tcp LISTEN 0 128 [::]:5522 [::]:*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="using-the-new-ssh-port"&gt;Using the New SSH Port &lt;a class="headline-link" href="#using-the-new-ssh-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To specify the port, invoke the &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;ssh&lt;/code&gt;&lt;/a&gt;
command followed by the &lt;code&gt;-p &amp;lt;port_number&amp;gt;&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -p &lt;span class="m"&gt;5522&lt;/span&gt; username@remote_host_or_ip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are regularly connecting to multiple systems, you can simplify your workflow by defining all of your connections in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Connection refused after changing the port&lt;/strong&gt;&lt;br&gt;
Confirm the SSH daemon is listening on the new port with &lt;code&gt;ss -tlnp | grep sshd&lt;/code&gt;. If the output still shows port 22, the daemon did not pick up the change. On Ubuntu 22.10 and later check socket activation; otherwise restart with &lt;code&gt;sudo systemctl restart sshd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Error: Permission denied or SELinux blocks the new port&lt;/strong&gt;&lt;br&gt;
SELinux only allows SSH on ports defined in the &lt;code&gt;ssh_port_t&lt;/code&gt; type. Run &lt;code&gt;sudo semanage port -a -t ssh_port_t -p tcp 5522&lt;/code&gt;. Confirm with &lt;code&gt;sudo semanage port -l | grep ssh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Firewall rule not persisted after reboot&lt;/strong&gt;&lt;br&gt;
UFW and FirewallD persist rules by default. With plain &lt;code&gt;iptables&lt;/code&gt;, save the rules with &lt;code&gt;sudo iptables-save &amp;gt; /etc/iptables/rules.v4&lt;/code&gt; or use the &lt;code&gt;iptables-persistent&lt;/code&gt; package.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cannot connect after editing sshd_config&lt;/strong&gt;&lt;br&gt;
Test the config syntax before restarting: &lt;code&gt;sudo sshd -t&lt;/code&gt;. Keep an existing SSH session open while testing changes so that a fresh session can be opened from another terminal to verify.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You have changed the default SSH port on a Linux server and adjusted the firewall to allow traffic on the new port. For a stronger layer of security, also set up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
and restrict SSH access to trusted IPs in your firewall.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-change-ssh-port-in-linux/featured_hu_9419f8ba5db022a0.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>The ~/.ssh Folder: Files, Permissions, and Layout</title><link>https://linuxize.com/post/ssh-folder-files-and-permissions/</link><pubDate>Tue, 16 Jun 2026 10:15:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ssh-folder-files-and-permissions/</guid><category>ssh</category><description>What lives inside ~/.ssh on Linux: private keys, authorized_keys, known_hosts, config, and the recommended permissions for each file.</description><content:encoded>&lt;p&gt;When SSH stops accepting a key after you copy files to a new computer, restore a backup, or change ownership, the first place to check is &lt;code&gt;~/.ssh&lt;/code&gt;. OpenSSH uses this directory for your private and public keys, trusted host records, and per-host connection settings.&lt;/p&gt;
&lt;p&gt;Some files inside the directory are public, while others must stay private. This guide explains what each file does, which permissions to use, and how the layout differs between an SSH client and server.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Permissions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.ssh/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The directory itself&lt;/td&gt;
&lt;td&gt;&lt;code&gt;700&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.ssh/id_ed25519&lt;/code&gt;, &lt;code&gt;id_rsa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Private keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;600&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt;, &lt;code&gt;id_rsa.pub&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Public keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;644&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Public keys allowed to log in to this account&lt;/td&gt;
&lt;td&gt;&lt;code&gt;600&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.ssh/known_hosts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Host keys of servers you have connected to&lt;/td&gt;
&lt;td&gt;&lt;code&gt;644&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.ssh/config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Client config and per-host shortcuts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;600&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="where-the-folder-lives"&gt;Where the Folder Lives &lt;a class="headline-link" href="#where-the-folder-lives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;~/.ssh&lt;/code&gt; directory sits inside your home directory. OpenSSH tools create it when needed, such as when you generate a key or connect to a host for the first time.&lt;/p&gt;
&lt;p&gt;You can confirm the location with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -ld ~/.ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;drwx------ 2 sara sara 4096 Mar 4 14:22 /home/sara/.ssh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this output, &lt;code&gt;sara&lt;/code&gt; owns the directory and &lt;code&gt;rwx------&lt;/code&gt; corresponds to mode &lt;code&gt;700&lt;/code&gt;. This gives the owner full access while blocking everyone else.&lt;/p&gt;
&lt;p&gt;OpenSSH does not require every file in the directory to be secret. However, group or world write access can make the server reject &lt;code&gt;authorized_keys&lt;/code&gt;, while loose private-key permissions make the client ignore that key.&lt;/p&gt;
&lt;h2 id="private-and-public-keys"&gt;Private and Public Keys &lt;a class="headline-link" href="#private-and-public-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you generate a key pair with &lt;code&gt;ssh-keygen&lt;/code&gt;, two files land in &lt;code&gt;~/.ssh&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519 -C &lt;span class="s2"&gt;&amp;#34;sara@workstation&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/sara/.ssh/id_ed25519):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default path. After the key is generated, you will have two new files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;id_ed25519&lt;/code&gt; is the private key. It must stay on the machine where you generated it and must never be shared. Permissions are &lt;code&gt;600&lt;/code&gt; (owner read/write only). If the file is even readable by the group, OpenSSH refuses to use it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;id_ed25519.pub&lt;/code&gt; is the public key. It is meant to be copied to other machines, pasted into hosting dashboards, or added to &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; on servers. Permissions are usually &lt;code&gt;644&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may also see &lt;code&gt;id_rsa&lt;/code&gt; and &lt;code&gt;id_rsa.pub&lt;/code&gt; on older systems. OpenSSH recognizes these default names and tries them automatically when no &lt;code&gt;IdentityFile&lt;/code&gt; is set. For new keys, Ed25519 is the better default because the keys are smaller and authentication is fast.&lt;/p&gt;
&lt;h2 id="authorized_keys"&gt;authorized_keys &lt;a class="headline-link" href="#authorized_keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On the server side, &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; lists the public keys that are allowed to log in as this user. Each line is one full public key, exactly as it appears in a &lt;code&gt;.pub&lt;/code&gt; file on the client.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE2... sara@workstation
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPgs... sara@laptop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each line grants access to one public key. The optional comment at the end, such as &lt;code&gt;sara@workstation&lt;/code&gt;, helps you identify where the key came from.&lt;/p&gt;
&lt;p&gt;The file must belong to the account that uses it and must not be writable by other users. Mode &lt;code&gt;600&lt;/code&gt; is the recommended setting. With &lt;code&gt;StrictModes&lt;/code&gt; enabled (the default), the SSH server also checks the parent path, so your home directory must not be group- or world-writable even if &lt;code&gt;~/.ssh&lt;/code&gt; itself is correct.&lt;/p&gt;
&lt;p&gt;To copy a public key to a server, use &lt;code&gt;ssh-copy-id&lt;/code&gt; instead of editing the file manually:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id sara@example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command appends your public key and avoids replacing keys that are already in the file.&lt;/p&gt;
&lt;h2 id="known_hosts"&gt;known_hosts &lt;a class="headline-link" href="#known_hosts" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt; file records the host keys of servers you have connected to before. The first time you SSH into a new host, OpenSSH prints the host fingerprint and asks you to confirm. After you accept, the key is appended here, and any future change to that host key triggers a sharp warning instead of a silent reconnect.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -F example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;# Host example.com found: line 3
|1|abc...=|def...= ssh-ed25519 AAAAC3Nz...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows the matching entry and its line number. The leading &lt;code&gt;|1|&lt;/code&gt; means the hostname is hashed. OpenSSH uses this format when &lt;code&gt;HashKnownHosts yes&lt;/code&gt; is enabled in the client configuration. The upstream default is &lt;code&gt;no&lt;/code&gt;, although your Linux distribution may enable it in &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When a server gets a new host key, such as after a reinstall, remove only the old entry instead of deleting the whole file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -R example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Mode &lt;code&gt;644&lt;/code&gt; is common because the file contains public host keys. On a shared machine, you can use mode &lt;code&gt;600&lt;/code&gt; to stop other users from reading unhashed server names.&lt;/p&gt;
&lt;h2 id="config"&gt;config &lt;a class="headline-link" href="#config" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;~/.ssh/config&lt;/code&gt; file is where per-host shortcuts and per-host options live. A short example:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host work-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; HostName example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; User sara
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Port 2222
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; IdentityFile ~/.ssh/id_ed25519_work
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; IdentitiesOnly yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host *
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ServerAliveInterval 60
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ServerAliveCountMax 3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With this configuration, &lt;code&gt;ssh work-server&lt;/code&gt; connects to &lt;code&gt;example.com&lt;/code&gt; on port &lt;code&gt;2222&lt;/code&gt; as &lt;code&gt;sara&lt;/code&gt; and uses only the specified key. The &lt;code&gt;Host *&lt;/code&gt; block applies to every host, which makes it a useful place for defaults such as keepalives.&lt;/p&gt;
&lt;p&gt;OpenSSH uses the first value it finds for each option. Put specific host blocks at the top and general settings at the bottom.&lt;/p&gt;
&lt;p&gt;OpenSSH requires that &lt;code&gt;~/.ssh/config&lt;/code&gt; is not writable by other users. Mode &lt;code&gt;600&lt;/code&gt; also prevents other users on the machine from reading your hostnames and account names.&lt;/p&gt;
&lt;h2 id="reset-ssh-permissions"&gt;Reset SSH Permissions &lt;a class="headline-link" href="#reset-ssh-permissions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If the permissions changed after copying or restoring the directory, use the following commands to reset the standard files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;700&lt;/span&gt; ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find ~/.ssh -maxdepth &lt;span class="m"&gt;1&lt;/span&gt; -type f -name &lt;span class="s1"&gt;&amp;#39;id_*&amp;#39;&lt;/span&gt; ! -name &lt;span class="s1"&gt;&amp;#39;*.pub&amp;#39;&lt;/span&gt; -exec chmod &lt;span class="m"&gt;600&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; +
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find ~/.ssh -maxdepth &lt;span class="m"&gt;1&lt;/span&gt; -type f -name &lt;span class="s1"&gt;&amp;#39;*.pub&amp;#39;&lt;/span&gt; -exec chmod &lt;span class="m"&gt;644&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; +
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; file in authorized_keys config&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;[&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh/&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; chmod &lt;span class="m"&gt;600&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh/&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt; -e ~/.ssh/known_hosts &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; chmod &lt;span class="m"&gt;644&lt;/span&gt; ~/.ssh/known_hosts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The first &lt;code&gt;find&lt;/code&gt; command sets mode &lt;code&gt;600&lt;/code&gt; on private keys, while the second sets mode &lt;code&gt;644&lt;/code&gt; on public keys. The remaining checks update only files that exist, so you can run the block on a client or server account without errors for missing files.&lt;/p&gt;
&lt;h2 id="client-vs-server-layout"&gt;Client vs Server Layout &lt;a class="headline-link" href="#client-vs-server-layout" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The same &lt;code&gt;~/.ssh&lt;/code&gt; directory holds different files depending on whether the machine acts as a client or a server in a given session.&lt;/p&gt;
&lt;p&gt;A typical client has:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;config id_ed25519 id_ed25519.pub known_hosts&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This client has a key pair, a connection configuration, and a record of known servers.&lt;/p&gt;
&lt;p&gt;A typical server account has:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The server only needs &lt;code&gt;authorized_keys&lt;/code&gt; to accept key-based logins for this account. A machine can also be both a client and a server. For example, your workstation may use private keys for outgoing connections and keep &lt;code&gt;authorized_keys&lt;/code&gt; for incoming SCP transfers.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Permissions 0644 for '~/.ssh/id_ed25519' are too open&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The private key is readable by the group or by everyone. Run &lt;code&gt;chmod 600 ~/.ssh/id_ed25519&lt;/code&gt; and retry.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Authentication refused: bad ownership or modes for directory /home/sara&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
OpenSSH checks the whole path. The home directory is group-writable, which lets another user replace &lt;code&gt;.ssh&lt;/code&gt;. Run &lt;code&gt;chmod go-w ~&lt;/code&gt; on the server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Public key copied but login still fails&lt;/strong&gt;&lt;br&gt;
Confirm the key was appended, not overwritten, in &lt;code&gt;authorized_keys&lt;/code&gt;. Compare fingerprints with &lt;code&gt;ssh-keygen -lf ~/.ssh/id_ed25519.pub&lt;/code&gt; on the client and &lt;code&gt;ssh-keygen -lf ~/.ssh/authorized_keys&lt;/code&gt; on the server.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Can I move ~/.ssh to a different path?&lt;/strong&gt;&lt;br&gt;
Yes, but you must configure the new path. On the client, pass &lt;code&gt;-i&lt;/code&gt; or set &lt;code&gt;IdentityFile&lt;/code&gt; for each host. On the server, set &lt;code&gt;AuthorizedKeysFile&lt;/code&gt; in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;. Keeping the default layout is usually simpler.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is it safe to back up ~/.ssh?&lt;/strong&gt;&lt;br&gt;
Public keys can be backed up freely. The &lt;code&gt;config&lt;/code&gt; and &lt;code&gt;known_hosts&lt;/code&gt; files can expose account names and server addresses, so keep those backups private. Treat private keys like passwords: encrypt the backup and never store it in a public cloud bucket or Git repository.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why does OpenSSH care about home-directory permissions?&lt;/strong&gt;&lt;br&gt;
If your home directory is group-writable, another user can replace &lt;code&gt;~/.ssh&lt;/code&gt; with their own. To prevent that class of attack, OpenSSH refuses to use a &lt;code&gt;~/.ssh&lt;/code&gt; reachable through a too-permissive path.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use mode &lt;code&gt;700&lt;/code&gt; for the directory, &lt;code&gt;600&lt;/code&gt; for private keys and &lt;code&gt;authorized_keys&lt;/code&gt;, and &lt;code&gt;644&lt;/code&gt; for public keys and &lt;code&gt;known_hosts&lt;/code&gt;. When key authentication fails after a file copy or restore, checking these modes is a good first step.&lt;/p&gt;
&lt;p&gt;For related reading, see our guides on &lt;a href="https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/"&gt;generating SSH keys&lt;/a&gt;
and the &lt;a href="https://linuxize.com/post/ssh-copy-id-command/"&gt;ssh-copy-id command&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ssh-folder-files-and-permissions/featured_hu_87f8f0b16fb7b8cf.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Generate SSH Keys on Linux with ssh-keygen</title><link>https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/</link><pubDate>Fri, 23 Jan 2026 14:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/</guid><category>ssh</category><category>security</category><description>Generate an SSH key pair on Linux with ssh-keygen, choose between Ed25519 and RSA, and install the public key on a server, a Git host, or a cloud provider.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a network protocol for creating a secure connection between a client and a server. With SSH, you can run commands on remote machines, create tunnels, forward ports, and more.&lt;/p&gt;
&lt;p&gt;SSH provides multiple authentication mechanisms. The two most common authentication methods are password-based and public-key-based. Public-key authentication is more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;This guide shows you how to create SSH keys on Linux with &lt;code&gt;ssh-keygen&lt;/code&gt;, which key type to pick, and where to install the public key once you have it.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-keygen -t ed25519&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate Ed25519 key pair&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate RSA key pair&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id user@host&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy public key to server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-add ~/.ssh/id_ed25519&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add key to SSH agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-add -l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List keys in agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ssh-add -D&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove all keys from the agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cat ~/.ssh/id_ed25519.pub&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Display public key&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you begin, make sure you have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Linux system with an SSH client installed (included by default on most distributions)&lt;/li&gt;
&lt;li&gt;Somewhere to install the public key, such as a remote server, a Git hosting account, or a cloud provider&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="check-for-existing-ssh-keys"&gt;Check for Existing SSH Keys &lt;a class="headline-link" href="#check-for-existing-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before generating a new key pair, check if you already have SSH keys on your system:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you see files like &lt;code&gt;id_rsa.pub&lt;/code&gt; or &lt;code&gt;id_ed25519.pub&lt;/code&gt;, you already have SSH keys. You can either use the existing keys or generate new ones. Generating a new key pair with the same name will overwrite the old one.&lt;/p&gt;
&lt;p&gt;If the command returns &lt;code&gt;No such file or directory&lt;/code&gt;, you don&amp;rsquo;t have SSH keys and may proceed with generating a new pair.&lt;/p&gt;
&lt;h2 id="generate-an-ssh-key-pair"&gt;Generate an SSH Key Pair &lt;a class="headline-link" href="#generate-an-ssh-key-pair" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;ssh-keygen&lt;/code&gt; command creates a new SSH key pair. You can choose between different key types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ed25519&lt;/strong&gt; (recommended) - Modern, secure, and fast&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSA&lt;/strong&gt; - Widely compatible, use 4096 bits for security&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generate-an-ed25519-key-recommended"&gt;Generate an Ed25519 Key (Recommended) &lt;a class="headline-link" href="#generate-an-ed25519-key-recommended" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ed25519 keys are shorter, faster, and considered more secure than RSA keys:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519 -C &lt;span class="s2"&gt;&amp;#34;your_email@example.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="generate-an-rsa-key"&gt;Generate an RSA Key &lt;a class="headline-link" href="#generate-an-rsa-key" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you need compatibility with legacy systems that don&amp;rsquo;t support Ed25519, use RSA with 4096 bits:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@example.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-C&lt;/code&gt; flag adds a comment (usually your email) to help identify the key.&lt;/p&gt;
&lt;h3 id="key-generation-process"&gt;Key Generation Process &lt;a class="headline-link" href="#key-generation-process" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;After running the command, you&amp;rsquo;ll be prompted to specify the file location:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/username/.ssh/id_ed25519):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default location, or specify a custom path.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll be prompted to enter a passphrase:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A passphrase adds another layer of security. If someone gets your private key, they&amp;rsquo;ll still need the passphrase to use it. Keep in mind, you&amp;rsquo;ll have to enter the passphrase each time you use the key unless you use an SSH agent.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; for no passphrase, or type a secure passphrase and confirm it.&lt;/p&gt;
&lt;p&gt;The output will look similar to this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Your identification has been saved in /home/username/.ssh/id_ed25519
Your public key has been saved in /home/username/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:AbCdEf1234567890AbCdEf1234567890AbCdEf12 your_email@example.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The command creates two files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.ssh/id_ed25519&lt;/code&gt; - Your private key (keep this secret)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt; - Your public key (safe to share)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="where-to-put-your-public-key"&gt;Where to Put Your Public Key &lt;a class="headline-link" href="#where-to-put-your-public-key" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Generating a key pair is only half the job. The public key (&lt;code&gt;id_ed25519.pub&lt;/code&gt;) has to be installed wherever you want to authenticate, and the method depends on the destination. The private key never leaves your machine.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A Linux server you control.&lt;/strong&gt; Install the key in the remote account&amp;rsquo;s &lt;code&gt;authorized_keys&lt;/code&gt; file with &lt;code&gt;ssh-copy-id&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id username@server_ip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted for the remote user password once. After that the key is in place and the password prompts stop. Our guide on &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;passwordless SSH login&lt;/a&gt;
covers the full flow, including the manual copy method and how to disable password authentication afterwards.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GitHub, GitLab, or Bitbucket.&lt;/strong&gt; These hosts have no shell account, so &lt;code&gt;ssh-copy-id&lt;/code&gt; does not apply. Print the public key and paste the output into the SSH key settings of your account:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_ed25519.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8k... your_email@domain.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then confirm the key works against the host endpoint. For GitHub:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -T git@github.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A cloud provider.&lt;/strong&gt; AWS, DigitalOcean, and Hetzner let you register a public key in the control panel and inject it into new instances at creation time. Paste the same output into the provider key form before launching the machine, and it lands in the default user&amp;rsquo;s &lt;code&gt;authorized_keys&lt;/code&gt; automatically.&lt;/p&gt;
&lt;h2 id="using-the-ssh-agent"&gt;Using the SSH Agent &lt;a class="headline-link" href="#using-the-ssh-agent" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you set a passphrase on your key, entering it for every connection can be tedious. The SSH agent stores your decrypted private key in memory, so you only need to enter the passphrase once per session.&lt;/p&gt;
&lt;p&gt;Start the SSH agent:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ssh-agent -s&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Agent pid 12345&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add your private key to the agent:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-add ~/.ssh/id_ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You&amp;rsquo;ll be prompted for your passphrase. After entering it, subsequent SSH connections will use the cached key without asking for the passphrase again.&lt;/p&gt;
&lt;p&gt;To list keys currently loaded in the agent:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-add -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="managing-ssh-keys"&gt;Managing SSH Keys &lt;a class="headline-link" href="#managing-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="view-your-public-key"&gt;View Your Public Key &lt;a class="headline-link" href="#view-your-public-key" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To display your public key (useful for adding to services like GitHub):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_ed25519.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="list-all-keys"&gt;List All Keys &lt;a class="headline-link" href="#list-all-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To see all key files in your SSH directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -la ~/.ssh/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="remove-a-key-from-the-agent"&gt;Remove a Key from the Agent &lt;a class="headline-link" href="#remove-a-key-from-the-agent" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To remove a specific key from the SSH agent:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-add -d ~/.ssh/id_ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To remove all keys from the agent:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-add -D&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="delete-a-key-pair"&gt;Delete a Key Pair &lt;a class="headline-link" href="#delete-a-key-pair" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To permanently delete a key pair, remove both the private and public key files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="permission-denied-publickey"&gt;Permission Denied (publickey) &lt;a class="headline-link" href="#permission-denied-publickey" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you see this error, check the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Verify the public key is in the remote server&amp;rsquo;s &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check permissions on the remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;700&lt;/span&gt; ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;600&lt;/span&gt; ~/.ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensure the private key has correct permissions locally:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;600&lt;/span&gt; ~/.ssh/id_ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="ssh-agent-not-running"&gt;SSH Agent Not Running &lt;a class="headline-link" href="#ssh-agent-not-running" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you get an error about the agent, start it with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ssh-agent -s&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="wrong-key-being-used"&gt;Wrong Key Being Used &lt;a class="headline-link" href="#wrong-key-being-used" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To specify which key to use for a connection:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -i ~/.ssh/my_custom_key username@server_ip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For permanent configuration, add an entry to &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="conf"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;conf&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-conf" data-lang="conf"&gt;Host myserver
HostName server_ip
User username
IdentityFile ~/.ssh/my_custom_key&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then connect using:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh myserver&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A single key pair works across every destination that accepts one, so generating a good key once and keeping the private half safe matters more than repeating the process per host.&lt;/p&gt;
&lt;p&gt;To keep your SSH connections organized, check out our guide on &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;using the SSH config file&lt;/a&gt;
. You can also &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;change the default SSH port&lt;/a&gt;
for extra security. If a key stops working after you copy files to a new machine or restore a backup, our guide to &lt;a href="https://linuxize.com/post/ssh-folder-files-and-permissions/"&gt;the files and permissions in the &lt;code&gt;~/.ssh&lt;/code&gt; folder&lt;/a&gt;
shows what each file should contain and the mode it needs.&lt;/p&gt;
&lt;p&gt;If you have questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/featured_hu_949bab1be49d3dd9.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Generate SSH Keys on Windows with PuTTYgen</title><link>https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/</link><pubDate>Sun, 05 May 2019 03:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/</guid><category>ssh</category><category>security</category><description>This tutorial explains how to generate SSH keys on Windows with PuTTYgen. We will also show you how to set up an SSH key-based authentication and connect to your remote Linux servers without entering a password.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol used for a secure connection between a client and a server and supports various authentication mechanisms.&lt;/p&gt;
&lt;p&gt;The two most popular mechanisms are passwords based authentication and public key-based authentication. Using SSH keys is more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;This tutorial explains how to generate SSH keys on Windows with PuTTYgen. We will also show you how to set up an SSH key-based authentication and connect to your remote Linux servers without entering a password.&lt;/p&gt;
&lt;h2 id="downloading-puttygen"&gt;Downloading PuTTYgen &lt;a class="headline-link" href="#downloading-puttygen" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;PuTTYgen is an open-source utility that allows you to generate SSH keys for the most popular Windows SSH client &lt;a href="https://www.putty.org/" target="_blank" rel="noopener noreferrer"&gt;PuTTY&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;PuTTYgen is available as a standalone executable file, and it is also a part of the PuTTY .msi installation package. If you don&amp;rsquo;t have PuTTYgen installed, head over to the &lt;a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html" target="_blank" rel="noopener noreferrer"&gt;PuTTY download page&lt;/a&gt;
and download the PuTTY installation package. The installation is simple, double-click on the installation package and follow the instructions.&lt;/p&gt;
&lt;h2 id="creating-ssh-keys-with-puttygen"&gt;Creating SSH keys with PuTTYgen &lt;a class="headline-link" href="#creating-ssh-keys-with-puttygen" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To generate an SSH key pair on Windows using PuTTYgen, perform the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Launch PuTTYgen by double-clicking on its &amp;ldquo;.exe&amp;rdquo; file or by going to the Windows Start menu → PuTTY (64-bit) → PuTTYgen.&lt;/p&gt;
&lt;p&gt;&lt;figure class=' my-4'&gt;&lt;picture&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/start-puttygen_hu_ce33e456cb1f762.webp 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/start-puttygen_hu_c621bf9c76396a02.webp 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/start-puttygen_hu_658611f5f359a8c8.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="my-4" loading="lazy"
decoding="async"
src="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/start-puttygen_hu_5c91de11c3b14f51.jpg"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/start-puttygen_hu_1a68acaffe514cf8.jpg 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/start-puttygen_hu_5c91de11c3b14f51.jpg 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/start-puttygen_hu_271a2031940d7e13.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="755"
alt="Start the PuTTYgen tool"&gt;
&lt;/picture&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;In the &amp;ldquo;Type of key to generate&amp;rdquo; block leave the default RSA. In the &amp;ldquo;Number of bits in a generated key&amp;rdquo; field leave the default value 2048, which is sufficient for most use cases. Optionally, you can change it to 4096.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click the &amp;ldquo;Generate&amp;rdquo; button to start the process of generating the new key pair.&lt;/p&gt;
&lt;p&gt;&lt;figure class=' my-4'&gt;&lt;picture&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/generate-key-puttygen_hu_be5e5aedc90cfc53.webp 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/generate-key-puttygen_hu_c609d1259b560593.webp 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/generate-key-puttygen_hu_d98abd02be7f54b9.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="my-4" loading="lazy"
decoding="async"
src="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/generate-key-puttygen_hu_ed7c7f820b03fb5f.jpg"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/generate-key-puttygen_hu_967379938784070f.jpg 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/generate-key-puttygen_hu_ed7c7f820b03fb5f.jpg 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/generate-key-puttygen_hu_d7a61924df357cf1.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="755"
alt="Generate SSH Keys PuTTYgen"&gt;
&lt;/picture&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;You will be asked to move your mouse over the blank area of the Key section to generate some randomness. As you move the pointer, the green progress bar will advance. The process should take a few seconds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once the public key is generated it will be displayed in the &amp;ldquo;Key&amp;rdquo; block.&lt;/p&gt;
&lt;p&gt;&lt;figure class=' my-4'&gt;&lt;picture&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/passphrase-puttygen_hu_f5203ca578216e46.webp 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/passphrase-puttygen_hu_6dbc43c6365cdb6b.webp 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/passphrase-puttygen_hu_dac33e74c317e46c.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="my-4" loading="lazy"
decoding="async"
src="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/passphrase-puttygen_hu_52fa7ba6946f006d.jpg"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/passphrase-puttygen_hu_df190564fb3bbfdf.jpg 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/passphrase-puttygen_hu_52fa7ba6946f006d.jpg 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/passphrase-puttygen_hu_ec87bf05c12700c1.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="755"
alt="Passphrase PuTTYgen"&gt;
&lt;/picture&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;If you want set a passphrase, type it in the &amp;ldquo;Key passphrase&amp;rdquo; field and confirm the same passphrase in the &amp;ldquo;Confirm passphrase&amp;rdquo; field. If you don&amp;rsquo;t want to use a passphrase leave the fields blank.&lt;/p&gt;
&lt;p&gt;It is recommended to use a passphrase when the private key files are intended for interactive use. Otherwise, when generating a key for automation, it may be set without a passphrase.&lt;/p&gt;
&lt;p&gt;A passphrase adds an extra layer of security by protecting the private key from unauthorized use.&lt;/p&gt;
&lt;p&gt;When a passphrase is set, it needs to be typed each time the private key is used.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save the private key by clicking the &amp;ldquo;Save private key&amp;rdquo; button. You can save the file in any directory as a &amp;ldquo;.ppk&amp;rdquo; file (PuTTY Private Key), but it is advisable to save in a place where you can easily find it. It&amp;rsquo;s common to use a descriptive name for the private key file.&lt;/p&gt;
&lt;p&gt;Optionally, you can also save the public key, though it can be regenerated later by loading the private key.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Right-click in the text field labeled &amp;ldquo;Public key for pasting into OpenSSH authorized_keys file&amp;rdquo; and select all characters by clicking &amp;ldquo;Select all&amp;rdquo;. Open a text editor, paste the characters and save it. Be sure you are pasting the entire key. It is advisable to save the file in the same directory where you saved the private key, using the same name the private key and &amp;ldquo;.txt&amp;rdquo; or &amp;ldquo;.pub&amp;rdquo; as a file extension.&lt;/p&gt;
&lt;p&gt;&lt;figure class=' my-4'&gt;&lt;picture&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/public-key-puttygen_hu_1d6ed3b778a972ca.webp 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/public-key-puttygen_hu_f6e09f30eaa4fb3b.webp 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/public-key-puttygen_hu_d5a1435b45ed6fa6.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="my-4" loading="lazy"
decoding="async"
src="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/public-key-puttygen_hu_3b3e76f2f198cc8b.jpg"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/public-key-puttygen_hu_eb0987e4165bc569.jpg 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/public-key-puttygen_hu_3b3e76f2f198cc8b.jpg 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/public-key-puttygen_hu_7f6cf01f686e53c3.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="755"
alt="Public Key PuTTYgen"&gt;
&lt;/picture&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;This is the key that you should add to your remote Linux server.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="copying-the-public-key-to-the-server"&gt;Copying the Public Key to the Server &lt;a class="headline-link" href="#copying-the-public-key-to-the-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that the SSH key pair is generated, the next step is to copy the public key to the server you want to manage.&lt;/p&gt;
&lt;p&gt;Launch the PuTTY program and login to your remote Linux server.&lt;/p&gt;
&lt;p&gt;If your user SSH directory does not exist, create it with the &lt;a href="https://linuxize.com/post/how-to-create-directories-in-linux-with-the-mkdir-command/"&gt;&lt;code&gt;mkdir&lt;/code&gt; command&lt;/a&gt;
and set the correct permissions:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;0700&lt;/span&gt; ~/.ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Open a &lt;a href="https://linuxize.com/post/how-to-use-nano-text-editor/"&gt;text editor&lt;/a&gt;
and paste the public key that you copied in step 4 when generating the key pair into the &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nano ~/.ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The entire public key text must be on a single line.&lt;/p&gt;
&lt;p&gt;Run the following &lt;a href="https://linuxize.com/post/chmod-command-in-linux/"&gt;&lt;code&gt;chmod&lt;/code&gt;&lt;/a&gt;
command to ensure only your user can read and write the &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;0600&lt;/span&gt; ~/.ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="login-to-the-server-using-ssh-keys"&gt;Login to the Server using SSH Keys &lt;a class="headline-link" href="#login-to-the-server-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pageant is a PuTTY SSH authentication agent that holds the private keys in the memory. Pageant binary is a part of the PuTTY .msi installation package and can be launch by going to the Windows Start menu → PuTTY (64-bit) → Pageant.&lt;/p&gt;
&lt;p&gt;When you start Pageant, it will place an icon into the system tray. Double-click on the icon, and the Pageant window will open.&lt;/p&gt;
&lt;p&gt;To load a key, press the &amp;ldquo;Add Key&amp;rdquo; button, which will open a new file dialog. Locate the private key file, and press &amp;ldquo;Open&amp;rdquo;. If you haven&amp;rsquo;t set a passphrase, the key will be loaded in immediately. Otherwise, you will be prompted to enter the passphrase.&lt;/p&gt;
&lt;p&gt;&lt;figure class=' my-4'&gt;&lt;picture&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/pageant_hu_2bf54bbd4aec4048.webp 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/pageant_hu_809951fc202e6584.webp 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/pageant_hu_11e1b57315d5b46b.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="my-4" loading="lazy"
decoding="async"
src="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/pageant_hu_c31b958b879b0afa.jpg"
srcset="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/pageant_hu_383de633a33d9f1.jpg 480w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/pageant_hu_c31b958b879b0afa.jpg 768w, https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/pageant_hu_bef9e3591b3af15e.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="552"
alt="Pageant Load Key"&gt;
&lt;/picture&gt;
&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Enter the password, and Pageant will load the private key.&lt;/p&gt;
&lt;p&gt;After completing the steps above, you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To test it out, open a new PuTTY SSH session and try to login into the remote server. PuTTY will use the loaded key, and you will be logged into the server without entering the password.&lt;/p&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add an extra layer of security to your server, you can disable password authentication for SSH.&lt;/p&gt;
&lt;p&gt;Before disabling the SSH password authentication make sure you can log in to your server without a password, and the user you are logging in with has &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-ubuntu/"&gt;sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Log into the remote server and open the SSH configuration file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Search for the following directives and modify as it follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ChallengeResponseAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once you are done, save the file and restart the SSH service by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At this point, the password-based authentication is disabled.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this tutorial, you have learned how to generate a new SSH key pair and set up an SSH key-based authentication. You can add the same key to multiple remote servers. We have also shown you how to disable SSH password authentication and add an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
will reduce the risk of automated attacks.&lt;/p&gt;
&lt;p&gt;If you have any questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/featured_hu_47cfecb9d0fa5f12.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up SSH Keys on Ubuntu 18.04</title><link>https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/</link><pubDate>Sat, 22 Sep 2018 03:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/</guid><category>ssh</category><category>security</category><category>ubuntu</category><description>In this tutorial, we will walk through how to generate SSH keys on Ubuntu 18.04 machines. We will also show you how to set up an SSH key-based authentication and connect to your remote Linux servers without entering a password.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol used for a secure connection between a client and a server and supports various authentication mechanisms.&lt;/p&gt;
&lt;p&gt;The two most popular mechanisms are passwords based authentication and public key-based authentication. Using SSH keys is more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;In this tutorial, we will walk through how to generate SSH keys on Ubuntu 18.04 machines. We will also show you how to set up an SSH key-based authentication and connect to your remote Linux servers without entering a password.&lt;/p&gt;
&lt;h2 id="creating-ssh-keys-on-ubuntu"&gt;Creating SSH keys on Ubuntu &lt;a class="headline-link" href="#creating-ssh-keys-on-ubuntu" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before generating a new SSH key pair first, check for existing SSH keys on your Ubuntu client machine. You can do that by running the following &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;ls command&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command above prints something like &lt;code&gt;No such file or directory&lt;/code&gt; or &lt;code&gt;no matches found&lt;/code&gt; it means that you don&amp;rsquo;t have SSH keys on your client machine and you can proceed with the next step, and generate SSH key pair.&lt;/p&gt;
&lt;p&gt;If there are existing keys, you can either use those and skip the next step or backup up the old keys and generate new ones.&lt;/p&gt;
&lt;p&gt;Generate a new 4096 bits SSH key pair with your email address as a comment by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output will look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default file location and file name.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll be prompted to type a secure passphrase. Whether you want to use a passphrase, it&amp;rsquo;s up to you. If you choose to use a passphrase you will get an extra layer of security.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use a passphrase just press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The whole interaction looks like this:&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 715 / 445"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/generate-a-new-ssh-key-pair_hu_a097fa0b6629c552.webp 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/generate-a-new-ssh-key-pair_hu_f9f0b0e9afac4d9c.webp 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/generate-a-new-ssh-key-pair_hu_daf5011dc861f378.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/generate-a-new-ssh-key-pair_hu_8ea618113c94b6c2.jpg"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/generate-a-new-ssh-key-pair_hu_f171d266a4953bcd.jpg 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/generate-a-new-ssh-key-pair_hu_8ea618113c94b6c2.jpg 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/generate-a-new-ssh-key-pair_hu_6cf9be72c06477c9.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="478"
alt="Generate a new SSH key pair"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To verify your new SSH key pair is generated, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh/id_*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/yourusername/.ssh/id_rsa /home/yourusername/.ssh/id_rsa.pub&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="copy-the-public-key-to-the-server"&gt;Copy the Public Key to the Server &lt;a class="headline-link" href="#copy-the-public-key-to-the-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you generated your SSH key pair, the next step is to copy the public key to the server you want to manage.&lt;/p&gt;
&lt;p&gt;The easiest and the recommended way to copy your public key to the server is to use a utility called &lt;code&gt;ssh-copy-id&lt;/code&gt;. On your local machine terminal type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the &lt;code&gt;remote_username&lt;/code&gt; password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@server_ip_address&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the user is authenticated, the public key &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt; will be appended to the remote user &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file and connection will be closed.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Number of key(s) added: 1
Now try logging into the machine, with: &amp;#34;ssh &amp;#39;username@server_ip_address&amp;#39;&amp;#34;
and check to make sure that only the key(s) you wanted were added.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If by some reason the &lt;code&gt;ssh-copy-id&lt;/code&gt; utility is not available on your local computer, you can use the following command to copy the public key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_rsa.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh remote_username@server_ip_address &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="login-to-your-server-using-ssh-keys"&gt;Login to your server using SSH keys &lt;a class="headline-link" href="#login-to-your-server-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After completing the steps above you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To test it, try to login to your server via SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you haven&amp;rsquo;t set a passphrase for the private key, you will be logged in immediately. Otherwise, you will be prompted to enter the passphrase.&lt;/p&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Disabling the password authentication adds an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;Before disabling SSH password authentication, make sure you can log in to your server without a password, and the user you are logging in with has &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-ubuntu/"&gt;sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Log into your remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh sudo_user@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Open the SSH configuration file &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; with your &lt;a href="https://linuxize.com/post/how-to-use-nano-text-editor/"&gt;text editor&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Search for the following directives and modify as it follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ChallengeResponseAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once you are done, save the file and restart the SSH service by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At this point, the password-based authentication is disabled.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this tutorial, you have learned how to generate a new SSH key pair and set up an SSH key-based authentication. You can add the same key to multiple remote servers. We have also shown you how to disable SSH password authentication and add an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
reduces the risk of automated attacks.&lt;/p&gt;
&lt;p&gt;If you are regularly connecting to multiple systems, you can simplify your workflow by defining all of your connections in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If you have any questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-1804/featured_hu_e585e9eb99f065c7.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up SSH Keys on Ubuntu 20.04</title><link>https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/</link><pubDate>Mon, 27 Jul 2020 18:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/</guid><category>ssh</category><category>security</category><category>ubuntu</category><description>This article explains how to generate SSH keys on Ubuntu 20.04 systems. We'll also show you how to set up an SSH key-based authentication and connect to remote Linux servers without entering a password.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a network protocol for creating a secure connection between a client and a server. With SSH, you can run commands on remote machines, create tunnels, forward ports, and more.&lt;/p&gt;
&lt;p&gt;SSH supports various authentication mechanisms. The two most common ones are password and public-key based authentication.&lt;/p&gt;
&lt;p&gt;Authentication using a public key is based on the use of digital signatures, and it is more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;This article explains how to generate SSH keys on Ubuntu 20.04 systems. We&amp;rsquo;ll also show you how to set up an SSH key-based authentication and connect to remote Linux servers without entering a password.&lt;/p&gt;
&lt;h2 id="creating-ssh-keys-on-ubuntu"&gt;Creating SSH keys on Ubuntu &lt;a class="headline-link" href="#creating-ssh-keys-on-ubuntu" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The chances are that you already have an SSH key pair on your Ubuntu client machine. If you generate a new key pair, the old one will be overwritten. To check whether the key files exist, run the following &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/a&gt;
command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command returns something like &lt;code&gt;No such file or directory&lt;/code&gt;, or &lt;code&gt;no matches found&lt;/code&gt;, it means that the user does not have SSH keys, and you can proceed with the next step and generate SSH key pair. Otherwise, if you have an SSH key pair, you can either the existing ones or backup up the old keys and generate a new pair.&lt;/p&gt;
&lt;p&gt;To generate a new 4096 bits SSH key pair with your email address as a comment, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to specify the file name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The default location and file name should be fine for most users. Press &lt;code&gt;Enter&lt;/code&gt; to accept and continue.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll be asked to type a secure passphrase. A passphrase adds an extra layer of security. If you set a passphrase, you&amp;rsquo;ll be prompted to enter it each time you use the key to login to the remote machine.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t want to set a passphrase, press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The whole interaction looks like this:&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 715 / 445"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/generate-a-new-ssh-key-pair_hu_a097fa0b6629c552.webp 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/generate-a-new-ssh-key-pair_hu_f9f0b0e9afac4d9c.webp 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/generate-a-new-ssh-key-pair_hu_daf5011dc861f378.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/generate-a-new-ssh-key-pair_hu_8ea618113c94b6c2.jpg"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/generate-a-new-ssh-key-pair_hu_f171d266a4953bcd.jpg 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/generate-a-new-ssh-key-pair_hu_8ea618113c94b6c2.jpg 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/generate-a-new-ssh-key-pair_hu_6cf9be72c06477c9.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="478"
alt="Generate a new SSH key pair"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To verify your new SSH key pair is generated, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh/id_*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/yourusername/.ssh/id_rsa /home/yourusername/.ssh/id_rsa.pub&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&amp;rsquo;s it. You’ve successfully generated an SSH key pair on your Ubuntu client machine.&lt;/p&gt;
&lt;h2 id="copy-the-public-key-to-the-remote-server"&gt;Copy the Public Key to the Remote Server &lt;a class="headline-link" href="#copy-the-public-key-to-the-remote-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you have an SSH key pair, the next step is to copy the public key to the remote server you want to manage.&lt;/p&gt;
&lt;p&gt;The easiest and the recommended way to copy the public key to the server is to use the &lt;code&gt;ssh-copy-id&lt;/code&gt; tool. On your local machine type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the remote user password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@server_ip_address&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the user is authenticated, the public key &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt; will be appended to the remote user &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file, and the connection will be closed.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Number of key(s) added: 1
Now try logging into the machine, with: &amp;#34;ssh &amp;#39;username@server_ip_address&amp;#39;&amp;#34;
and check to make sure that only the key(s) you wanted were added.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If by some reason the &lt;code&gt;ssh-copy-id&lt;/code&gt; utility is not available on your local computer, use the following command to copy the public key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_rsa.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh remote_username@server_ip_address &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="login-to-your-server-using-ssh-keys"&gt;Login to your server using SSH keys &lt;a class="headline-link" href="#login-to-your-server-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After completing the steps above, you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To test it, try to login to your server via SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you haven&amp;rsquo;t set a passphrase for the private key, you will be logged in immediately. Otherwise, you will be prompted to enter the passphrase.&lt;/p&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Disabling the password authentication adds an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;Before disabling SSH password authentication, make sure you can log in to your server without a password, and the user you are logging in with has &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-ubuntu/"&gt;sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Log into your remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh sudo_user@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Open the SSH configuration file with your &lt;a href="https://linuxize.com/post/how-to-use-nano-text-editor/"&gt;text editor&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Search for the following directives and modify as it follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ChallengeResponseAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once done, save the file and restart the SSH service by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At this point, the password-based authentication is disabled.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ve shown you how to generate a new SSH key pair and set up an SSH key-based authentication. You can use the same key to manage multiple remote servers. You have also learned how to disable SSH password authentication and add an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
reduces the risk of automated attacks. To simplify your workflow, use the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
to define all your SSH connections.&lt;/p&gt;
&lt;p&gt;If you have any questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/featured_hu_e5beee01254cff46.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up SSH Keys on CentOS 7</title><link>https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/</link><pubDate>Sun, 07 Oct 2018 13:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/</guid><category>ssh</category><category>security</category><category>centos</category><description>This tutorial explains how to generate SSH keys on CentOS 7 systems. We will also show you how to set up an SSH key-based authentication and connect to your remote Linux servers without entering a password.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol designed for a secure connection between a client and a server.&lt;/p&gt;
&lt;p&gt;The two most popular SSH authentication mechanisms are password based authentication and public-key based authentication. Using SSH keys is generally more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;This tutorial explains how to generate SSH keys on CentOS 7 systems. We will also show you how to set up an SSH key-based authentication and connect to your remote Linux servers without entering a password.&lt;/p&gt;
&lt;h2 id="creating-ssh-keys-on-centos"&gt;Creating SSH keys on CentOS &lt;a class="headline-link" href="#creating-ssh-keys-on-centos" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before generating a new SSH key pair, it is a good idea to check for existing SSH keys on your CentOS client machine.&lt;/p&gt;
&lt;p&gt;To do so, run the following &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;ls command&lt;/a&gt;
that lists all public keys if there are any:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the output of the command returns something like &lt;code&gt;No such file or directory&lt;/code&gt; or &lt;code&gt;no matches found&lt;/code&gt; it means that you don&amp;rsquo;t have SSH keys on your client machine, and you can proceed with the next step and generate SSH key pair.&lt;/p&gt;
&lt;p&gt;If there are existing keys, you can either use those and skip the next step or backup up the old keys and generate new ones.&lt;/p&gt;
&lt;p&gt;Start by generating a new 4096 bits SSH key pair with your email address as a comment:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to specify the file name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default file location and file name.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll be asked to type a secure passphrase. Whether you want to use a passphrase, it&amp;rsquo;s up to you. If you choose to use a passphrase, you will get an extra layer of security.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use a passphrase just press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The whole interaction looks like this:&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 715 / 445"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/generate-a-new-ssh-key-pair_hu_d7ccc828f7496420.webp 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/generate-a-new-ssh-key-pair_hu_78808929575846fc.webp 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/generate-a-new-ssh-key-pair_hu_5a8a47b65806c8f1.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/generate-a-new-ssh-key-pair_hu_def8f09ac826bcf6.jpg 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/generate-a-new-ssh-key-pair_hu_c1622ee926da47db.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="478"
alt="Generate a new SSH key pair"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To verify your new SSH key pair is generated, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh/id_*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/yourusername/.ssh/id_rsa /home/yourusername/.ssh/id_rsa.pub&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="copy-the-public-key-to-centos-server"&gt;Copy the Public Key to CentOS Server &lt;a class="headline-link" href="#copy-the-public-key-to-centos-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that the SSH key pair is generated, the next step is to copy the public key to the server you want to manage.&lt;/p&gt;
&lt;p&gt;The easiest and the recommended way to copy the public key to the remote server is by using a utility called &lt;code&gt;ssh-copy-id&lt;/code&gt;. On your local machine terminal type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the &lt;code&gt;remote_username&lt;/code&gt; password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@server_ip_address&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Type the password, and once the user is authenticated, the public key &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt; will be appended to the remote user &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file. The connection will be closed.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Number of key(s) added: 1
Now try logging into the machine, with: &amp;#34;ssh &amp;#39;username@server_ip_address&amp;#39;&amp;#34;
and check to make sure that only the key(s) you wanted were added.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the &lt;code&gt;ssh-copy-id&lt;/code&gt; utility is not available on your local computer, use the following command to copy the public key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_rsa.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh remote_username@server_ip_address &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="login-to-your-server-using-ssh-keys"&gt;Login to your server using SSH keys &lt;a class="headline-link" href="#login-to-your-server-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After completing the steps above, you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To verify it, try to login to your server via &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;SSH&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you haven&amp;rsquo;t set a passphrase for the private key, you will be logged in immediately. Otherwise, you will be asked to enter the passphrase.&lt;/p&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add an additional layer of security to your remote server, you can disable SSH password authentication.&lt;/p&gt;
&lt;p&gt;Before continuing, make sure you can log in to your server without a password as a user with &lt;a href="https://linuxize.com/post/create-a-sudo-user-on-centos/"&gt;sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Follow the steps below to disable SSH password authentication:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Log into your remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh sudo_user@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the SSH configuration file &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; with your &lt;a href="https://linuxize.com/post/how-to-use-nano-text-editor/"&gt;text editor&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the following directives and modify as it follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ChallengeResponseAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you are done save the file and restart the SSH service by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, the password-based authentication is disabled.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this tutorial, you have learned how to generate a new SSH key pair and set up an SSH key-based authentication. You can add the same key to multiple remote servers.&lt;/p&gt;
&lt;p&gt;We have also shown you how to disable SSH password authentication and add an additional layer of security to your server.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
reducess the risk of automated attacks.&lt;/p&gt;
&lt;p&gt;If you are regularly connecting to multiple systems, you can simplify your workflow by defining all of your connections in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If you have any questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-7/featured_hu_b906768f4be677fc.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up SSH Keys on CentOS 8</title><link>https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/</link><pubDate>Wed, 22 Apr 2020 20:50:54 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/</guid><category>ssh</category><category>security</category><category>centos</category><description>This article describes how to generate SSH keys on CentOS 8 systems. We'll also show you how to set up an SSH key-based authentication and connect to remote Linux servers without entering a password.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol designed for a secure connection between a client and a server.&lt;/p&gt;
&lt;p&gt;The two most popular SSH authentication mechanisms are password-based authentication and public-key based authentication. Using SSH keys is generally more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;This article describes how to generate SSH keys on CentOS 8 systems. We&amp;rsquo;ll also show you how to set up an SSH key-based authentication and connect to remote Linux servers without entering a password.&lt;/p&gt;
&lt;h2 id="creating-ssh-keys-on-centos"&gt;Creating SSH keys on CentOS &lt;a class="headline-link" href="#creating-ssh-keys-on-centos" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The chances are that you already have an SSH key pair on your CentOS client machine. If you are generating a new key pair, the old one will be overwritten.&lt;/p&gt;
&lt;p&gt;Run the following &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/a&gt;
command to check whether the key files exist:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the output of the command returns something like &lt;code&gt;No such file or directory&lt;/code&gt;, or &lt;code&gt;no matches found&lt;/code&gt; it means that the user does not have SSH keys, and you can proceed with the next step and generate SSH key pair.&lt;/p&gt;
&lt;p&gt;Otherwise, if you have an SSH key pair, you can either use those or backup up the old keys and generate new ones.&lt;/p&gt;
&lt;p&gt;To generate a new 4096 bits SSH key pair with your email address as a comment, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to specify the file name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default file location and file name.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll be asked to type a secure passphrase. Whether you want to use passphrase, it&amp;rsquo;s up to you. A passphrase will add an extra layer of security. If you don&amp;rsquo;t want to use passphrase just press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The whole interaction looks like this:&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 715 / 445"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/generate-a-new-ssh-key-pair_hu_d7ccc828f7496420.webp 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/generate-a-new-ssh-key-pair_hu_78808929575846fc.webp 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/generate-a-new-ssh-key-pair_hu_5a8a47b65806c8f1.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/generate-a-new-ssh-key-pair_hu_def8f09ac826bcf6.jpg 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/generate-a-new-ssh-key-pair_hu_c1622ee926da47db.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="478"
alt="Generate a new SSH key pair"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To verify your new SSH key pair is generated, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh/id_*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/yourusername/.ssh/id_rsa /home/yourusername/.ssh/id_rsa.pub&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&amp;rsquo;s it. You’ve successfully generated an SSH key pair on your CentOS client machine.&lt;/p&gt;
&lt;h2 id="copy-the-public-key-to-the-server"&gt;Copy the Public Key to the Server &lt;a class="headline-link" href="#copy-the-public-key-to-the-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that the SSH key pair is generated, the next step is to copy the public key to the server you want to manage.&lt;/p&gt;
&lt;p&gt;The easiest and the recommended way to copy the public key to the remote server is to use the &lt;code&gt;ssh-copy-id&lt;/code&gt; utility. On your local machine terminal type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command will ask you to enter the &lt;code&gt;remote_username&lt;/code&gt; password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@server_ip_address&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the user is authenticated, the content of the public key file (&lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt;) will be appended to the remote user &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file, and connection will be closed.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Number of key(s) added: 1
Now try logging into the machine, with: &amp;#34;ssh &amp;#39;username@server_ip_address&amp;#39;&amp;#34;
and check to make sure that only the key(s) you wanted were added.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;ssh-copy-id&lt;/code&gt; is not available on your local computer, use the following command to copy the public key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_rsa.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh remote_username@server_ip_address &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="login-to-your-server-using-ssh-keys"&gt;Login to your server using SSH keys &lt;a class="headline-link" href="#login-to-your-server-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After completing the steps above, you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To verify it, try to login to your server via &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;SSH&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you haven&amp;rsquo;t set a passphrase for the private key, you will be logged in immediately. Otherwise, you will be asked to enter the passphrase.&lt;/p&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add an additional layer of security to your remote server, you can disable SSH password authentication.&lt;/p&gt;
&lt;p&gt;Before continuing, make sure you can log in to your server without a password as a user with &lt;a href="https://linuxize.com/post/create-a-sudo-user-on-centos/"&gt;sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Follow the steps below to disable SSH password authentication:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Log into your remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh sudo_user@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the SSH configuration file &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; with your &lt;a href="https://linuxize.com/post/how-to-use-nano-text-editor/"&gt;text editor&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for the following directives and modify as it follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ChallengeResponseAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you are done save the file and restart the SSH service by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, the password-based authentication is disabled.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ve shown you how to generate a new SSH key pair and set up an SSH key-based authentication. You can use the same key to manage multiple remote servers. You have also learned how to disable SSH password authentication and add an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
reduces the risk of automated attacks. To simplify your workflow, use the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
to define all your SSH connections.&lt;/p&gt;
&lt;p&gt;If you have any questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-set-up-ssh-keys-on-centos-8/featured_hu_8004266ba4ffefac.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up SSH Keys on Debian 9</title><link>https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/</link><pubDate>Mon, 22 Oct 2018 03:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/</guid><category>ssh</category><category>security</category><category>debian</category><description>In this tutorial, we will describe how to generate SSH keys on Debian 9 systems. We will also show you how to setup an SSH key-based authentication and connect to your remote Linux servers without entering a password.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol used for a secure connection between a client and a server and supports various authentication mechanisms.&lt;/p&gt;
&lt;p&gt;The two most popular mechanisms are password based and public-key based authentication. Using SSH keys is more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;In this tutorial, we will describe how to generate SSH keys on Debian 9 systems. We will also show you how to set up an SSH key-based authentication and connect to your remote Linux servers without entering a password.&lt;/p&gt;
&lt;h2 id="creating-ssh-keys-on-debian"&gt;Creating SSH keys on Debian &lt;a class="headline-link" href="#creating-ssh-keys-on-debian" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before generating a new SSH key pair first, check for existing SSH keys on your Debian client machine. You can do that by running the following &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;ls command&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the output of the command above contains something like &lt;code&gt;No such file or directory&lt;/code&gt; or &lt;code&gt;no matches found&lt;/code&gt; it means that you don&amp;rsquo;t have SSH keys, and you can continue with the next step and generate a new SSH key pair.&lt;/p&gt;
&lt;p&gt;If there are existing keys, you can either use those and skip the next step or backup up the old keys and generate new ones.&lt;/p&gt;
&lt;p&gt;Start by generating a new 4096 bits SSH key pair with your email address as a comment using the following command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output will look similar to the following:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default file location and file name.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll be prompted to type a secure passphrase. Whether you want to use a passphrase, it&amp;rsquo;s up to you. With a passphrase, an extra layer of security is added to your key.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use a passphrase just press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The whole interaction looks like this:&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 715 / 445"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/generate-a-new-ssh-key-pair_hu_d7ccc828f7496420.webp 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/generate-a-new-ssh-key-pair_hu_78808929575846fc.webp 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/generate-a-new-ssh-key-pair_hu_5a8a47b65806c8f1.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/generate-a-new-ssh-key-pair_hu_def8f09ac826bcf6.jpg 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/generate-a-new-ssh-key-pair_hu_c1622ee926da47db.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="478"
alt="Generate a new SSH key pair"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To verify that the SSH key pair was generated, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh/id_*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/yourusername/.ssh/id_rsa /home/yourusername/.ssh/id_rsa.pub&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="copy-the-public-key-to-the-server"&gt;Copy the Public Key to the Server &lt;a class="headline-link" href="#copy-the-public-key-to-the-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you have your SSH key pair, the next step is to copy the public key to the server you want to manage.&lt;/p&gt;
&lt;p&gt;The easiest and the recommended way to copy the public key to the remote server is to use the &lt;code&gt;ssh-copy-id&lt;/code&gt; tool.&lt;/p&gt;
&lt;p&gt;On your local machine terminal run the following command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the &lt;code&gt;remote_username&lt;/code&gt; password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@server_ip_address&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the user is authenticated, the public key &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt; will be appended to the remote user &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file, and connection will be closed.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Number of key(s) added: 1
Now try logging into the machine, with: &amp;#34;ssh &amp;#39;username@server_ip_address&amp;#39;&amp;#34;
and check to make sure that only the key(s) you wanted were added.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the &lt;code&gt;ssh-copy-id&lt;/code&gt; utility is not available on your local computer, you can use the following command to copy the public key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_rsa.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh remote_username@server_ip_address &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="login-to-the-server-using-ssh-keys"&gt;Login to the Server using SSH Keys &lt;a class="headline-link" href="#login-to-the-server-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At this point, you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To test it, try to connect to the server via SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you haven&amp;rsquo;t set a passphrase, you will be logged in immediately. Otherwise, you will be prompted to enter the passphrase.&lt;/p&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add an extra layer of security to your server, you can disable the password authentication for SSH.&lt;/p&gt;
&lt;p&gt;Before disabling SSH password authentication, make sure you can log in to your server without a password, and the user you are logging in with has &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-debian/"&gt;sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Log into your remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh sudo_user@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Open the SSH configuration file &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo vim /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="https://linuxize.com/post/vim-search/"&gt;Search&lt;/a&gt;
for the following directives and modify as it follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ChallengeResponseAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once you are done, save the file and restart the SSH service using the following command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At this point, the password-based authentication is disabled.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this tutorial, you have learned how to generate a new SSH key pair and set up an SSH key-based authentication. You can add the same key to multiple remote servers.&lt;/p&gt;
&lt;p&gt;We have also shown you how to disable SSH password authentication and add an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
reduces the risk of automated attacks.&lt;/p&gt;
&lt;p&gt;If you are regularly connecting to multiple systems, you can simplify your workflow by defining all of your connections in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If you have any questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-9/featured_hu_25ad67f09a111f1.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up SSH Keys on Debian 10</title><link>https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/</link><pubDate>Sun, 29 Mar 2020 21:45:28 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/</guid><category>ssh</category><category>security</category><category>debian</category><description>This article describes how to generate SSH keys on Debian 10 systems. We will also show you how to set up an SSH key-based authentication and connect to a remote Linux servers without entering a password.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol used for a secure connection between a client and a server and supports various authentication mechanisms. The encrypted connection can be used to execute commands on the server, X11 tunneling, port forwarding, and more.&lt;/p&gt;
&lt;p&gt;Password and public-key based are the two most common mechanisms for authentications.&lt;/p&gt;
&lt;p&gt;Authentication using a public key is based on the use of digital signatures, and it is more secure and convenient than traditional password authentication.&lt;/p&gt;
&lt;p&gt;This article describes how to generate SSH keys on Debian 10 systems. We will also show you how to set up an SSH key-based authentication and connect to remote Linux servers without entering a password.&lt;/p&gt;
&lt;h2 id="creating-ssh-keys-on-debian"&gt;Creating SSH keys on Debian &lt;a class="headline-link" href="#creating-ssh-keys-on-debian" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The chances are that you already have an SSH key pair on your Debian client machine. If you are generating a new key pair, the old one will be overwritten.&lt;/p&gt;
&lt;p&gt;Run the following &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/a&gt;
command to check whether the key files exist:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the output of the command above contains something like &lt;code&gt;No such file or directory&lt;/code&gt; or &lt;code&gt;no matches found&lt;/code&gt;, it means that you don&amp;rsquo;t have SSH keys, and you can continue with the next step and generate a new SSH key pair.&lt;/p&gt;
&lt;p&gt;Otherwise, if you have an SSH key pair, you can either use those or backup up the old keys and generate new ones.&lt;/p&gt;
&lt;p&gt;Generate a new 4096 bits SSH key pair with your email address as a comment by entering the following command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output will look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default file location and file name.&lt;/p&gt;
&lt;p&gt;Next, you&amp;rsquo;ll be prompted to type a secure passphrase. Whether you want to use a passphrase, it&amp;rsquo;s up to you. The passphrase adds an extra layer of security.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use a passphrase, just press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The whole interaction looks like this:&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 715 / 445"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/generate-a-new-ssh-key-pair_hu_d7ccc828f7496420.webp 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/generate-a-new-ssh-key-pair_hu_78808929575846fc.webp 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/generate-a-new-ssh-key-pair_hu_5a8a47b65806c8f1.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg"
srcset="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/generate-a-new-ssh-key-pair_hu_def8f09ac826bcf6.jpg 480w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/generate-a-new-ssh-key-pair_hu_b8e020a2e9397147.jpg 768w, https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/generate-a-new-ssh-key-pair_hu_c1622ee926da47db.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="478"
alt="Generate a new SSH key pair"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To confirm the SSH key pair was generated, run the following command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh/id_*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command will list the key files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/yourusername/.ssh/id_rsa /home/yourusername/.ssh/id_rsa.pub&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="copy-the-public-key-to-the-server"&gt;Copy the Public Key to the Server &lt;a class="headline-link" href="#copy-the-public-key-to-the-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you have your SSH key pair, the next step is to copy the public key to the server you want to manage.&lt;/p&gt;
&lt;p&gt;The easiest and the recommended way to copy the public key to the remote server is to use the &lt;code&gt;ssh-copy-id&lt;/code&gt; tool.&lt;/p&gt;
&lt;p&gt;Run the following command on your local machine:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the &lt;code&gt;remote_username&lt;/code&gt; password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@server_ip_address&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the user is authenticated, the content of the public key file (&lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt;) will be appended to the remote user &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file, and connection will be closed.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Number of key(s) added: 1
Now try logging into the machine, with: &amp;#34;ssh &amp;#39;username@server_ip_address&amp;#39;&amp;#34;
and check to make sure that only the key(s) you wanted were added.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the &lt;code&gt;ssh-copy-id&lt;/code&gt; utility is not available on your local machine, use the following command to copy the public key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_rsa.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh remote_username@server_ip_address &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="login-to-the-server-using-ssh-keys"&gt;Login to the Server using SSH Keys &lt;a class="headline-link" href="#login-to-the-server-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At this point, you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To test it, try to connect to the server via SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you haven&amp;rsquo;t set a passphrase, you will be logged in immediately. Otherwise, you will be prompted to enter the passphrase.&lt;/p&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add an extra layer of security to your server, you can disable the SSH password authentication.&lt;/p&gt;
&lt;p&gt;Before disabling the password authentication, make sure you can log in to your server without a password, and the user you are logging in with has &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-debian/"&gt;sudo privileges&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Log into your remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh sudo_user@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Open the SSH server configuration file &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Search for the following directives and modify as it follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ChallengeResponseAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once done, save the file and restart the SSH service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At this point, the password-based authentication is disabled.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ve shown you how to generate a new SSH key pair and set up an SSH key-based authentication. You can use the same key to manage multiple remote servers. You have also learned how to disable SSH password authentication and add an extra layer of security to your server.&lt;/p&gt;
&lt;p&gt;By default, SSH listens on port 22. &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;Changing the default SSH port&lt;/a&gt;
reduces the risk of automated attacks. To simplify your workflow, use the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
to define all your SSH connections.&lt;/p&gt;
&lt;p&gt;If you have any questions or feedback, feel free to leave a comment.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-set-up-ssh-keys-on-debian-10/featured_hu_e5fc93b8d52d876f.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>ssh-copy-id Command: Copy SSH Keys to a Remote Server</title><link>https://linuxize.com/post/ssh-copy-id-command/</link><pubDate>Sat, 31 Jan 2026 19:30:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ssh-copy-id-command/</guid><category>ssh</category><description>How to use the ssh-copy-id command to copy your SSH public key to a remote server and set up passwordless login. Covers options, a manual fallback, and common errors.</description><content:encoded>&lt;p&gt;&lt;code&gt;ssh-copy-id&lt;/code&gt; is a utility that copies your local SSH public key to a remote server&amp;rsquo;s &lt;code&gt;authorized_keys&lt;/code&gt; file. This sets up key-based authentication, allowing you to log in without entering a password. The command connects to the remote host over SSH to perform the installation, using the same &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;ssh client&lt;/a&gt;
settings as a normal login, including any matching entry in your &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In this guide, we will show you how to use the &lt;code&gt;ssh-copy-id&lt;/code&gt; command with practical examples.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before using &lt;code&gt;ssh-copy-id&lt;/code&gt;, you need to have an SSH key pair. If you do not have one, generate it with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This creates a private key (&lt;code&gt;~/.ssh/id_ed25519&lt;/code&gt;) and a public key (&lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt;). For more details, see our guide on &lt;a href="https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/"&gt;how to generate SSH keys on Linux&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;The command itself ships with the OpenSSH client, so it is already present on most systems. If your shell reports &lt;code&gt;command not found&lt;/code&gt;, install the client package. On Ubuntu, Debian, and derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install openssh-client&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install openssh-clients&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;macOS includes the command at &lt;code&gt;/usr/bin/ssh-copy-id&lt;/code&gt;, so there is nothing to install there.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The basic syntax of &lt;code&gt;ssh-copy-id&lt;/code&gt; is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id [options] [user@]hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command copies the public key to the remote server and appends it to the &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file. If the &lt;code&gt;.ssh&lt;/code&gt; directory or &lt;code&gt;authorized_keys&lt;/code&gt; file does not exist, &lt;code&gt;ssh-copy-id&lt;/code&gt; creates it with restrictive permissions. It does not change the permissions of an existing directory or file.&lt;/p&gt;
&lt;h2 id="copying-the-default-key"&gt;Copying the Default Key &lt;a class="headline-link" href="#copying-the-default-key" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To copy your default public key to a remote server, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the remote user&amp;rsquo;s password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: &amp;#34;/home/user/.ssh/id_ed25519.pub&amp;#34;
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
user@remote_host&amp;#39;s password:
Number of key(s) added: 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When you do not specify &lt;code&gt;-i&lt;/code&gt;, &lt;code&gt;ssh-copy-id&lt;/code&gt; uses the keys returned by &lt;code&gt;ssh-add -L&lt;/code&gt;. If the agent has no keys, the command uses the most recently modified file that matches &lt;code&gt;~/.ssh/id*.pub&lt;/code&gt;, excluding certificate files. Before copying, it tests each key and skips any that are already installed. Run &lt;code&gt;ssh-add -L&lt;/code&gt; to see which keys the agent provides, or use &lt;code&gt;-i&lt;/code&gt; to copy a specific key.&lt;/p&gt;
&lt;p&gt;After the key is copied, you can log in without a password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To confirm that the login uses a specific key, tell SSH to try public-key authentication only and specify the matching private key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -o &lt;span class="nv"&gt;PreferredAuthentications&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;publickey -o &lt;span class="nv"&gt;IdentitiesOnly&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes -i ~/.ssh/id_ed25519 user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the connection succeeds, the server accepted that key. You may still be prompted for the private key&amp;rsquo;s passphrase, which is different from the remote user&amp;rsquo;s password. A &lt;code&gt;Permission denied (publickey)&lt;/code&gt; error means the server rejected the tested key. Common causes include selecting the wrong key, incorrect ownership or permissions, a custom &lt;code&gt;AuthorizedKeysFile&lt;/code&gt; path, or disabled public-key authentication. Our guide on &lt;a href="https://linuxize.com/post/fix-ssh-permission-denied-publickey/"&gt;fixing SSH Permission denied (publickey)&lt;/a&gt;
covers these checks in detail.&lt;/p&gt;
&lt;h2 id="specifying-a-key-file"&gt;Specifying a Key File &lt;a class="headline-link" href="#specifying-a-key-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you have multiple SSH keys, use the &lt;code&gt;-i&lt;/code&gt; option to specify which public key to copy:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="using-a-non-standard-port"&gt;Using a Non-Standard Port &lt;a class="headline-link" href="#using-a-non-standard-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If the remote SSH server listens on a port other than the default 22, use the &lt;code&gt;-p&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id -p &lt;span class="m"&gt;2222&lt;/span&gt; user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can combine &lt;code&gt;-i&lt;/code&gt; and &lt;code&gt;-p&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id -i ~/.ssh/id_ed25519.pub -p &lt;span class="m"&gt;2222&lt;/span&gt; user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="copying-keys-manually"&gt;Copying Keys Manually &lt;a class="headline-link" href="#copying-keys-manually" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If &lt;code&gt;ssh-copy-id&lt;/code&gt; is not available on your system, you can copy the key manually using &lt;a href="https://linuxize.com/post/linux-cat-command/"&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/a&gt;
and SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_ed25519.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh user@remote_host &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This command does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creates the &lt;code&gt;~/.ssh&lt;/code&gt; directory on the remote server if it does not exist.&lt;/li&gt;
&lt;li&gt;Sets the correct permissions (&lt;code&gt;700&lt;/code&gt;) on the &lt;code&gt;.ssh&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Appends the public key to the &lt;code&gt;authorized_keys&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Sets the correct permissions (&lt;code&gt;600&lt;/code&gt;) on the &lt;code&gt;authorized_keys&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="common-options"&gt;Common Options &lt;a class="headline-link" href="#common-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-i identity_file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specify the public key file to copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-p port&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect to a non-standard SSH port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-o ssh_option&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass options to the underlying SSH connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Force copying the key even if it is already installed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dry run, print the key that would be copied without installing it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use SFTP instead of remote commands, for servers that allow only SFTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-t target_path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install the key somewhere other than &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-F ssh_config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read connection settings from an alternative SSH config file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Trace the script itself, for debugging the copy process&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Permission denied&lt;/strong&gt;&lt;br&gt;
A &amp;ldquo;Permission denied&amp;rdquo; error during &lt;code&gt;ssh-copy-id&lt;/code&gt; is almost always caused by the remote server rejecting the password login that the command needs in order to install the key. The most common reason is that password authentication is disabled. Check &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; on the remote server for:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PasswordAuthentication yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Restart the SSH service after making changes:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If password authentication is already enabled, double-check that you are using the correct username, that the user is not locked, and that no &lt;code&gt;AllowUsers&lt;/code&gt; or &lt;code&gt;AllowGroups&lt;/code&gt; directive in &lt;code&gt;sshd_config&lt;/code&gt; is restricting who can log in over SSH.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connection refused or timeout&lt;/strong&gt;&lt;br&gt;
If the connection is refused or hangs, the SSH server is either not reachable or not running on the port you are trying. Make sure that the SSH service is active on the remote host, and use the &lt;code&gt;-p&lt;/code&gt; option if it listens on a non-standard port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id -p &lt;span class="m"&gt;2222&lt;/span&gt; user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A firewall on the remote server or somewhere on the network path can also block port 22. Try a plain &lt;code&gt;ssh user@remote_host&lt;/code&gt; first to confirm that you can reach the host before running &lt;code&gt;ssh-copy-id&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key already installed&lt;/strong&gt;&lt;br&gt;
If the key is already in the remote &lt;code&gt;authorized_keys&lt;/code&gt; file, &lt;code&gt;ssh-copy-id&lt;/code&gt; will skip it and display:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Use the &lt;code&gt;-f&lt;/code&gt; option to force installation if needed.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Copy default key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy specific key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id -i ~/.ssh/key.pub user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use non-standard port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id -p 2222 user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dry run&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id -n user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Force copy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id -f user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What does ssh-copy-id actually do?&lt;/strong&gt;&lt;br&gt;
It checks whether your public key is already installed, then appends it to the remote server&amp;rsquo;s &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file if needed. It also creates the &lt;code&gt;.ssh&lt;/code&gt; directory and &lt;code&gt;authorized_keys&lt;/code&gt; file when they do not exist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use ssh-copy-id on macOS?&lt;/strong&gt;&lt;br&gt;
Yes. macOS includes the command at &lt;code&gt;/usr/bin/ssh-copy-id&lt;/code&gt; and has shipped it since macOS 10.13, so most users do not need to install anything. Homebrew also provides a separate, keg-only &lt;code&gt;ssh-copy-id&lt;/code&gt; formula if you need a newer version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is ssh-copy-id safe to use?&lt;/strong&gt;&lt;br&gt;
Yes. It only copies your public key, not your private key. The public key is meant to be shared.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What permissions does ssh-copy-id set?&lt;/strong&gt;&lt;br&gt;
When &lt;code&gt;ssh-copy-id&lt;/code&gt; creates the remote &lt;code&gt;.ssh&lt;/code&gt; directory and &lt;code&gt;authorized_keys&lt;/code&gt; file, its restrictive umask gives them &lt;code&gt;700&lt;/code&gt; and &lt;code&gt;600&lt;/code&gt; permissions. It does not reset permissions on existing paths. For a full breakdown of every file in &lt;code&gt;~/.ssh&lt;/code&gt; and the mode it needs, see &lt;a href="https://linuxize.com/post/ssh-folder-files-and-permissions/"&gt;the &lt;code&gt;~/.ssh&lt;/code&gt; folder guide&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I copy keys to multiple servers?&lt;/strong&gt;&lt;br&gt;
Yes. Run &lt;code&gt;ssh-copy-id&lt;/code&gt; once for each server. There is no built-in option to copy to multiple hosts at once, but you can use a loop: &lt;code&gt;for host in server1 server2; do ssh-copy-id user@$host; done&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;ssh-copy-id&lt;/code&gt; command is the simplest way to set up key-based SSH authentication. It checks for an existing key, installs it when needed, and creates the required remote path if it is missing.&lt;/p&gt;
&lt;p&gt;After installing the key, test the SSH login in a new terminal before closing your current session. Once key-based login works for every account you need, disabling password authentication is the sensible next step, and our &lt;a href="https://linuxize.com/post/ssh-hardening-best-practices/"&gt;SSH hardening guide&lt;/a&gt;
walks through that change.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ssh-copy-id-command/featured_hu_fe9f55e7dcc6e8b1.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up Passwordless SSH Login</title><link>https://linuxize.com/post/how-to-setup-passwordless-ssh-login/</link><pubDate>Sat, 16 Jun 2018 03:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-setup-passwordless-ssh-login/</guid><category>ssh</category><category>security</category><description>Set up passwordless SSH login with Ed25519 or RSA key pairs. Copy public keys with ssh-copy-id, use the ssh-agent, and disable password authentication for hardened access.</description><content:encoded>&lt;p&gt;Secure Shell (SSH) is a cryptographic network protocol used for a secure connection between a client and a server. It supports various authentication mechanisms, the two most popular being password-based authentication and public-key-based authentication. If you are new to SSH, see our &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;SSH command guide&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file guide&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;In this guide, we will show you how to set up SSH key-based authentication and connect to your Linux server without entering a password.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Generate Ed25519 key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-keygen -t ed25519 -C &amp;quot;email@example.com&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate RSA key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-keygen -t rsa -b 4096 -C &amp;quot;email@example.com&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy key to server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log in with key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start SSH agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eval &amp;quot;$(ssh-agent -s)&amp;quot; &amp;amp;&amp;amp; ssh-add ~/.ssh/id_ed25519&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List public keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls -al ~/.ssh/id_*.pub&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="check-for-existing-ssh-keys"&gt;Check for Existing SSH Keys &lt;a class="headline-link" href="#check-for-existing-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before generating a new SSH key pair, check if you already have one on your client machine so you do not overwrite existing keys.&lt;/p&gt;
&lt;p&gt;Run the following &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;ls command&lt;/a&gt;
to see if existing SSH keys are present:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -al ~/.ssh/id_*.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If there are existing keys, you can either use those and skip the next step or back up the old keys and generate a new one.&lt;/p&gt;
&lt;p&gt;If you see &lt;code&gt;No such file or directory&lt;/code&gt; or &lt;code&gt;no matches found&lt;/code&gt;, it means that you do not have an SSH key and you can proceed with the next step.&lt;/p&gt;
&lt;h2 id="generate-a-new-ssh-key-pair"&gt;Generate a New SSH Key Pair &lt;a class="headline-link" href="#generate-a-new-ssh-key-pair" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The recommended key type is Ed25519, which offers better security and performance than RSA with shorter keys:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519 -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you need to work with older systems that do not support Ed25519, you can generate a 4096-bit RSA key instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt; -C &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Our guide on &lt;a href="https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/"&gt;generating SSH keys with ssh-keygen&lt;/a&gt;
goes deeper into key types, custom filenames, and managing more than one key pair.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;Enter&lt;/code&gt; to accept the default file location and file name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter file in which to save the key (/home/yourusername/.ssh/id_ed25519):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, the &lt;code&gt;ssh-keygen&lt;/code&gt; tool will ask you to type a secure passphrase. Whether you want to use a passphrase is up to you. If you choose to use a passphrase, you will get an extra layer of security. In most cases, developers and system administrators use SSH without a passphrase because it is useful for fully automated processes. If you do not want to use a passphrase, just press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Enter passphrase (empty for no passphrase):&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A sample interaction looks like this:&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 810 / 508"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/generate-a-new-ssh-key-pair_hu_fd5056401f17800e.webp 480w, https://linuxize.com/post/how-to-setup-passwordless-ssh-login/generate-a-new-ssh-key-pair_hu_a39cd9746f08faa1.webp 768w, https://linuxize.com/post/how-to-setup-passwordless-ssh-login/generate-a-new-ssh-key-pair_hu_6471125b87f4a6bb.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/generate-a-new-ssh-key-pair_hu_3f384a69a03252cc.jpg"
srcset="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/generate-a-new-ssh-key-pair_hu_3eea0fd07e6c298a.jpg 480w, https://linuxize.com/post/how-to-setup-passwordless-ssh-login/generate-a-new-ssh-key-pair_hu_3f384a69a03252cc.jpg 768w, https://linuxize.com/post/how-to-setup-passwordless-ssh-login/generate-a-new-ssh-key-pair_hu_d6bfdc9503826a2.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="482"
alt="Generate a new SSH key pair"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;To verify that the SSH keys were generated, list your new private and public keys with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls ~/.ssh/id_*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/yourusername/.ssh/id_ed25519 /home/yourusername/.ssh/id_ed25519.pub&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="copy-the-public-key-to-the-server"&gt;Copy the Public Key to the Server &lt;a class="headline-link" href="#copy-the-public-key-to-the-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you have generated an SSH key pair, you need to copy the public key to the server you want to manage.&lt;/p&gt;
&lt;p&gt;The easiest way to copy your public key to your server is to use the &lt;code&gt;ssh-copy-id&lt;/code&gt; command. On your local machine, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the &lt;code&gt;remote_username&lt;/code&gt; password:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@server_ip_address&amp;#39;s password:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the user is authenticated, the public key will be appended to the remote user&amp;rsquo;s &lt;code&gt;authorized_keys&lt;/code&gt; file and the connection will be closed.&lt;/p&gt;
&lt;p&gt;If for some reason the &lt;code&gt;ssh-copy-id&lt;/code&gt; utility is not available on your local computer, you can use the following command to copy the public key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_ed25519.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh remote_username@server_ip_address &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;The correct permissions are critical for SSH key authentication to work. The &lt;code&gt;~/.ssh&lt;/code&gt; directory must be &lt;code&gt;700&lt;/code&gt; and the &lt;code&gt;authorized_keys&lt;/code&gt; file must be &lt;code&gt;600&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="copy-a-non-default-key"&gt;Copy a Non-Default Key &lt;a class="headline-link" href="#copy-a-non-default-key" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you generated a key with a custom filename, specify it with &lt;code&gt;-i&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id -i ~/.ssh/id_ed25519_work.pub remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="log-in-using-ssh-keys"&gt;Log In Using SSH Keys &lt;a class="headline-link" href="#log-in-using-ssh-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After completing the steps above, you should be able to log in to the remote server without being prompted for a password.&lt;/p&gt;
&lt;p&gt;To test it, try to log in to your server via SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh remote_username@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If everything went well, you will be logged in immediately.&lt;/p&gt;
&lt;h2 id="using-the-ssh-agent"&gt;Using the SSH Agent &lt;a class="headline-link" href="#using-the-ssh-agent" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you set a passphrase on your key, you will be asked to enter it every time you connect. To avoid this, you can use &lt;code&gt;ssh-agent&lt;/code&gt; to cache your passphrase for the duration of your session:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ssh-agent -s&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-add ~/.ssh/id_ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The agent will remember your passphrase until you log out or the agent is stopped.&lt;/p&gt;
&lt;h3 id="loading-keys-into-the-agent-automatically"&gt;Loading Keys into the Agent Automatically &lt;a class="headline-link" href="#loading-keys-into-the-agent-automatically" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To load the key into the agent automatically on first use, add this block to &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host *
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; AddKeysToAgent yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; IdentityFile ~/.ssh/id_ed25519
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; IdentitiesOnly yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;AddKeysToAgent yes&lt;/code&gt; pushes the key into a running &lt;code&gt;ssh-agent&lt;/code&gt; the first time it is used, so the passphrase is requested only once per session. &lt;code&gt;IdentityFile&lt;/code&gt; selects the key explicitly, and &lt;code&gt;IdentitiesOnly yes&lt;/code&gt; prevents the client from offering every key from the agent and triggering &lt;code&gt;Too many authentication failures&lt;/code&gt; on strict servers.&lt;/p&gt;
&lt;h2 id="generating-ssh-keys-on-windows"&gt;Generating SSH Keys on Windows &lt;a class="headline-link" href="#generating-ssh-keys-on-windows" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Windows 10 and later include a built-in OpenSSH client. You can use the same commands shown above directly in PowerShell or Command Prompt.&lt;/p&gt;
&lt;p&gt;To generate a key on Windows, open PowerShell and run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="powershell"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;powershell&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;ssh-keygen&lt;/span&gt; &lt;span class="n"&gt;-t&lt;/span&gt; &lt;span class="n"&gt;ed25519&lt;/span&gt; &lt;span class="n"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;your_email@domain.com&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The keys will be stored in &lt;code&gt;C:\Users\your_username\.ssh\&lt;/code&gt;. To copy the public key to the server, you can use the following PowerShell command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="powershell"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;powershell&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;type &lt;/span&gt;&lt;span class="nv"&gt;$env:USERPROFILE&lt;/span&gt;&lt;span class="p"&gt;\.&lt;/span&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;id_ed25519&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;pub&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ssh&lt;/span&gt; &lt;span class="n"&gt;remote_username&lt;/span&gt;&lt;span class="nv"&gt;@server_ip_address&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="disabling-ssh-password-authentication"&gt;Disabling SSH Password Authentication &lt;a class="headline-link" href="#disabling-ssh-password-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add an extra layer of security to your server, you can disable password authentication for SSH.&lt;/p&gt;
&lt;p&gt;Before disabling SSH password authentication, make sure you can log in to your server without a password and the user you are logging in with has sudo privileges.&lt;/p&gt;
&lt;p&gt;The following tutorials describe how to configure sudo access:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-ubuntu/"&gt;How to create sudo user on Ubuntu&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linuxize.com/post/create-a-sudo-user-on-centos/"&gt;How to create sudo user on CentOS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-debian/"&gt;How to create sudo user on Debian&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Log into your remote server with SSH keys, either as a user with sudo privileges or root:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh sudo_user@server_ip_address&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Keep this session open while you make the changes below. If the new configuration locks you out, you will still have a working shell to revert it.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On Ubuntu 22.04, Debian 12, and other recent releases, &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; begins with an &lt;code&gt;Include /etc/ssh/sshd_config.d/*.conf&lt;/code&gt; line. OpenSSH uses the first value it obtains for each keyword, and the included files are read in lexical order, so a directive set in a drop-in file wins over the same directive further down in the main file. Cloud images are where this bites most often: &lt;code&gt;cloud-init&lt;/code&gt; writes &lt;code&gt;/etc/ssh/sshd_config.d/50-cloud-init.conf&lt;/code&gt; with &lt;code&gt;PasswordAuthentication yes&lt;/code&gt;, and editing &lt;code&gt;sshd_config&lt;/code&gt; alone changes nothing.&lt;/p&gt;
&lt;p&gt;Check whether your server uses drop-in files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls /etc/ssh/sshd_config.d/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the directory is empty or missing, edit &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; directly and set the following directives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PubkeyAuthentication yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;KbdInteractiveAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;UsePAM yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the directory already contains files, add your own drop-in with a name that sorts before them. A file named &lt;code&gt;99-hardening.conf&lt;/code&gt; is read after &lt;code&gt;50-cloud-init.conf&lt;/code&gt; and loses to it, so use a low number instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config.d/01-hardening.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config.d/01-hardening.conf&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PubkeyAuthentication yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PasswordAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;KbdInteractiveAuthentication no&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;On older OpenSSH versions (before 8.7), the directive is called &lt;code&gt;ChallengeResponseAuthentication&lt;/code&gt; instead of &lt;code&gt;KbdInteractiveAuthentication&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Save the file and test the configuration syntax before restarting anything:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sshd -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command prints no output, the syntax is valid. Confirm that the values you set are the ones OpenSSH will actually use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sshd -T &lt;span class="p"&gt;|&lt;/span&gt; grep -iE &lt;span class="s2"&gt;&amp;#34;passwordauthentication|pubkeyauthentication&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;pubkeyauthentication yes
passwordauthentication no&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This dumps the effective configuration after all includes are resolved, so it is the only reliable way to confirm that a drop-in file is not overriding you. Once the output is correct, restart the SSH service.&lt;/p&gt;
&lt;p&gt;On Ubuntu or Debian servers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Recent Ubuntu releases start SSH through socket activation, which spawns a fresh &lt;code&gt;sshd&lt;/code&gt; for each connection. The authentication changes above apply to the next login either way. Before closing the session, open a second terminal and confirm that key login still works.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Permission denied (publickey)&lt;/strong&gt;&lt;br&gt;
The server did not accept the offered key. Check three things: the public key is appended to the remote &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;, the remote &lt;code&gt;~/.ssh&lt;/code&gt; is &lt;code&gt;700&lt;/code&gt; and &lt;code&gt;authorized_keys&lt;/code&gt; is &lt;code&gt;600&lt;/code&gt;, and the username in &lt;code&gt;ssh user@host&lt;/code&gt; matches the account that owns &lt;code&gt;authorized_keys&lt;/code&gt;. Run &lt;code&gt;ssh -v user@host&lt;/code&gt; to see which keys are being offered.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Authentication refused: bad ownership or modes for file&lt;/strong&gt;&lt;br&gt;
The remote &lt;code&gt;authorized_keys&lt;/code&gt; file or &lt;code&gt;~/.ssh&lt;/code&gt; directory has loose permissions. Fix with &lt;code&gt;chmod 700 ~/.ssh &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&lt;/code&gt; on the server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PasswordAuthentication no has no effect&lt;/strong&gt;&lt;br&gt;
A file under &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt; sets the directive before the main file does, and OpenSSH keeps the first value it obtains. Run &lt;code&gt;sudo sshd -T | grep -i passwordauthentication&lt;/code&gt; to see the effective value, then edit the drop-in that sets it or add one with a lower-numbered filename.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Too many authentication failures&lt;/strong&gt;&lt;br&gt;
The client is offering every key in &lt;code&gt;~/.ssh/&lt;/code&gt; and the server cuts the session after the limit. Use &lt;code&gt;ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes user@host&lt;/code&gt; for a one-shot fix, or set &lt;code&gt;IdentitiesOnly yes&lt;/code&gt; for the host in &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Could not open a connection to your authentication agent&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;ssh-agent&lt;/code&gt; is not running in the current shell. Start it with &lt;code&gt;eval &amp;quot;$(ssh-agent -s)&amp;quot;&lt;/code&gt; and re-run &lt;code&gt;ssh-add&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between Ed25519 and RSA keys?&lt;/strong&gt;&lt;br&gt;
Ed25519 keys are shorter, faster, and considered more secure than RSA. They are supported on OpenSSH 6.5+ (released 2014). Use RSA only if you need compatibility with very old systems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use the same key for multiple servers?&lt;/strong&gt;&lt;br&gt;
Yes. You can copy the same public key to as many servers as you want using &lt;code&gt;ssh-copy-id&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What permissions should the SSH files have?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;~/.ssh&lt;/code&gt; directory should be &lt;code&gt;700&lt;/code&gt;, the private key should be &lt;code&gt;600&lt;/code&gt;, and the &lt;code&gt;authorized_keys&lt;/code&gt; file should be &lt;code&gt;600&lt;/code&gt;. Incorrect permissions will cause SSH to reject the key.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I use different keys for different servers?&lt;/strong&gt;&lt;br&gt;
You can configure per-host keys in your &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
(&lt;code&gt;~/.ssh/config&lt;/code&gt;) using the &lt;code&gt;IdentityFile&lt;/code&gt; directive.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do I need to edit /etc/ssh/sshd_config to log in with a key?&lt;/strong&gt;&lt;br&gt;
No. Key-based login works out of the box on most distributions. You only edit the server configuration when you want to turn password authentication off afterwards.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SSH key-based authentication lets you log in without typing an account password while keeping access tied to your private key. After you confirm key login works from a second terminal, disabling password authentication reduces the attack surface for public SSH servers.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/featured_hu_c91f6949595e0571.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>SSH Tunnel: Local, Remote, and Dynamic Port Forwarding</title><link>https://linuxize.com/post/how-to-setup-ssh-tunneling/</link><pubDate>Thu, 08 Aug 2019 20:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-setup-ssh-tunneling/</guid><category>ssh</category><category>security</category><description>Set up SSH tunnels with the -L, -R, and -D options for local, remote, and dynamic port forwarding, with working examples for Linux, macOS, and Windows.</description><content:encoded>&lt;p&gt;SSH tunneling (SSH port forwarding) is a method of creating an encrypted SSH connection between a client and a server through which service ports can be relayed.&lt;/p&gt;
&lt;p&gt;SSH tunneling is useful for transporting network data of services that use an unencrypted protocol, such as VNC or &lt;a href="https://linuxize.com/post/how-to-use-linux-ftp-command-to-transfer-files/"&gt;FTP&lt;/a&gt;
, accessing geo-restricted content, or bypassing intermediate firewalls. You can forward any TCP port and tunnel the traffic over a secure SSH connection.&lt;/p&gt;
&lt;p&gt;Common use cases for SSH port forwarding include secure remote access to internal services, creating a temporary SOCKS proxy for browsing, and exposing a local dev server to a remote machine.&lt;/p&gt;
&lt;p&gt;There are three types of SSH port forwarding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Local Port Forwarding&lt;/strong&gt;: Forwards a connection from the client host to the SSH server host and then to the destination host port.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote Port Forwarding&lt;/strong&gt;: Forwards a port from the server host to the client host and then to the destination host port.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Port Forwarding&lt;/strong&gt;: Creates a SOCKS proxy server that allows communication across a range of ports.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This guide explains how to set up local, remote, and dynamic encrypted SSH tunnels.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;ssh cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local port forwarding&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -L 8080:localhost:80 user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote port forwarding&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -R 8080:localhost:3000 user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic port forwarding (SOCKS)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -D 9090 user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run tunnel in background&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -L 8080:localhost:80 -N -f user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple local forwards&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -L 8080:host1:80 -L 8081:host2:80 user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jump host&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -J jump.host user@destination&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="local-port-forwarding"&gt;Local Port Forwarding &lt;a class="headline-link" href="#local-port-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Local port forwarding allows you to forward a port on the local (SSH client) machine to a port on the remote (SSH server) machine, which is then forwarded to a port on the destination machine.&lt;/p&gt;
&lt;p&gt;In this forwarding type, the SSH client listens on a given port and tunnels any connection to that port to the specified port on the remote SSH server, which then connects to a port on the destination machine. The destination machine can be the remote SSH server or any other machine.&lt;/p&gt;
&lt;p&gt;Local port forwarding is mostly used to connect to a remote service on an internal network, such as a database or VNC server.&lt;/p&gt;
&lt;p&gt;In Linux, macOS, and other Unix systems, to create a local port forwarding, pass the &lt;code&gt;-L&lt;/code&gt; option to the &lt;code&gt;ssh&lt;/code&gt; client:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -L &lt;span class="o"&gt;[&lt;/span&gt;LOCAL_IP:&lt;span class="o"&gt;]&lt;/span&gt;LOCAL_PORT:DESTINATION:DESTINATION_PORT &lt;span class="o"&gt;[&lt;/span&gt;USER@&lt;span class="o"&gt;]&lt;/span&gt;SSH_SERVER&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The options used are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[LOCAL_IP:]LOCAL_PORT&lt;/code&gt; - The local machine IP address and port number. When &lt;code&gt;LOCAL_IP&lt;/code&gt; is omitted, the ssh client binds on the localhost.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DESTINATION:DESTINATION_PORT&lt;/code&gt; - The IP or hostname and the port of the destination machine.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[USER@]SSH_SERVER&lt;/code&gt; - The remote SSH user and server IP address.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can use any port number &lt;code&gt;1024&lt;/code&gt; or higher as a &lt;code&gt;LOCAL_PORT&lt;/code&gt;. Port numbers below &lt;code&gt;1024&lt;/code&gt; are privileged ports and can be used only by root. If your SSH server is listening on a &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;port other than 22&lt;/a&gt;
(the default), use the &lt;code&gt;-p [PORT_NUMBER]&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;The destination hostname must be resolvable from the SSH server.&lt;/p&gt;
&lt;p&gt;Say you have a MySQL database server running on machine &lt;code&gt;db001.host&lt;/code&gt; on an internal (private) network, on port 3306, which is accessible from the machine &lt;code&gt;pub001.host&lt;/code&gt;, and you want to connect using your local machine&amp;rsquo;s MySQL client to the database server. To do so, you can forward the connection using the following command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -L 3336:db001.host:3306 user@pub001.host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once you run the command, you will be prompted to enter the remote SSH user password. Once entered, you will be logged into the remote server, and the SSH tunnel will be established. It is also a good idea to &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;set up an SSH key-based authentication&lt;/a&gt;
and connect to the server without entering a password.&lt;/p&gt;
&lt;p&gt;Now, if you point your local machine database client to &lt;code&gt;127.0.0.1:3336&lt;/code&gt;, the connection will be forwarded to the &lt;code&gt;db001.host:3306&lt;/code&gt; MySQL server through the &lt;code&gt;pub001.host&lt;/code&gt; machine that acts as an intermediate server. For a full walkthrough of this setup, including the client commands on Linux, macOS, and Windows, see how to &lt;a href="https://linuxize.com/post/mysql-ssh-tunnel/"&gt;connect to a remote MySQL server over an SSH tunnel&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;You can forward multiple ports to multiple destinations in a single ssh command. For example, if you have another MySQL database server running on machine &lt;code&gt;db002.host&lt;/code&gt; and you want to connect to both servers from your local client, you would run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -L 3336:db001.host:3306 -L 3337:db002.host:3306 user@pub001.host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To connect to the second server, you would use &lt;code&gt;127.0.0.1:3337&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When the destination host is the same as the SSH server, instead of specifying the destination host IP or hostname, you can use &lt;code&gt;localhost&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Say you need to connect to a remote machine through VNC, which runs on the same server, and it is not accessible from the outside. The command you would use is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -L 5901:127.0.0.1:5901 -N -f user@remote.host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-f&lt;/code&gt; option tells the &lt;code&gt;ssh&lt;/code&gt; command to run in the background and &lt;code&gt;-N&lt;/code&gt; not to execute a remote command. We are using &lt;code&gt;127.0.0.1&lt;/code&gt; because the VNC and the SSH server are running on the same host.&lt;/p&gt;
&lt;h2 id="remote-port-forwarding"&gt;Remote Port Forwarding &lt;a class="headline-link" href="#remote-port-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Remote port forwarding is the opposite of local port forwarding. It allows you to forward a port on the remote (SSH server) machine to a port on the local (SSH client) machine, which is then forwarded to a port on the destination machine. This is also called a reverse SSH tunnel, because the traffic travels back toward the client instead of away from it.&lt;/p&gt;
&lt;p&gt;In this forwarding type, the SSH server listens on a given port and tunnels any connection to that port to the specified port on the local SSH client, which then connects to a port on the destination machine. The destination machine can be the local or any other machine.&lt;/p&gt;
&lt;p&gt;In Linux, macOS, and other Unix systems, to create a remote port forwarding, pass the &lt;code&gt;-R&lt;/code&gt; option to the &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;ssh&lt;/code&gt;&lt;/a&gt;
client:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -R &lt;span class="o"&gt;[&lt;/span&gt;REMOTE:&lt;span class="o"&gt;]&lt;/span&gt;REMOTE_PORT:DESTINATION:DESTINATION_PORT &lt;span class="o"&gt;[&lt;/span&gt;USER@&lt;span class="o"&gt;]&lt;/span&gt;SSH_SERVER&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The options used are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[REMOTE:]REMOTE_PORT&lt;/code&gt; - The bind address and port number on the remote SSH server. If &lt;code&gt;REMOTE&lt;/code&gt; is omitted, the listening address is controlled by the SSH server&amp;rsquo;s &lt;code&gt;GatewayPorts&lt;/code&gt; setting. To make the port reachable from other hosts, use an explicit bind address such as &lt;code&gt;0.0.0.0&lt;/code&gt; when the server allows it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DESTINATION:DESTINATION_PORT&lt;/code&gt; - The IP or hostname and the port of the destination machine.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[USER@]SSH_SERVER&lt;/code&gt; - The remote SSH user and server IP address.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remote port forwarding is mostly used to give access to an internal service to someone from the outside.&lt;/p&gt;
&lt;p&gt;Say you are developing a web application on your local machine, and you want to show a preview to your fellow developer. You do not have a public IP, so the other developer cannot access the application via the Internet.&lt;/p&gt;
&lt;p&gt;If you have access to a remote SSH server, you can set up a remote port forwarding as follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -R 8080:127.0.0.1:3000 -N -f user@remote.host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command above will make the ssh server listen on port &lt;code&gt;8080&lt;/code&gt;, and tunnel all traffic from this port to your local machine on port &lt;code&gt;3000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once the port is reachable from the outside, your fellow developer can type &lt;code&gt;the_ssh_server_ip:8080&lt;/code&gt; in their browser and preview your application.&lt;/p&gt;
&lt;p&gt;By default, however, the SSH server binds a remotely forwarded port to its loopback interface only, so nothing outside the server can reach it. That behavior is controlled by the &lt;code&gt;GatewayPorts&lt;/code&gt; directive in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;, which is set to &lt;code&gt;no&lt;/code&gt; unless you change it. Setting it to &lt;code&gt;yes&lt;/code&gt; binds remote forwards on all interfaces, while &lt;code&gt;clientspecified&lt;/code&gt; lets the client choose the bind address itself:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -R 0.0.0.0:8080:127.0.0.1:3000 -N -f user@remote.host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;An explicit bind address such as &lt;code&gt;0.0.0.0&lt;/code&gt; only takes effect when &lt;code&gt;GatewayPorts&lt;/code&gt; is enabled on the server. Without it, the client reports no error and the port quietly stays on loopback. Restart the SSH service after editing the directive, and enable it only for as long as the port needs to be reachable from the outside.&lt;/p&gt;
&lt;h2 id="dynamic-port-forwarding"&gt;Dynamic Port Forwarding &lt;a class="headline-link" href="#dynamic-port-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dynamic port forwarding allows you to create a socket on the local (SSH client) machine, which acts as a SOCKS proxy server. When a client connects to this port, the connection is forwarded to the remote (SSH server) machine, which is then forwarded to a dynamic port on the destination machine.&lt;/p&gt;
&lt;p&gt;This way, all the applications using the SOCKS proxy will connect to the SSH server, and the server will forward all the traffic to its actual destination.&lt;/p&gt;
&lt;p&gt;In Linux, macOS, and other Unix systems, to create a dynamic port forwarding (SOCKS), pass the &lt;code&gt;-D&lt;/code&gt; option to the &lt;code&gt;ssh&lt;/code&gt; client:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -D &lt;span class="o"&gt;[&lt;/span&gt;LOCAL_IP:&lt;span class="o"&gt;]&lt;/span&gt;LOCAL_PORT &lt;span class="o"&gt;[&lt;/span&gt;USER@&lt;span class="o"&gt;]&lt;/span&gt;SSH_SERVER&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The options used are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[LOCAL_IP:]LOCAL_PORT&lt;/code&gt; - The local machine IP address and port number. When &lt;code&gt;LOCAL_IP&lt;/code&gt; is omitted, the SSH client binds on localhost.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[USER@]SSH_SERVER&lt;/code&gt; - The remote SSH user and server IP address.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A typical example of dynamic port forwarding is tunneling web browser traffic through an SSH server.&lt;/p&gt;
&lt;p&gt;The following command will create a SOCKS tunnel on port &lt;code&gt;9090&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -D &lt;span class="m"&gt;9090&lt;/span&gt; -N -f user@remote.host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once the tunneling is established, you can configure your application to use it. &lt;a href="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/"&gt;This article&lt;/a&gt;
explains how to configure Firefox and Google Chrome browser to use the SOCKS proxy.&lt;/p&gt;
&lt;p&gt;The port forwarding has to be separately configured for each application that you want to tunnel the traffic through.&lt;/p&gt;
&lt;h2 id="using-ssh-config-file-for-tunnels"&gt;Using SSH Config File for Tunnels &lt;a class="headline-link" href="#using-ssh-config-file-for-tunnels" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of typing long &lt;code&gt;ssh&lt;/code&gt; commands each time, you can define tunnels in your &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
(&lt;code&gt;~/.ssh/config&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host tunnel-db
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; HostName pub001.host
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; User user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; LocalForward &lt;span class="m"&gt;3336&lt;/span&gt; db001.host:3306
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host tunnel-socks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; HostName remote.host
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; User user
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DynamicForward &lt;span class="m"&gt;9090&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With this configuration, you can start a tunnel by simply running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -N tunnel-db&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="set-up-ssh-tunneling-in-windows"&gt;Set up SSH Tunneling in Windows &lt;a class="headline-link" href="#set-up-ssh-tunneling-in-windows" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Windows 10 and later include a built-in OpenSSH client. You can use the same &lt;code&gt;ssh&lt;/code&gt; commands shown above directly in PowerShell or Command Prompt.&lt;/p&gt;
&lt;p&gt;To verify that OpenSSH is installed, open PowerShell and run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="powershell"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;powershell&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ssh&lt;/span&gt; &lt;span class="n"&gt;-V&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command returns a version number, OpenSSH is available and you can use all the &lt;code&gt;-L&lt;/code&gt;, &lt;code&gt;-R&lt;/code&gt;, and &lt;code&gt;-D&lt;/code&gt; options described in the previous sections.&lt;/p&gt;
&lt;h3 id="using-putty"&gt;Using PuTTY &lt;a class="headline-link" href="#using-putty" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Alternatively, you can use the PuTTY SSH client. You can download PuTTY &lt;a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html" target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;
.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Launch PuTTY and enter the SSH server IP Address in the &lt;code&gt;Host name (or IP address)&lt;/code&gt; field.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/launch-putty_hu_57e3850a3e595f45.webp 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/launch-putty_hu_da639bc271578176.webp 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/launch-putty_hu_bfddb3a79736e8ec.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-tunneling/launch-putty_hu_d7ac6d9960e1de90.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/launch-putty_hu_a532257ecc9b6326.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/launch-putty_hu_d7ac6d9960e1de90.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/launch-putty_hu_cbc7689b1481261b.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Launch Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under the &lt;code&gt;Connection&lt;/code&gt; menu, expand &lt;code&gt;SSH&lt;/code&gt; and select &lt;code&gt;Tunnels&lt;/code&gt;. Check the &lt;code&gt;Local&lt;/code&gt; radio button to set up local, &lt;code&gt;Remote&lt;/code&gt; for remote, and &lt;code&gt;Dynamic&lt;/code&gt; for dynamic port forwarding.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When setting up local forwarding, enter the local forwarding port in the &lt;code&gt;Source Port&lt;/code&gt; field and in &lt;code&gt;Destination&lt;/code&gt; enter the destination host and IP, for example, &lt;code&gt;localhost:5901&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For remote port forwarding, enter the remote SSH server forwarding port in the &lt;code&gt;Source Port&lt;/code&gt; field and in &lt;code&gt;Destination&lt;/code&gt; enter the destination host and IP, for example, &lt;code&gt;localhost:3000&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If setting up dynamic forwarding, enter only the local SOCKS port in the &lt;code&gt;Source Port&lt;/code&gt; field.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/configure-tunnel-putty_hu_cf3c509560850e94.webp 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/configure-tunnel-putty_hu_86cabff9ad42592d.webp 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/configure-tunnel-putty_hu_f58fc0a41c37d6a0.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-tunneling/configure-tunnel-putty_hu_a11d2d302abf86a.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/configure-tunnel-putty_hu_96804e8ca927c7f2.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/configure-tunnel-putty_hu_a11d2d302abf86a.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/configure-tunnel-putty_hu_12ee3fa6926988fd.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Configure Tunnel Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on the &lt;code&gt;Add&lt;/code&gt; button, as shown in the image below.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/add-tunnel-putty_hu_81e62f6d375d6098.webp 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/add-tunnel-putty_hu_a4eebdb01e515414.webp 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/add-tunnel-putty_hu_cad0c363a004508d.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-tunneling/add-tunnel-putty_hu_96050a0a42d20975.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/add-tunnel-putty_hu_be226897b00ee531.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/add-tunnel-putty_hu_96050a0a42d20975.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/add-tunnel-putty_hu_45ad6f2869e81f85.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Add Tunnel Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go back to the &lt;code&gt;Session&lt;/code&gt; page to save the settings so that you do not need to enter them each time. Enter the session name in the &lt;code&gt;Saved Session&lt;/code&gt; field and click on the &lt;code&gt;Save&lt;/code&gt; button.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/save-session-putty_hu_8b987acdab8a9049.webp 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/save-session-putty_hu_8fd13ec001cb44bf.webp 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/save-session-putty_hu_9aeb0b852db65be4.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-tunneling/save-session-putty_hu_13cf5d69e9a37ef9.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/save-session-putty_hu_31c121558bd31d26.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/save-session-putty_hu_13cf5d69e9a37ef9.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/save-session-putty_hu_fa9366204889fbee.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Save Session Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the saved session and log in to the remote server by clicking on the &lt;code&gt;Open&lt;/code&gt; button.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/open-session-putty_hu_63c7d3a17fc9afe3.webp 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/open-session-putty_hu_ea207e0baf8ec003.webp 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/open-session-putty_hu_ef6e1fd3ebb6213d.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-tunneling/open-session-putty_hu_ea39f8204bd36997.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-tunneling/open-session-putty_hu_5f08dfca6e8dd6cb.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-tunneling/open-session-putty_hu_ea39f8204bd36997.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-tunneling/open-session-putty_hu_35984c83e88ffe74.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Open Session Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;A new window asking for your username and password will show up. Once you enter your username and password, you will be logged in to your server, and the SSH tunnel will be started.&lt;/p&gt;
&lt;p&gt;Setting up &lt;a href="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/"&gt;public key authentication&lt;/a&gt;
allows you to connect to your server without entering a password.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="common-ssh-tunneling-options"&gt;Common SSH Tunneling Options &lt;a class="headline-link" href="#common-ssh-tunneling-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here are some useful options you can combine with SSH tunnels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-N&lt;/code&gt; - Do not execute a remote command. Useful when you only want to forward ports.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; - Run SSH in the background after authentication.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-L&lt;/code&gt; - Set up local port forwarding.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-R&lt;/code&gt; - Set up remote port forwarding.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-D&lt;/code&gt; - Set up dynamic port forwarding (SOCKS proxy).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o ExitOnForwardFailure=yes&lt;/code&gt; - Exit if the tunnel cannot be established.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o ServerAliveInterval=60&lt;/code&gt; - Send keep-alives to keep long-lived tunnels up.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; - Specify the SSH server port (if not the default 22).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-J&lt;/code&gt; - Use a jump host (ProxyJump) to reach a server through an intermediate host. For example: &lt;code&gt;ssh -J jump.host user@destination.host&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;channel 2: open failed: connect failed: Connection refused&lt;/strong&gt;&lt;br&gt;
The tunnel is up, but SSH could not reach the destination host and port. With local forwarding (&lt;code&gt;-L&lt;/code&gt;), the SSH server connects to the destination, so test the service from that server. With remote forwarding (&lt;code&gt;-R&lt;/code&gt;), the SSH client connects to the destination, so test it from your local machine. Confirm that the service is running and listening on the address you specified. The &lt;a href="https://linuxize.com/post/fix-ssh-connection-refused/"&gt;SSH connection refused error&lt;/a&gt;
guide covers the same failure when it happens on the SSH port itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;bind: Address already in use&lt;/strong&gt;&lt;br&gt;
Another process is already listening on the local port you picked. Check what holds it with &lt;code&gt;ss -tlnp 'sport = :8080'&lt;/code&gt;, then stop that process or choose a different local port.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning: remote port forwarding failed for listen port 8080&lt;/strong&gt;&lt;br&gt;
The SSH server refused to bind the requested port. The port may already be in use on the server, or it may be a privileged port below &lt;code&gt;1024&lt;/code&gt; that your remote user cannot bind. Pick a higher port, or check for a stale tunnel left behind by an earlier session.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;channel 1: open failed: administratively prohibited: open failed&lt;/strong&gt;&lt;br&gt;
The SSH server rejected the forwarding request. Check &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; for &lt;code&gt;AllowTcpForwarding&lt;/code&gt;, &lt;code&gt;DisableForwarding&lt;/code&gt;, &lt;code&gt;PermitOpen&lt;/code&gt;, and &lt;code&gt;PermitListen&lt;/code&gt; restrictions. Also check whether the key entry in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; uses &lt;code&gt;restrict&lt;/code&gt; or &lt;code&gt;no-port-forwarding&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The tunnel drops after a period of inactivity&lt;/strong&gt;&lt;br&gt;
Add &lt;code&gt;-o ServerAliveInterval=60 -o ServerAliveCountMax=3&lt;/code&gt; so the client disconnects after three unanswered keep-alives. Use &lt;code&gt;-o ExitOnForwardFailure=yes&lt;/code&gt; separately so SSH exits when it cannot create a requested forwarding at startup. For tunnels that must survive network drops, use &lt;code&gt;autossh&lt;/code&gt; to restart them automatically.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between local and remote port forwarding?&lt;/strong&gt;&lt;br&gt;
Local forwarding listens on your local machine and forwards traffic to a remote destination. Remote forwarding listens on the remote server and forwards traffic back to your local machine or another host.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I forward UDP traffic through an SSH tunnel?&lt;/strong&gt;&lt;br&gt;
No, SSH tunnels only support TCP traffic. For UDP forwarding, you would need tools like &lt;code&gt;socat&lt;/code&gt; or a VPN solution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I close a background SSH tunnel?&lt;/strong&gt;&lt;br&gt;
Find the process with &lt;code&gt;ps aux | grep &amp;quot;ssh -&amp;quot;&lt;/code&gt; and terminate it with &lt;code&gt;kill &amp;lt;PID&amp;gt;&lt;/code&gt;. You can also match the forwarding rule directly, for example &lt;code&gt;pkill -f &amp;quot;ssh -L 3336&amp;quot;&lt;/code&gt;. A tunnel running in the foreground closes with &lt;code&gt;Ctrl+C&lt;/code&gt; in the terminal where it was started.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is SSH tunneling secure?&lt;/strong&gt;&lt;br&gt;
Yes, all traffic through the tunnel is encrypted by the SSH connection. However, the traffic between the SSH server and the final destination is not encrypted by the tunnel itself.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For ease of use, define your tunnels in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
so you can start any tunnel with &lt;code&gt;ssh -N tunnel-name&lt;/code&gt; instead of typing the full command each time.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-setup-ssh-tunneling/featured_hu_c1db61ad4b373065.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>SSH SOCKS Proxy: Create a SOCKS5 Tunnel for Browsing</title><link>https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/</link><pubDate>Mon, 29 Oct 2018 20:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/</guid><category>ssh</category><category>security</category><description>Create an SSH SOCKS proxy with a SOCKS5 tunnel, configure Firefox or Chrome to use it, proxy DNS requests, and verify the browser exits through your SSH server.</description><content:encoded>&lt;p&gt;There are times when you want to route browser traffic through a remote server, access content from another network, or bypass an intermediate firewall.&lt;/p&gt;
&lt;p&gt;One option is to use a VPN, but that requires installing client software on your machine and &lt;a href="https://linuxize.com/post/how-to-set-up-an-openvpn-server-on-ubuntu-18-04/"&gt;setting up your own VPN server&lt;/a&gt;
or subscribing to a VPN service.&lt;/p&gt;
&lt;p&gt;The simpler alternative is to route your local browser traffic through an encrypted SSH SOCKS proxy. Applications configured to use the proxy connect to the SSH server first, and the server forwards the traffic to the final destination.&lt;/p&gt;
&lt;p&gt;An SSH SOCKS proxy changes the exit IP address and encrypts traffic between your computer and the SSH server. It does not make browsing anonymous, and DNS requests can still leak unless your browser is configured to proxy DNS through the tunnel.&lt;/p&gt;
&lt;p&gt;This tutorial walks you through the process of creating an encrypted SSH tunnel and configuring Firefox and &lt;a href="https://linuxize.com/post/how-to-install-google-chrome-web-browser-on-ubuntu-26-04/"&gt;Google Chrome&lt;/a&gt;
web browsers to use a SOCKS proxy.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create SOCKS tunnel&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -N -D 127.0.0.1:9090 user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run tunnel in background&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -fN -D 127.0.0.1:9090 user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use custom SSH port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -N -D 127.0.0.1:9090 -p 2222 user@server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check local listener&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ss -ltnp | grep 9090&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test through tunnel&lt;/td&gt;
&lt;td&gt;&lt;code&gt;curl --socks5-hostname 127.0.0.1:9090 https://ifconfig.me&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Server running any flavor of Linux, with SSH access to route your traffic through it.&lt;/li&gt;
&lt;li&gt;Web browser.&lt;/li&gt;
&lt;li&gt;SSH client.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="set-up-the-ssh-tunnel"&gt;Set Up the SSH Tunnel &lt;a class="headline-link" href="#set-up-the-ssh-tunnel" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We will create an &lt;a href="https://linuxize.com/post/how-to-setup-ssh-tunneling/"&gt;SSH tunnel&lt;/a&gt;
that opens a local SOCKS proxy on &lt;code&gt;127.0.0.1:9090&lt;/code&gt; and forwards traffic through the SSH server. You can use any local port number greater than &lt;code&gt;1024&lt;/code&gt;; only root can open privileged ports.&lt;/p&gt;
&lt;h3 id="linux-and-macos"&gt;Linux and macOS &lt;a class="headline-link" href="#linux-and-macos" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you run Linux, macOS or any other Unix-based operating system on your local machine, you can easily start an SSH tunnel with the following &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;&lt;code&gt;ssh&lt;/code&gt;&lt;/a&gt;
command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -N -D 127.0.0.1:9090 user@server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The options used are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-N&lt;/code&gt; - Tells SSH not to execute a remote command.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-D 127.0.0.1:9090&lt;/code&gt; - Opens a SOCKS tunnel bound to localhost on port &lt;code&gt;9090&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;user@server&lt;/code&gt; - Your remote SSH user and server IP address or hostname.&lt;/li&gt;
&lt;li&gt;To run the command in the background, use &lt;code&gt;ssh -fN -D 127.0.0.1:9090 user@server&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If your SSH server is listening on a &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;port other than 22&lt;/a&gt;
, add &lt;code&gt;-p PORT_NUMBER&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Binding the SOCKS listener to &lt;code&gt;127.0.0.1&lt;/code&gt; keeps it available only on your local machine. Once you run the command, you will be prompted to enter your user password. After entering it, the SSH tunnel will be established.&lt;/p&gt;
&lt;p&gt;You can &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;set up an SSH key-based authentication&lt;/a&gt;
and connect to your server without entering a password.&lt;/p&gt;
&lt;h3 id="windows"&gt;Windows &lt;a class="headline-link" href="#windows" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Windows users can create an SSH tunnel using the PuTTY SSH client. You can download PuTTY &lt;a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html" target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;
.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Launch Putty and enter your server IP Address in the &lt;code&gt;Host name (or IP address)&lt;/code&gt; field.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/launch-putty_hu_57e3850a3e595f45.webp 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/launch-putty_hu_da639bc271578176.webp 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/launch-putty_hu_bfddb3a79736e8ec.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/launch-putty_hu_d7ac6d9960e1de90.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/launch-putty_hu_a532257ecc9b6326.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/launch-putty_hu_d7ac6d9960e1de90.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/launch-putty_hu_cbc7689b1481261b.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Launch Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under the &lt;code&gt;Connection&lt;/code&gt; menu, expand &lt;code&gt;SSH&lt;/code&gt; and select &lt;code&gt;Tunnels&lt;/code&gt;. Enter the port &lt;code&gt;9090&lt;/code&gt; in the &lt;code&gt;Source Port&lt;/code&gt; field, and check the &lt;code&gt;Dynamic&lt;/code&gt; radio button.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/configure-tunnel-putty_hu_cf3c509560850e94.webp 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/configure-tunnel-putty_hu_86cabff9ad42592d.webp 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/configure-tunnel-putty_hu_f58fc0a41c37d6a0.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/configure-tunnel-putty_hu_a11d2d302abf86a.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/configure-tunnel-putty_hu_96804e8ca927c7f2.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/configure-tunnel-putty_hu_a11d2d302abf86a.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/configure-tunnel-putty_hu_12ee3fa6926988fd.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Configure Tunnel Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on the &lt;code&gt;Add&lt;/code&gt; button as shown in the image below.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/add-tunnel-putty_hu_81e62f6d375d6098.webp 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/add-tunnel-putty_hu_a4eebdb01e515414.webp 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/add-tunnel-putty_hu_cad0c363a004508d.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/add-tunnel-putty_hu_96050a0a42d20975.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/add-tunnel-putty_hu_be226897b00ee531.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/add-tunnel-putty_hu_96050a0a42d20975.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/add-tunnel-putty_hu_45ad6f2869e81f85.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Add Tunnel Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go back to the &lt;code&gt;Session&lt;/code&gt; page to save the settings so that you do not need to enter them each time. Enter the session name in the &lt;code&gt;Saved Session&lt;/code&gt; field and click on the &lt;code&gt;Save&lt;/code&gt; button.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/save-session-putty_hu_8b987acdab8a9049.webp 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/save-session-putty_hu_8fd13ec001cb44bf.webp 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/save-session-putty_hu_9aeb0b852db65be4.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/save-session-putty_hu_13cf5d69e9a37ef9.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/save-session-putty_hu_31c121558bd31d26.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/save-session-putty_hu_13cf5d69e9a37ef9.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/save-session-putty_hu_fa9366204889fbee.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Save Session Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the saved session and log in to the remote server by clicking on the &lt;code&gt;Open&lt;/code&gt; button.&lt;/p&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 750 / 500"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/open-session-putty_hu_63c7d3a17fc9afe3.webp 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/open-session-putty_hu_ea207e0baf8ec003.webp 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/open-session-putty_hu_ef6e1fd3ebb6213d.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/open-session-putty_hu_ea39f8204bd36997.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/open-session-putty_hu_5f08dfca6e8dd6cb.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/open-session-putty_hu_ea39f8204bd36997.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/open-session-putty_hu_35984c83e88ffe74.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="512"
alt="Open Session Putty"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;A new window asking for your username and password will show up. Once you enter your username and password you will be logged in to your server and the SSH tunnel will be started.&lt;/p&gt;
&lt;p&gt;Setting up &lt;a href="https://linuxize.com/post/generate-ssh-keys-on-windows-with-puttygen/"&gt;public key authentication&lt;/a&gt;
will allow you to connect to your server without entering a password.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="configuring-your-browser-to-use-proxy"&gt;Configuring Your Browser to Use Proxy &lt;a class="headline-link" href="#configuring-your-browser-to-use-proxy" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you have opened the SSH SOCKS tunnel, the last step is to configure your preferred browser to use it.&lt;/p&gt;
&lt;h3 id="firefox"&gt;Firefox &lt;a class="headline-link" href="#firefox" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The steps below are the same for Windows, macOS, and Linux.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;In the upper right-hand corner, click on the hamburger icon &lt;code&gt;☰&lt;/code&gt; to open Firefox&amp;rsquo;s menu:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on the &lt;code&gt;⚙ Settings&lt;/code&gt; link.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scroll down to the &lt;code&gt;Network Settings&lt;/code&gt; section and click on the &lt;code&gt;Settings...&lt;/code&gt; button.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A new window will open.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Select the &lt;code&gt;Manual proxy configuration&lt;/code&gt; radio button.&lt;/li&gt;
&lt;li&gt;Enter &lt;code&gt;127.0.0.1&lt;/code&gt; in the &lt;code&gt;SOCKS Host&lt;/code&gt; field and &lt;code&gt;9090&lt;/code&gt; in the &lt;code&gt;Port&lt;/code&gt; field.&lt;/li&gt;
&lt;li&gt;Check the &lt;code&gt;Proxy DNS when using SOCKS v5&lt;/code&gt; checkbox.&lt;/li&gt;
&lt;li&gt;Click on the &lt;code&gt;OK&lt;/code&gt; button to save the settings.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class='relative w-full'&gt;&lt;div class="relative block w-full mx-auto my-0"&gt;&lt;div class="block" style="aspect-ratio: 842 / 887"&gt;&lt;/div&gt;
&lt;div class="bg-gray-100 absolute inset-0 w-full h-full m-auto overflow-hidden "&gt;&lt;picture class="absolute inset-0 w-full h-full m-auto"&gt;
&lt;source
type="image/webp"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/firefox-ssh-proxy_hu_87d713651454da15.webp 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/firefox-ssh-proxy_hu_8604a3bc412a15c0.webp 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/firefox-ssh-proxy_hu_3003557412c3e23c.webp 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"&gt;
&lt;img class="absolute inset-0 w-full h-full m-auto object-cover " loading="lazy"
decoding="async"
src="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/firefox-ssh-proxy_hu_37d2afda9283765b.jpg"
srcset="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/firefox-ssh-proxy_hu_4da830f6464acef4.jpg 480w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/firefox-ssh-proxy_hu_37d2afda9283765b.jpg 768w, https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/firefox-ssh-proxy_hu_8762819b7750aab0.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1200px"
width="768"
height="809"
alt="Firefox SSH Proxy"&gt;
&lt;/picture&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, Firefox is configured and you can browse through the SSH tunnel. To verify, open a search engine and search for &amp;ldquo;what is my ip&amp;rdquo;. The displayed IP address should be the IP address of your SSH server.&lt;/p&gt;
&lt;p&gt;To revert back to the default settings go to &lt;code&gt;Network Settings&lt;/code&gt;, select the &lt;code&gt;Use system proxy settings&lt;/code&gt; radio button and save the settings.&lt;/p&gt;
&lt;p&gt;There are also several plugins that can help you to configure Firefox&amp;rsquo;s proxy settings such as &lt;a href="https://addons.mozilla.org/firefox/addon/foxyproxy-standard/" target="_blank" rel="noopener noreferrer"&gt;FoxyProxy&lt;/a&gt;
.&lt;/p&gt;
&lt;h3 id="google-chrome"&gt;Google Chrome &lt;a class="headline-link" href="#google-chrome" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Google Chrome uses the default system proxy settings. Instead of changing your operating system proxy settings, you can start Chrome from the command line with a separate profile.&lt;/p&gt;
&lt;p&gt;To launch Chrome using a new profile and your SSH tunnel use the following command:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linux :&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/usr/bin/google-chrome &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --user-data-dir&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/proxy-profile&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --proxy-server&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;socks5://127.0.0.1:9090&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;macOS :&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;/Applications/Google Chrome.app/Contents/MacOS/Google Chrome&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --user-data-dir&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/proxy-profile&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --proxy-server&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;socks5://127.0.0.1:9090&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Windows :&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;C:\Program Files (x86)\Google\Chrome\Application\chrome.exe&amp;#34;&lt;/span&gt; ^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --user-data-dir&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;%USERPROFILE%\proxy-profile&amp;#34;&lt;/span&gt; ^
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --proxy-server&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;socks5://127.0.0.1:9090&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The profile will be created automatically if it does not exist. This way you can run multiple instances of Chrome at the same time.&lt;/p&gt;
&lt;p&gt;To confirm the SSH tunnel is working properly, search for &amp;ldquo;what is my ip&amp;rdquo;. The IP shown in your browser should be the IP address of your SSH server.&lt;/p&gt;
&lt;h2 id="verifying-the-socks-proxy"&gt;Verifying the SOCKS Proxy &lt;a class="headline-link" href="#verifying-the-socks-proxy" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can verify the local SOCKS listener from the terminal:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -ltnp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;9090&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To test the tunnel without changing browser settings, send a request through the SOCKS proxy:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl --socks5-hostname 127.0.0.1:9090 https://ifconfig.me&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should show the public IP address of your SSH server. The &lt;code&gt;--socks5-hostname&lt;/code&gt; option sends DNS lookups through the SOCKS proxy, which helps avoid local DNS leaks.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;bind: Address already in use&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Another process is already using port &lt;code&gt;9090&lt;/code&gt;. Pick a different local port, such as &lt;code&gt;1080&lt;/code&gt;, and update the browser proxy settings to match.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Permission denied (publickey)&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The SSH server did not accept your key. Check that your public key is installed on the server, or connect with the correct username and key file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The browser still shows your local IP&lt;/strong&gt;&lt;br&gt;
Confirm the tunnel is running with &lt;code&gt;ss -ltnp | grep 9090&lt;/code&gt;, then check that the browser is using &lt;code&gt;127.0.0.1&lt;/code&gt; as the SOCKS host and &lt;code&gt;9090&lt;/code&gt; as the port.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DNS still resolves locally&lt;/strong&gt;&lt;br&gt;
In Firefox, make sure &lt;code&gt;Proxy DNS when using SOCKS v5&lt;/code&gt; is enabled. For command-line tests, use &lt;code&gt;curl --socks5-hostname&lt;/code&gt; instead of &lt;code&gt;curl --socks5&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The tunnel closes when the terminal closes&lt;/strong&gt;&lt;br&gt;
Run the SSH command with &lt;code&gt;-fN&lt;/code&gt;, define the tunnel in your SSH config, or start it inside &lt;a href="https://linuxize.com/post/getting-started-with-tmux/"&gt;&lt;code&gt;tmux&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/how-to-use-linux-screen/"&gt;&lt;code&gt;screen&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For easier reuse, define the tunnel in your &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
or wrap it in a &lt;a href="https://linuxize.com/post/how-to-create-bash-aliases/"&gt;Bash alias&lt;/a&gt;
that starts the tunnel and browser together.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-setup-ssh-socks-tunnel-for-private-browsing/featured_hu_1a11ea43a98c8855.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>scp Command in Linux: Secure File Transfer Examples</title><link>https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/</link><pubDate>Wed, 19 Sep 2018 00:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/</guid><category>ssh</category><category>linux commands</category><description>SCP copies files securely between local and remote hosts over SSH. This guide covers syntax, common options, and practical examples for everyday file transfers.</description><content:encoded>&lt;p&gt;When you need to copy files to or from a remote server over SSH, &lt;code&gt;scp&lt;/code&gt; does the job with a single command. It encrypts both the transferred data and the authentication credentials, so nothing extra is needed if SSH access is already in place.&lt;/p&gt;
&lt;p&gt;This guide explains how to use the &lt;code&gt;scp&lt;/code&gt; command with practical examples and detailed explanations of the most common options.&lt;/p&gt;
&lt;h2 id="before-you-begin"&gt;Before You Begin &lt;a class="headline-link" href="#before-you-begin" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before using &lt;code&gt;scp&lt;/code&gt;, keep the following in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SCP relies on SSH for data transfer. You need either an SSH key or a password to authenticate on the remote system.&lt;/li&gt;
&lt;li&gt;The colon (&lt;code&gt;:&lt;/code&gt;) is how &lt;code&gt;scp&lt;/code&gt; distinguishes between local and remote paths. A path without a colon is treated as local.&lt;/li&gt;
&lt;li&gt;You must have read permission on the source and write permission on the destination.&lt;/li&gt;
&lt;li&gt;SCP overwrites files without warning when the source and destination share the same name.&lt;/li&gt;
&lt;li&gt;When transferring large files, run the &lt;code&gt;scp&lt;/code&gt; command inside a &lt;a href="https://linuxize.com/post/how-to-use-linux-screen/"&gt;&lt;code&gt;screen&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/getting-started-with-tmux/"&gt;&lt;code&gt;tmux&lt;/code&gt;&lt;/a&gt;
session to keep the transfer running if your terminal disconnects.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="scp-command-syntax"&gt;SCP Command Syntax &lt;a class="headline-link" href="#scp-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax of the &lt;code&gt;scp&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp [OPTIONS] [[user@]host:]source [[user@]host:]destination&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[[user@]host:]source&lt;/code&gt; — Source path. Include the username and hostname (or IP address) when the file is on a remote machine.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[[user@]host:]destination&lt;/code&gt; — Destination path. Same format as the source.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Local paths can be absolute or relative. Remote paths must include the host and colon.&lt;/p&gt;
&lt;p&gt;The most commonly used &lt;code&gt;scp&lt;/code&gt; options are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-P&lt;/code&gt; — Remote host SSH port (uppercase P)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; — Preserve modification time, access time, and mode&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; — Copy directories recursively&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt; — Compress data during transfer&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-q&lt;/code&gt; — Suppress the progress meter and non-error messages&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; — Path to the SSH private key (identity file)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; — Limit bandwidth in Kbit/s&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o&lt;/code&gt; — Pass an SSH option (e.g., &lt;code&gt;-o StrictHostKeyChecking=no&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-3&lt;/code&gt; — Route traffic between two remote hosts through the local machine&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-O&lt;/code&gt; — Force the legacy SCP protocol instead of SFTP&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="copy-a-local-file-to-a-remote-system"&gt;Copy a Local File to a Remote System &lt;a class="headline-link" href="#copy-a-local-file-to-a-remote-system" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To copy a file from the local machine to a remote server, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp file.txt remote_username@10.10.0.2:/remote/directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this example, &lt;code&gt;file.txt&lt;/code&gt; is the local file, &lt;code&gt;remote_username&lt;/code&gt; is the user on the remote server, and &lt;code&gt;10.10.0.2&lt;/code&gt; is the server IP address. The file is copied to &lt;code&gt;/remote/directory&lt;/code&gt; on the remote host. If you omit the remote directory, the file is copied to the remote user&amp;rsquo;s home directory.&lt;/p&gt;
&lt;p&gt;You will be prompted to enter the user password, and the transfer process will start:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote_username@10.10.0.2&amp;#39;s password:
file.txt 100% 14KB 82.1KB/s 00:00&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To save the file under a different name on the remote host, specify the new filename in the destination path:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp file.txt remote_username@10.10.0.2:/remote/directory/newfilename.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If SSH on the remote host is listening on a port other than the default 22, use the &lt;code&gt;-P&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -P &lt;span class="m"&gt;2322&lt;/span&gt; file.txt remote_username@10.10.0.2:/remote/directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To copy a directory and all its contents, use the &lt;code&gt;-r&lt;/code&gt; flag for recursive copy:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -r /local/directory remote_username@10.10.0.2:/remote/directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you want to copy multiple local files that match a pattern, let the local shell expand the wildcard before &lt;code&gt;scp&lt;/code&gt; runs. In the following example, all &lt;code&gt;.txt&lt;/code&gt; files from the local &lt;code&gt;Projects&lt;/code&gt; directory are copied to the remote &lt;code&gt;Projects&lt;/code&gt; directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;/Projects/*.txt remote_username@10.10.0.2:/home/user/Projects/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To preserve file metadata (modification time, access time, and mode), use the &lt;code&gt;-p&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -p file.txt remote_username@10.10.0.2:/remote/directory/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To use a specific SSH key for authentication, pass it with the &lt;code&gt;-i&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -i ~/.ssh/id_ed25519 file.txt remote_username@10.10.0.2:/remote/directory/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="copy-a-remote-file-to-the-local-system"&gt;Copy a Remote File to the Local System &lt;a class="headline-link" href="#copy-a-remote-file-to-the-local-system" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To copy a file from a remote server to the local machine, use the remote location as the source and the local path as the destination:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp remote_username@10.10.0.2:/remote/file.txt /local/directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you have not set up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;passwordless SSH login&lt;/a&gt;
, you will be prompted to enter the user password.&lt;/p&gt;
&lt;p&gt;To copy an entire remote directory, add the &lt;code&gt;-r&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -r remote_username@10.10.0.2:/remote/directory /local/directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="copy-files-between-two-remote-systems"&gt;Copy Files Between Two Remote Systems &lt;a class="headline-link" href="#copy-files-between-two-remote-systems" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With &lt;code&gt;scp&lt;/code&gt;, you do not need to log in to either server to transfer files between two remote machines. The following command copies &lt;code&gt;/files/file.txt&lt;/code&gt; from &lt;code&gt;host1.com&lt;/code&gt; to the &lt;code&gt;/files&lt;/code&gt; directory on &lt;code&gt;host2.com&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp user1@host1.com:/files/file.txt user2@host2.com:/files&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the passwords for both remote accounts. By default, the data flows directly between the two remote hosts.&lt;/p&gt;
&lt;p&gt;To route the traffic through the local machine instead, use the &lt;code&gt;-3&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp -3 user1@host1.com:/files/file.txt user2@host2.com:/files&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="using-an-ssh-config-file"&gt;Using an SSH Config File &lt;a class="headline-link" href="#using-an-ssh-config-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you regularly connect to the same hosts, defining them in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
simplifies your &lt;code&gt;scp&lt;/code&gt; commands. Create or edit the file at &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ssh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;ssh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-ssh" data-lang="ssh"&gt;Host myserver
HostName 10.10.0.2
User leah
Port 2222
IdentityFile ~/.ssh/id_ed25519&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this configuration, you can use the alias instead of the full connection details:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp file.txt myserver:/remote/directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Setting up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
removes the password prompt entirely, making transfers faster and easier to script.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Permission denied (publickey)&lt;/strong&gt;&lt;br&gt;
The remote server does not accept your SSH key. Verify that the correct key is offered with &lt;code&gt;-i&lt;/code&gt;, or check that the public key is in the remote user&amp;rsquo;s &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connection refused&lt;/strong&gt;&lt;br&gt;
The SSH daemon is not running or is listening on a different port. Confirm the port with &lt;code&gt;-P&lt;/code&gt; and ensure the firewall allows SSH traffic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Not a regular file&lt;/strong&gt;&lt;br&gt;
You are trying to copy a directory without the &lt;code&gt;-r&lt;/code&gt; flag. Add &lt;code&gt;-r&lt;/code&gt; to copy directories recursively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Host key verification failed&lt;/strong&gt;&lt;br&gt;
The remote host key does not match the entry in &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt;. If the server was reinstalled, remove the old key with &lt;code&gt;ssh-keygen -R hostname&lt;/code&gt; and try again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transfer is slow&lt;/strong&gt;&lt;br&gt;
Enable compression with &lt;code&gt;-C&lt;/code&gt; to speed up transfers over slow connections. You can also limit bandwidth with &lt;code&gt;-l&lt;/code&gt; to avoid saturating the link on shared networks.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/scp/"&gt;scp cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp file.txt user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy local file to remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp user@host:/path/file.txt .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy remote file to local&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -r dir/ user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy directory recursively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -P 2222 file.txt user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use custom SSH port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -i ~/.ssh/key file.txt user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use specific SSH key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -p file.txt user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Preserve timestamps and mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -C file.txt user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compress during transfer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -l 5000 file.txt user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Limit bandwidth to 5000 Kbit/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -3 user1@host1:/f user2@host2:/f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy between two remotes via local&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scp -O file.txt user@host:/path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Force legacy SCP protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does scp overwrite existing files?&lt;/strong&gt;&lt;br&gt;
Yes. SCP overwrites destination files without prompting. There is no built-in confirmation flag, so verify the destination path before running the command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between scp and sftp?&lt;/strong&gt;&lt;br&gt;
Both use SSH for encryption. SFTP is an interactive file transfer protocol that supports resuming transfers, directory listings, and file removal. SCP is a simpler one-shot copy command. Modern OpenSSH versions run the SFTP protocol internally when you use &lt;code&gt;scp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is scp still recommended?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;scp&lt;/code&gt; command is still widely available and works the same way from the user&amp;rsquo;s perspective. Starting with OpenSSH 9.0, it uses the SFTP protocol internally rather than the legacy SCP/RCP protocol. For new scripts or automation, &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;&lt;code&gt;sftp&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/"&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/a&gt;
may be a better long-term choice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I resume an interrupted scp transfer?&lt;/strong&gt;&lt;br&gt;
No. SCP does not support resuming partial transfers. If the connection drops, you must start the transfer over. For resumable transfers, use &lt;a href="https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/"&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/a&gt;
with the &lt;code&gt;--partial&lt;/code&gt; flag.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I copy files without a password prompt?&lt;/strong&gt;&lt;br&gt;
Set up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
between the local and remote machines. Once the public key is installed on the remote host, SCP authenticates automatically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does the -O flag do?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;-O&lt;/code&gt; flag forces &lt;code&gt;scp&lt;/code&gt; to use the legacy SCP/RCP protocol instead of the SFTP protocol. This is sometimes needed when connecting to very old servers that do not support SFTP.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SCP is a straightforward tool for copying files between local and remote systems over SSH. While modern OpenSSH versions now use the SFTP protocol internally, the &lt;code&gt;scp&lt;/code&gt; command remains widely available and works the same way from the user&amp;rsquo;s perspective.&lt;/p&gt;
&lt;p&gt;For advanced workflows, use &lt;a href="https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/"&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/a&gt;
for resumable transfers and large directory trees, or follow the &lt;a href="https://linuxize.com/post/rsync-incremental-backups-with-link-dest/"&gt;&lt;code&gt;--link-dest&lt;/code&gt; backup guide&lt;/a&gt;
to create dated incremental snapshots. For interactive file management over SSH, use &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;&lt;code&gt;sftp&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/featured_hu_1972292bad1df554.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>sftp Command in Linux: Transfer Files Securely</title><link>https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/</link><pubDate>Sat, 17 Nov 2018 20:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/</guid><category>ssh</category><category>linux commands</category><description>The sftp command transfers files securely over SSH. Connect to servers, upload and download files, resume transfers, and automate batch jobs.</description><content:encoded>&lt;p&gt;When you need to move files to or from a remote server over SSH, SFTP (SSH File Transfer Protocol) gives you an interactive file transfer shell. You can browse remote directories, upload and download files, resume interrupted transfers, and manage files without opening a full SSH shell.&lt;/p&gt;
&lt;p&gt;Compared to &lt;a href="https://linuxize.com/post/how-to-use-linux-ftp-command-to-transfer-files/"&gt;FTP&lt;/a&gt;
, SFTP provides the same core functionality while being significantly more secure and easier to configure.&lt;/p&gt;
&lt;p&gt;Unlike &lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;SCP&lt;/a&gt;
, which supports only file transfers, SFTP supports a full range of file operations on remote files, including resuming interrupted transfers.&lt;/p&gt;
&lt;p&gt;This guide shows you how to use the &lt;code&gt;sftp&lt;/code&gt; command on Linux with practical examples for everyday file transfers.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To upload or modify files via SFTP, you need write permission on the remote system.&lt;/p&gt;
&lt;p&gt;For large transfers, it is recommended to run the &lt;code&gt;sftp&lt;/code&gt; command inside a &lt;a href="https://linuxize.com/post/how-to-use-linux-screen/"&gt;&lt;code&gt;screen&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/getting-started-with-tmux/"&gt;&lt;code&gt;tmux&lt;/code&gt;&lt;/a&gt;
session to prevent interruptions.&lt;/p&gt;
&lt;p&gt;The directory from which you run the &lt;code&gt;sftp&lt;/code&gt; command becomes your local working directory.&lt;/p&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Do not confuse SFTP with FTPS. Both protocols serve the same purpose. However, FTPS stands for FTP Secure, and it is an extension to the standard FTP protocol that adds TLS/SSL encryption.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="sftp-command-syntax"&gt;SFTP Command Syntax &lt;a class="headline-link" href="#sftp-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The basic syntax of the &lt;code&gt;sftp&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp [OPTIONS] [user@]host[:path]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also use an SFTP URI:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp://[user@]host[:port][/path]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;user&lt;/code&gt; value is the remote username, and &lt;code&gt;host&lt;/code&gt; is the server hostname or IP address. If you add a path after the host, SFTP opens that remote directory after login. When the path points to a file and non-interactive authentication is available, SFTP can retrieve the file directly.&lt;/p&gt;
&lt;h2 id="connecting-to-a-remote-server"&gt;Connecting to a Remote Server &lt;a class="headline-link" href="#connecting-to-a-remote-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SFTP works on a client-server model. It is a subsystem of SSH and supports all SSH authentication methods.&lt;/p&gt;
&lt;p&gt;To connect to a remote system, run the &lt;code&gt;sftp&lt;/code&gt; command followed by the remote server username and the IP address or domain name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp remote_username@server_ip_or_hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are connecting to the host using password authentication, you will be prompted to enter the user password.&lt;/p&gt;
&lt;p&gt;Once authenticated, you will be presented with the &lt;code&gt;sftp&lt;/code&gt; prompt, and you can start interacting with the remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Connected to remote_username@server_ip_or_hostname.
sftp&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the remote SSH server listens on a non-standard &lt;a href="https://linuxize.com/post/sftp-port/"&gt;port&lt;/a&gt;
(for example, 2222), use the &lt;code&gt;-P&lt;/code&gt; option to specify the port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp -P &lt;span class="m"&gt;2222&lt;/span&gt; remote_username@server_ip_or_hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="common-sftp-options"&gt;Common SFTP Options &lt;a class="headline-link" href="#common-sftp-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;sftp&lt;/code&gt; command accepts several options that modify its behavior. Here are the most commonly used ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-P port&lt;/code&gt; - Specifies the port to connect to on the remote host.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i identity_file&lt;/code&gt; - Selects the private key file for public key authentication.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o ssh_option&lt;/code&gt; - Passes options to SSH in the format used in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt; - Enables compression, which can speed up transfers over slow connections.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt; - Prints debugging messages about the connection and authentication process.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-b batchfile&lt;/code&gt; - Reads SFTP commands from a file instead of the terminal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; - Preserves modification times, access times, and file modes during transfers.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; - Recursively copies entire directories when uploading and downloading. SFTP does not follow symbolic links during the traversal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt; - Attempts to continue interrupted transfers instead of overwriting existing partial copies. Use it only when the existing partial contents match the source, or the resulting file may be corrupt.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l limit&lt;/code&gt; - Limits bandwidth in Kbit/s.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-J destination&lt;/code&gt; - Connects through a jump host.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, to connect with verbose output and compression enabled:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp -v -C remote_username@server_ip_or_hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="basic-sftp-commands"&gt;Basic SFTP Commands &lt;a class="headline-link" href="#basic-sftp-commands" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most SFTP commands are similar or identical to the Linux shell commands.&lt;/p&gt;
&lt;p&gt;To get a list of all available SFTP commands, type &lt;code&gt;help&lt;/code&gt;, or &lt;code&gt;?&lt;/code&gt;.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;help&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output will include a long list of all available commands, including a short description of each command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Available commands:
bye Quit sftp
cd path Change remote directory to &amp;#39;path&amp;#39;
...
...
version Show SFTP version
!command Execute &amp;#39;command&amp;#39; in local shell
! Escape to local shell
? Synonym for help&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="navigating-directories-with-sftp"&gt;Navigating Directories with SFTP &lt;a class="headline-link" href="#navigating-directories-with-sftp" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you are logged in to the remote server, your &lt;a href="https://linuxize.com/post/current-working-directory/"&gt;current working directory&lt;/a&gt;
is the remote user&amp;rsquo;s home directory. You can check that by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Remote working directory: /home/remote_username&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To list the remote files and directories, use the &lt;code&gt;ls&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To navigate to another directory, use the &lt;code&gt;cd&lt;/code&gt; command. For example, to switch to the &lt;code&gt;/tmp&lt;/code&gt; directory, you would type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The above commands are used to navigate and work on the remote location.&lt;/p&gt;
&lt;p&gt;The SFTP shell also provides commands for local navigation, information, and file management. The local commands are prefixed with the letter &lt;code&gt;l&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, to print the local working directory, you would type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lpwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Local working directory: /home/local_username&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To list local files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lls&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;lcd&lt;/code&gt; command changes the local working directory, which is where downloaded files are written. If you want everything you fetch to land in &lt;code&gt;~/Downloads&lt;/code&gt;, switch to it before running &lt;code&gt;get&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lcd ~/Downloads&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you need something the SFTP shell does not provide, prefix a command with &lt;code&gt;!&lt;/code&gt; to run it in your local shell. Typing &lt;code&gt;!&lt;/code&gt; on its own drops you into a local shell, and &lt;code&gt;exit&lt;/code&gt; brings you back to the SFTP prompt:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;!tar -czf archive.tar.gz project/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;progress&lt;/code&gt; command toggles the transfer progress meter. Turning it off keeps the output readable when you are piping a session to a log file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="downloading-files"&gt;Downloading Files &lt;a class="headline-link" href="#downloading-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To download a single file from the remote server, use the &lt;code&gt;get&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get filename.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Fetching /home/remote_username/filename.zip to filename.zip
/home/remote_username/filename.zip 100% 24MB 1.8MB/s 00:13&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When downloading files with &lt;code&gt;sftp&lt;/code&gt;, the files are saved in the directory from which you typed the &lt;code&gt;sftp&lt;/code&gt; command, or in whichever directory you last set with &lt;code&gt;lcd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you want to save the downloaded file with a different name, specify the new name as the second argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get filename.zip local_filename.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To download a directory from the remote system, use the recursive &lt;code&gt;-r&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get -r remote_directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If a file transfer fails or is interrupted, you can resume it using the &lt;code&gt;reget&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;The syntax of &lt;code&gt;reget&lt;/code&gt; is the same as the syntax of &lt;code&gt;get&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reget filename.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To resume a recursive directory download, add &lt;code&gt;-r&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reget -r remote_directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="uploading-files"&gt;Uploading Files &lt;a class="headline-link" href="#uploading-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To upload a file from the local machine to the remote SFTP server, use the &lt;code&gt;put&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;put filename.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Uploading filename.zip to /home/remote_username/filename.zip
filename.zip 100% 12MB 1.7MB/s 00:06&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first line confirms the local source and the remote destination, and the second line reports the progress, the transferred size, the average speed, and the elapsed time. The file lands in the remote working directory, which is the remote user&amp;rsquo;s home directory unless you moved somewhere else with &lt;code&gt;cd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the file you want to upload is not located in your current working directory, use the absolute path to the file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;put /home/local_username/backups/filename.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To store the file under a different name on the remote server, pass the new name as the second argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;put filename.zip archive-2026.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also send a file straight into a specific remote directory without changing the remote working directory first. End the path with a slash so SFTP treats it as a directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;put filename.zip /var/www/uploads/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When working with &lt;code&gt;put&lt;/code&gt;, you can use the same options that are available with the &lt;code&gt;get&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;To upload a local directory, use &lt;code&gt;-r&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;put -r local_directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To resume an interrupted upload:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reput filename.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To resume a recursive directory upload, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reput -r local_directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="transferring-multiple-files"&gt;Transferring Multiple Files &lt;a class="headline-link" href="#transferring-multiple-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;put&lt;/code&gt; accept glob patterns, so you do not need a separate command to move several files at once. To download every &lt;code&gt;.txt&lt;/code&gt; file from the remote working directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get *.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Uploading works the same way:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;put *.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are coming from &lt;code&gt;ftp&lt;/code&gt; or from PuTTY&amp;rsquo;s &lt;code&gt;psftp&lt;/code&gt;, you will probably reach for &lt;code&gt;mget&lt;/code&gt; and &lt;code&gt;mput&lt;/code&gt;. OpenSSH SFTP accepts both names, but they are undocumented aliases, so &lt;code&gt;mget *.csv&lt;/code&gt; and &lt;code&gt;get *.csv&lt;/code&gt; do exactly the same thing. Prefer the documented names, because the aliases appear neither in the man page nor in the &lt;code&gt;help&lt;/code&gt; output.&lt;/p&gt;
&lt;p&gt;There is also no &lt;code&gt;prompt&lt;/code&gt; command to switch off. Wildcard transfers always run for every matching file without asking for confirmation, so check the pattern before you point it at a large directory.&lt;/p&gt;
&lt;h2 id="file-manipulations-with-sftp"&gt;File Manipulations with SFTP &lt;a class="headline-link" href="#file-manipulations-with-sftp" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Typically, to perform tasks on a remote server, you would connect via SSH and run your commands in the shell. However, in some situations, the user may have only SFTP access (no full SSH shell) to the remote server. This is what an &lt;a href="https://linuxize.com/post/how-to-set-up-sftp-chroot-jail/"&gt;SFTP chroot jail&lt;/a&gt;
gives you: an account that can move files but cannot log in to a shell.&lt;/p&gt;
&lt;p&gt;SFTP allows you to perform some basic file manipulation commands. Below are some examples of how to use the SFTP shell:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Get information about the remote system&amp;rsquo;s &lt;a href="https://linuxize.com/post/how-to-check-disk-space-in-linux-using-the-df-command/"&gt;disk usage&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;df&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; Size Used Avail (root) %Capacity
20616252 1548776 18002580 19067476 7%&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new directory on the remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir directory_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rename a file on the remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rename file_name new_file_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete a file on the remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm file_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Delete a directory on the remote server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rmdir directory_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the &lt;a href="https://linuxize.com/post/chmod-command-in-linux/"&gt;permissions&lt;/a&gt;
of a file on the remote system:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;644&lt;/span&gt; file_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the owner of a file on the remote system:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chown user_id file_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You must supply the user ID to the &lt;a href="https://linuxize.com/post/linux-chown-command/"&gt;&lt;code&gt;chown&lt;/code&gt;&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/chgrp-command-in-linux/"&gt;&lt;code&gt;chgrp&lt;/code&gt;&lt;/a&gt;
commands.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the group owner of a remote file with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chgrp group_id file_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="transferring-files-without-the-interactive-shell"&gt;Transferring Files Without the Interactive Shell &lt;a class="headline-link" href="#transferring-files-without-the-interactive-shell" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You do not always need the SFTP prompt. When the destination includes a path that points to a file rather than a directory, &lt;code&gt;sftp&lt;/code&gt; fetches it and exits:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp remote_username@server_ip_or_hostname:/var/log/nginx/access.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The file is saved in your current local directory under the same name. To save it somewhere else, or under a different name, add a local path as a second argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp remote_username@server_ip_or_hostname:/var/log/nginx/access.log ~/logs/access-copy.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With non-interactive public-key authentication and host verification already configured, the whole transfer runs unattended. With password authentication, &lt;code&gt;sftp&lt;/code&gt; asks for the password first and then fetches the file.&lt;/p&gt;
&lt;p&gt;If the path points to a directory, SFTP logs in and opens the interactive shell there instead of transferring anything. Add a trailing slash when you want to force that behavior for a name that could be read either way:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp remote_username@server_ip_or_hostname:/var/www/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="batch-mode"&gt;Batch Mode &lt;a class="headline-link" href="#batch-mode" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can use batch mode to automate file transfers in scripts. Create a file containing SFTP commands, one per line, then execute it with the &lt;code&gt;-b&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;In the following example, we create a batch file with commands to download files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;sftp_commands.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd /var/www
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get database_backup.sql
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get config.php
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bye&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run the batch file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp -b sftp_commands.txt remote_username@server_ip_or_hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For batch mode to work without manual intervention, you must use &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If one of the batch commands fails, SFTP terminates immediately. To continue after a specific command fails, prefix that command with &lt;code&gt;-&lt;/code&gt; inside the batch file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;sftp_commands.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd /var/www
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-get optional-report.csv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;get database_backup.sql
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bye&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this example, SFTP continues if &lt;code&gt;optional-report.csv&lt;/code&gt; is missing, but it still stops if &lt;code&gt;cd /var/www&lt;/code&gt; or &lt;code&gt;get database_backup.sql&lt;/code&gt; fails.&lt;/p&gt;
&lt;h2 id="disconnecting"&gt;Disconnecting &lt;a class="headline-link" href="#disconnecting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once you are done with your work, close the connection by typing &lt;code&gt;bye&lt;/code&gt; or &lt;code&gt;quit&lt;/code&gt;. Both commands end the session:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="sftp&amp;gt;"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bye&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="tips-for-frequent-use"&gt;Tips for Frequent Use &lt;a class="headline-link" href="#tips-for-frequent-use" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Set up an &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
and connect to your Linux servers without entering a password.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you regularly connect to the same hosts, simplify your workflow by defining all of your connections in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ssh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;ssh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-ssh" data-lang="ssh"&gt;Host myserver_name
HostName 10.10.0.2
User leah
Port 2222&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/sftp/"&gt;SFTP cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Connect to server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sftp user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connect on custom port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sftp -P 2222 user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download one file and exit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sftp user@host:/path/file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download one file to a local path&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sftp user@host:/path/file ./local.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get filename&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get -r directory&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resume download&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reget filename&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resume directory download&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reget -r directory&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upload file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put filename&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upload under a different name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put filename newname&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upload into a remote directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put filename /remote/dir/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upload directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put -r directory&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resume upload&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reput filename&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resume directory upload&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reput -r directory&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download multiple files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get *.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upload multiple files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;put *.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List remote files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List local files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change remote directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cd /path&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change local directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lcd /path&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Print remote directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Print local directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lpwd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create remote directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mkdir dirname&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete remote file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rm filename&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete remote directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rmdir dirname&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rename remote file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rename oldname newname&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change permissions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chmod 644 filename&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run a local shell command&lt;/td&gt;
&lt;td&gt;&lt;code&gt;!command&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run batch file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sftp -b sftp_commands.txt user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bye&lt;/code&gt; or &lt;code&gt;quit&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Connection refused&lt;/strong&gt;&lt;br&gt;
The SSH server may not be running, or a firewall is blocking port 22 (or your custom port). Verify the server is accessible and the SSH service is running.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied (publickey)&lt;/strong&gt;&lt;br&gt;
Your SSH key is not authorized on the remote server, or you are using the wrong key. Use &lt;code&gt;-i /path/to/key&lt;/code&gt; to specify the correct identity file, or check that your public key is in the remote user&amp;rsquo;s &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No such file or directory&lt;/strong&gt;&lt;br&gt;
The file or directory you are trying to access does not exist. Use &lt;code&gt;ls&lt;/code&gt; to verify the path and check for typos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied when uploading&lt;/strong&gt;&lt;br&gt;
You do not have write permission to the destination directory. Contact the server administrator or choose a directory where you have write access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connection timed out&lt;/strong&gt;&lt;br&gt;
Network issues or firewall rules are preventing the connection. Check your network connection and verify the server IP address is correct.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Broken pipe or connection reset&lt;/strong&gt;&lt;br&gt;
The connection was interrupted, often due to network instability or server-side timeouts. Use &lt;code&gt;reget&lt;/code&gt; or &lt;code&gt;reput&lt;/code&gt; to resume interrupted transfers.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the default SFTP port?&lt;/strong&gt;&lt;br&gt;
SFTP uses port 22 by default, the same as SSH. You can specify a different port with the &lt;code&gt;-P&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between SFTP and SCP?&lt;/strong&gt;&lt;br&gt;
Both use SSH for secure transfers. SCP is simpler and only transfers files, while SFTP provides an interactive shell with directory navigation, file manipulation, and the ability to resume interrupted transfers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between SFTP and FTPS?&lt;/strong&gt;&lt;br&gt;
SFTP runs over SSH (port 22), while FTPS is FTP with TLS/SSL encryption (typically port 990 or 21). SFTP is generally easier to configure since it uses a single port.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use SFTP without a password?&lt;/strong&gt;&lt;br&gt;
Yes, by setting up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
. This is also required for batch mode automation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I transfer an entire directory?&lt;/strong&gt;&lt;br&gt;
Use the &lt;code&gt;-r&lt;/code&gt; (recursive) option with &lt;code&gt;get&lt;/code&gt; or &lt;code&gt;put&lt;/code&gt; inside the SFTP prompt. For example: &lt;code&gt;get -r remote_directory&lt;/code&gt; or &lt;code&gt;put -r local_directory&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I resume a failed transfer?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;reget&lt;/code&gt; to resume downloads and &lt;code&gt;reput&lt;/code&gt; to resume uploads. For recursive directory transfers, use &lt;code&gt;reget -r&lt;/code&gt; or &lt;code&gt;reput -r&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;sftp&lt;/code&gt; command is useful when you need secure, interactive file transfers over SSH. For one-time copies, &lt;code&gt;scp&lt;/code&gt; may be faster to type, but SFTP is a better fit when you need to browse directories, resume transfers, or automate a set of file operations with batch mode.&lt;/p&gt;
&lt;p&gt;If you are working on a desktop machine, you can use a GUI SFTP client like &lt;a href="https://winscp.net/eng/index.php" target="_blank" rel="noopener noreferrer"&gt;WinSCP&lt;/a&gt;
or &lt;a href="https://filezilla-project.org/" target="_blank" rel="noopener noreferrer"&gt;FileZilla&lt;/a&gt;
to connect to the remote server and download or upload files.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/featured_hu_7032c1a6a885af6a.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Change the SFTP Port</title><link>https://linuxize.com/post/sftp-port/</link><pubDate>Fri, 24 Jul 2020 21:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/sftp-port/</guid><category>ssh</category><category>security</category><description>SFTP runs on SSH port 22 by default. This guide explains how to change the SFTP port on Linux, configure your firewall for the new port, and connect using the updated port number.</description><content:encoded>&lt;p&gt;SFTP (SSH File Transfer Protocol) is a secure file protocol for transferring files between two hosts over an encrypted connection. It also allows you to perform various file operations on remote files and to resume file transfers.&lt;/p&gt;
&lt;p&gt;SFTP can be used as a replacement for the legacy FTP protocol. It has all the functionality of FTP but with a more secure connection.&lt;/p&gt;
&lt;p&gt;This article explains how to change the default SFTP port in Linux. We will also show you how to configure your firewall to allow connections on the new port.&lt;/p&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Do not confuse SFTP with FTPS. Both protocols serve the same purpose. However, FTPS stands for FTP Secure, and it is an extension to the standard FTP protocol with support for TLS.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="what-port-does-sftp-use"&gt;What Port Does SFTP Use &lt;a class="headline-link" href="#what-port-does-sftp-use" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SFTP is a subsystem of SSH and shares the same port and the same level of security as SSH.&lt;/p&gt;
&lt;p&gt;The default &lt;strong&gt;SFTP port is 22&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow 4422/tcp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open port in UFW&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo firewall-cmd --permanent --zone=public --add-port=4422/tcp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open port in FirewallD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo sshd -t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Test sshd_config for syntax errors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl restart ssh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restart SSH service (Debian, Ubuntu)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl restart sshd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restart SSH service (Fedora, RHEL)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -an | grep 4422&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify SSH is listening on the new port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sftp -P 4422 user@host&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Connect via SFTP on a custom port&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="changing-the-sftp-port"&gt;Changing the SFTP Port &lt;a class="headline-link" href="#changing-the-sftp-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Changing the default SFTP/SSH port adds an extra layer of security to your server by reducing the risk of automated attacks.&lt;/p&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;The best way to protect your server from attacks is to configure your firewall to allow access to port 22 only from trusted hosts and set up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/" target="_blank" rel="noopener noreferrer"&gt;SSH key-based authentication&lt;/a&gt;
. For a broader set of hardening steps, see &lt;a href="https://linuxize.com/post/ssh-hardening-best-practices/" target="_blank" rel="noopener noreferrer"&gt;SSH Hardening Best Practices&lt;/a&gt;
.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following steps describe how to change the SSH port on Linux machines.&lt;/p&gt;
&lt;h3 id="1-choosing-a-new-port-number"&gt;1. Choosing a New Port Number &lt;a class="headline-link" href="#1-choosing-a-new-port-number" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In Linux, port numbers below 1024 are reserved for well-known services and can only be bound to by root. Although you can use a port within the 1–1024 range for the SSH service, it is recommended to choose a port above 1024 to avoid conflicts with other services. The range 49152–65535 consists of ephemeral ports not assigned to any standard service and is a safe choice.&lt;/p&gt;
&lt;p&gt;Before picking a port, verify it is not already in use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tlnp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;4422&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command returns no output, the port is free. This example uses port &lt;code&gt;4422&lt;/code&gt;, but you can choose any available port.&lt;/p&gt;
&lt;h3 id="2-adjusting-the-firewall"&gt;2. Adjusting the Firewall &lt;a class="headline-link" href="#2-adjusting-the-firewall" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before changing the SFTP/SSH port, you will need to open the new port in your firewall.&lt;/p&gt;
&lt;p&gt;If you are using &lt;a href="https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-20-04/"&gt;UFW&lt;/a&gt;
, run the following command to open the port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 4422/tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives, the default firewall management tool is FirewallD. To open the port, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --permanent --zone&lt;span class="o"&gt;=&lt;/span&gt;public --add-port&lt;span class="o"&gt;=&lt;/span&gt;4422/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives, you may also need to update the SELinux policy to allow the new SSH port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo semanage port -a -t ssh_port_t -p tcp &lt;span class="m"&gt;4422&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are using another Linux distribution that runs iptables, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -p tcp --dport &lt;span class="m"&gt;4422&lt;/span&gt; -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="3-configuring-sftpssh"&gt;3. Configuring SFTP/SSH &lt;a class="headline-link" href="#3-configuring-sftpssh" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The SSH server configuration is stored in the &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; file. Open the file with your text editor:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo vim /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="https://linuxize.com/post/vim-search/"&gt;Search&lt;/a&gt;
for the line starting with &lt;code&gt;Port 22&lt;/code&gt;. Typically, this line is commented out using the hash (&lt;code&gt;#&lt;/code&gt;) symbol. Remove the hash and enter your new SSH port number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Port 4422&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Before restarting the service, test the configuration file for syntax errors:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sshd -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command returns no output, the configuration is valid. An incorrect configuration will prevent the SSH service from starting, so always run this check before restarting.&lt;/p&gt;
&lt;p&gt;Once done, save the file and restart the SSH service for the changes to take effect.&lt;/p&gt;
&lt;p&gt;On Debian and Ubuntu:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives, the SSH service is named &lt;code&gt;sshd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Verify that the SSH daemon is &lt;a href="https://linuxize.com/post/check-listening-ports-linux/"&gt;listening&lt;/a&gt;
on the new port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -an &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="m"&gt;4422&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;tcp LISTEN 0 128 0.0.0.0:4422 0.0.0.0:*
tcp ESTAB 0 0 192.168.121.108:4422 192.168.121.1:57638
tcp LISTEN 0 128 [::]:4422 [::]:*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="using-the-new-sftp-port"&gt;Using the New SFTP Port &lt;a class="headline-link" href="#using-the-new-sftp-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To specify the port number, invoke the &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;&lt;code&gt;sftp&lt;/code&gt;&lt;/a&gt;
command with the &lt;code&gt;-P&lt;/code&gt; option followed by the new port number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp -P &lt;span class="m"&gt;4422&lt;/span&gt; username@remote_host_or_ip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are using a GUI SFTP client, enter the new port number in the client interface.&lt;/p&gt;
&lt;p&gt;To avoid specifying the port on every connection, you can define it in the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Host myserver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;HostName remote_host_or_ip&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;Port 4422&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;User username&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With this in place, you can connect with just &lt;code&gt;sftp myserver&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SSH service fails to restart after changing the port&lt;/strong&gt;&lt;br&gt;
A syntax error in &lt;code&gt;sshd_config&lt;/code&gt; will prevent the service from starting. Run &lt;code&gt;sudo sshd -t&lt;/code&gt; to check for errors before restarting. Fix any reported issues, then retry.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cannot connect on the new port&lt;/strong&gt;&lt;br&gt;
The firewall rule may not have been applied correctly. Run &lt;code&gt;ss -tlnp | grep 4422&lt;/code&gt; to confirm the SSH daemon is listening, and run &lt;code&gt;sudo ufw status&lt;/code&gt; or &lt;code&gt;sudo firewall-cmd --list-ports&lt;/code&gt; to confirm the port is open in the firewall.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SELinux denying the new port on RHEL or Fedora&lt;/strong&gt;&lt;br&gt;
SELinux restricts SSH to ports it knows about. Register the new port with &lt;code&gt;sudo semanage port -a -t ssh_port_t -p tcp 4422&lt;/code&gt;. If &lt;code&gt;semanage&lt;/code&gt; is not installed, install it with &lt;code&gt;sudo dnf install policycoreutils-python-utils&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Locked out of the server after changing the port&lt;/strong&gt;&lt;br&gt;
Do not close your existing SSH session until you have verified the new port works by opening a second session with &lt;code&gt;ssh -p 4422 user@host&lt;/code&gt;. If you are locked out, use the server provider&amp;rsquo;s emergency console or out-of-band access to revert the port change.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does changing the SSH port also change the SFTP port?&lt;/strong&gt;&lt;br&gt;
Yes. SFTP is a subsystem of SSH and runs on the same port. Changing the SSH port in &lt;code&gt;sshd_config&lt;/code&gt; automatically changes the port for both SSH and SFTP connections.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can SSH listen on multiple ports at the same time?&lt;/strong&gt;&lt;br&gt;
Yes. Add multiple &lt;code&gt;Port&lt;/code&gt; lines to &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;, one per port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Port 22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Port 4422&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This lets you keep port 22 open temporarily while you verify the new port works.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What port number should I choose?&lt;/strong&gt;&lt;br&gt;
Choose a port above 1024 to avoid conflicts with reserved services. Ports in the range 49152–65535 are not assigned to any standard service. Avoid commonly scanned alternatives such as 2222 or 8022.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Will changing the port stop all brute-force attacks?&lt;/strong&gt;&lt;br&gt;
It significantly reduces automated scan traffic but is not a substitute for proper security measures. Use SSH key-based authentication and restrict access by IP address in your firewall for effective protection.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Changing the default SFTP/SSH port is a simple step that reduces exposure to automated scanning. Combined with &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
and firewall rules, it forms part of a solid baseline for securing remote access. For more ways to restrict SFTP access, see &lt;a href="https://linuxize.com/post/how-to-set-up-sftp-chroot-jail/"&gt;How to Set Up an SFTP Chroot Jail&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to leave a comment below.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/sftp-port/featured_hu_aea58286cadc9f8d.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Set Up SFTP Chroot Jail</title><link>https://linuxize.com/post/how-to-set-up-sftp-chroot-jail/</link><pubDate>Sun, 07 Apr 2019 13:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-set-up-sftp-chroot-jail/</guid><category>ssh</category><category>security</category><description>Step-by-step instructions for setting up an SFTP Chroot Jail on Linux to restrict users to their home directories using OpenSSH.</description><content:encoded>&lt;p&gt;If you are a system administrator managing a Linux server, you may need to grant SFTP access to some users to upload files to their home directories. By default, users that can log in to the system via SSH, SFTP, and &lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;SCP&lt;/a&gt;
can browse the entire filesystem, including other users&amp;rsquo; directories.&lt;/p&gt;
&lt;p&gt;This may not be a problem if these users are trusted. If you do not want logged-in users to navigate around the system, you will need to restrict user access to their home directory. This adds an extra layer of security, especially on systems with multiple users.&lt;/p&gt;
&lt;p&gt;In this guide, we will explain how to set up an SFTP Chroot Jail environment that will restrict users to their home directories. The users will have SFTP access only; SSH access will be disabled. These instructions work for any modern Linux distribution including Ubuntu, Debian, and Fedora.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create SFTP group&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo groupadd sftponly&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create chroot user&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo useradd -g sftponly -s /bin/false -m -d /home/user user&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set home directory ownership&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chown root: /home/user&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set home directory permissions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chmod 755 /home/user&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restart SSH (Debian/Ubuntu)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl restart ssh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restart SSH (Fedora/RHEL)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl restart sshd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test SSH config syntax&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo sshd -t&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="creating-an-sftp-group"&gt;Creating an SFTP Group &lt;a class="headline-link" href="#creating-an-sftp-group" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of configuring the OpenSSH server for each user individually, we will &lt;a href="https://linuxize.com/post/how-to-create-groups-in-linux/"&gt;create a new group&lt;/a&gt;
and add all our chrooted users to this group.&lt;/p&gt;
&lt;p&gt;Run the following &lt;a href="https://linuxize.com/post/how-to-create-groups-in-linux/"&gt;&lt;code&gt;groupadd&lt;/code&gt;&lt;/a&gt;
command to create the &lt;code&gt;sftponly&lt;/code&gt; user group:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo groupadd sftponly&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-tip"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"&gt;
&lt;path d="M25 6c-1.645 0-3 1.355-3 3v1.406c-1.945.457-3.645 1.36-4.953 2.676C15.094 15.055 14 17.848 14 21.062v7.801c0 1.836-1.004 4.164-2.04 5.89l-1.792 2.692a1.01 1.01 0 0 0-.05 1.028c.175.324.515.527.882.527h9c0 2.746 2.254 5 5 5s5-2.254 5-5h9c.367 0 .707-.203.883-.527a1.01 1.01 0 0 0-.051-1.028l-1.785-2.68-.004-.003C36.996 33.016 36 30.836 36 29v-7.8c0-5.368-3.195-9.524-8-10.759V9c0-1.645-1.355-3-3-3zm0 2c.555 0 1 .445 1 1v1.113c-.223-.02-.441-.043-.668-.05A1.064 1.064 0 0 0 25 10c-.11 0-.215.02-.316.059-.235.004-.457.027-.684.043V9c0-.555.445-1 1-1zM3.48 9.477C1.25 13.102 0 17.418 0 22s1.25 8.898 3.48 12.523l1.708-1.046C3.151 30.168 2 26.219 2 22s1.152-8.168 3.188-11.477zm43.04 0l-1.708 1.046C46.849 13.832 48 17.781 48 22s-1.152 8.168-3.188 11.477l1.708 1.046C48.75 30.898 50 26.582 50 22s-1.25-8.898-3.48-12.523zM25 12c5.512 0 9 3.668 9 9.2V29c0 2.512 1.203 4.918 2.328 6.797.012.012.02.027.027.039L37.13 37H12.87l.774-1.164c.007-.012.015-.027.027-.04C14.809 33.903 16 31.376 16 28.864v-7.8c0-2.766.914-5.004 2.469-6.57C20.019 12.925 22.239 12 25 12zm-17.184.14C5.996 15.083 5 18.356 5 22c0 3.672 1.129 7.047 2.809 9.848l1.714-1.032C8.008 28.286 7 25.262 7 22c0-3.29.871-6.148 2.516-8.809zm34.368 0l-1.7 1.051C42.13 15.851 43 18.711 43 22c0 3.262-1.008 6.285-2.527 8.816l1.718 1.032C43.871 29.047 45 25.672 45 22c0-3.645-.996-6.918-2.816-9.86zM22 39h6a3 3 0 0 1-6 0z"/&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Tip&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;You can name the group as you like.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="adding-users-to-the-sftp-group"&gt;Adding Users to the SFTP Group &lt;a class="headline-link" href="#adding-users-to-the-sftp-group" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The next step is to add the users you want to restrict to the &lt;code&gt;sftponly&lt;/code&gt; group.&lt;/p&gt;
&lt;p&gt;If this is a new setup and the user does not exist, you can &lt;a href="https://linuxize.com/post/how-to-create-users-in-linux-using-the-useradd-command/"&gt;create a new user account&lt;/a&gt;
by typing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo useradd -g sftponly -s /bin/false -m -d /home/username username&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;-g sftponly&lt;/code&gt; option will add the user to the sftponly group.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;-s /bin/false&lt;/code&gt; option sets the user&amp;rsquo;s login shell. By setting the login shell to &lt;code&gt;/bin/false&lt;/code&gt;, the user will not be able to log in to the server via SSH.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;-m -d /home/username&lt;/code&gt; options tell useradd to create the user home directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://linuxize.com/post/how-to-change-user-password-in-linux/"&gt;Set a strong password&lt;/a&gt;
for the newly created user:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo passwd username&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the user you want to restrict already exists, &lt;a href="https://linuxize.com/post/how-to-add-user-to-group-in-linux/"&gt;add the user to the &lt;code&gt;sftponly&lt;/code&gt; group&lt;/a&gt;
and change the user&amp;rsquo;s shell:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo usermod -G sftponly -s /bin/false username2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The user home directory must be owned by root and have &lt;a href="https://linuxize.com/post/chmod-command-in-linux/"&gt;&lt;code&gt;755&lt;/code&gt; permissions&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown root: /home/username
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;755&lt;/span&gt; /home/username&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Since the user home directories are owned by the root user, these users will not be able to create files and directories in their home directories. If there are no directories in the user&amp;rsquo;s home, you will need to &lt;a href="https://linuxize.com/post/how-to-create-directories-in-linux-with-the-mkdir-command/"&gt;create new directories&lt;/a&gt;
to which the user will have full access. For example, you can create the following directories:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir /home/username/&lt;span class="o"&gt;{&lt;/span&gt;public_html,uploads&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;755&lt;/span&gt; /home/username/&lt;span class="o"&gt;{&lt;/span&gt;public_html,uploads&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown username:sftponly /home/username/&lt;span class="o"&gt;{&lt;/span&gt;public_html,uploads&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If a web application is using the user&amp;rsquo;s &lt;code&gt;public_html&lt;/code&gt; directory as document root, these changes may lead to permissions issues. For example, if you are running WordPress you will need to create a PHP pool that will run as the user owning the files and add the web server to the &lt;code&gt;sftponly&lt;/code&gt; group.&lt;/p&gt;
&lt;h2 id="configuring-ssh"&gt;Configuring SSH &lt;a class="headline-link" href="#configuring-ssh" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SFTP is a subsystem of SSH and supports all SSH authentication mechanisms.&lt;/p&gt;
&lt;p&gt;Open the SSH configuration file &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; with your &lt;a href="https://linuxize.com/post/how-to-use-nano-text-editor/"&gt;text editor&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/sshd_config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Search for the line starting with &lt;code&gt;Subsystem sftp&lt;/code&gt;, usually at the end of the file. If the line starts with a hash &lt;code&gt;#&lt;/code&gt;, remove the hash and modify it to look like the following:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Subsystem sftp internal-sftp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Towards the end of the file, add the following block of settings:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Match Group sftponly&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ChrootDirectory %h&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ForceCommand internal-sftp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;AllowTcpForwarding no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;X11Forwarding no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;ChrootDirectory&lt;/code&gt; directive specifies the path to the chroot directory. &lt;code&gt;%h&lt;/code&gt; means the user home directory. This directory must be owned by the root user and not writable by any other user or group.&lt;/p&gt;
&lt;p&gt;Be extra careful when modifying the SSH configuration file. An incorrect configuration may cause the SSH service to fail to start. You can test the configuration syntax before restarting the service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sshd -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once you are done, save the file and restart the SSH service to apply the changes. On Ubuntu and Debian:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives, the SSH service is named &lt;code&gt;sshd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="testing-the-configuration"&gt;Testing the Configuration &lt;a class="headline-link" href="#testing-the-configuration" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that you have configured SFTP chroot, you can try to log in to the remote machine through SFTP using the credentials of the chrooted user. In most cases, you will use a desktop SFTP client like &lt;a href="https://filezilla-project.org/" target="_blank" rel="noopener noreferrer"&gt;FileZilla&lt;/a&gt;
, but in this example, we will use the &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;sftp command&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Open an SFTP connection using the sftp command followed by the remote server username and the server IP address or domain name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sftp username@192.168.121.30&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted to enter the user password. Once connected, the remote server will display a confirmation message and the &lt;code&gt;sftp&amp;gt;&lt;/code&gt; prompt:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;username@192.168.121.30&amp;#39;s password:
sftp&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run the &lt;code&gt;pwd&lt;/code&gt; command, and if everything is working as expected the command should return &lt;code&gt;/&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;sftp&amp;gt; pwd
Remote working directory: /&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also list the remote files and directories using the &lt;code&gt;ls&lt;/code&gt; command, and you should see the directories that we have previously created:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;sftp&amp;gt; ls
public_html uploads&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;bad ownership or modes for chroot directory&amp;rdquo; error&lt;/strong&gt;
The chroot directory must be owned by root and must not be writable by the group or other users. Run &lt;code&gt;sudo chown root: /home/username&lt;/code&gt; and &lt;code&gt;sudo chmod 755 /home/username&lt;/code&gt; to fix ownership and permissions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSH service fails to start after editing &lt;code&gt;sshd_config&lt;/code&gt;&lt;/strong&gt;
Run &lt;code&gt;sudo sshd -t&lt;/code&gt; before restarting the service to check the configuration for syntax errors. Fix any reported errors before restarting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;User can still log in via SSH&lt;/strong&gt;
Verify the user shell is set to &lt;code&gt;/bin/false&lt;/code&gt; with &lt;code&gt;getent passwd username&lt;/code&gt;. Also confirm the &lt;code&gt;ForceCommand internal-sftp&lt;/code&gt; line is present inside the &lt;code&gt;Match Group sftponly&lt;/code&gt; block in &lt;code&gt;sshd_config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SFTP connection is refused or times out&lt;/strong&gt;
Ensure the &lt;code&gt;Subsystem sftp internal-sftp&lt;/code&gt; line is uncommented in &lt;code&gt;sshd_config&lt;/code&gt; and the SSH service has been restarted. Check the SSH service status with &lt;code&gt;sudo systemctl status ssh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives, use &lt;code&gt;sudo systemctl status sshd&lt;/code&gt; instead.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Can I allow SFTP access without granting SSH shell access?&lt;/strong&gt;
Yes. Set the user&amp;rsquo;s login shell to &lt;code&gt;/bin/false&lt;/code&gt; and add &lt;code&gt;ForceCommand internal-sftp&lt;/code&gt; inside the &lt;code&gt;Match Group&lt;/code&gt; block. This allows SFTP connections while blocking interactive SSH sessions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does SFTP chroot support SSH key authentication?&lt;/strong&gt;
Yes. SFTP is a subsystem of SSH and supports all SSH authentication mechanisms, including key-based authentication.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can multiple users share the same chroot setup?&lt;/strong&gt;
Yes. Add all users to the &lt;code&gt;sftponly&lt;/code&gt; group and set &lt;code&gt;ChrootDirectory %h&lt;/code&gt; so each user is jailed to their own home directory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why must the chroot directory be owned by root?&lt;/strong&gt;
OpenSSH requires the chroot directory to be owned by root and not writable by anyone else. If this condition is not met, the connection will fail with a &amp;ldquo;bad ownership or modes&amp;rdquo; error.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You have now set up an SFTP Chroot Jail on your Linux server, restricting SFTP users to their own home directories while blocking SSH shell access. For additional security, consider &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;changing the default SSH port&lt;/a&gt;
or enabling &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;SSH key-based authentication&lt;/a&gt;
to further harden your server.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-set-up-sftp-chroot-jail/featured_hu_af48a8920954b23c.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Use SSHFS to Mount Remote Directories over SSH</title><link>https://linuxize.com/post/how-to-use-sshfs-to-mount-remote-directories-over-ssh/</link><pubDate>Sun, 12 May 2019 19:40:24 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-use-sshfs-to-mount-remote-directories-over-ssh/</guid><category>ssh</category><category>mount</category><description>SSHFS lets you mount a remote directory over SSH and browse it like a local filesystem. This guide covers installation on Linux, macOS, and Windows, mounting with options, persistent fstab mounts, and troubleshooting.</description><content:encoded>&lt;p&gt;SSHFS (SSH Filesystem) is a filesystem client based on FUSE for mounting remote directories over an SSH connection. SSHFS uses the SFTP protocol, which is a subsystem of SSH and is enabled by default on most SSH servers.&lt;/p&gt;
&lt;p&gt;When compared to other network file system protocols such as NFS and &lt;a href="https://linuxize.com/post/how-to-install-and-configure-samba-on-ubuntu-18-04/"&gt;Samba&lt;/a&gt;
, the advantage of SSHFS is that it does not require any additional configuration on the server side. To use SSHFS you only need SSH access to the remote server.&lt;/p&gt;
&lt;p&gt;Because SSHFS uses &lt;a href="https://linuxize.com/post/how-to-use-linux-sftp-command-to-transfer-files/"&gt;SFTP&lt;/a&gt;
, all data transmitted between the server and the client is encrypted and decrypted. This results in slightly degraded performance compared to NFS and higher CPU usage on both the client and server.&lt;/p&gt;
&lt;p&gt;This guide explains how to install SSHFS on Linux, macOS, and Windows and how to mount a remote directory.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mount remote directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshfs user@host:/remote/dir /local/mountpoint&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mount with SSH key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshfs -o IdentityFile=~/.ssh/id_rsa user@host:/remote/dir /local/mountpoint&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mount with custom port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshfs -o port=2222 user@host:/remote/dir /local/mountpoint&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mount with reconnect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sshfs -o reconnect,ServerAliveInterval=15 user@host:/remote/dir /local/mountpoint&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unmount&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fusermount -u /local/mountpoint&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List SSHFS mounts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mount | grep fuse.sshfs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install on Ubuntu/Debian&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo apt install sshfs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install on Fedora/RHEL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo dnf install fuse-sshfs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="installing-sshfs"&gt;Installing SSHFS &lt;a class="headline-link" href="#installing-sshfs" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SSHFS packages are available for all major operating systems.&lt;/p&gt;
&lt;h3 id="ubuntu-debian-and-derivatives"&gt;Ubuntu, Debian, and Derivatives &lt;a class="headline-link" href="#ubuntu-debian-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;SSHFS is available from the default Ubuntu and Debian repositories. Update the packages index and install the sshfs client:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install sshfs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="fedora-rhel-and-derivatives"&gt;Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives, run the following command to install SSHFS:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install fuse-sshfs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="macos"&gt;macOS &lt;a class="headline-link" href="#macos" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On macOS, SSHFS requires macFUSE. Install macFUSE first, then install an SSHFS build from the official SSHFS releases:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install --cask macfuse&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Homebrew no longer ships a maintained &lt;code&gt;sshfs&lt;/code&gt; formula for macOS. After installing macFUSE, download a compatible SSHFS package from the &lt;a href="https://github.com/libfuse/sshfs/releases" target="_blank" rel="noopener noreferrer"&gt;official SSHFS releases&lt;/a&gt;
or follow the current instructions in the &lt;a href="https://github.com/macfuse/macfuse/wiki/File-Systems-%E2%80%90-SSHFS" target="_blank" rel="noopener noreferrer"&gt;macFUSE SSHFS guide&lt;/a&gt;
.&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id="windows"&gt;Windows &lt;a class="headline-link" href="#windows" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Windows users need to install two packages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/winfsp/winfsp/releases" target="_blank" rel="noopener noreferrer"&gt;WinFsp&lt;/a&gt;
— a Windows filesystem driver required by SSHFS-Win&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/winfsp/sshfs-win/releases" target="_blank" rel="noopener noreferrer"&gt;SSHFS-Win&lt;/a&gt;
— the SSHFS client for Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Install WinFsp first, then install SSHFS-Win.&lt;/p&gt;
&lt;h2 id="mounting-a-remote-file-system"&gt;Mounting a Remote File System &lt;a class="headline-link" href="#mounting-a-remote-file-system" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The following instructions apply to Linux and macOS.&lt;/p&gt;
&lt;p&gt;To &lt;a href="https://linuxize.com/post/how-to-mount-and-unmount-file-systems-in-linux/"&gt;mount&lt;/a&gt;
a remote directory, the SSH user must have access to it. The &lt;code&gt;sshfs&lt;/code&gt; command takes the following form:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sshfs [user@]host:[remote_directory] mountpoint [options]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;sshfs&lt;/code&gt; command reads the &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
and applies per-host settings automatically. If the remote directory is not specified, it defaults to the remote user&amp;rsquo;s home directory.&lt;/p&gt;
&lt;p&gt;For example, to mount the home directory of a user named &lt;code&gt;linuxize&lt;/code&gt; on a remote host with IP address &lt;code&gt;192.168.121.121&lt;/code&gt;, first &lt;a href="https://linuxize.com/post/how-to-create-directories-in-linux-with-the-mkdir-command/"&gt;create a directory&lt;/a&gt;
to use as a mount point:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir ~/linuxizeremote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then mount the remote directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sshfs linuxize@192.168.121.121:/home/linuxize ~/linuxizeremote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You will be prompted for the user&amp;rsquo;s password. To avoid entering the password each time you mount, set up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;passwordless SSH login&lt;/a&gt;
using SSH keys.&lt;/p&gt;
&lt;p&gt;Once mounted, you can interact with the remote files as if they were local — edit, delete, rename, or &lt;a href="https://linuxize.com/post/create-a-file-in-linux/"&gt;create new files&lt;/a&gt;
and directories.&lt;/p&gt;
&lt;p&gt;Verify the mount is active:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mount &lt;span class="p"&gt;|&lt;/span&gt; grep fuse.sshfs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;linuxize@192.168.121.121:/home/linuxize on /home/linuxize/linuxizeremote type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="common-mount-options"&gt;Common Mount Options &lt;a class="headline-link" href="#common-mount-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can pass options to &lt;code&gt;sshfs&lt;/code&gt; with the &lt;code&gt;-o&lt;/code&gt; flag. Multiple options are separated by commas:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sshfs -o reconnect,ServerAliveInterval&lt;span class="o"&gt;=&lt;/span&gt;15,ServerAliveCountMax&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; linuxize@192.168.121.121:/home/linuxize ~/linuxizeremote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Useful options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-o reconnect&lt;/code&gt; — reconnect automatically if the connection is interrupted&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o ServerAliveInterval=15&lt;/code&gt; — send a keep-alive packet every 15 seconds&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o ServerAliveCountMax=3&lt;/code&gt; — disconnect after 3 unanswered keep-alive packets&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o allow_other&lt;/code&gt; — allow other users on the local machine to access the mount (requires &lt;code&gt;user_allow_other&lt;/code&gt; in &lt;code&gt;/etc/fuse.conf&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o follow_symlinks&lt;/code&gt; — follow symbolic links on the remote host&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o IdentityFile=~/.ssh/id_rsa&lt;/code&gt; — specify which SSH private key to use&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o port=2222&lt;/code&gt; — connect to a non-standard SSH port&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o compression=yes&lt;/code&gt; — enable compression (useful on slow connections)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="persistent-mount-with-etcfstab"&gt;Persistent Mount with /etc/fstab &lt;a class="headline-link" href="#persistent-mount-with-etcfstab" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To mount a remote directory automatically at boot, add an entry to the local machine&amp;rsquo;s &lt;a href="https://linuxize.com/post/etc-fstab-file/"&gt;&lt;code&gt;/etc/fstab&lt;/code&gt;&lt;/a&gt;
file. Use &lt;code&gt;fuse.sshfs&lt;/code&gt; as the filesystem type.&lt;/p&gt;
&lt;p&gt;When creating a persistent mount, SSH key-based authentication is required since there is no interactive prompt at boot time.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fstab&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;user@host:/remote/dir /local/mountpoint fuse.sshfs defaults,_netdev,nofail,x-systemd.automount,IdentityFile&lt;span class="o"&gt;=&lt;/span&gt;/home/user/.ssh/id_rsa,reconnect,ServerAliveInterval&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The key options for SSHFS fstab entries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_netdev&lt;/code&gt; — tells the system this is a network mount; wait for the network before mounting&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nofail&lt;/code&gt; — do not report an error if the remote host is unreachable at boot&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-systemd.automount&lt;/code&gt; — mount on first access rather than at boot (avoids boot delays)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IdentityFile&lt;/code&gt; — path to the SSH private key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After editing &lt;code&gt;/etc/fstab&lt;/code&gt;, test the entry without rebooting:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mount -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="mounting-a-remote-directory-on-windows"&gt;Mounting a Remote Directory on Windows &lt;a class="headline-link" href="#mounting-a-remote-directory-on-windows" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Windows users can use Windows Explorer to map a network drive to the remote directory.&lt;/p&gt;
&lt;p&gt;Open Windows Explorer, right-click on &amp;ldquo;This PC&amp;rdquo;, and select &amp;ldquo;Map network drive&amp;rdquo;. Choose a drive letter and enter the remote path in the following format in the &amp;ldquo;Folder&amp;rdquo; field:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;\\sshfs\user@host[\PATH]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="unmounting-a-remote-file-system"&gt;Unmounting a Remote File System &lt;a class="headline-link" href="#unmounting-a-remote-file-system" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To detach a mounted SSHFS filesystem, use either &lt;code&gt;fusermount&lt;/code&gt; or &lt;code&gt;umount&lt;/code&gt; followed by the mount point:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fusermount -u ~/linuxizeremote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;umount ~/linuxizeremote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the mount is unresponsive (for example, after a network interruption), add the &lt;code&gt;-z&lt;/code&gt; flag to force a lazy unmount:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fusermount -uz ~/linuxizeremote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Transport endpoint is not connected&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
This error appears when the SSHFS connection dropped but the mount point was not cleaned up. Unmount with &lt;code&gt;fusermount -uz /local/mountpoint&lt;/code&gt; and remount. To prevent this, use the &lt;code&gt;-o reconnect,ServerAliveInterval=15&lt;/code&gt; options when mounting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Connection reset by peer&amp;rdquo; or mount goes unresponsive&lt;/strong&gt;&lt;br&gt;
The SSH server dropped the connection due to inactivity. Add &lt;code&gt;-o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3&lt;/code&gt; to your mount command or fstab entry to keep the connection alive and reconnect automatically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Permission denied (publickey)&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
SSH key-based authentication failed. Check that the correct key is being used with &lt;code&gt;-o IdentityFile=~/.ssh/id_rsa&lt;/code&gt; and that the public key is present in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; on the remote host.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mount disappears after reboot&lt;/strong&gt;&lt;br&gt;
If the mount was created manually with &lt;code&gt;sshfs&lt;/code&gt;, it does not survive a reboot. Add an entry to &lt;code&gt;/etc/fstab&lt;/code&gt; with the &lt;code&gt;_netdev&lt;/code&gt; and &lt;code&gt;x-systemd.automount&lt;/code&gt; options as shown in the persistent mount section.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Other users cannot access the mount&lt;/strong&gt;&lt;br&gt;
By default, only the user who created the SSHFS mount can access it. To allow other users, mount with &lt;code&gt;-o allow_other&lt;/code&gt; and ensure &lt;code&gt;/etc/fuse.conf&lt;/code&gt; contains the line &lt;code&gt;user_allow_other&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between SSHFS and SCP or rsync?&lt;/strong&gt;&lt;br&gt;
SCP and rsync transfer files between systems — they copy files from one place to another. SSHFS mounts the remote directory so you can access it in place, using any application or tool as if the files were local. No copying is needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does SSHFS work with password authentication?&lt;/strong&gt;&lt;br&gt;
Yes, for manual mounts. You will be prompted for a password on each mount. For persistent fstab mounts or automated scripts, SSH key-based authentication is required since there is no prompt at boot time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is SSHFS suitable for high-performance file transfers?&lt;/strong&gt;&lt;br&gt;
SSHFS has higher latency than NFS or direct access because all data is encrypted over SSH. It is well suited for occasional file access and editing. For large-scale or performance-critical transfers, use rsync or NFS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I mount as a different user?&lt;/strong&gt;&lt;br&gt;
Specify the remote username in the mount command: &lt;code&gt;sshfs remoteuser@host:/path /local/mountpoint&lt;/code&gt;. The remote user must have read access to the directory being mounted.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SSHFS is a simple way to access remote files over SSH without any server-side configuration. For a complete list of options, run &lt;code&gt;man sshfs&lt;/code&gt; in your terminal. To further secure your SSH server, consider setting up an &lt;a href="https://linuxize.com/post/how-to-set-up-sftp-chroot-jail/"&gt;SFTP chroot jail&lt;/a&gt;
for restricted users and &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;changing the default SSH port&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-use-sshfs-to-mount-remote-directories-over-ssh/featured_hu_305214e442091101.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Transfer Files with Rsync over SSH</title><link>https://linuxize.com/post/how-to-transfer-files-with-rsync-over-ssh/</link><pubDate>Mon, 19 Aug 2019 20:11:37 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-transfer-files-with-rsync-over-ssh/</guid><category>rsync</category><category>linux commands</category><description>Use rsync over SSH to copy and synchronize files and directories between local and remote systems, with examples for custom ports, dry runs, compression, and progress display.</description><content:encoded>&lt;p&gt;&lt;code&gt;rsync&lt;/code&gt; over SSH is one of the most efficient ways to copy and synchronize files between Linux systems. It combines secure transport with fast incremental transfers, making it useful for backups, deployments, and routine file sync tasks.&lt;/p&gt;
&lt;p&gt;This guide explains how to transfer files with &lt;a href="https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/"&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/a&gt;
over SSH, including local-to-remote and remote-to-local copies, custom SSH ports, dry runs, and directory synchronization.&lt;/p&gt;
&lt;p&gt;If you want to keep dated backup versions instead of one synchronized copy, see our guide to &lt;a href="https://linuxize.com/post/rsync-incremental-backups-with-link-dest/"&gt;rsync incremental backups with &lt;code&gt;--link-dest&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Our interactive &lt;a href="https://linuxize.com/tools/rsync-command-builder/"&gt;rsync command builder&lt;/a&gt;
generates these commands for you, including the &lt;code&gt;-e &amp;quot;ssh -p PORT&amp;quot;&lt;/code&gt; option for custom ports.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Common &lt;code&gt;rsync&lt;/code&gt; over SSH patterns. For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/rsync/"&gt;rsync cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a file.txt user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy a file to remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a user@host:/src/file.txt /dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy a file from remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a /src/ user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sync directory contents to remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a -n /src/ user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dry run: preview changes without transferring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a -P /src/ user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show progress bar during transfer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a -z /src/ user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable compression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a --delete /src/ user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mirror: delete extra files on remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a --exclude=&amp;quot;*.log&amp;quot; /src/ user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exclude files by pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rsync -a -e &amp;quot;ssh -p PORT&amp;quot; /src/ user@host:/dest/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use a custom SSH port&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="requirements"&gt;Requirements &lt;a class="headline-link" href="#requirements" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;rsync&lt;/code&gt; utility must be installed on both the destination and the source systems. If it is not installed you can install it using your distribution&amp;rsquo;s package manager:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ubuntu and Debian:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install rsync&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Fedora, RHEL, and Derivatives:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install rsync&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SSH access to the remote computer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The user running the &lt;code&gt;rsync&lt;/code&gt; command and the remote SSH user must have appropriate permissions to read and write files.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="using-rsync-to-transfer-files-over-ssh"&gt;Using &lt;code&gt;rsync&lt;/code&gt; to Transfer Files over SSH &lt;a class="headline-link" href="#using-rsync-to-transfer-files-over-ssh" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With &lt;code&gt;rsync&lt;/code&gt;, you can transfer files and directories over SSH from and to remote servers.&lt;/p&gt;
&lt;p&gt;The general syntax for transferring files with &lt;code&gt;rsync&lt;/code&gt; is as follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Local to Remote: rsync [OPTION]... -e ssh [SRC]... [USER@]HOST:DEST
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Remote to Local: rsync [OPTION]... -e ssh [USER@]HOST:SRC... [DEST]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Where &lt;code&gt;SRC&lt;/code&gt; is the source directory, &lt;code&gt;DEST&lt;/code&gt; is the destination directory &lt;code&gt;USER&lt;/code&gt; is the remote SSH username and &lt;code&gt;HOST&lt;/code&gt; is the remote SSH host or IP Address.&lt;/p&gt;
&lt;p&gt;The newer versions of rsync are configured to use SSH as default remote shell so you can omit the &lt;code&gt;-e ssh&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;For example, to transfer a single file &lt;code&gt;/opt/file.zip&lt;/code&gt; from the local system to the &lt;code&gt;/var/www/&lt;/code&gt; directory on the remote system with IP &lt;code&gt;12.12.12.12&lt;/code&gt; you would run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a /opt/file.zip user@12.12.12.12:/var/www/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-a&lt;/code&gt; option stands for archive mode which syncs directories recursively, transfers special and block devices, preserves symbolic links, modification times, group, ownership, and permissions.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t set a &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;passwordless SSH login&lt;/a&gt;
to the remote machine, you will be prompted to enter the user password.&lt;/p&gt;
&lt;p&gt;If the file exists on the remote server it will be overwritten. If you want to save the file under a different name, specify the new name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a /opt/file.zip user@12.12.12.12:/var/www/file2.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To transfer data from a remote to a local machine, use the remote location as the source and the local location as destination:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a user@12.12.12.12:/var/www/file.zip /opt/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Transferring directories with &lt;code&gt;rsync&lt;/code&gt; over SSH is the same as transferring files.&lt;/p&gt;
&lt;p&gt;One of the most important &lt;code&gt;rsync&lt;/code&gt; behaviors to understand is how a trailing slash on the source path changes the result.&lt;/p&gt;
&lt;p&gt;It is important to know that &lt;code&gt;rsync&lt;/code&gt; gives different treatment to the source directories with a trailing slash &lt;code&gt;/&lt;/code&gt;. When the source directory has a trailing slash, &lt;code&gt;rsync&lt;/code&gt; will copy only the contents of the source directory to the destination directory. When the trailing slash is omitted the source directory will be copied inside the destination directory.&lt;/p&gt;
&lt;p&gt;For example to transfer the local &lt;code&gt;/opt/website/images/&lt;/code&gt; directory to the &lt;code&gt;/var/www/images/&lt;/code&gt; directory on a remote machine you would type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a /home/linuxize/images/ user@12.12.12.12:/var/www/images/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use the &lt;code&gt;--delete&lt;/code&gt; option if you want to synchronize the local and remote directory. Be careful when using this option as it will delete files in the destination directory if they do not exist in the source directory.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a --delete /home/linuxize/images/ user@12.12.12.12:/var/www/images/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If SSH on the remote host is &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;listening&lt;/a&gt;
on a port other than the default &lt;code&gt;22&lt;/code&gt;, specify the port using the &lt;code&gt;-e&lt;/code&gt; option. For example, if SSH is listening on port &lt;code&gt;3322&lt;/code&gt; you would use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a -e &lt;span class="s2"&gt;&amp;#34;ssh -p 3322&amp;#34;&lt;/span&gt; /home/linuxize/images/ user@12.12.12.12:/var/www/images/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When transferring large amounts of data it is recommended to run the &lt;code&gt;rsync&lt;/code&gt; command inside a &lt;a href="https://linuxize.com/post/how-to-use-linux-screen/"&gt;screen&lt;/a&gt;
session or use the &lt;code&gt;-P&lt;/code&gt; option which tells &lt;code&gt;rsync&lt;/code&gt; to show a progress bar during the transfer and keep the partially transferred files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a -P /home/linuxize/images/ user@12.12.12.12:/var/www/images/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To reduce bandwidth usage on slow connections, add the &lt;code&gt;-z&lt;/code&gt; flag to enable compression during the transfer:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a -z /home/linuxize/images/ user@12.12.12.12:/var/www/images/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Before running a destructive operation such as &lt;code&gt;--delete&lt;/code&gt;, use the &lt;code&gt;-n&lt;/code&gt; (or &lt;code&gt;--dry-run&lt;/code&gt;) flag to preview exactly what &lt;code&gt;rsync&lt;/code&gt; would transfer or remove without making any changes:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rsync -a -n --delete /home/linuxize/images/ user@12.12.12.12:/var/www/images/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To &lt;a href="https://linuxize.com/post/how-to-exclude-files-and-directories-with-rsync/"&gt;exclude files or directories&lt;/a&gt;
from the transfer, use the &lt;code&gt;--exclude&lt;/code&gt; option.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;rsync: command not found&lt;/code&gt;&lt;/strong&gt;
&lt;code&gt;rsync&lt;/code&gt; is not installed on the local or remote system. Install it on both machines; see the Requirements section above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Permission denied (publickey)&lt;/code&gt;&lt;/strong&gt;
The SSH key is missing or not authorized on the remote host. Set up &lt;a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/"&gt;passwordless SSH login&lt;/a&gt;
or pass the password interactively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ssh: connect to host port 22: Connection refused&lt;/code&gt;&lt;/strong&gt;
SSH is running on a non-default port. Use &lt;code&gt;-e &amp;quot;ssh -p PORT&amp;quot;&lt;/code&gt; to specify the correct port.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Files are not syncing as expected&lt;/strong&gt;
Check the trailing slash on the source path. &lt;code&gt;rsync -a /src/ dest/&lt;/code&gt; copies the contents of &lt;code&gt;src&lt;/code&gt;; &lt;code&gt;rsync -a /src dest/&lt;/code&gt; copies the &lt;code&gt;src&lt;/code&gt; directory itself into &lt;code&gt;dest&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transfer is slow over a high-latency connection&lt;/strong&gt;
Add &lt;code&gt;-z&lt;/code&gt; to enable compression. For large files this can significantly reduce transfer time.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What does the &lt;code&gt;-a&lt;/code&gt; flag do?&lt;/strong&gt;
Archive mode (&lt;code&gt;-a&lt;/code&gt;) is equivalent to &lt;code&gt;-rlptgoD&lt;/code&gt;. It syncs recursively and preserves symbolic links, permissions, timestamps, group, owner, and device files, making it the most common choice for backups and migrations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I preview what rsync will do before transferring?&lt;/strong&gt;
Add &lt;code&gt;-n&lt;/code&gt; or &lt;code&gt;--dry-run&lt;/code&gt; to your command. &lt;code&gt;rsync&lt;/code&gt; will print every file it would transfer or delete without making any actual changes. Combine it with &lt;code&gt;-v&lt;/code&gt; for verbose output.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;rsync&lt;/code&gt; and &lt;code&gt;scp&lt;/code&gt;?&lt;/strong&gt;
&lt;a href="https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/"&gt;&lt;code&gt;scp&lt;/code&gt;&lt;/a&gt;
always copies the full file. &lt;code&gt;rsync&lt;/code&gt; compares source and destination and transfers only the differences, which makes repeat transfers of large directories much faster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use &lt;code&gt;rsync&lt;/code&gt; with an SSH config file?&lt;/strong&gt;
Yes. If you have a host alias defined in &lt;code&gt;~/.ssh/config&lt;/code&gt;, you can use it directly (for example, &lt;code&gt;rsync -a /src/ myserver:/dest/&lt;/code&gt;) and &lt;code&gt;rsync&lt;/code&gt; will pick up the port, key, and username from the config entry.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We have shown you how to use &lt;code&gt;rsync&lt;/code&gt; over SSH to copy and synchronize files and directories. Use &lt;code&gt;-n&lt;/code&gt; to preview any operation before running it, and &lt;code&gt;-z&lt;/code&gt; to speed up transfers over slow connections.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-transfer-files-with-rsync-over-ssh/featured_hu_6c359e778dd415c8.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>SSH Hardening Guide: Best Practices for Linux Servers</title><link>https://linuxize.com/post/ssh-hardening-best-practices/</link><pubDate>Sun, 01 Feb 2026 11:40:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ssh-hardening-best-practices/</guid><category>ssh</category><category>security</category><description>SSH hardening best practices for Linux servers, including sshd_config checks, key-only logins, root login restrictions, firewall rules, timeouts, and Fail2Ban.</description><content:encoded>&lt;p&gt;SSH makes remote Linux server administration easy, but defaults are not always safe. A poorly configured SSH server can be an easy target for brute-force attacks, exposed accounts, and unauthorized access.&lt;/p&gt;
&lt;p&gt;This guide covers practical SSH hardening best practices for Linux servers. We will adjust &lt;code&gt;sshd_config&lt;/code&gt;, test the configuration before restarting the service, and add protections that reduce the attack surface without making the server hard to manage.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PasswordAuthentication&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Force key-based authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;KbdInteractiveAuthentication&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable keyboard-interactive password prompts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PermitRootLogin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable root SSH login&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AllowUsers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deploy admin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restrict SSH access to listed users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PermitEmptyPasswords&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Block empty passwords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoginGraceTime&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;30&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shorten the authentication window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MaxAuthTries&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Limit failed login attempts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X11Forwarding&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable X11 forwarding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AllowAgentForwarding&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable agent forwarding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AllowTcpForwarding&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable SSH tunnels for users who do not need them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ClientAliveInterval&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;300&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set idle timeout interval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ClientAliveCountMax&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disconnect after 2 missed keep-alives&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A server running Linux with SSH access&lt;/li&gt;
&lt;li&gt;Root or &lt;a href="https://linuxize.com/post/how-to-add-user-to-sudoers-in-ubuntu/"&gt;sudo privileges&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A working SSH key pair (see &lt;a href="https://linuxize.com/post/how-to-generate-ssh-keys-on-linux/"&gt;how to generate SSH keys&lt;/a&gt;
)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All SSH server settings are configured in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;. Some distributions also load files from &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt;, which is useful when you want to keep local changes separate from package defaults.&lt;/p&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Before applying any of these changes, keep your current SSH session open and make sure you have an alternative way to access your server, such as a console connection, in case you lock yourself out.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Before editing the SSH configuration, create a backup:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After each change, test the configuration before restarting SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sshd -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command prints no output, the configuration syntax is valid. Then restart the SSH service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On some distributions the service is named &lt;code&gt;sshd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="use-key-based-authentication"&gt;Use Key-Based Authentication &lt;a class="headline-link" href="#use-key-based-authentication" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Password authentication is vulnerable to brute-force attacks. Key-based authentication is more secure because it requires possession of the private key.&lt;/p&gt;
&lt;p&gt;First, make sure you have &lt;a href="https://linuxize.com/post/ssh-copy-id-command/"&gt;copied your SSH key&lt;/a&gt;
to the server and can log in without a password.&lt;/p&gt;
&lt;p&gt;Then disable password authentication in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PasswordAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;KbdInteractiveAuthentication no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PubkeyAuthentication yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This forces users to authenticate with SSH keys and disables keyboard-interactive password prompts. Keep password authentication enabled until you have confirmed that your key login works from a new terminal session.&lt;/p&gt;
&lt;h2 id="disable-root-login"&gt;Disable Root Login &lt;a class="headline-link" href="#disable-root-login" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Allowing direct root login over SSH is a security risk. Attackers commonly target the &lt;code&gt;root&lt;/code&gt; account in brute-force attacks.&lt;/p&gt;
&lt;p&gt;Disable root login in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PermitRootLogin no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you need root access, log in as a regular user and use &lt;a href="https://linuxize.com/post/sudo-command-in-linux/"&gt;&lt;code&gt;sudo&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/su-command-in-linux/"&gt;&lt;code&gt;su&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If you still need root login with keys only, use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PermitRootLogin prohibit-password&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This allows root login only with SSH keys, not passwords.&lt;/p&gt;
&lt;h2 id="restrict-ssh-by-firewall"&gt;Restrict SSH by Firewall &lt;a class="headline-link" href="#restrict-ssh-by-firewall" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If only a few IP addresses need SSH access, restrict the SSH port at the firewall. This is usually stronger than only changing the SSH port because unwanted hosts cannot reach the daemon at all.&lt;/p&gt;
&lt;p&gt;With UFW, allow SSH from a trusted IP address:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow from 203.0.113.10 to any port &lt;span class="m"&gt;22&lt;/span&gt; proto tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you manage the server from more than one location, add each trusted IP address before removing broader SSH rules. Do not close the current SSH port until you have tested a new connection.&lt;/p&gt;
&lt;h2 id="change-the-default-port"&gt;Change the Default Port &lt;a class="headline-link" href="#change-the-default-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The default SSH port is 22. Changing it does not provide real security, but it reduces noise from automated bots that scan port 22.&lt;/p&gt;
&lt;p&gt;Change the port in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Port 2222&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Make sure to open the new port in your &lt;a href="https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-24-04/"&gt;firewall&lt;/a&gt;
before restarting SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 2222/tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For more details, see our guide on &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;how to change the SSH port&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="limit-user-access"&gt;Limit User Access &lt;a class="headline-link" href="#limit-user-access" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, all system users can log in via SSH. You can restrict access to specific users with the &lt;code&gt;AllowUsers&lt;/code&gt; directive:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;AllowUsers deploy admin&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Only the listed users will be able to connect. All others will be denied.&lt;/p&gt;
&lt;p&gt;To restrict access by group instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;AllowGroups sshusers&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="disable-empty-passwords"&gt;Disable Empty Passwords &lt;a class="headline-link" href="#disable-empty-passwords" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Make sure accounts with empty passwords cannot log in via SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PermitEmptyPasswords no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="set-login-grace-time"&gt;Set Login Grace Time &lt;a class="headline-link" href="#set-login-grace-time" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;LoginGraceTime&lt;/code&gt; setting controls how long the server waits for a user to authenticate before disconnecting. The default is 120 seconds, which is too long:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;LoginGraceTime 30&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="limit-authentication-attempts"&gt;Limit Authentication Attempts &lt;a class="headline-link" href="#limit-authentication-attempts" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Reduce the number of authentication attempts per connection to slow down brute-force attacks:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;MaxAuthTries 3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="disable-x11-forwarding"&gt;Disable X11 Forwarding &lt;a class="headline-link" href="#disable-x11-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you do not need to forward graphical applications over SSH, disable X11 forwarding:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;X11Forwarding no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;OpenSSH disables X11 forwarding by default on many systems, but setting it explicitly keeps the intended policy clear.&lt;/p&gt;
&lt;h2 id="disable-agent-forwarding"&gt;Disable Agent Forwarding &lt;a class="headline-link" href="#disable-agent-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Agent forwarding lets a remote server use your local SSH agent for onward connections. Disable it unless users need to connect from this server to other hosts with forwarded credentials:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;AllowAgentForwarding no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="disable-tcp-forwarding"&gt;Disable TCP Forwarding &lt;a class="headline-link" href="#disable-tcp-forwarding" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If your users do not need to create SSH tunnels, disable TCP forwarding:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;AllowTcpForwarding no&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This blocks SSH port forwarding requests. It does not stop users with shell access from running their own forwarding tools, but it removes the built-in SSH tunneling path.&lt;/p&gt;
&lt;h2 id="use-strong-key-types"&gt;Use Strong Key Types &lt;a class="headline-link" href="#use-strong-key-types" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When generating SSH keys, use Ed25519 or RSA with at least 4096 bits. Ed25519 is the recommended choice for new keys:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For RSA:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t rsa -b &lt;span class="m"&gt;4096&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Older key types like DSA and ECDSA with small key sizes should be avoided.&lt;/p&gt;
&lt;h2 id="set-idle-timeout"&gt;Set Idle Timeout &lt;a class="headline-link" href="#set-idle-timeout" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Disconnect idle SSH sessions after a period of inactivity. This prevents abandoned sessions from remaining open:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ClientAliveInterval 300&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ClientAliveCountMax 2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This sends a keep-alive message every 300 seconds (5 minutes) and disconnects after 2 missed responses, giving a total timeout of 10 minutes.&lt;/p&gt;
&lt;h2 id="set-up-fail2ban"&gt;Set Up Fail2Ban &lt;a class="headline-link" href="#set-up-fail2ban" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Fail2Ban monitors authentication logs and bans IP addresses that show malicious activity, such as repeated failed login attempts. It is most useful on public SSH servers that still receive frequent connection attempts.&lt;/p&gt;
&lt;p&gt;Install Fail2Ban:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install fail2ban&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Create a jail override file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/fail2ban/jail.d/sshd.local&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add the SSH jail configuration:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fail2ban/jail.d/sshd.local&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[sshd]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ssh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;sshd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;maxretry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;bantime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;findtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;600&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This configuration bans an IP address for 1 hour after 3 failed login attempts within 10 minutes. The default &lt;code&gt;sshd&lt;/code&gt; jail usually knows where your distribution writes SSH authentication logs, so you do not need to set &lt;code&gt;logpath&lt;/code&gt; unless your server uses a custom logging setup.&lt;/p&gt;
&lt;p&gt;If you changed SSH to a custom port, set &lt;code&gt;port&lt;/code&gt; to that value in the jail file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fail2ban/jail.d/sshd.local&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;2222&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Start and enable Fail2Ban:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; fail2ban
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start fail2ban&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To check the status of the SSH jail:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo fail2ban-client status sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="display-a-warning-banner"&gt;Display a Warning Banner &lt;a class="headline-link" href="#display-a-warning-banner" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can display a legal warning banner before authentication. Create a banner file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/ssh/banner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add your warning text:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="text"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/banner&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;text&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Authorized access only. All activity is monitored and logged.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then enable it in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Banner /etc/ssh/banner&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SSH does not restart after editing sshd_config&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo sshd -t&lt;/code&gt; to find syntax errors. If you need to revert quickly, restore the backup with &lt;code&gt;sudo cp /etc/ssh/sshd_config.backup /etc/ssh/sshd_config&lt;/code&gt;, then test the configuration again before restarting SSH.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Password login still works after setting PasswordAuthentication no&lt;/strong&gt;&lt;br&gt;
Check whether &lt;code&gt;KbdInteractiveAuthentication&lt;/code&gt; is still enabled. On PAM-based systems, keyboard-interactive authentication can still ask for a password, so set both &lt;code&gt;PasswordAuthentication no&lt;/code&gt; and &lt;code&gt;KbdInteractiveAuthentication no&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The service name is different on your system&lt;/strong&gt;&lt;br&gt;
Ubuntu and Debian commonly use &lt;code&gt;ssh.service&lt;/code&gt;, while RHEL, Fedora, and many other distributions use &lt;code&gt;sshd.service&lt;/code&gt;. Check the active unit with &lt;code&gt;systemctl status ssh&lt;/code&gt; or &lt;code&gt;systemctl status sshd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You changed the port but cannot connect&lt;/strong&gt;&lt;br&gt;
Make sure the firewall allows the new port before restarting SSH. If you use Ubuntu socket activation, &lt;code&gt;ssh.socket&lt;/code&gt; may still listen on port 22 unless the socket configuration is updated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fail2Ban does not show bans for SSH&lt;/strong&gt;&lt;br&gt;
Check the jail status with &lt;code&gt;sudo fail2ban-client status sshd&lt;/code&gt;. If the jail is active but no failures are detected, review your authentication logs with &lt;code&gt;sudo journalctl -u ssh&lt;/code&gt; or &lt;code&gt;sudo journalctl -u sshd&lt;/code&gt; and confirm that Fail2Ban is using the correct backend for your distribution.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Should I change the SSH port?&lt;/strong&gt;&lt;br&gt;
Changing the port reduces automated scanning noise but does not provide real security. It is useful as part of a defense-in-depth strategy, not as a standalone measure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I lock myself out by disabling password authentication?&lt;/strong&gt;&lt;br&gt;
Yes. Before disabling password authentication, make sure you can log in with your SSH key. Keep a console connection available as a backup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is Fail2Ban necessary if I use key-only authentication?&lt;/strong&gt;&lt;br&gt;
It is not strictly necessary, but it still helps. Fail2Ban reduces log noise and blocks IPs that repeatedly attempt to connect, even if they cannot authenticate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the most important hardening step?&lt;/strong&gt;&lt;br&gt;
Disabling password authentication and using key-based authentication. This eliminates the most common attack vector: brute-force password guessing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I check my current SSH configuration?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo sshd -T&lt;/code&gt; to display the effective SSH server configuration, including all defaults and overrides.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SSH hardening starts with safe configuration changes: key-based authentication, no direct root login, limited users, firewall restrictions, timeouts, and tested &lt;code&gt;sshd_config&lt;/code&gt; edits. Apply the settings that fit your server, and always test a new SSH session before closing the old one.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ssh-hardening-best-practices/featured_hu_2086069a211fd0eb.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>SSH Permission Denied (publickey): Causes and Fixes</title><link>https://linuxize.com/post/fix-ssh-permission-denied-publickey/</link><pubDate>Mon, 02 Feb 2026 10:30:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/fix-ssh-permission-denied-publickey/</guid><category>ssh</category><description>How to troubleshoot the SSH "Permission denied (publickey)" error in Linux. Covers file permissions, missing keys, SELinux, SSH agent issues, and server-side debugging.</description><content:encoded>&lt;p&gt;The &amp;ldquo;Permission denied (publickey)&amp;rdquo; error occurs when the SSH server rejects your connection because it cannot verify your identity using public key authentication.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;user@remote_host: Permission denied (publickey).&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is one of the most common SSH errors. Seeing it is actually a good sign for the network path, because the server answered and reached the authentication stage; a connection that stops earlier with &lt;a href="https://linuxize.com/post/fix-ssh-connection-refused/"&gt;connection refused&lt;/a&gt;
is a different problem. In this guide, we will go through the most frequent causes and how to fix them.&lt;/p&gt;
&lt;h2 id="debugging-the-connection"&gt;Debugging the Connection &lt;a class="headline-link" href="#debugging-the-connection" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before trying specific fixes, run SSH in verbose mode to see exactly where the authentication fails:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -v user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For even more detail, use &lt;code&gt;-vv&lt;/code&gt; or &lt;code&gt;-vvv&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -vvv user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Look for lines like:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;debug1: Offering public key: /home/user/.ssh/id_ed25519
debug1: Server accepts key: /home/user/.ssh/id_ed25519&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;debug1: Trying private key: /home/user/.ssh/id_ed25519
debug1: No more authentication methods to try.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The verbose output tells you which keys are being tried and where the process fails.&lt;/p&gt;
&lt;h2 id="common-causes-and-fixes"&gt;Common Causes and Fixes &lt;a class="headline-link" href="#common-causes-and-fixes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="1-public-key-not-on-the-remote-server"&gt;1. Public Key Not on the Remote Server &lt;a class="headline-link" href="#1-public-key-not-on-the-remote-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The most common cause is that your public key is not in the remote server&amp;rsquo;s &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Copy your public key to the server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-copy-id user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;ssh-copy-id&lt;/code&gt; is not available, copy it manually:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat ~/.ssh/id_ed25519.pub &lt;span class="p"&gt;|&lt;/span&gt; ssh user@remote_host &lt;span class="s2"&gt;&amp;#34;mkdir -p ~/.ssh &amp;amp;&amp;amp; chmod 700 ~/.ssh &amp;amp;&amp;amp; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys &amp;amp;&amp;amp; chmod 600 ~/.ssh/authorized_keys&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For more details, see our guide on &lt;a href="https://linuxize.com/post/ssh-copy-id-command/"&gt;how to copy SSH keys with ssh-copy-id&lt;/a&gt;
.&lt;/p&gt;
&lt;h3 id="2-wrong-file-permissions"&gt;2. Wrong File Permissions &lt;a class="headline-link" href="#2-wrong-file-permissions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;SSH is strict about file permissions. If the permissions are too open, the SSH server will reject the key.&lt;/p&gt;
&lt;p&gt;On the &lt;strong&gt;remote server&lt;/strong&gt;, set the correct permissions:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;700&lt;/span&gt; ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;600&lt;/span&gt; ~/.ssh/authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On the &lt;strong&gt;local machine&lt;/strong&gt;, set the correct permissions on your private key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;600&lt;/span&gt; ~/.ssh/id_ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The SSH server will also reject keys if the home directory is writable by others:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;755&lt;/span&gt; ~&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These checks are enforced by the &lt;code&gt;StrictModes yes&lt;/code&gt; setting in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;, which is enabled by default. Do not disable it; fix the permissions instead.&lt;/p&gt;
&lt;h3 id="3-wrong-user-or-hostname"&gt;3. Wrong User or Hostname &lt;a class="headline-link" href="#3-wrong-user-or-hostname" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Make sure you are connecting as the correct user. The key must be in that user&amp;rsquo;s &lt;code&gt;authorized_keys&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh deploy@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you have a host alias in your &lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;SSH config file&lt;/a&gt;
, verify it points to the correct hostname and user.&lt;/p&gt;
&lt;h3 id="4-ssh-agent-not-running"&gt;4. SSH Agent Not Running &lt;a class="headline-link" href="#4-ssh-agent-not-running" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If your key is protected with a passphrase and the SSH agent is not running, the key will not be offered to the server.&lt;/p&gt;
&lt;p&gt;Start the SSH agent and add your key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;ssh-agent -s&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-add ~/.ssh/id_ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To list the keys currently loaded in the agent:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-add -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="5-wrong-key-being-used"&gt;5. Wrong Key Being Used &lt;a class="headline-link" href="#5-wrong-key-being-used" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you have multiple SSH keys, the client may be offering the wrong one. Specify the key explicitly:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -i ~/.ssh/id_ed25519 user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Or configure it in your &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ssh/config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host remote_host
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; HostName 192.168.1.10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; User deploy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; IdentityFile ~/.ssh/id_ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="6-public-key-authentication-disabled-on-the-server"&gt;6. Public Key Authentication Disabled on the Server &lt;a class="headline-link" href="#6-public-key-authentication-disabled-on-the-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If public key authentication is disabled on the server, key-based login will not work regardless of your key setup. Check &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; on the server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PasswordAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PubkeyAuthentication yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;PubkeyAuthentication&lt;/code&gt; is set to &lt;code&gt;no&lt;/code&gt;, key-based login will not work. Change it to &lt;code&gt;yes&lt;/code&gt; and restart SSH:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="7-key-type-not-accepted"&gt;7. Key Type Not Accepted &lt;a class="headline-link" href="#7-key-type-not-accepted" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Some servers are configured to accept only certain key types. If your key type is not allowed, the server will reject it.&lt;/p&gt;
&lt;p&gt;Check the &lt;code&gt;PubkeyAcceptedAlgorithms&lt;/code&gt; setting in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PubkeyAcceptedAlgorithms +ssh-rsa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are using an older RSA key, the server may require you to explicitly allow it. This should be a last resort because &lt;code&gt;ssh-rsa&lt;/code&gt; is deprecated on modern OpenSSH. A better solution is to generate a new Ed25519 key:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="8-selinux-blocking-access"&gt;8. SELinux Blocking Access &lt;a class="headline-link" href="#8-selinux-blocking-access" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On systems with SELinux enabled (Fedora, RHEL, and derivatives), SELinux may prevent the SSH server from reading the &lt;code&gt;authorized_keys&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Check for SELinux denials:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ausearch -m avc -ts recent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Restore the correct SELinux context:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo restorecon -R ~/.ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="9-home-directory-on-network-storage"&gt;9. Home Directory on Network Storage &lt;a class="headline-link" href="#9-home-directory-on-network-storage" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If the user&amp;rsquo;s home directory is on NFS or another network filesystem, the SSH server may not be able to read the &lt;code&gt;authorized_keys&lt;/code&gt; file before the filesystem is mounted.&lt;/p&gt;
&lt;p&gt;You can configure an alternative location for authorized keys in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;AuthorizedKeysFile /etc/ssh/authorized_keys/%u&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then place the user&amp;rsquo;s keys in &lt;code&gt;/etc/ssh/authorized_keys/username&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="server-side-debugging"&gt;Server-Side Debugging &lt;a class="headline-link" href="#server-side-debugging" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you have access to the server, check the authentication log for the exact reason SSH rejected the connection.&lt;/p&gt;
&lt;p&gt;On Ubuntu and Debian:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo tail -f /var/log/auth.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo tail -f /var/log/secure&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The log entries usually show whether the issue is permissions, a missing key, or a configuration mismatch on the server side.&lt;/p&gt;
&lt;p&gt;For the most detailed output, run the SSH server in debug mode temporarily on a different port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo /usr/sbin/sshd -d -p &lt;span class="m"&gt;2222&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then connect to it from the client:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -p &lt;span class="m"&gt;2222&lt;/span&gt; user@remote_host&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The server will print every step of the authentication exchange to the terminal, which makes it easy to see exactly where the login fails.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Key not on server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh-copy-id user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong permissions on &lt;code&gt;~/.ssh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chmod 700 ~/.ssh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong permissions on &lt;code&gt;authorized_keys&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chmod 600 ~/.ssh/authorized_keys&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong permissions on private key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chmod 600 ~/.ssh/id_ed25519&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSH agent not running&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eval &amp;quot;$(ssh-agent -s)&amp;quot; &amp;amp;&amp;amp; ssh-add&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wrong key offered&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -i ~/.ssh/key user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SELinux blocking access&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo restorecon -R ~/.ssh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check auth log (Ubuntu)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo tail -f /var/log/auth.log&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debug SSH connection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -vvv user@host&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Why does SSH care about file permissions?&lt;/strong&gt;&lt;br&gt;
SSH refuses to use keys with overly permissive file permissions because other users on the system could read your private key or modify your &lt;code&gt;authorized_keys&lt;/code&gt; file. This is a security feature, not a bug.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I copied my key but it still does not work. What should I check?&lt;/strong&gt;&lt;br&gt;
Check the permissions on the remote &lt;code&gt;~/.ssh&lt;/code&gt; directory (700), the &lt;code&gt;authorized_keys&lt;/code&gt; file (600), and the home directory (755 or stricter). Also verify you are connecting as the correct user.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I check which keys the SSH client is trying?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;ssh -v user@host&lt;/code&gt; and look for lines starting with &lt;code&gt;debug1: Offering public key&lt;/code&gt; or &lt;code&gt;debug1: Trying private key&lt;/code&gt;. This shows which keys are being offered to the server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does this error always mean a key problem?&lt;/strong&gt;&lt;br&gt;
Not always. If the server has &lt;code&gt;PasswordAuthentication no&lt;/code&gt; and &lt;code&gt;PubkeyAuthentication no&lt;/code&gt;, all authentication methods are disabled and you will see this error regardless.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I temporarily enable password login to fix the key?&lt;/strong&gt;&lt;br&gt;
Yes. If you have console access, set &lt;code&gt;PasswordAuthentication yes&lt;/code&gt; in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;, restart SSH, copy your key with &lt;code&gt;ssh-copy-id&lt;/code&gt;, then disable password authentication again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I get this error on an AWS, GCP, or Azure instance. What should I check?&lt;/strong&gt;&lt;br&gt;
Cloud instances use a specific key pair set during provisioning. Make sure you are using that key: &lt;code&gt;ssh -i ~/.ssh/my-cloud-key.pem user@host&lt;/code&gt;. The default username also varies by provider (e.g., &lt;code&gt;ec2-user&lt;/code&gt; on Amazon Linux, &lt;code&gt;ubuntu&lt;/code&gt; on Ubuntu instances, &lt;code&gt;azureuser&lt;/code&gt; on Azure). Check your provider&amp;rsquo;s documentation for the correct username.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before disabling password authentication or closing your current session, open a second terminal and confirm that key-based login works end-to-end. Otherwise, a small mistake in &lt;code&gt;sshd_config&lt;/code&gt; or in the &lt;code&gt;authorized_keys&lt;/code&gt; file can lock you out of the server.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/fix-ssh-permission-denied-publickey/featured_hu_8e09011ea3c31e20.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>SSH Connection Refused: Causes and Fixes</title><link>https://linuxize.com/post/fix-ssh-connection-refused/</link><pubDate>Thu, 23 Jul 2026 14:20:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/fix-ssh-connection-refused/</guid><category>ssh</category><description>Fix the SSH "Connection refused" error by checking the destination, listening port, OpenSSH service or socket, firewall rules, and port forwarding.</description><content:encoded>&lt;p&gt;You try to log in and SSH stops immediately with &lt;code&gt;connect to host example.com port 22: Connection refused&lt;/code&gt;. The failure happens before SSH checks your key or password, so changing authentication settings will not fix it.&lt;/p&gt;
&lt;p&gt;An immediate refusal means the target address has no process listening on that port, or a firewall or network device actively rejected the request. The usual causes are a stopped SSH server, the wrong host or port, a listener bound to another address, a firewall reject rule, or port forwarding to the wrong machine. A connection that hangs and then times out is different because no response came back.&lt;/p&gt;
&lt;p&gt;This guide starts with checks you can run from the client, then moves to the SSH service, listening port, firewall, and network path on the server.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Confirm the destination address&lt;/td&gt;
&lt;td&gt;&lt;code&gt;getent ahosts example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show SSH connection details&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ssh -vvv user@example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test the default SSH port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nc -vz example.com 22&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check for a listener on port 22&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ss -ltnp 'sport = :22'&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show the effective SSH port and addresses&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo sshd -T | grep -E '^(port|listenaddress) '&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check SSH on Ubuntu or Debian&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl status ssh.service ssh.socket&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check SSH on Fedora or RHEL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl status sshd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check UFW rules&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw status numbered&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check firewalld services&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo firewall-cmd --list-services&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="confirm-the-host-and-port-from-the-client"&gt;Confirm the Host and Port from the Client &lt;a class="headline-link" href="#confirm-the-host-and-port-from-the-client" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before changing the server, confirm that the hostname resolves to the address you expect:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;getent ahosts example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the result points to an old server or the wrong public address, correct the DNS record or connect to the intended IP address directly. Reaching the wrong host can produce a refusal even when SSH is working on the real server.&lt;/p&gt;
&lt;p&gt;Next, run SSH with verbose output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -vvv user@example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The relevant lines look like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;debug1: Connecting to example.com [203.0.113.10] port 22.
ssh: connect to host example.com port 22: Connection refused&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The client resolved &lt;code&gt;example.com&lt;/code&gt; to &lt;code&gt;203.0.113.10&lt;/code&gt; and received an immediate refusal from port 22. You can test the TCP port without starting an SSH login:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nc -vz example.com &lt;span class="m"&gt;22&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the server uses a custom port, test and connect to that port instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nc -vz example.com &lt;span class="m"&gt;2222&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -p &lt;span class="m"&gt;2222&lt;/span&gt; user@example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A hostname can also have separate IPv4 and IPv6 addresses. Test each address family when one DNS record may point to the wrong server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -4 user@example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -6 user@example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The remaining checks require access to the server through a cloud console, virtual machine console, physical terminal, or another management channel.&lt;/p&gt;
&lt;h2 id="check-whether-ssh-is-listening"&gt;Check Whether SSH Is Listening &lt;a class="headline-link" href="#check-whether-ssh-is-listening" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The listening socket is the quickest way to tell whether the server can accept SSH connections on port 22. Run this command on the server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ss -ltnp &lt;span class="s1"&gt;&amp;#39;sport = :22&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A working listener appears as either &lt;code&gt;sshd&lt;/code&gt; or &lt;code&gt;systemd&lt;/code&gt;, depending on whether the distribution runs the daemon continuously or uses socket activation. If the command returns nothing, no process is accepting connections on port 22.&lt;/p&gt;
&lt;p&gt;To see the port and addresses from the effective OpenSSH configuration, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sshd -T &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s1"&gt;&amp;#39;^(port|listenaddress) &amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Typical output looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;port 22
listenaddress [::]:22
listenaddress 0.0.0.0:22&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows that SSH is configured for port 22 on all IPv6 and IPv4 addresses. If it reports another port, connect with the &lt;code&gt;-p&lt;/code&gt; option and verify that the firewall allows that port. See our guide on &lt;a href="https://linuxize.com/post/how-to-change-ssh-port-in-linux/"&gt;changing the SSH port&lt;/a&gt;
if you need to correct the configuration.&lt;/p&gt;
&lt;h2 id="check-the-ssh-service-or-socket"&gt;Check the SSH Service or Socket &lt;a class="headline-link" href="#check-the-ssh-service-or-socket" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Linux distributions use different systemd unit names for OpenSSH. Ubuntu and Debian use &lt;code&gt;ssh.service&lt;/code&gt;, while Fedora, RHEL, and their derivatives use &lt;code&gt;sshd.service&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On Ubuntu and Debian, check the service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status ssh.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Ubuntu 22.10 and later use &lt;code&gt;ssh.socket&lt;/code&gt; by default, so check that unit as well:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When &lt;code&gt;ssh.socket&lt;/code&gt; is active and owns port 22, &lt;code&gt;ssh.service&lt;/code&gt; may remain inactive until a client connects. In that setup, an inactive service alone does not indicate a problem. If the socket is disabled or stopped, enable it and start it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now ssh.socket&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On systems without &lt;code&gt;ssh.socket&lt;/code&gt;, enable and start the service instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and derivatives, check and start &lt;code&gt;sshd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status sshd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the unit reports &lt;code&gt;failed&lt;/code&gt;, validate the SSH server configuration:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sshd -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;No output means the configuration passed the test. If OpenSSH prints an error, correct the reported line before restarting the unit. You can also inspect the current boot logs on Ubuntu and Debian:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u ssh.service -u ssh.socket -b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For Fedora and RHEL, use the &lt;code&gt;sshd&lt;/code&gt; unit name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u sshd -b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="install-the-openssh-server"&gt;Install the OpenSSH Server &lt;a class="headline-link" href="#install-the-openssh-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some minimal installations include the SSH client but not the server. If &lt;code&gt;systemctl&lt;/code&gt; reports that the SSH unit does not exist, install the &lt;code&gt;openssh-server&lt;/code&gt; package.&lt;/p&gt;
&lt;h3 id="ubuntu-debian-and-derivatives"&gt;Ubuntu, Debian, and Derivatives &lt;a class="headline-link" href="#ubuntu-debian-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Update the package index and install the server package:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install openssh-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The package normally starts the appropriate SSH service or socket during installation. Check port 22 again with &lt;code&gt;ss&lt;/code&gt; instead of assuming that the listener started successfully.&lt;/p&gt;
&lt;h3 id="fedora-rhel-and-derivatives"&gt;Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Install the server package, then enable and start &lt;code&gt;sshd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install openssh-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="check-the-listening-address"&gt;Check the Listening Address &lt;a class="headline-link" href="#check-the-listening-address" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SSH can run normally but listen only on the loopback interface or one private address. In that case, a local connection works while connections to other server addresses are refused.&lt;/p&gt;
&lt;p&gt;Review the &lt;code&gt;listenaddress&lt;/code&gt; lines from &lt;code&gt;sshd -T&lt;/code&gt;. A value such as &lt;code&gt;127.0.0.1:22&lt;/code&gt; accepts only local IPv4 connections. OpenSSH reads its main configuration from &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; and may also read files under &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt;. A listener on a &lt;a href="https://linuxize.com/post/what-is-localhost/"&gt;loopback address&lt;/a&gt;
is reachable from the server itself and from nowhere else.&lt;/p&gt;
&lt;p&gt;Before changing &lt;code&gt;Port&lt;/code&gt; or &lt;code&gt;ListenAddress&lt;/code&gt;, keep console access open and validate the new configuration with &lt;code&gt;sudo sshd -t&lt;/code&gt;. On Ubuntu systems using socket activation, the socket must also reload the generated listening configuration. The port-change guide linked above covers the service and socket steps in order.&lt;/p&gt;
&lt;h2 id="check-the-firewall"&gt;Check the Firewall &lt;a class="headline-link" href="#check-the-firewall" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A firewall is less likely to cause an immediate refusal than a missing listener. Rules that silently drop traffic usually end with &lt;code&gt;Connection timed out&lt;/code&gt;, while an explicit &lt;code&gt;REJECT&lt;/code&gt; rule can return &lt;code&gt;Connection refused&lt;/code&gt;. Check the firewall after confirming the service and port.&lt;/p&gt;
&lt;p&gt;If the server uses UFW, list its rules with numbers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw status numbered&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Allow the standard OpenSSH profile when SSH uses port 22:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow OpenSSH&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For a custom port, allow the exact TCP port instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 2222/tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On a server using firewalld, first check the services allowed in the active zone:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --list-services&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add SSH to both the runtime and permanent configurations if it is missing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --add-service&lt;span class="o"&gt;=&lt;/span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --permanent --add-service&lt;span class="o"&gt;=&lt;/span&gt;ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For a custom port, use &lt;code&gt;--add-port=2222/tcp&lt;/code&gt; in both commands. Our &lt;a href="https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-24-04/"&gt;UFW firewall guide&lt;/a&gt;
explains how to review and manage rules in more detail.&lt;/p&gt;
&lt;h2 id="check-port-forwarding-and-external-firewalls"&gt;Check Port Forwarding and External Firewalls &lt;a class="headline-link" href="#check-port-forwarding-and-external-firewalls" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If SSH works from the same machine or local network but fails from the internet, the OpenSSH listener may already be correct. Check that the router or virtualization platform forwards the external port to the server&amp;rsquo;s current private address and SSH port.&lt;/p&gt;
&lt;p&gt;The same issue can occur with a virtual machine, container, load balancer, or cloud firewall. Confirm that public DNS points to the expected system and that each forwarding rule uses the same port you pass to &lt;code&gt;ssh&lt;/code&gt;. Cloud firewall rules often drop traffic and cause a timeout, but an edge device that rejects the request or forwards it to the wrong host can produce a refusal.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Connection refused started after an SSH configuration change&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo sshd -t&lt;/code&gt; and correct every reported error. On Ubuntu with socket activation, reload systemd and restart &lt;code&gt;ssh.socket&lt;/code&gt; after a valid &lt;code&gt;Port&lt;/code&gt; or &lt;code&gt;ListenAddress&lt;/code&gt; change, then verify the listener with &lt;code&gt;ss&lt;/code&gt; before closing console access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSH works with localhost but not the server address&lt;/strong&gt;&lt;br&gt;
Check the effective &lt;code&gt;ListenAddress&lt;/code&gt; values and the firewall rules for the external interface. A listener restricted to &lt;code&gt;127.0.0.1&lt;/code&gt; or &lt;code&gt;::1&lt;/code&gt; cannot accept remote connections.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPv4 works but IPv6 is refused&lt;/strong&gt;&lt;br&gt;
The server may have an AAAA record without an IPv6 listener. Compare &lt;code&gt;ssh -4&lt;/code&gt; and &lt;code&gt;ssh -6&lt;/code&gt;, then correct the DNS record or configure SSH to listen on the intended IPv6 address.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Only one client address is refused&lt;/strong&gt;&lt;br&gt;
A source-specific firewall rule or a tool such as Fail2ban may be rejecting that address. Review the firewall rules and, if Fail2ban is installed, check the SSH jail with &lt;code&gt;sudo fail2ban-client status sshd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSH reaches the server but reports Permission denied&lt;/strong&gt;&lt;br&gt;
The network path and listener are working, and the failure has moved to authentication. Follow the &lt;a href="https://linuxize.com/post/fix-ssh-permission-denied-publickey/"&gt;SSH Permission denied (publickey) guide&lt;/a&gt;
instead.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once the port test succeeds, SSH should move on to host-key verification or authentication. Before exposing the restored service to the internet, review our &lt;a href="https://linuxize.com/post/ssh-hardening-best-practices/"&gt;SSH hardening best practices&lt;/a&gt;
and restrict firewall access where possible.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/fix-ssh-connection-refused/featured_hu_6253d7bc6f917ca6.webp" medium="image" type="image/webp" width="1200" height="630"/></item></channel></rss>