## Pattern Matching Gotchas ## ======================== ## ## 1. If two stanzas both try to set a value, OpenSSH will use the ## FIRST setting stanza that matches, rather than (as you might ## expect) the last or tightest match. Therefore, this file is ## maintained in a "bottom up" fashion, with the most general ## settings at the BOTTOM of the file, so they can be overridden. ## ## 2. Matching is not done against the "real" hostname. In the ## example config below, "ssh cao" will not connect as joshua. ## ## Host cao ## HostName crawl.akrasiac.org ## Host crawl.akrasiac.org ## User joshua ## ## 4. Conditionals aren't supported. For example, you can't tell it ## to connect via the gateway ONLY when you're offsite: ## ## Host *.lan.example.net ## if my domain is lan.example.net ## ProxyCommand none ## else ## ProxyCommand ssh gw.example.net -W %h:%p ## ## 3. You can't include the Host value in HostName. For example, ## instead of ## ## Host dhcp[0-9][0-9] ## HostName %h.lan.example.net ## ProxyCommand ssh gw.example.net -W %h:%p ## ## you would need to define each of the hundred matches separately: ## ## Host dhcp99 ## HostName dhcp99.lan.example.net ## ProxyCommand ssh gw.example.net -W %h:%p ## Host dhcp98 ## HostName dhcp98.lan.example.net ## ProxyCommand ssh gw.example.net -W %h:%p ## ... ## ## UPDATE: (3) is fixed as at Debian openssh-client=1:6.7p1-2 & ## Ubuntu openssh-client:6.6.p1-2ubuntu2, ## possibly much older version. --twb, Jul 2015 # Override the default username (root/twb) where necessary. Host crawl.akrasiac.org User joshua Host crawl.develz.org crawl.project357.org User crawl Host darcs.net User darcs-unstable #Host darcs.net # User gitit Host *.debian.org User twb-guest Host code.haskell.org sdf.org User twb Host xipe User root # LDAP-less exceptions aside, I'm twb on all Cyber hosts. Host zhug zhug.cyber.com.au User cyber Host alpha alpha.cyber.com.au omega omega.cyber.com.au User root Host wifi? wifi?.cyber.com.au User root Host *.cyber.com.au User twb # Direct-access exceptions aside, Cyber FQDNs are reached via login. Host login.cyber.com.au alpha.cyber.com.au zhug.cyber.com.au exetel.cyber.com.au internode.cyber.com.au ProxyCommand none Host *.cyber.com.au ProxyCommand ssh login.cyber.com.au -W %h:%p Compression no # Ad-hoc multihop sshing, e.g. "ssh gw.example.net,fs". # DOES NOT WORK with me@gw,you@fs. # # The leading ">&1" is because SSH passes the string to sh -c, but # prepends "exec ". To assign %h to a variable so we can use pattern # substitution, we must disarm this exec; we do so by using the exec # redirection syntax to redirect stdout to stdout. Host *,* ProxyCommand >&1; h="%h"; exec ssh "${h%%,*}" -W "${h##*,}":%p Compression no Host *.* # Compression should be enabled when bandwidth is scarcer than # processing power, i.e. on the internet, but not on the LAN. # Compressing a stream twice is slightly wasteful, so don't compress # nested SSH, i.e. ProxyCommand implies Compression=no (above). Compression yes # My primary use cases are connecting to hosts on the LAN (as me), # and connecting to customer machines (as root/cyber). Making root@ # the default for FQDNs requires the fewest exceptions (above). # Unqualified hostnames retain their (implied) User=twb. User root Host * # https://security-tracker.debian.org/tracker/CVE-2016-0777 UseRoaming no # Disallow the SSHv1 protocol entirely. If I run into a piece of # kit so old that it doesn't support SSHv2, I want ssh to throw an # error rather than silently using SSHv1. That way, I will KNOW the # kit is a piece of crap that should be replaced. Protocol 2 # Do not enable gaping security holes by default. If these were on, # root on the remote host could use them to fuck me. That includes # the case where the remote host has been compromised. ForwardX11 no ForwardX11Trusted no ForwardAgent no # By default, SSH will prompt when connecting to a host for the # first time ("Are you sure you want to continue connecting?"). # This CONFUSINGLY NAMED option just makes the answer always "yes". StrictHostKeyChecking no # Try destination-specific keys before falling back on the generic defaults. # I symlink id_rsa to my "default" key, so ssh-add will find it. # Note that ~/.ssh/id_rsa et al are ALWAYS tried (after these). IdentityFile %d/Classified/%r@%h.ecdsa IdentityFile %d/Classified/%r@%h.rsa IdentityFile %d/Classified/%h.ecdsa IdentityFile %d/Classified/%h.rsa # Perform keepalive pings at the SSH layer, not the TCP layer. # # russm> twb: TCPKeepalive is spoofable at the TCP layer, where ServerAliveFoo sends ssh ping commands inside the encrypted connection # twb> why does it matter if someone spoofs a keepalive? # russm> they could attack your routing and hijack the connection without you noticing that the other end had actually gone away # russm> whether that's a problem depends on what you're doing with the connection, of course # russm> if you're expecting asynchronous data to come back, then you'd never notice the other end was gone # russm> if you're doing interactive, or request/response then obviously you'd notice at a higher layer (perhaps the human layer) ServerAliveInterval 30 ServerAliveCountMax 10 TCPKeepAlive no # When run from a screen session, rename the screen window to the destination. # This is better done in .profile on the remote host where possible. LocalCommand case $TERM in (screen*) printf %%bk%%s%%b%%b \\033 %n \\033 \\0134;; esac >&2 PermitLocalCommand yes # Enable ubiquitous connection pooling. The implications are: # # BONUS: slave do not prompt for passwords/passphrases. # BONUS: less likely to be blacklisted by a firewall that limits the # rate/number of TCP connections. # BONUS: faster tab completion of remote paths in zsh/bash if there # is already a master session open. # MALUS: master stays open until all slaves close. If you mistake # this for a hung connection and ^C or ~^M. it, open slaves # will be cut off at the knees. # MALUS: testing if a stateful firewall still allows SSH can no # longer be done by simply SSHing in again, because that will # be a slave of the existing (already accepted) TCP flow. # Can be override if you remember to pass -M to the test ssh. # MALUS: ssh and scp share a flow, and thus share ToS bits. This # presents as interactive ssh "hanging" while scp is running. ControlMaster auto ControlPath ~/.ssh/master-%l-%r@%h:%p # FIXME UPDATE - ControlPersist seems to address some of those Maluses. # I think it was added around 2012. ControlPersist 3600 # FIXME: HERE IS A RECENT (c. 2015) DOCUMENT ON SSH BEST PRACTICE. # I SHOULD DO THIS, BUT ALL THE SERVERS ARE FUCKING ANCIENT. # https://stribika.github.io/2015/01/04/secure-secure-shell.html