3

So here's the problem:

  • I have a single server with multiple hostnames, meaning I have A records example.com and *.example.com pointing to the server's ip-address
  • I want to limit incoming ssh connections to a specific hostname, that is I want to allow only logins to user@secret.example.com, and disallow login attempts using user@ip-address or user@example.com

The man page from sshd_config has the following for ListenAddress:

Specifies the local addresses sshd(8) should listen on.  
The following forms may be used:

ListenAddress host|IPv4_addr|IPv6_addr
ListenAddress host|IPv4_addr:port
ListenAddress [host|IPv6_addr]:port

which seems to indicate that sshd has the ability to restrict itself to a a specific hostname. However I've tried ListenAddress secret.example.com:22, but after restarting sshd that doesn't seem to add any restrictions based on hostname used.

man sshd_config doesn't seem to show any other options in that vein.

Is there something I'm missing, or does sshd simply not have that ability?

cobaco
  • 443
  • 1
  • 4
  • 10

4 Answers4

6

There is no such thing as a "DNS" connection. Once the client gets an IP, it can ONLY make a TCP/IP connection. The server only sees IPs, so it has no idea what name the client used to find the server.

The reason we have website Virtual hosts is because the client transmits a header asking for a specific host. In fact, virtual hosts didn't work with SSL until SSL(TLS) was modified to allow "Server Name Indication" during the initial connection.

For "virtual hosts" to work with SSH, it would need a way for the client to transmit the hostname upon connection. But even if SSH supported such a feature, you're adding zero security by requiring a specific hostname. The reason is that sshd must decrypt the atacker's packet to run the filter. As long as you disable SSH passwords, there's little difference to decrypting the attacker's packet to compare with your SSH key.

If you don't want to be scanned, move the SSH port and/or install fail2ban. If you're really paranoid, you can install a port knocker that "hides" your open port from the casual scanner and/or use iptables to whitelist IP addresses.

  • 2
    in other words even though the ssh client differentiates between 2 domain names for the same host (asking fingerprint confirmation twice), it's not transmitting the host name used to the server while setting up a connection and hence the server can't differentiate. That clears things up, thanks. – cobaco Feb 17 '13 at 09:40
2

Is there something I'm missing, or does sshd simply not have that ability?

Fundamentally, DNS does not have that ability. The client resolves a DNS name into an IP, then attempts to connect to that, so this information is lost at connect time (unless SSH transmits it in a way the server can use it pre-login, which I don't think it does).

Jay
  • 6,544
  • 25
  • 34
  • 1
    I get that DNS doesn't work that way, that's besides the point. Basically I'm looking for the sshd equivalent of a webserver's virtual hosts. The ssh clientside does differentiate between different hostnames, at least if I login to the same server using first user@ssh1.examle.com and then user@ssh2.example.com, I get prompted for the fingerprint twice. So it doesn't seem that unlikely that sshd has the ability to differentiate based on the hostname used. Alas, sofar it seems the answer is simply 'not possible'. – cobaco Feb 17 '13 at 00:20
1

Cribbed from another SF question, how 'bout this?

You could use the AllowUsers directive in /etc/ssh/sshd_config e.g. AllowUsers you@ip.add.re.ss

If you make any changes in your sshd_config file don't forget to restart sshd.

from the sshd_config manpage

This keyword can be followed by a list of user name patterns, separated by spaces. If specified, login is allowed only for user names that match one of the patterns. ‘*’ and ‘?’ can be used as wildcards in the patterns. Only user names are valid; a numerical user ID is not recognized. By default, login is allowed for all users. If the pattern takes the form USER@HOST then USER and HOST are separately checked, restricting logins to particular users from particular hosts.

-- original answer ends --

From what I can see, you could define a wildcard so only users presenting with the correct wildcard-matching hostname element would be listened to by SSHd, e.g. *@sub.domain.tld. Boom! IP-based userlogins denied.

Do NOT put anything like DenyUsers * until after your AllowUsers / AllowGroups declarations. Deny lists are evaluated before Allow lists and will override any explicit Allows. I haven't experimented, but from what I've read in the past you probably don't even need to define the DenyUsers * once you explicitly define an Allow list.

Just don't forget to always Allow yourself. ;-)

Chris Woods
  • 398
  • 3
  • 22
0

What you can do is have multiple IP address on the machine. Then each of your A record points to a different IP address which ultimately all go to the same box. Then you'll be able to use ListenAddress to restrict. Not quite sure what you gain from that since ultimately, it's the same machine anyway.

ETL
  • 6,513
  • 1
  • 28
  • 48
  • Well the idea is that by having a `*.example.com` A record, and then restricting ssh access to a specfic not explicitly specified subdomain an attacker would have to guess: first the right subdomain and port, then the right user (specified with `AllowUsers`), and then the password. Thus making a brute force attack that much less likely to succeed. – cobaco Feb 17 '13 at 00:11
  • If you're worried about attackers guessing your password don't allow password authentication for incoming ssh users. Require a pre-shared key, and keep the key password-encrypted on the machine from which you want to initiate the ssh connection. – Michael McNally Feb 17 '13 at 05:29
  • You can also combine `sshd_config` `AllowUsers jane bob woody` with i.e. `Match Address ::1,127.0.0.1,192.168.0.0/16,10.0.0.0/8\n PasswordAuthentication yes` So as to allow only a specific set of users, and passwords only on your local LAN. – sastorsl Apr 19 '21 at 13:14