|
| 1 | +# Annotated SSH Configuration |
| 2 | + |
| 3 | +Please also see the workflow documentation: [`workflow.md`](workflow.md). |
| 4 | + |
| 5 | + |
| 6 | +## Example SSH Config |
| 7 | + |
| 8 | +``` |
| 9 | +# insecure |
| 10 | +Host insecure insecure.example.com |
| 11 | + HostName insecure.example.com |
| 12 | +
|
| 13 | +# bastion |
| 14 | +Host bastion bastion.example.com |
| 15 | + HostName bastion.example.com |
| 16 | + ControlPersist 8h |
| 17 | +
|
| 18 | +# production |
| 19 | +Host prod production prod*.example.com |
| 20 | + HostName production.example.com |
| 21 | + ControlPersist 2h |
| 22 | + ProxyCommand ssh -q bastion nc -w30 %h %p |
| 23 | +
|
| 24 | +# global defaults |
| 25 | +Host * |
| 26 | + ControlMaster auto |
| 27 | + ControlPath ~/.ssh/cp_%r_%h |
| 28 | + ControlPersist 5m |
| 29 | + ServerAliveCountMax 60 |
| 30 | + ServerAliveInterval 30 |
| 31 | + TCPKeepAlive no |
| 32 | + User arthur |
| 33 | +``` |
| 34 | + |
| 35 | + |
| 36 | +### Section: `# insecure` |
| 37 | + |
| 38 | +This section is for a server on the Internet that we think is insecure (we |
| 39 | +do not trust the administrators--those with root access). |
| 40 | + |
| 41 | +``` |
| 42 | +# insecure |
| 43 | +Host insecure insecure.example.com |
| 44 | + HostName insecure.example.com |
| 45 | +``` |
| 46 | + |
| 47 | +1. `# insecure` is a comment. It helps provide context for for the |
| 48 | + line that follows it. |
| 49 | +2. `Host insecure insecure.example.com` indicates the host patterns that the |
| 50 | + subsequent parameters apply to. All of the following will work to connect |
| 51 | + to the configured HostName: |
| 52 | + - `ssh insecure` |
| 53 | + - `ssh insecure.example.com` |
| 54 | +3. `HostName insecure.example.com` specifies the real host name to log into. |
| 55 | + |
| 56 | + |
| 57 | +### Section: `# bastion` |
| 58 | + |
| 59 | +This section is for a server on the Internet that acts as a SSH bastion. It |
| 60 | +provides access to servers behind a firewall. :: |
| 61 | + |
| 62 | +``` |
| 63 | +# bastion |
| 64 | +Host bastion bastion.example.com |
| 65 | + HostName bastion.example.com |
| 66 | + ControlPersist 8h |
| 67 | +``` |
| 68 | + |
| 69 | +1. `# bastion` is a comment. It helps provide context for for the |
| 70 | + line that follows it. |
| 71 | +2. `Host bastion bastion.example.com` indicates the host patterns that the |
| 72 | + subsequent parameters apply to. All of the following will work to connect |
| 73 | + to the configured HostName: |
| 74 | + - `ssh bastion` |
| 75 | + - `ssh bastion.example.com` |
| 76 | +3. `HostName bastion.example.com` specifies the real host name to log into. |
| 77 | +4. `ControlPersist 8h` specifies that the master connection should remain open |
| 78 | + and idle in the background for up to 8 hours. This is especially convenient |
| 79 | + when the bastion server requires Multifactor authentication (MFA). |
| 80 | + - `ControlPersist` is available as of OpenSSH 5.6. For previous versions, |
| 81 | + simply omit it. |
| 82 | + |
| 83 | + |
| 84 | +### Section: `# production` |
| 85 | + |
| 86 | +This section is for a server on the Internet that acts as a SSH production. It |
| 87 | +provides access to servers behind a firewall. |
| 88 | + |
| 89 | +``` |
| 90 | +# production |
| 91 | +Host prod production prod*.example.com |
| 92 | + HostName production.example.com |
| 93 | + ControlPersist 2h |
| 94 | + ProxyJump bastion |
| 95 | +``` |
| 96 | + |
| 97 | +1. `# production` is a comment. It helps provide context for for the |
| 98 | + line that follows it. |
| 99 | +2. `Host prod production prod*.example.com` indicates the host patterns that |
| 100 | + the subsequent parameters apply to. All of the following will work to |
| 101 | + connect to the configured HostName: |
| 102 | + - `ssh prod` |
| 103 | + - `ssh production` |
| 104 | + - `ssh prod.example.com` |
| 105 | + - `ssh production.example.com` |
| 106 | +3. `HostName production.example.com` specifies the real host name to log into. |
| 107 | +4. `ControlPersist 2h` specifies that the master connection should remain open |
| 108 | + and idle in the background for up to 2 hours. |
| 109 | + - `ControlPersist` is available as of OpenSSH 5.6. For previous versions, |
| 110 | + simply omit it. |
| 111 | +5. `ProxyJump bastion` specifies that SSH host to proxy connections through. |
| 112 | + Any SSH client (ex. ssh command line, git, Transmit app) will see the |
| 113 | + production session as a single connection. It just works! |
| 114 | + - `ProxyJump` is available as of OpenSSH 7.3 |
| 115 | + - For OpenSSH versions 5.4 through 7.2 use: |
| 116 | + ``` |
| 117 | + ProxyCommand ssh bastion -W %h:%p |
| 118 | + ``` |
| 119 | + - For OpenSSH versions 5.3 and below use: |
| 120 | + ``` |
| 121 | + ProxyCommand ssh -q bastion nc -w30 %h %pi |
| 122 | + ``` |
| 123 | +
|
| 124 | +
|
| 125 | +### Section: `# global defaults` |
| 126 | +
|
| 127 | +The global defaults for all hosts is specified last. Its parameters apply if |
| 128 | +they are not previously defined (which is why it should be the *last* section |
| 129 | +of your SSH config). |
| 130 | +
|
| 131 | +``` |
| 132 | +# global defaults |
| 133 | +Host * |
| 134 | + ControlMaster auto |
| 135 | + ControlPath ~/.ssh/cp_%r_%h |
| 136 | + ControlPersist 5m |
| 137 | + ServerAliveCountMax 60 |
| 138 | + ServerAliveInterval 30 |
| 139 | + TCPKeepAlive no |
| 140 | + User arthur |
| 141 | +``` |
| 142 | +
|
| 143 | +1. `# global defaults` is a comment. It helps provide context for for the |
| 144 | + line that follows it. |
| 145 | +2. `Host *` indicates this is the global defaults section. |
| 146 | +3. `ControlPath ~/.ssh/cp_%r_%h` supports the ControlMaster parameter. The |
| 147 | + path given here supports longer host names which can otherwise cause |
| 148 | + issues. |
| 149 | +4. `ControlPersist 5m` specifies that the master connection should remain open |
| 150 | + and idle in the background for up to 5 minutes. This will speedup version |
| 151 | + control commands while also being a good conservative default. |
| 152 | + - `ControlPersist` is available as of OpenSSH 5.6. For previous versions, |
| 153 | + simply omit it. |
| 154 | +5. `ServerAliveCountMax 60` helps ensure robust proxied sessions. |
| 155 | +6. `ServerAliveInterval 30` helps ensure robust proxied sessions. |
| 156 | + - A `ServerAliveInterval` of 30s combined with a `ServerAliveCountMax` of |
| 157 | + 60 will result in disconnections of unresponsive clients after half an |
| 158 | + hour. |
| 159 | + - The relatively short `ClientAliveInterval` should ensure aggressive TTLs |
| 160 | + do not severe connections. The larger `ClientAliveCountMax` should allow |
| 161 | + brief interruptions without disrupting work. |
| 162 | +7. `TCPKeepAlive no` allows connections to weather short network outages |
| 163 | + (especially useful when connected via WiFi). |
| 164 | +8. `User arthur` specifies the user to log in as (remember, in our example |
| 165 | + the local username is arthurdent). |
| 166 | +
|
| 167 | +Additionally, the following defaults are important. The parameter is not in |
| 168 | +this section because the OpenSSH default value is appropriate. It should be |
| 169 | +acknowledged so that it is not unintentionally superseded by a configured |
| 170 | +parameter: |
| 171 | +
|
| 172 | +- `ForwardAgent no` specifies that the authentication agent will **not** be |
| 173 | + forwarded. This prevents administrators on untrusted remote servers from |
| 174 | + masquerading as you on *any* system on which you have your SSH public key. |
| 175 | + See [SSH Agent Hijacking][hijacking] for more information. |
| 176 | +
|
| 177 | +
|
| 178 | +## References |
| 179 | +
|
| 180 | +- **[ssh_config(5)][mansshconfig]** |
| 181 | +- [SSH Agent Hijacking][hijacking] |
| 182 | +
|
| 183 | +[mansshconfig]:http://man.openbsd.org/OpenBSD-current/man5/ssh_config.5 |
| 184 | +[hijacking]:http://www.clockwork.net/blog/2012/09/28/602/ssh_agent_hijacking |
0 commit comments