Ssh – How to match a CIDR range for an SSH config host entry

ssh

I'm looking for a way to use specific CIDR blocks to match hosts in the SSH client configuration (usually ~/.ssh/config). For example, I have an entry to forward all traffic through a bastion host if the IP falls into a certain range, let's say 10.1.0.0/16:

host 10.1.*
    proxycommand ssh -q bastion -W %h:%p

This works very well, but how about when I add some ranges that don't fit the dot notation exactly?

# doesn't work, unfortunately
host 10.2.0.0/18
    proxycommand ssh -q bastion-foo -W %h:%p
host 10.2.64.0/18
    proxycommand ssh -q bastion-bar -W %h:%p

Is there something in the manual that I've missed, or a clever scripting trick that would enable matching these host IP ranges?

Best Answer

Matching against patterns in the ssh_config file is done as basic pattern matching, not as a network/CIDR matching. So using CIDR notation is not going to work.

The man page explains that:

A pattern consists of zero or more non-whitespace characters, * (a wildcard that matches zero or more characters), or ? (a wildcard that matches exactly one character).

The best you can do is to use a list of more than one pattern. Again, from the manual page:

A pattern-list is a comma-separated list of patterns. Patterns within pattern-lists may be negated by preceding them with an exclamation mark (!).

So to cover your two /18 nets, you'd need to list:

  • all hosts matching 10.2.?.* (i.e. 10.2.0.0–10.2.9.255)
  • all hosts matching 10.2.??.* (i.e. 10.2.10.0–10.2.99.255)
  • all hosts matching 10.2.10?.* (i.e. 10.2.100.0–10.2.109.255)
  • all hosts matching 10.2.11?.* (i.e. 10.2.110.0–10.2.119.255)
  • all hosts matching 10.2.12?.* EXCEPT the ones matching 10.2.128.* and 10.12.129.* (and remember that the exclusion must come first!)

Your pattern list should then look like this:

Host "10.2.?.*","10.2.??.*", "10.2.10?.*","10.2.11?.*","!10.2.128.*","!10.2.129.*","10.2.12?.*"