← all posts

SSH on Mac: A Guide for People Who Are Tired of Googling the Same Commands

Jul 2026

The first time I got “Permission denied (publickey)” I had no idea what it meant, so I just… retyped the same command. Three times. It did not work three times. For months after that I was googling the same handful of SSH commands over and over, every single time I needed to connect to something new. If that’s you right now, this is the guide I wish someone had handed me instead of a man page.

What SSH Actually Does

SSH (Secure Shell) is how you talk to a remote computer from your own. You type commands on your Mac, they run on the server, encrypted the whole way there. If you’ve ever deployed a website, poked around a VPS, or SSH’d into a Raspberry Pi at 1am because something broke — this is the tool doing the work.

Part 1: Making Your First Connection

Open Terminal (Cmd + Space, type “Terminal”). Then:

ssh username@server_address

For example:

ssh john@192.168.1.100

The first time you connect to any server, you’ll get something like this:

The authenticity of host '167.235.62.3 (167.235.62.3)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

This looks alarming the first time. It isn’t. SSH just doesn’t recognize the server yet and wants you to confirm it. Type yes. Your Mac saves this to ~/.ssh/known_hosts, and you won’t see the prompt again for that server.

Part 2: SSH Keys, and Why Passwords Are the Worse Option

You can log in with a password. Most people who’ve used SSH for more than a week don’t, though — keys are faster and harder to crack.

Check if you already have keys:

ls -la ~/.ssh

Look for id_ed25519 and id_ed25519.pub. If they’re there, you’re already set. If Terminal says “No such file or directory,” generate a pair:

ssh-keygen -t ed25519 -C "your_email@example.com"

Hit Enter to accept the default save location. It’ll ask for a passphrase — more on that in a second, but say yes to it.

This gives you two files:

  • id_ed25519 — your private key. This one doesn’t leave your machine, ever.
  • id_ed25519.pub — your public key. This is the one you hand out.

To look at your public key:

cat ~/.ssh/id_ed25519.pub

It’ll print something like ssh-ed25519 AAAAC3Nz... your_email@example.com. That’s the string you paste into a server’s authorized keys.

Part 3: Passphrases (Don’t Skip This)

A passphrase encrypts your private key on disk. Without one, anyone who gets a copy of that file — off a stolen laptop, a bad backup, whatever — can use it to log into every server you’ve added it to. With one, that file is useless to them without also knowing your passphrase.

The usual objection is “I don’t want to type this every time.” Fair, but macOS already solves it: Keychain remembers the passphrase after you enter it once, so in practice you’re typing it right after a restart and basically never after that.

Check whether your key has a passphrase:

ssh-keygen -y -f ~/.ssh/id_ed25519

If it asks you for a passphrase before showing the public key, you’re covered.

Change it:

ssh-keygen -p -f ~/.ssh/id_ed25519

Old passphrase, then new one twice.

You can actually see where it’s stored — open Keychain Access, search “ssh,” and there’s the entry, sitting in the same encrypted store as your other passwords.

Part 4: Key Auth vs. Password Auth

Key-based: your public key sits in ~/.ssh/authorized_keys on the server, your private key proves you’re you, no password typed at all. Set it up with:

ssh-copy-id username@server_address

or, if that’s not available:

cat ~/.ssh/id_ed25519.pub | ssh username@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Password-based: you type a username and password, same as logging into a website. It works, but it’s weaker, and a fair number of servers — especially anything production — turn it off entirely. That’s what’s behind the “Permission denied (publickey)” error: the server is telling you it will only accept a key, and yours isn’t on the list yet.

Part 5: Never Type the Full Command Again

ssh username@192.168.1.100 -p 2222 gets old around the third time you type it. Fix it with a config file:

nano ~/.ssh/config

A basic entry:

Host myserver
    HostName 192.168.1.100
    User john
    IdentityFile ~/.ssh/id_ed25519

Now ssh myserver does the same thing as the long version.

Custom port:

Host webserver
    HostName example.com
    Port 2222
    User admin
    IdentityFile ~/.ssh/id_ed25519

Password-only server:

Host oldserver
    HostName 82.112.239.96
    Port 21098
    User username
    PreferredAuthentications password

One thing worth saying directly: don’t put your actual password in that file. PreferredAuthentications password just tells SSH which method to try — it still prompts you for the password at connection time.

You can also set defaults that apply everywhere:

Host *
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60

Put it together and a real config might look like this:

Host *
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60

Host production
    HostName 203.0.113.10
    User deploy

Host dev
    HostName dev.mycompany.com
    User developer

Host client-server
    HostName 82.112.239.96
    Port 21098
    User clientuser
    PreferredAuthentications password

ssh production, ssh dev, ssh client-server — done.

Part 6: Moving Files Around

scp, for one-off transfers:

scp file.txt myserver:/home/user/
scp myserver:/home/user/file.txt ~/Desktop/
scp -r my-folder/ myserver:/home/user/

rsync, when you’re moving a lot or doing it repeatedly:

rsync -avz local-folder/ myserver:/remote/path/

-a preserves permissions and timestamps, -v shows you what’s happening, -z compresses in transit.

Your config shortcuts work here too — scp important.pdf production:~/uploads/ is all it takes.

Part 7: When It Doesn’t Connect

“Connection refused” — the server’s down, a firewall’s in the way, or you’ve got the wrong port. Check the port first; it’s usually the port.

“Permission denied (publickey)” — your key isn’t on the server, or the server only takes keys and you tried a password. Add your public key to ~/.ssh/authorized_keys on the server.

“Connection timeout” — wrong IP, server’s offline, or your network’s the problem.

For anything else, run it in verbose mode and read what it actually says:

ssh -v myserver

Part 8: Keeping This Secure

Private key stays on your machine. Public key goes on servers. Passphrase protects the private key if your machine gets stolen or backed up somewhere it shouldn’t be. That covers most of it.

A couple things I’d actually bother with:

  • Never send your private key over email, Slack, or any cloud storage. If you need it on a second device, AirDrop it or use an encrypted drive — or just generate a fresh key pair for that device instead. Separate keys per device means one stolen laptop doesn’t compromise everything.
  • If you run the server yourself, turning off password authentication entirely is worth doing once you’re comfortable with keys. Changing the default port and setting up fail2ban cuts down on the constant background noise of bots trying to log in.

Part 9: A Few Things That Come In Handy Later

Run one command without staying logged in:

ssh myserver "ls -la /var/www"

Reach a service on the server as if it were running locally:

ssh -L 8080:localhost:80 myserver

Now localhost:8080 on your Mac points at port 80 on the server.

Stop SSH from silently dropping the connection when you’re idle:

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

Different keys for different servers:

Host work-server
    HostName work.example.com
    IdentityFile ~/.ssh/work_key

Host personal-server
    HostName personal.example.com
    IdentityFile ~/.ssh/personal_key

Cheat Sheet

ssh username@server                          # connect
ssh myserver                                  # connect via config shortcut
ls -la ~/.ssh                                 # check for keys
ssh-keygen -t ed25519 -C "email@example.com"  # generate a key
cat ~/.ssh/id_ed25519.pub                     # view public key
cat ~/.ssh/id_ed25519.pub | pbcopy            # copy public key to clipboard
ssh-keygen -p -f ~/.ssh/id_ed25519            # change passphrase
nano ~/.ssh/config                            # edit config
scp file.txt myserver:/path/                  # copy file to server
scp myserver:/path/file.txt ~/Desktop/        # copy file from server
ssh -v myserver                               # debug a connection
exit                                          # disconnect
Host *
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60

Host nickname
    HostName actual.server.address
    User username
    Port 22

Where This Leaves You

Once you’ve got one key pair and a couple of servers in your config, ssh myserver is the whole interaction. That’s it. Everything that felt arcane the first week was really just three or four ideas wearing different outfits.

If I had to boil it down to one rule: keep the private key on your machine, use a passphrase, don’t overthink the rest.