1

edit: I have seen cases where this works and cases where this doe not and I'm not sure I follow when/why it does.

Suppose I have a complicated enough entry where I specify multiple parameters to get to thathost:

Host thathost
    ControlMaster auto
    ServerAliveInterval 8
    ConnectTimeout 8
    Hostname 192.168.5.1
    User mememe
    ProxyJump thejumpbox

I want to re-use this definition in creating additional entries that provide different functionality by adding or overriding some configs. Specifically specifying an alternate port (no, I don't want it on the command-line).

Ideally I'd be able to do something like

Host theirhost
    Hostname thathost
    User themthem

or

Host my-remote-serialport
    Hostname thathost
    RequestTTY yes
    RemoteCommand some-script-that-launches-kermit-on-a-specific-dev-tty

or

Host my-remote-serialport
    Hostname thathost
    Port 3004

I'm strictly looking to specify one host in terms of another existing one, I'm not looking to modify my Host entries to match some pattern "tricks".

Obviously I can utilize ProxyCommand ssh -q nc thathost... or ProxyJump thathost +Hostname localhost followed by all the other overrides (well for port override would pass that to nc) but that's both ugly and wasteful (an extra session) - please don't answer with that.

For me this has been the missing feature of ssh-config, but maybe I did not look hard enough.

nhed
  • 5,774
  • 3
  • 30
  • 44

2 Answers2

5

It can't be used in the way you asked, like reuse a hostname definition, but the provided solution of ssh can solve much more problems.

A host rule can span multiple hosts.

Host thathost theirhost my-remote-serialport
    ControlMaster auto
    ServerAliveInterval 8
    ConnectTimeout 8
    Hostname 192.168.5.1
    User mememe
    ProxyJump thejumpbox

But obviously this doesn't solve your problem with modifying some properties.
The trick is, that the ssh config uses the first wins strategy for properties.

In your case you just has to add the modifications in front of the main config

Host theirhost
    Hostname thathost
    User themthem

Host my-remote-serialport
    Hostname thathost
    Port 3004

Host thathost theirhost my-remote-serialport
    ControlMaster auto
    ServerAliveInterval 8
    ConnectTimeout 8
    Hostname 192.168.5.1
    User mememe
    ProxyJump thejumpbox

theirhost is defined at two places, the properties Hostname and User are taken from the first definition, all other properties from the second definition.

The host part also accepts wildcards, example for a jumpbox with multiple reverse ssh endpoints:

HOST my_1
   port 2001

HOST my_2
   port 2002

HOST my_3
   port 2003

HOST my_*
   user pi
   hostname localhost
   ProxyJump thejumpbox
jeb
  • 78,592
  • 17
  • 171
  • 225
  • Thanks for clarifying the mystery of why it sometimes works for me and sometimes doesn't (order of definition). It might not be practical for me to update my whole config (we have hundreds of host entries). – nhed Dec 30 '21 at 18:44
  • I'm familiar with ssh-config wildcarding (see my note `I'm not looking to modify my Host entries to match some pattern "tricks"`). The `hostname localhost` in the last block implies to me that there is a "wasted" local socket connection also called out in my post as known (by me) but less than undesirable solution. – nhed Dec 30 '21 at 18:46
  • 1
    @nhed The last block with localhost is meant as example when you already use reverse tunnels, but probably it's a bad example here. You are not looking for pattern tricks, but these aren't tricks, this is the default way of openssh to solve such situations – jeb Dec 30 '21 at 22:43
2

There's no way to reference a different block; however, you can include a specific configuration file that has a global configuration. For example, create a file meant for use by thathost, theirhost, and my-remote-serialport. Let's just call it foo-config.

ControlMaster auto
ServerAliveInterval 8
ConnectTimeout 8
Hostname 192.168.5.1
User mememe
ProxyJump thejumpbox

Then you can use the Include directive to read this in as needed:

Host theirhost
    Include foo-config
    User themthem

Host my-remote-serialport
    Include foo-config
    RequestTTY yes
    RemoteCommand some-script-that-launches-kermit-on-a-specific-dev-tty

Host my-remote-serialport
    Include foo-config
    Port 3004

However, I suspect this approach is rarely necessary, and the approach given by jeb will probably be sufficient in most cases.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • We already use the `Include` directive extensively and most of the files are defining hosts within a specific test-bed or site. Breaking up those site or test-bed specific files will make things harder to find. I do like the conditional `Include` (i.e. within a `Host` or `Match` block) and use it, but probably not as much as I should. Yes @jeb's solution in their 2nd block seems closest so far (and probably forever save for an explicit openssh keyword which might be a hard-sell) – nhed Dec 30 '21 at 19:03