Your ~/.ssh/config file is the most underused productivity tool in your terminal. Here’s how to make SSH work for you.

Basic Structure

HostHUPmosoyserstrteNraa2vmd2eemri1n92.168.1.100

Now ssh myserver replaces ssh admin@192.168.1.100.

Aliases for Everything

#HH#H#HooooPssDsPsrttetetoHUIHUIvHUrHPUdposdposdedosshoosurseerseeleseoosrecotrnotrnovtrnmttrtdNtdNtpNaeNiadi-apimadla2mometdmotemem2enepybesyneve2lFtFte2spoidgidlherylbrleooroe.eevpmvdps.eee.~r~er.re/o/xesx.d.axas.smamsespmphxhlpl/a/elepmp.e.rprc.coloocodedmom_._mkckeoeymy

Wildcards

Match multiple hosts with patterns:

HHoossttUIUSsd1st.ee9erprn2rirt.codi1atdet6dH.py8moelF.isxoi1ntayl.Kme*epyl~Ce/h..ecscoskmhi/npgrondo_key

Jump Hosts (Bastion)

Access internal servers through a bastion:

HHHHoooossssttttHUPUHHbosirsioioasenoensnsstrtxrtttttNeyeNeNiajrJararaomunudnmnmnemammaeaeplpillb-n-1-1a*bd0a0sab.p.ts0p0it..oi11no...n55e01xample.com

Now ssh internal-db automatically routes through bastion. No manual tunneling.

Old ProxyCommand Style

HostHPiornsottxeNyraCnmoaemlm1a0n.d0.s1s.h50-W%h:%pbastion

ProxyJump is cleaner, but ProxyCommand offers more control.

Keep Connections Alive

Prevent timeouts on flaky networks:

HostSSeerrvveerrAAlliivveeICnotuenrtvMaalx630

Sends keepalive every 60 seconds, disconnects after 3 failures.

Connection Multiplexing

Reuse connections for speed:

HostCCCooonnntttrrrooolllMPPaaestrthseir~s/ta.us6ts0oh0/sockets/%r@%h-%p

First connection opens a socket. Subsequent connections reuse it. 10x faster for repeated connections.

1
2
3
# Create the socket directory
mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/sockets

Identity Management

Specific Keys Per Host

HHHooossstttIIIIIIgddgddwddieeieeoeetnntnnrnnhttlttkttuiiaii-iibttbtt*tt.yi.yiyicFecFeFeoisoisismlOmlOlOenenenlll~y~y~y///.y.y.ysesesesssssshhh///ggwiiottrhlkua_bbk__ekkyeeyy

IdentitiesOnly yes prevents SSH from trying other keys.

Agent Forwarding

HostFboarswtairodnAgentyes

Your local SSH agent is available on the remote host. Use sparingly — security risk on untrusted hosts.

Port Forwarding

Local Forward (Access Remote Service Locally)

HostHLPdoorbsco-taxtNlyuaFJnmounermewpldabrb-dasse5tr4iv3oe2nr.lionctaelrhnoaslt:5432

Now ssh db-tunnel creates a tunnel. Connect to localhost:5432 for the remote database.

Remote Forward (Expose Local Service)

HostHReoexsmptooNtsaeemF-eolroswceaarrlvder8.0e8x0amlpolcea.lchoomst:3000

Makes your local port 3000 available on the server’s port 8080.

Dynamic SOCKS Proxy

HostHDpoyrsnotaxNmyaimceFosrewravredr.1e0x8a0mple.com

Creates a SOCKS5 proxy on localhost:1080. Route browser traffic through it.

Per-Host Settings

HHoossttHCTSHCsooCefoolsmPrasmotpKvstpwNreetNr-aeer-aecmspAlmsoesAloesnilicinroiva1oeenvel9ncmeI2toyn.niteyt1ooesee6n.sr8ev.xa1al.m5p30l0e.com

Security Settings

Host#KHCM#H#VeoiAaiPxspCDsVsrAthsohiuelKenKsafgerh'nuleoysmtoaHrrAawloilcchnsstgh-aHhtehoassooKcmrchhsseusihattyrta2ksech2-nkyum05oneears-1woyslvp2ngeso-vo2sleher5hytori5-1msit1e3@tfh9d0osim-25pcss5@e(ah5onmta1psai29esko5,nhen6rs.s@ssclahodi-.mebsc,bshohusammgh2,ag.-acio5e-nr1ssgg22h,5aed62ai--sfg2ifc5eim6re@-)-oehpteemln@lsomspahen.n-csgosrmho.ucpo-mexchange-sha256

Handling Legacy Servers

Old servers need old algorithms:

HostHKHPloeouesxsbgtAtkaNlKecageyymoyA-erAcsilceotgerlhopvdmrte.sieretdx+hKadmemisypfTlf+yeisp.esec-hsoh-mer+lsslasmha-nr-sgaroup1-sha1

The + prepends to defaults rather than replacing.

Include Files

Split config into multiple files:

#IIHnno~ccs/llt.uu#sddseeGhl/cwocoobonranfklfi-igcdg.oednf/fa*iuglts
1
2
3
mkdir -p ~/.ssh/config.d
# Put work hosts in ~/.ssh/config.d/work
# Put personal hosts in ~/.ssh/config.d/personal

Match Blocks

Conditional configuration:

#M#MaaOtAtncpclhPphPyrlrhoyhoaoxoxpsytsyptJotJluuymam.pl.pwilihnnnbetohtanenoesresrtontninasaollnwwoehrxekencnne"otitwpoorrnkouwtoerk|ngertewpor-kq10.0.0.0/8"

Useful Aliases in Shell

Combine with shell aliases:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# ~/.bashrc or ~/.zshrc

# Quick SSH with agent
alias ssh='ssh -A'

# SSH without host key checking (for ephemeral servers)
alias sshn='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'

# Copy SSH key to server
alias ssh-copy='ssh-copy-id -i ~/.ssh/id_ed25519.pub'

# Kill all control sockets
alias ssh-kill='rm -f ~/.ssh/sockets/*'

Complete Example

##H#HH#HHHHH#HHoooooooooo~GsGssWsssssHss/ltittotttttott.oAISSCCCtIIrHUIPUIHHHLmHPUIHUsbddeeooogdgdkbosdprsdpopopooehoosdpossaderrnnnhieieaseeroeersrsrscosreeisehlKnvvtttotntnistrnoxrnotototanmttrntr/eteerrrshtltntNtdytdNdNdNleeNtNcdyirroootuiaifiaai-Jdi-a-a-aFta2miapoestAAlllsbtbtromdt*uetwmamdmowm2etminfTillMPP.y.yanemympyeepeberoe2yefaoeiiaaecFcFsiFplFbiwr2FiuAsvvstroioitbnioi111akhi1glgOeethsmlmlralbyl000rol9tenICeieeuseae...dme2snlnor~scts000e.tytu/t~~ti~t~...5.~1ena.//uo/i/1114d/6yyrtus6..rn.o....3u.8eevMts0sse.sns1122cs.ssaaoh0sswss010ks1lx/hhohhldh.s//r//on/563oggkwwcsh00cii.ooa.okttcrrlomehlokkhretuam__og_sbbkksk/__eete%eeyy:yrdd5@224%553h552-11%99p

Debugging

1
2
3
4
5
6
7
8
9
# Verbose output
ssh -v myserver
ssh -vvv myserver  # Even more verbose

# Test config without connecting
ssh -G myserver | grep -i proxy

# Check what config applies
ssh -G hostname | head -20

Key Takeaways

  1. Alias everything — Never type full hostnames
  2. Use ProxyJump — Clean bastion access
  3. Enable multiplexing — Faster repeated connections
  4. Separate keys per purpose — Work, personal, per-service
  5. Use Include — Organize large configs

Your SSH config should eliminate typing and thinking. If you’re typing a hostname or remembering a port, your config is incomplete. 🌍