Still typing ssh -i ~/.ssh/my-key.pem -p 2222 user@server.example.com? There’s a better way.

The SSH Config File

~/.ssh/config transforms verbose commands into simple ones.

#s#sssBhAheff-tpoierrroe~d/.ssh/prod-key.pem-p2222deploy@prod.example.com

Basic Config

#HHHooo~sss/ttt.HUPIHUIHUsposodsosddossrseretseeesehotrtnatrnvtr/dNtgNtNcad2iiadiadome2tnmetmenep2ygepyevfl2FlFeipoisoi1lgryltyl9ooeae2pdg.e.~i~1re/n/6x.g.8as.s.mses1phxh.l/a/1epms0.rpt0colaodegm-.ikcneogym-.kpeeym.pem

Now just:

1
2
3
ssh prod
ssh staging
ssh dev

Wildcards and Patterns

#H#H#HoooAsAsDsltltetlUIlUIPfAISSsdpsdraddees.eepreeouderreernrornxlKnvvrxtodtyteteevadid-diJyirremetu*etufstAArppycpymoTillsllFtlFproeiieoiioiAsvvi.yloylbegOeenceneavenICosenlnoem~s~trtytux/e/iyena.r.otyyrtmsvsnheevMpsesissaalhrhnlxe/s/g.dp63cer0opomldo-dyko-emkyae.iypn.epmem

Jump Hosts (Bastion)

HHHHoooossssttttHUIPUIHHbosdirsdioioaseenoeensnsstrntxrntttttNteyteNeNiajirJairaraomutnudtnmnmnemyammyaeaepFlpiFllbi-ni-1-1al*bld0a0seaeb.p.ts0p0i~t~..o/i/11n.o....sns55ess01xhha//mbipanlstete.ircononam-lk-ekye.yp.epmem
1
2
# Connects through bastion automatically
ssh internal-db

Port Forwarding

Local Forward

Access remote service locally:

HostHLPdoorbsco-taxtNlyuaFJnmounermewpldabrb-dasse5tr4iv3oe2nr.lionctaelrhnoaslt:5432
1
2
ssh -N db-tunnel &
psql -h localhost -p 5432  # Connects to remote DB

Dynamic Forward (SOCKS Proxy)

HostHDsoyosnctakNmsai-mcpeFroobrxawysatridon1.0e8x0ample.com
1
2
ssh -N socks-proxy &
curl --socks5 localhost:1080 http://internal-service/

Agent Forwarding

Use your local keys on remote servers:

HostHFbooasrstwtNaiaromdneAgbeansttiyoens.example.com

Now you can SSH from bastion to other servers using your local keys.

Security note: Only enable ForwardAgent for trusted hosts.

Multiplexing (Connection Sharing)

Reuse connections for speed:

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

First connection is normal. Subsequent connections to the same host are instant.

Common Options

Host#HPU#II#SS#CCC#FL#P#CeoosddeeoooooroxCsreAeeKrrCnnnFrcJoCmaottrunnevvotttowauxopmnNttteeenrrrralmymrpna2mhiiprrnooowrFpJpelem2yettAAellladourseceunyiallcMPPrArhmeststFeliitaaedgwopsiiseiisivvistrieassooerclOveeothsnnrtbinnraeneICneigtdaovtlnor~ssnyei~ytur/tn8tero/enea.o0i(s.n.yrtuus68osesevMsts00nlxssaaeoh0oahlx/lwm/sopm63oclly0caie-kln.kehkcetosoyss)m/t%:r8###@#0%OSDhDnei-elns%fydcpaouuknlsenteeepcosatfplfeiacvffietoferierevsde3erckymueiry6si0stseyd

AWS EC2 Pattern

HHHooossstttUISUHHesdtseoeoceerecscs2rnir2t2t-tcK-N-N*eitnwadactHoembm2yowbee-FsnuitH55slKo44eees..ryt11~Cs22/hF33.ei..scl44ske55hi../n/66agd78wesnv-o/kneuyl.lpe#mIPschangeoften

Git Over SSH

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

Use in git:

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

Debugging

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

# More verbose
ssh -vvv prod

# Test config
ssh -G prod | grep -E "^(hostname|user|port|identityfile)"

Security Hardening

Host#I#P#S#H#F#KHCdataoeoiUeDsSrHsNrPxspsnistiahowrAthetswrcsKaelKeiaoithnarfgerotbrcHogdeoysnildtokweArrAleeAsnnngrilcysuhtoHteetghOptoKwondhoasnahsensftmrcplsetytoasiheysnChsrnltacwtkhowogch2iyoieesyaoum0fercycterrrs-isdakssdivpetciitesodaihnnh2sluoeggm5hyktncs5-1ehkab1e3ynisy(9d0sonkm-25gdos5@edh5ofea1par29eun5nl)6st@slhi.bcsosmh.org

Full Example

##H#H#H#HHH#H#Hoooooooo~DsGsWsWsssPsAs/etitototttetWt.fAISSCCCtUIrHUIrPUIHHLrHUPISUISUsaddeeoooHgsdkbosdkwrsdwowooshosodasdtssuderrnnnuieeaseeooeeososcoosereweerehlKnvvtttbtrnbstrnsrxrnrtrtanmtrtnsrnir/teteerrrhtatNtekytkNkNlaeNt-tcKcsyirrooougisiajir-Jai-a-aFlam2i*eitnostAAlllbittomutv*udtwmdmome2tctHonTillMPP.tyinemyemmyeeberse2y2yowfoeiiaaecFopFrpiFbwe2F-FsniAsvvstroinbisni11arhiuitHggOeethsmlalbl00rvolslKoenICeieseae..demeeeesnlnor~stvs00reryttytu/t~i~it~..5s.~~Csena./o/ai/114e//hFyyrtus6.n.o...3x..eieevMts0s.sbns122assclssaaoh0swsas00msskelx/hohshlphhis/r/t/ol//n/63ogkwiwcepagd0ci.oooa.ewektcrnrlcrsnvehok)khoso/tumomonsbsnu/tal%:llr5@4%3h2-%p

The SSH Config Checklist

  • One Host entry per server
  • Keys specified per host
  • Bastion/jump hosts configured
  • Connection multiplexing enabled
  • Keepalives for long sessions
  • Git hosts configured

A good SSH config means never typing a hostname or remembering a port again. Invest 10 minutes, save hours.