15

Many services (like GitHub) use a wide range of IPs, and obviously the same public key.

How can I add an IP range (preferably in a single) to known_hosts file?

For the GitHub example, it uses the following ranges:

  • 207.97.227.224/27
  • 173.203.140.192/27
  • 204.232.175.64/27
  • 72.4.117.96/27
  • 192.30.252.0/22

And the key is:

AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==

  • 1
    those IPs are completely public here – RSFalcon7 Oct 14 '13 at 14:14
11

As noted in other answers, known_hosts does not have support for IP address ranges. It does, however, support wildcards. Of course wild-cards aren't quite the same thing so you need to be really careful about how you use them in IP addresses, but in the particular case of Github this can be done safely.

The situation seems to have gotten simpler since the question was asked. According to Github's official documentation there is only one IP address range in use (at least as far as IPv4 goes). This is the 192.30.252.0/22 range. That makes for 1020 possible IP addresses that conveniently span the entire possible range for the last octet in just four different C blocks.

From man 8 sshd, this is what we have to work with in known_hosts:

Hostnames is a comma-separated list of patterns (*' and?' act as wildcards); each pattern in turn is matched against the canonical host name (when authenticating a client) or against the user-supplied name (when authenticating a server). A pattern may also be preceded by !' to indicate negation: if the host name matches a negated pattern, it is not accepted (by that line) even if it matched another pattern on the line. A hostname or address may optionally be enclosed within[' and ]' brackets then followed by:' and a non-standard port number.

Using this info, we can construct an entry using the * wildcard for the last octet that matches all possible Github endpoints (and ONLY those endpoints) like so:

github.com,192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.* ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==

If the IP range you needed to construct did not fill a full C block and thus all possible values for an octet, it would be impossible to use wildcards for such an accurate match.

8

I do not think you can easily add the ranges, but I think (can't test this right now) that the same effect can be achieved by adding the following to .ssh/ssh_config:

Host *.github.com
HostKeyAlias github-server-pool.github.com

Next, you would add the key to the known_hosts file under the name github-server-pool.github.com.

Assumption: the host github-server-pool.github.com does not exist or is never connected to through SSH.

The idea behind it, is that ssh will use the key github-server-pool.github.com as the key to lookup the public host key for all hosts of the github.com domain.

  • This is a great answer, and easier than the original. – kael Feb 14 '18 at 19:15
4

There is no support for IP address sets in the known_hosts file. You'll have to have one line per address.

Although the host name part of entries is hashed by default, this is only for privacy so that someone getting hold of your .known_hosts wouldn't be able to easily find out which hosts you've been connecting to. (They can still verify guesses.) You can use a plain host name or IP address.

for net in 207.97.227.224/27 173.203.140.192/27 204.232.175.64/27 72.4.117.96/27 192.30.252.0/24 192.30.252.1/24 192.30.252.2/24 192.30.252.3/24; do
  base=${net%/*}; d=${base##*.}; abc=${base%.*}
  bits=$((32 - ${net#*/}))
  e=0
  while [ $e -lt $((2 ** bits) ]; do
    echo "$abc.$((d + e)) ssh-rsa AAAAB3NzaC1yc…" >>~/.ssh/known_hosts
    e=$((e + 1))
  done
done

Note that this may add duplicates.

  • fixed, but only working for networks up to 0.0.0.0/24 – RSFalcon7 Oct 14 '13 at 14:27
  • @RSFalcon7 Indeed. IP address arithmetic is annoying. I made a quick-and-dirty workaround… If you need support for larger networks, convert the IP address to a 32-bit number before doing the enumeration. – Gilles Oct 14 '13 at 17:44
0

SSH seem to have no concept of IP ranges for known_hosts. I think the assumption is that each host would have a unique key for security reasons.

Two ways I can see to pre-populate your known_hosts:

  1. ssh-keyscan - Write a brief script to iterate through all those addresses and either feed it to ssh-keyscan or a file for ssh-keyscan to read. ssh-keyscan can scan multiple hosts per invocation, either via specifying on one line or specifying a list of the hosts.

  2. Populate known_hosts yourself with a script or editor. The format is fairly simple if you use the non-hashed version. It is:

    hostname,IP address ssh-keytype key

hostname is the hostname you contact, and would be the same for all the GitHub addresses. IP address would be what a script would iterate through. key is the key you provided above.

Neither is elegant, but I think the SSH folks assumed no one would do what GitHub is doing.

  • Nobody should be doing what github is doing. It's a host key, not a "group of similar hosts" key. – user41515 Oct 14 '13 at 14:57
  • @WumpusQ.Wumbley I agree. But I doubt GitHub will change on my say so. – kurtm Oct 14 '13 at 14:58
0

Hi I found the script from Gilles quite usefull, but only working for networks up to 0.0.0.0/24 was a limitation, I've extended the script to work with larger networks up to 0.0.0.0/16 perhaps it will be useful for someone else.

#!/bin/sh
# http://unix.stackexchange.com/questions/94448/how-to-add-an-ip-range-to-known-hosts
# answered Oct 11 '13 at 0:21  Gilles
# only working for networks up to 0.0.0.0/24
# Declan Forde - Increased the range up to 0.0.0.0/16 networks


NETWORKS="127.0.0.0/30 127.0.0.0/29 127.0.0.0/28 127.0.0.0/27 127.0.0.0/26 127.0.0.0/25 127.0.0.0/24 127.0.0.0/23 127.0.0.0/22 127.0.0.0/21 127.0.0.0/16"

for net in ${NETWORKS}
do
  base=${net%/*}
  bits=$((32 - ${net#*/}))

  abc=${base%.*}
  ab=${abc%.*}
  c=${abc##*.}
  d=${base##*.}

  if [ $bits -gt 8 ] && [ $bits -le 16 ]
  then
    netbits=$((bits - 8))
    bits=8
  else
    netbits=0
  fi

  netcount=0
  while [ $netcount -lt $((2 ** netbits)) ]
  do
    count=0
    while [ $count -lt $((2 ** bits)) ]
    do
      echo "$ab.$c.$((d + count))"
      echo "$ab.$c.$((d + count)) ssh-rsa AAAAB3NzaC1yc." >>~/.ssh/known_hosts
    count=$((count + 1))
    done
    netcount=$((netcount + 1))
    c=$((c + 1))
  done
done

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.