If you’re still typing ssh -i ~/.ssh/mykey.pem ec2-user@ec2-54-123-45-67.compute-1.amazonaws.com, you’re working too hard.

SSH config transforms verbose commands into simple ssh prod invocations.

The Basics

Create or edit ~/.ssh/config:

HostHUIposdrseeotrndNtaeimcte2y-F5ui4sl.ee1r2~3/..4s5s.h6/7prod-key.pem

Now ssh prod connects with the right key and user. No more remembering IP addresses.

Multiple Environments

HHHooossstttHUIHUIHUIdosdsosdposdeseetseerseevtrnatrnotrnNtgNtdNtadiiadiadimetnmetmetevygepyepyeFlFlFdlisoipoieoltylrylvpeaeoe.egder~i~.~x/n/e/a.g.x.ms.saspsesmslhxhphe/a/l/.dmsepcept.rovlacom-egodk.im-ecnkyogem-ykey

Commands like scp file.txt staging:/app/ just work.

Wildcard Patterns

Apply settings to multiple hosts:

#HHHHooooAsssslttttlUIHHHasdaoaoaoAweewswswsWsrnstststS-t-N-N-N*eiwawadahctemembmo2ybebees-F--tui11211ssl000ee...r000~.../112....s111s010h/aws-key.pem

Or match by domain:

HostUIsd.eeernxtaaimdtpmyliFeni.lceom~/.ssh/example-key

Jump Hosts (Bastion)

Access private servers through a bastion:

#H#HHHooooTsPssshtrttteHUIiPUIHHbosdvprsdpopobaseearoeersrsastrntixrnititstNtevytvNvNtiajiaJaiaaaaiomutstudttmtmonemyeemmyeeeenpFr-piF--/b-iv*nid1a1jauleblb0p0usserae.p.mtess00pir~t~..o/ai/21hn.co...o.scns51seses00txhsh0a/s/mbeipadnlstette.ihrcornonoam-ulkg-ehkyebyastion

Now ssh private-db automatically tunnels through the bastion. No manual port forwarding needed.

Connection Persistence

Keep connections alive and reuse them:

Host#SS#CCCeeoooSrrRnnnevvetttneeurrrdrrsoooAAelllkllMPPeiicaaeevvostrpeenthsaICneilnoer~situc/tventa.ertius6svMots0aanoh0elxs/vse63(or0mcyakse6st0isv/se%ercs@op%nehde-sd%upp)

Create the sockets directory:

1
2
mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/sockets

First connection opens the socket. Subsequent connections reuse it instantly.

Port Forwarding

#H#HooFsAsotctrHULcHULwdosoegosoabsecsrsecr-trasatradtNlfNluatFraaaFlnmuoenmdoonenrmaemrcenwo-iwalbeattmnalalreuors-dnndptuwniois5eet3roe4blo0tnr3r0.2Ui0teInoxiglanl.ormtoecepecxamlraaloenlmht.alpoeclylso-etsmd.:ebc3r.o0vem0ix0caemple.com:5432

Run ssh -N db-tunnel to create the tunnel. Your local localhost:5432 connects to the remote database.

Dynamic SOCKS Proxy

Route browser traffic through a server:

HostHUDposyrsenotraxNmyapimrceoFxotyrr-wuuassrtederd1-0s8e0rver.example.com

Connect with ssh -N proxy, then configure your browser to use localhost:1080 as a SOCKS5 proxy.

Per-Host Settings

HHoossttH#C#CH#KC#PsooosoeirlsLnCmesFxpReotonopctoAhefwNnemruNrleqe-agcperacgrursmetrsemeosireerTes-errerisissicedvltmsoevpthAeeieinraeha2urgmoovucmcFtaeunyelishAhcotertfaeyufs.ic2(n.t3oecu0kte0rxr-eixfaavpycaosmleobamrlpg2lotpolo5yailswer51roel.i13dn.olct90-scwioh-5ionmms@nkmckshoteosapeyn2erbn5naoe6scacstrthidi.v-oceino)nsmteractive,publickey

Git Over SSH

Configure GitHub/GitLab with specific keys:

HHoossttHUIHUIgosdgosdiseeiseettrnttrnhNthNtuagiuagibmitbmit.ety-etycFwFogiogimilriltektehhu~u~b/b/....cscsososmhmh//ggiitthhuubb--pweorrskonal

Clone work repos with:

1
git clone git@github-work:company/repo.git

Organizing Large Configs

Split into multiple files:

#IHno~cs/lt.uIAsdddseedhnK/ctecoiyontsnfiTfieoigsAg.Ogdne/ln*ytyyeess
#HHoo~ss/tt.UIHswsdwosoeeoshrrnrt/ktkNc-wi-ao*otpmnryrefkFoi-idpgulr.seoded/r~.w/wo.orsrkskh./cwoomrk-key
#Ho~s/t.HUPshosososerhmtrt/eNcam2ome2ne2f2ihgo.mde/.peexrasmopnlael.com

Security Settings

H#HoosOstnt#I#A#H#S#FlHFddatoytooOeAdHsVrDrrsrnndKaheiowfutwltdesKrcnaosNayiyhnit'rrtartksofHtdwemduieTkwyoAadeAseyonnsfgr-gessAoHhtoedsteOgwooKrnernentenssewtarutxlon_ttyagvspythsCrneetylaokhdonreeiygysyeetdsceeeteyca.isnsssskgtettieoxlfnnayaogttmurrpctabuloopsysenmrkt.faidecitvedogiafmuccahrayuoellsdlttyskeys

Useful Shortcuts

#H#H#HoooQsDsKsutatutiHU#tHL##bHLcuosapooekookpseUbrscUTr8scltrsaotashnstafoNasdNlaee-Nliaauge-aFgnttaFldmpedmoe:eumoeel:aber:snerocwmnwtfascbasycebaridcearssllaralepssdhqusdnerstlsts-fi3-ti6fsio3N-eo4eeln0hrn4rre.6p.3sv.er1aeetxmo2cxkrxayd7ca8.tms-.emsepqd0sp-xullb.slaape.0epml.i&..ipocn1c.laotoiedme-mn.:rPtc/neoia3rmnl3nc:0ao36lm3:i06n64g4/3

Debugging Connections

1
2
3
4
5
6
7
8
# Verbose output
ssh -v prod

# Very verbose
ssh -vv prod

# Show which config options apply
ssh -G prod | grep -E "^(hostname|user|identityfile|proxyjump)"

The ~/.ssh Directory

~/.ssccskiiggaahoonddiiwunnco__ttstffkweehh-hiiwpendduupoggoet_22bbrr.rrsh55--oidkso55pwdz/s11eo.ent99rrpdas.ske_lpomkunebayls#######MICHDSKanooeeeicnsfrynlttavsuruicdoflctoelitehndMn-afagksticseepgotryecnepcafrriniifgsniasotcccsckkeeestysssTHISmachine

Permissions matter:

1
2
3
4
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub

The Payoff

Before:

1
ssh -i ~/.ssh/prod-key.pem -o ProxyJump=ec2-user@bastion.example.com admin@10.0.1.50

After:

1
ssh prod-app

Your muscle memory will thank you.


Good SSH config is invisible. You forget it exists until you’re on a machine without it.