If you’re still typing ssh -i ~/.ssh/prod-key.pem -p 2222 ubuntu@ec2-54-123-45-67.compute-1.amazonaws.com, you’re working too hard. SSH config files let you define aliases with all your connection details.

Basic Config

Create or edit ~/.ssh/config:

HostHUPIposodrsereotrtndNtau2imb2teu2yn2Feticul2e-5~4/-.1s2s3h-/4p5r-o6d7-.kceoym.ppuetme-1.amazonaws.com

Now connect with just:

1
ssh prod

Common Options

HostHUPI#SS#CCC#F#CmosodeeoooooysereKrrRnnnFrCmstrtnevvetttowopeNteeeurrrramrrad2iprrsooowrpevme2tAAellladrseepycllMPPrAesrlFoiicaaedgsisoinvvostresoeylneenthsaninreeICneigtovcnoer~senye~ttuc/tnyer/ienta.te(s..ortius6sgesnvMots0(oxsaanoh0coahalxs/adm/lsrpii63oefldv0cfoe_ekur.eelcdtso2swlm5/io5%tw1rh9@c%tohhn-in%sep)ctions)

Wildcards and Patterns

#H#H#HoooAsMsNsltutetlUIlUIgSsdtdsdaeh.eeieeetroernpvrni!vsxtltogetaaiesdinirsmdttettApmyhapyhliliFoglFuinenisioibv.ltnyl.eacesgecIoondm~p~mto/r/em.o.rasdsvissanhhl//ed6xe0apmlpolye--kkeeyy..ppeemm

Jump Hosts (Bastion)

When you need to hop through a bastion server:

#H#HHHooooTsSssshtettteHUIrUPHHbosdvisrioiobaseeeneonsnsastrnrtrxttttstNtseyeNeNtiaairdJraraiomdtbneunmnmonemyeapmaeaeniFhllpllbnii-o-1-1aln*yba0d0sedap.b.tsp00i~bt..o/ai11n.so...stn55esi01xhoa/nmbpalset.icoonm-key.pem

Now ssh internal-app automatically jumps through the bastion.

Legacy ProxyCommand

For older SSH versions:

HostPirnotxeyrCnoamlm-a*ndssh-W%h:%pbastion

Port Forwarding

Local Forward (access remote service locally)

HostHLtoouscntanNleaFlmo-erdwbsaerrdve5r4.3e2xalmopclael.hcoosmt:5432

Connect and access remote PostgreSQL on localhost:5432:

1
2
ssh tunnel-db
psql -h localhost -p 5432

Remote Forward (expose local service remotely)

HostHReoexsmptooNtsaeemF-eolroswceaarrlvder8.0e8x0amlpolcea.lchoomst:3000

Dynamic SOCKS Proxy

HostHDpoyrsnotaxNmyaimceFosrewravredr.1e0x8a0mple.com
1
2
ssh proxy
# Configure browser to use SOCKS5 proxy at localhost:1080

AWS and Cloud Patterns

EC2 Instances

HHoossttHUIISUaosdadtswseewerestrnsnir-Nt-tcKpaei*itnrmcttHooe2yyowd-FFsn5uiitH4sllKo.eeees1ryt2~~Cs3//hF...ei4sscl5sske.hhi6//n/7aagdwwessnv--o/pdnreuofldal.upletm.pem

With SSM (no direct SSH)

1
2
3
4
# Use AWS Session Manager as a ProxyCommand
Host i-*
    ProxyCommand aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'
    User ec2-user

GitHub and GitLab

#H#H#HoooGsWsGsitotittHUIrHUItHUIPHgosdkgosdLgosdruiseeiseeaiseeebttrnGttrnbttrnfhNtihNtlNtewuagituagiaagiribmitHbmitbmitrt.etyu-ety.etyehcFbwFcFdogiogiogiAsmil(rilmiluptedktetetehihlhcu~fu~a~eib/fb/b/nf..e....ticsrcscsicoseososcmhnmhmhak/t//tegggiyiaiiotcttnhchlsuouabubbp-n--uktwkbe)oelyryikc-kkeeyy

For multiple GitHub accounts, clone with the alias:

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

Connection Multiplexing

Speed up repeated connections:

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

Create the socket directory:

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

Now the first connection opens a socket, subsequent connections reuse it (much faster).

Security Options

HostH#CMK#PP#FsoiAearoesPpCxDseDrctrhsAisfowuNeelswenarafrhgaor'remesmobrrtd-erarldeAsacieAdfgesse-tuAoeretsshpturnvcr2hmahtwteuo5asseharrn62snerneg--cwtndo.eg5uoiterc1rrciaxm2vdacgaa@-etaemloe2aitnpgpt5uoitloem5tnoern@1hn.iso9nsctsp-oohhespmm.nhuscsabos2lmh5i,.6ccc,khoceamuyc,rhhvame2a20c5--5ps1oh9la-y2s1-h32a052565@-6oe@ptlemin@bsosspsheh.n.csoosrmhg.com

Defaults for All Hosts

Put at the end of your config:

Host#SS#HV#I#A#UeeaiddsSrrSssUeAdmeevvehusndKaKneecKaetdecesrrunliyOyiAAroHmtksScblliwooyeT:hliitnsdFyoaevvyHteisAUieeoKrlgsndICseneteeenotyonyftusk~tkeaenye/aesurtyey.gyylvMesseectaassnshslxhta/i63in0d_ed25519

Include Other Configs

Split configs by environment:

#IHno~cs/lt.uSsdeserhv/cecoronAnflfiiigvg.edI/n*terval60
#Ho~s/t.UIswsdsoeehrrn/ktc-aio*dtnmyfiFinigl.ed/~w/o.rsksh/work-key
#Ho~s/t.UIshsdsoeehmrn/etc-pio*itnyfFiigl.ed/~p/e.rsssohn/aplersonal-key

Complete Example

##H#HHH#H#H#Hooooooo~WsWsssPsGsDs/ototttetitet.rHUIrUIPHHLrHUPtUIfSCCCAskbosdkwsdrwowooshosoHgsdaeooodsaseeoeeoososcooseruieeurnnndhbstrnsrrnxrtrtanmtrtbtrnlvtttK/atNtektykNkNlaeNhtterrrecsiaair-diJ-a-aFlap2ugisroooyotomdtv*etuamdmomi2bitAlllsninemyepympebere2.tylMPPTfoiFrlFppw2cFiaaeoinbnisoi11ahoivstrAgalylb00romlethsgseea..dmeIeietvs00enr~sni~i~t..5.~t/tto/a/i114e/ea.n..o..3x.rus6y.sbsn122asvts0ecsas00msaoh0sohshlphl/m/t/ol/spwiwceg6oaoooa.i0cnrnrlctkyk)khohe...omutcppsbsoeet/mmm:%5r4@3%2h-%p

Debugging

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

# Very verbose
ssh -vvv myserver

# Check which config file options are being used
ssh -G myserver

Quick Reference

OptionPurpose
HostNameActual hostname/IP
UserLogin username
PortSSH port
IdentityFilePrivate key path
ProxyJumpJump host
LocalForwardForward remote port locally
ServerAliveIntervalKeepalive interval
ControlMasterConnection multiplexing

A good SSH config file is like a phone book for your servers. Set it up once, update it when things change, and stop typing the same options repeatedly. Your fingers will thank you.