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

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
    proxycommand ssh -q bastion-foo -W %h:%p
    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?

3 Answers 3


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.–
  • all hosts matching 10.2.??.* (i.e.–
  • all hosts matching 10.2.10?.* (i.e.–
  • all hosts matching 10.2.11?.* (i.e.–
  • 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?.*"
  • 5
    To be precise, this is not a regular expression, it's a globbing wildcard. Sep 19, 2016 at 11:56
  • 2
    Thanks for the answer, it nearly works for me but I actually needed to differentiate those two ranges with separate host entries. It also needed each one quoted separately (ssh/Mac). Shortest I could find: host "10.2.?.*", "10.2.??.*", "!10.2.64*", "!10.2.65*", "!10.2.66*", "!10.2.67*", "!10.2.68*", "!10.2.69*", "!10.2.7*", "!10.2.8*", "!10.2.9*" and host "10.2.??.*", "10.2.10?.*", "10.2.11?.*", "10.2.12?.*", "!10.2.1?.*", "!10.2.2?.*", "!10.2.3?.*", "!10.2.4?.*", "!10.2.5?.*", "!10.2.60.*", "!10.2.61.*", "!10.2.62.*", "!10.2.63.*", "!10.2.128.*", "!10.2.129.*"
    – fazy
    May 12, 2017 at 17:16

You could use the very powerful Match directive with the grepcidr tool:

Match exec "grepcidr <(echo %h) &>/dev/null"
   Proxycommand ssh -q bastion-foo -W %h:%p

How this works:

  • %h in the commandline gets expanded to the hostname (see Tokens)
  • <(echo %h) wraps this into a temporary "file"
  • Maybe use <(dig +short %h) if working with hostnames
  • then use grepcidr to match the hostname %h against a.b.c.d/e
  • &>/dev/null because we only care about the return code, not the output.

This needs the additional tiny grepcidr package, which should exist in your package manager.


Keep an eye on http://bugzilla.mindrot.org/show_bug.cgi?id=1169 which may eventually provide a mechanism for this.

  • last comment 2014 ⌚⌚
    – nhed
    Sep 26, 2019 at 16:45
  • OpenSSH developer Damien Miller recently responded to my asking this on twitter by saying “I think we're more likely to turn off CheckHostIP (the thing that spams addresses into known_hosts) in the short term, as nobody has satisfactorily explained what problem it solves to me. CIDR in ssh_config probably is less likely, as there are too many chicken and egg problems in config parsing vs address resolution.”
    – Adam Katz
    Dec 14, 2020 at 3:23
  • Link only answer. :( Feb 4, 2021 at 0:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.