16

I want to be able to log in to a (publicly-accessible) SSH server from the local network (192.168.1.*) using some SSH key, but I don't want that key to be usable from outside the local network.
I want some other key to be used for external access instead (same user in both cases).

Is such a thing possible to achieve in SSH?

4

3 Answers 3

25

Yes.

In the file ~/.ssh/authorized_keys on the server, each entry now probably looks like

ssh-ed25519 AAAAC3NzaC1lZSOMEKEYFINGERPRINT comment

(or similar)

There is an optional first column that may contain options. These are described in the sshd manual.

One of the options is

from="pattern-list"

Specifies that in addition to public key authentication, either the canonical name of the remote host or its IP address must be present in the comma-separated list of patterns. See PATTERNS in ssh_config(5) for more information on patterns.

In addition to the wildcard matching that may be applied to hostnames or addresses, a from stanza may match IP addresses using CIDR address/masklen notation.

The purpose of this option is to optionally increase security: public key authentication by itself does not trust the network or name servers or anything (but the key); however, if somebody somehow steals the key, the key permits an intruder to log in from anywhere in the world. This additional option makes using a stolen key more difficult (name servers and/or routers would have to be compromised in addition to just the key).

This means that you should be able to modify ~/.ssh/authorized_keys from

ssh-ed25519 AAAAC3NzaC1lZSOMEKEYFINGERPRINT comment

to

from="pattern" ssh-ed25519 AAAAC3NzaC1lZSOMEKEYFINGERPRINT comment

Where pattern is a pattern matching the client host that you're connecting from, for example by its public DNS name, IP address, or some network block:

from="192.168.1.0/24" ssh-ed25519 AAAAC3NzaC1lZSOMEKEYFINGERPRINT comment

(this would only allow the use of this key from a host in the 192.168.1.* network)

4
  • 2
    @Mehrdad Notice that pattern needs to match the client from the server's perspective. A local IP address pattern like 192.168.1.* may not work (unless the server is on the same network).
    – Kusalananda
    Mar 22, 2017 at 11:11
  • Interesting, why would it not work given they are both on the same network? There's by definition no NAT involved if they're on the same network, right? (Edit: Just saw your edit. Yeah, this was specifically for the local network so it should work.)
    – user541686
    Mar 22, 2017 at 11:14
  • @Mehrdad Just added that because you said the server was "publically available", so I thought it was "remote".
    – Kusalananda
    Mar 22, 2017 at 11:14
  • Ah. Nah, I mentioned that so people wouldn't start arguing with me about why disabling remote logins isn't a solution if I'm only using the server locally or something. You have to ask questions very defensively on SE in my experience... some people really go out of their way to give non-solutions. :(
    – user541686
    Mar 22, 2017 at 11:15
5

You can achieve this by adding from="192.168.1.0/24" in front of the public key in the .authorized_keys file. The entire row should look like this:

from="192.168.1.0/24" ssh-rsa AAAA....
0
0

The sshd server-side configuration via authorized_keys has already been discussed. However, one can also generate a key with an option to limit which source addresses are valid for that key. It'll work the same for all systems to which you connect. This key would need to be regenerated any time the source address list changes.

This removes the need to touch all the authorized_keys files across multiple servers you might want to limit in a special way in case, say, you happen to be doing that automatically and don't want to mess with changing the automation to handle one key. Or in case you want another layer of protection in case there's a reversion on the server. Or if you want to limit this key no matter what the server configuration happens to be.

In the options for ssh-keygen there's an option called source-address which takes a comma-separated list of address/netmask pairs in CIDR format. The command to generate the key will look something like this assuming you want to be able to use this key only from 192.168.1.* and 10.255.255.254 as source addresses.:

ssh-keygen -t rsa -b 4096 -O source-address=192.168.1.0/24,10.255.255.254/32

Sorry to mislead anyone. It looks like BowlOfRed is correct. This requires the use of certificates rather than bare keys.

1
  • 2
    That option requires that you're using certificates, not the bare ssh keys. Did you test this?
    – BowlOfRed
    Apr 17, 2018 at 21:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .