How to Connect to SSH: A Practical Guide to Accessing Linux Servers
Learn how to connect to SSH on Linux servers securely: key-based auth, config file, troubleshooting, and production hardening best practices for developers.
SSH (Secure Shell) is the standard protocol for managing remote Linux servers. If you just provisioned a VPS or received access credentials for a server, the first step is opening an SSH session — everything else (deployments, package installation, service configuration) depends on this working correctly.
This tutorial covers the full path: initial password-based connection, SSH key generation and usage, configuring ~/.ssh/config to simplify repetitive commands, and resolving the most common errors encountered on first access. The focus is practical usage on Linux and macOS environments, with targeted notes for Windows via native OpenSSH or WSL.
Estimated time: 15 to 25 minutes, including key generation and configuration adjustments.
Prerequisites
Before attempting a connection, confirm you have the server’s access credentials and an SSH client available on your local machine.
A server with SSH enabled (default port 22, open in the firewall), access credentials (username + password or key), and a terminal with the OpenSSH client installed. Linux and macOS include it by default. On Windows 10/11, the OpenSSH Client is available via Settings → Apps → Optional features.
The typical data you receive when provisioning a VPS looks like this:
203.0.113.42 root 22 sent via email Keep these values handy — you will use them in the next steps. If the password arrived by email in plain text, change it on first login.
First Connection via Password
The ssh command follows the format ssh user@host -p port. For a basic connection using the credentials above:
Open your local terminal and run:
ssh [email protected]If the port is not 22, add -p:
ssh [email protected] -p 2222On the first connection, the client will display the host fingerprint:
The authenticity of host '203.0.113.42 (203.0.113.42)' can't be established.
ED25519 key fingerprint is SHA256:abc123...
Are you sure you want to continue connecting (yes/no/[fingerprint])?Type yes and press Enter. This fingerprint is saved to ~/.ssh/known_hosts and protects against man-in-the-middle attacks on future connections.
Enter the password when prompted. Note that the terminal does not display characters as you type — this is normal behavior, not a bug.
After authenticating, you will see the server prompt:
root@server:~#You are in. To end the session, type exit or press Ctrl+D.
Password access is acceptable for the first login, but not for routine use. Passwords are vulnerable to brute force — any server with SSH exposed to the internet receives thousands of attempts per day. Set up key-based authentication (next section) and disable password auth as soon as possible.
SSH Key Authentication
SSH keys use asymmetric cryptography: you generate a key pair (private key + public key), store the private key on your local machine, and upload the public key to the server. Authentication happens without ever transmitting secrets over the network.
Generating the Key Pair
On your local machine, generate an ED25519 key (a modern algorithm, faster than RSA and considered secure):
ssh-keygen -t ed25519 -C "[email protected]"The command asks where to save the key (default: ~/.ssh/id_ed25519) and prompts for an optional passphrase. The passphrase encrypts the private key on disk — recommended, especially on laptops.
The result is two files:
~/.ssh/id_ed25519— private key (never share this)~/.ssh/id_ed25519.pub— public key (this goes to the server)
Copy the public key to the server using ssh-copy-id:
ssh-copy-id [email protected]Enter the server password (one last time). The command appends your public key to ~/.ssh/authorized_keys on the remote server, creating the file if it does not exist and setting the correct permissions.
If ssh-copy-id is not available (common on Windows), do it manually:
cat ~/.ssh/id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"Test the passwordless connection:
ssh [email protected]This time you connect directly, or are prompted only for the private key passphrase (if you set one). The server password is no longer used in this authentication flow.
Configuring ~/.ssh/config
Typing ssh [email protected] -p 2222 -i ~/.ssh/specific_key every time gets tedious. The ~/.ssh/config file lets you create per-server aliases.
Create or edit the file:
nano ~/.ssh/configAdd one block per server:
Host production
HostName 203.0.113.42
User root
Port 22
IdentityFile ~/.ssh/id_ed25519
Host staging
HostName 198.51.100.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_stagingFix the file permissions:
chmod 600 ~/.ssh/configNow connecting is simply:
ssh productionThe client reads the config, resolves the alias, and applies all parameters. This also works with scp, rsync, and tools that rely on the SSH client (such as git with SSH remotes).
Add ControlMaster auto, ControlPath ~/.ssh/sockets/%r@%h:%p, and ControlPersist 10m at the top of ~/.ssh/config (under a Host * block) to multiplex connections. A second SSH session to the same server opens instantly by reusing the first connection’s tunnel.
Hardening SSH Access
With key-based auth working, the next step is to disable password login and tighten the SSH service configuration on the server.
Connected to the server, edit the SSH service configuration:
sudo nano /etc/ssh/sshd_configAdjust (or uncomment) these lines:
PasswordAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yesprohibit-password allows root login via key but blocks password — useful on VPS instances where the initial user is root. If you created a non-root user with sudo, prefer PermitRootLogin no.
Validate the syntax before reloading:
sudo sshd -tNo output means the configuration is valid. Apply it:
sudo systemctl reload sshDo not close the current terminal before testing a NEW SSH connection in a separate terminal. If you made an error in sshd_config and close the active session, you may lock yourself out of the server. Always test with a parallel session.
Verification
Confirm everything works as expected:
ssh -v production
Verbose mode (-v) shows every step: config file reading, algorithm negotiation, key offers. Look for:
debug1: Authentication succeeded (publickey).
This confirms authentication was done by key, not password. If you see password, something has not been applied correctly.
On the server side, check recent connection attempts:
sudo journalctl -u ssh --since "10 minutes ago"
You should see lines like Accepted publickey for root from ... port ... ssh2.
Troubleshooting
Permission denied (publickey)
The public key is not in ~/.ssh/authorized_keys on the server, or the permissions are wrong. On the server:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Also verify that the correct key is being offered by the client — run ssh -v and look for Offering public key.
Connection refused
The SSH service is not running, or the firewall is blocking the port. On the server:
sudo systemctl status ssh
sudo ss -tlnp | grep ssh
If the service is active, check the firewall (sudo ufw status or your provider’s firewall rules).
Connection timed out
Usually a network issue or wrong IP address. Test basic connectivity:
ping 203.0.113.42
nc -zv 203.0.113.42 22
If nc fails but ping works, the port is being blocked somewhere along the path.
Host key verification failed
The server’s fingerprint changed since your last connection (server reinstalled, IP recycled). Remove the old entry:
ssh-keygen -R 203.0.113.42
Then reconnect — the client will prompt you to confirm the new fingerprint.
Next Steps
With SSH working securely, the server is ready for real work. Some directions to explore further:
- Configure
fail2banto ban IPs with excessive authentication attempts. - Use
moshon unstable connections (mobile, poor Wi-Fi) — it keeps the session alive even through network changes. - Learn port forwarding (
ssh -Landssh -R) to access internal server services without exposing them to the internet. - Configure
ssh-agentto enter the passphrase once per work session. - Study
Matchblocks insshd_configfor per-user or per-network access policies.
If you are deploying a project to production and want to avoid headaches with misconfigured SSH and firewalls, a Hostini VPS comes with SSH enabled, a dedicated IPv4 address, and immediate root access — just follow the steps in this tutorial starting from the provisioning email.
Frequently asked questions
What is the difference between RSA and ED25519 keys?
ED25519 is a newer algorithm based on elliptic curves. It produces much smaller keys (around 68 characters vs 400+ for RSA), is faster at signing and verification, and is considered secure against known attacks. Use ED25519 by default; fall back to RSA-4096 only if the server is too old to support it.
Can I use the same SSH key on multiple servers?
Yes, a public key can be added to as many servers as you need — that is how most people use them. The private key stays only on your local machine. Consider separate keys for sensitive contexts (production vs personal) to limit the blast radius if one is ever compromised.
How do I use SSH on Windows without installing PuTTY?
Windows 10 and 11 include a native OpenSSH client. Open PowerShell or CMD and use the same `ssh`, `ssh-keygen`, and `ssh-copy-id` commands as on Linux. If it is not available, enable it via Settings → Apps → Optional features → OpenSSH Client. WSL is also a robust alternative.
What should I do if I forget my private key passphrase?
There is no recovery path. The passphrase encrypts the private key file on disk and has no reset mechanism. You will need to generate a new key pair and update `authorized_keys` on every server where the old key was authorized. This is why many developers use `ssh-agent` to enter the passphrase only once per work session.
Is it safe to keep SSH on port 22?
Yes, provided you disable password authentication and use keys. Changing to a non-standard port (security through obscurity) reduces noise in logs from automated scanners, but adds no real security against targeted attackers. The effective gains come from strong keys, fail2ban, and non-root users.
How do I prevent SSH from disconnecting due to inactivity?
Add `ServerAliveInterval 60` to `~/.ssh/config` on the client — it sends a keepalive packet every 60 seconds. On the server side, setting `ClientAliveInterval 60` and `ClientAliveCountMax 3` in `/etc/ssh/sshd_config` has the equivalent effect. This prevents disconnections caused by NAT timeouts on home or office connections.