The ssh command connects you to remote servers over an encrypted channel, replacing older plaintext protocols like Telnet and rsh. Common use cases include managing remote Linux servers, running commands without opening a full shell session, forwarding ports to access internal services through encrypted tunnels, and transferring files securely. This guide covers ssh command syntax, key options, practical connection examples, tunneling and port forwarding, SSH key authentication, configuration file management, and troubleshooting common connection errors.
Understand the ssh Command
SSH (Secure Shell) is both a protocol and a command-line tool. The protocol defines how two machines negotiate encryption, authenticate users, and exchange data. The ssh command is the client-side tool that initiates these connections from your terminal.
SSH encrypts all traffic between client and server, preventing eavesdropping on credentials and data. It supports password-based login, public key authentication, and multi-factor authentication. Beyond interactive shells, ssh handles remote command execution, secure file piping, port forwarding, SOCKS proxying, and X11 display forwarding.
Verify ssh Is Available
The OpenSSH client ships pre-installed on most Linux distributions. Confirm it is available by checking the version:
ssh -V
OpenSSH_9.6p1 Ubuntu-3ubuntu13.5, OpenSSL 3.0.13 30 Jan 2024
The version string confirms which OpenSSH release and SSL library your system uses. If ssh is not found, install the openssh-client package on Debian/Ubuntu or openssh-clients on Fedora/RHEL.
ssh Command Syntax
Every ssh invocation follows this pattern:
ssh [options] [user@]hostname [command]
[options]: Flags that control port, identity file, forwarding, verbosity, and other connection behavior.[user@]: The remote username. If omitted,sshuses your local username.hostname: The server’s DNS name or IP address.[command]: An optional command to execute remotely. When provided,sshruns the command and exits instead of opening an interactive shell.
A basic connection with no options uses your current username and the default port 22:
ssh example.com
Essential ssh Options Quick Reference
The table below summarizes the most commonly used ssh flags. Each option is demonstrated in the examples that follow.
| Option | Purpose | Example |
|---|---|---|
-p | Connect to a non-default port | ssh -p 2222 user@host |
-i | Specify a private key file | ssh -i ~/.ssh/deploy_key user@host |
-v | Enable verbose/debug output | ssh -v user@host |
-L | Local port forwarding | ssh -L 8080:localhost:80 user@host |
-R | Remote port forwarding | ssh -R 9090:localhost:3000 user@host |
-D | Dynamic SOCKS proxy | ssh -D 1080 user@host |
-N | No remote command (tunnel only) | ssh -N -L 8080:localhost:80 user@host |
-f | Background after authentication | ssh -f -N -L 8080:localhost:80 user@host |
-J | Jump through a bastion host | ssh -J bastion@jump user@target |
-A | Forward the SSH agent | ssh -A user@host |
-X | Enable X11 forwarding | ssh -X user@host |
-C | Enable compression | ssh -C user@host |
-o | Set an SSH config option inline | ssh -o ConnectTimeout=10 user@host |
-F | Use a custom config file | ssh -F ~/.ssh/alt_config user@host |
-c | Select an encryption cipher | ssh -c aes256-gcm@openssh.com user@host |
Practical ssh Command Examples
Example 1: Execute a Single Remote Command
Append a command after the hostname to run it on the remote server and return the output to your local terminal. The session closes automatically after the command finishes.
ssh user@192.168.1.50 'df -h /'
Filesystem Size Used Avail Use% Mounted on /dev/sda1 50G 12G 36G 25% /
The 'df -h /' portion runs inside a shell on the remote host. Single quotes prevent your local shell from expanding variables or wildcards before they reach the server.
Example 2: Run Multiple Commands Remotely
Chain commands with a semicolon inside the quoted string. Each command runs sequentially in the same remote shell session.
ssh user@192.168.1.50 'cd /var/www; git pull; systemctl reload nginx'
This pattern is useful for quick deployment tasks: pull new code and reload the web server in one connection. For longer scripts, consider piping a local script file over ssh instead: ssh user@host 'bash -s' < deploy.sh.
Example 3: Connect with a Specific Private Key
When you manage multiple key pairs (one per project, client, or environment), the -i flag tells ssh which private key to offer during authentication.
ssh -i ~/.ssh/deploy_key user@192.168.1.50
The private key file must have restricted file permissions. SSH refuses to use a key that is readable by other users. Set the correct permissions with chmod 600 ~/.ssh/deploy_key.
Example 4: Connect on a Non-Default Port
SSH listens on port 22 by default, but many administrators change this to reduce automated scan noise. Use -p to specify the custom port.
ssh -p 2222 user@192.168.1.50
The -p flag is lowercase for the client. Do not confuse it with the uppercase -P used by scp.
Example 5: Enable Verbose Mode for Debugging
When a connection fails or authentication is rejected, verbose output shows every negotiation step so you can identify the problem.
ssh -v user@192.168.1.50
OpenSSH_9.6p1, OpenSSL 3.0.13 debug1: Connecting to 192.168.1.50 [192.168.1.50] port 22. debug1: Connection established. debug1: Authentications that can continue: publickey,password debug1: Offering public key: /home/user/.ssh/id_ed25519 debug1: Authentication succeeded (publickey).
Add more v characters for deeper detail: -vv shows protocol-level messages and -vvv adds packet-level tracing. Start with -v and increase only if the initial output does not reveal the issue.
Example 6: Forward X11 for Graphical Applications
X11 forwarding lets you launch graphical applications on the server while rendering the window on your local display. Your local machine must have an X server running (included by default on most Linux desktops).
ssh -X user@192.168.1.50
Once connected, run a GUI application like xeyes or firefox and the window appears locally. Use -Y instead of -X if the application requires trusted X11 forwarding (bypasses X11 SECURITY extension restrictions).
Example 7: Transfer a File Through an ssh Pipe
You can pipe data through ssh for quick, one-off file transfers without installing additional tools.
cat backup.sql | ssh user@192.168.1.50 'cat > /tmp/backup.sql'
This reads backup.sql locally and writes it to /tmp/backup.sql on the remote host. For routine file transfers, scp or rsync are better options because they handle progress display, recursive directory copies, and resume on interruption.
Example 8: Use Compression for Slow Links
The -C flag enables gzip compression for the SSH session, which reduces bandwidth on slow or metered connections.
ssh -C user@192.168.1.50
Compression helps most with text-heavy streams (log tailing, database dumps) but adds CPU overhead. On fast local networks, skip it.
Advanced ssh Techniques
Create an ssh Tunnel with Local Port Forwarding
Local port forwarding maps a port on your machine to a service accessible from the remote server. This is the most common ssh tunnel type, used to reach internal web interfaces, databases, and admin panels that are not exposed to the public internet.
ssh -L 8080:localhost:80 user@192.168.1.50
After connecting, open http://localhost:8080 in your browser. Traffic flows from your local port 8080, through the encrypted SSH tunnel, to port 80 on the remote server. The localhost in the middle refers to the remote host’s loopback address.
To forward multiple ports in one connection, repeat the -L flag:
ssh -N -f -L 8080:localhost:80 -L 3306:localhost:3306 user@192.168.1.50
The -N flag prevents opening a remote shell (useful when you only need the tunnel), and -f sends SSH to the background after authentication so your terminal stays free. This example forwards both a web server (port 80) and a MySQL/MariaDB instance (port 3306) at the same time.
Set Up Remote Port Forwarding
Remote forwarding works in the opposite direction: it makes a local service accessible from the remote server. This is useful when the remote machine needs to reach a development server running on your laptop.
ssh -R 9090:localhost:3000 user@192.168.1.50
Connections to port 9090 on the remote server are forwarded through the tunnel to port 3000 on your local machine. The remote server’s sshd must have GatewayPorts enabled in /etc/ssh/sshd_config for non-loopback access.
Create a SOCKS Proxy with ssh
Dynamic port forwarding turns ssh into a SOCKS5 proxy. Any application configured to use the proxy routes its traffic through the remote server. This encrypts browsing on untrusted networks and lets you access region-restricted resources.
ssh -D 1080 -N -f user@192.168.1.50
Configure your browser or system proxy settings to use localhost:1080 as a SOCKS5 proxy. The -N and -f flags keep the tunnel running in the background without an interactive shell.
Connect Through a Jump Host
In environments where servers sit behind a bastion host, the -J flag chains connections without manual two-step logins.
ssh -J user@bastion.example.com user@10.0.0.5
SSH connects to bastion.example.com first, then tunnels through to 10.0.0.5. You can chain multiple jump hosts by separating them with commas: ssh -J user@jump1,user@jump2 user@target. The -J flag is the command-line equivalent of the ProxyJump config directive, both introduced in OpenSSH 7.3. They replaced the older ProxyCommand approach, which required manually specifying the tunnel command.
Enable ssh Agent Forwarding
Agent forwarding lets a remote server use your local SSH keys for onward connections, so you do not need to copy private keys to intermediate hosts.
ssh -A user@bastion.example.com
Only enable agent forwarding (
-A) to servers you trust. A compromised intermediate host can use your forwarded agent to authenticate as you to other servers for the duration of the session.
Verify your local agent has keys loaded before connecting with ssh-add -l. If the agent has no keys, add one with ssh-add ~/.ssh/id_ed25519.
Generate an ssh Key Pair
Public key authentication is more secure than passwords and eliminates interactive password prompts. Generate a key pair with ssh-keygen:
ssh-keygen -t ed25519 -C "user@workstation"
Generating public/private ed25519 key pair. Enter file in which to save the key (/home/user/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Your identification has been saved in /home/user/.ssh/id_ed25519 Your public key has been saved in /home/user/.ssh/id_ed25519.pub
Ed25519 keys are shorter and faster than RSA while offering equivalent security. The -C flag adds a comment label (typically your email or hostname) to the public key for identification. Copy the public key to your server with ssh-copy-id:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@192.168.1.50
This appends your public key to ~/.ssh/authorized_keys on the remote host. Subsequent connections authenticate with the key pair instead of a password.
Keep ssh Sessions Alive
Firewalls and NAT devices often drop idle connections. Configure SSH to send keepalive packets at regular intervals so the connection stays active.
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@192.168.1.50
This sends a keepalive every 60 seconds. If three consecutive keepalives get no response, ssh disconnects. To apply this setting permanently, add it to your SSH config file (see below).
Set a Connection Timeout
Limit how long ssh waits for the initial TCP connection. This prevents scripts from hanging when a host is unreachable.
ssh -o ConnectTimeout=10 user@192.168.1.50
If the connection is not established within 10 seconds, ssh exits with an error. Combine this with ServerAliveInterval for fully timeout-controlled sessions.
Select an Encryption Cipher
Override the default cipher negotiation when you need a specific algorithm for compliance or performance testing.
ssh -c aes256-gcm@openssh.com user@192.168.1.50
List available ciphers on your system with ssh -Q cipher. The aes256-gcm@openssh.com cipher combines AES-256 encryption with GCM authenticated encryption, providing both confidentiality and integrity in a single pass.
Run a Background Command with ssh
The -f flag tells SSH to drop to the background after authentication but before command execution. This is useful for starting a long-running process on the server without keeping the local terminal open.
ssh -f user@192.168.1.50 'nohup /opt/scripts/backup.sh > /dev/null 2>&1 &'
The -f flag must appear before the hostname. SSH options placed after the hostname are interpreted as part of the remote command, which causes errors. The remote command uses nohup and output redirection so the process survives after the SSH session closes.
Configure ssh with a Config File
Typing long ssh commands with multiple flags gets tedious. The SSH config file (~/.ssh/config) lets you define per-host settings that apply automatically when you connect.
Create or edit the file:
nano ~/.ssh/config
Add host entries with the settings you need:
Host webserver
HostName 192.168.1.50
User deploy
Port 2222
IdentityFile ~/.ssh/deploy_key
Host bastion
HostName bastion.example.com
User admin
IdentityFile ~/.ssh/admin_key
Host internal-db
HostName 10.0.0.20
User dbadmin
ProxyJump bastion
LocalForward 3306 localhost:3306
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Compression yes
With these entries in place, ssh webserver connects to 192.168.1.50 on port 2222 as user deploy using the specified key. The Host * block applies keepalive and compression settings to every connection. The internal-db entry automatically jumps through the bastion host and sets up a local port forward for the database.
Use -F to point SSH at a non-default config file:
ssh -F ~/.ssh/project_config webserver
Set restrictive permissions on the config file to prevent other users from reading your host settings:
chmod 600 ~/.ssh/config
Troubleshoot Common ssh Errors
Connection Refused
If ssh returns this error immediately, the SSH daemon is not running or a firewall is blocking port 22 on the remote host.
ssh: connect to host 192.168.1.50 port 22: Connection refused
On the remote server, verify that the SSH daemon is running. The service name is sshd on RHEL-based distributions and ssh on Debian/Ubuntu:
sudo systemctl status sshd
If the service is not running, the output shows inactive (dead) or failed:
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
Active: inactive (dead)
Start the service with sudo systemctl start sshd (or ssh on Debian/Ubuntu). If a firewall is active, confirm that port 22 (or your custom port) is allowed. On Ubuntu/Debian with UFW: sudo ufw allow 22/tcp.
Permission Denied (publickey)
This error means the server rejected all offered authentication methods. The most common cause is a missing or incorrect key on the server.
Permission denied (publickey).
Verify your public key is in ~/.ssh/authorized_keys on the remote server. Check that the files have the correct permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Run ssh -v user@host to see which keys the client offers. If the correct key is not listed, specify it explicitly with -i or add it to your SSH config file.
Host Key Verification Failed
SSH stores server fingerprints in ~/.ssh/known_hosts to detect man-in-the-middle attacks. If a server’s key changes (after a reinstall or IP reassignment), SSH blocks the connection.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Host key verification failed.
If the key change is expected (you reinstalled the server), remove the old entry:
ssh-keygen -R 192.168.1.50
Reconnect and verify the new fingerprint. If the key change is unexpected, do not connect until you confirm the server’s identity through a separate channel.
Connection Timed Out
A timeout typically means the host is unreachable, the IP address is wrong, or a network firewall is silently dropping packets.
ssh: connect to host 192.168.1.50 port 22: Connection timed out
Start by confirming basic connectivity with ping 192.168.1.50. If ping succeeds but SSH does not, the firewall is likely blocking port 22. Use ssh -v to see where the connection stalls. On the remote side, check firewall rules with sudo iptables -L -n or sudo ufw status.
Conclusion – ssh Command
The ssh command handles remote server access, encrypted tunneling, and key-based authentication from a single tool. The patterns covered here (remote command execution, local and remote port forwarding, SOCKS proxying, jump hosts, and config file management) apply across distributions. Use ssh -v as your first troubleshooting step for any connection issue, and store frequently used settings in ~/.ssh/config to simplify daily workflows.
Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags:
<code>command</code>command<pre>block of code</pre><strong>bold</strong><em>italic</em><a href="URL">link</a><blockquote>quote</blockquote>