Restricting ssh to a specific hostname
Solution 1:
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.
Solution 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).
Solution 3:
Cribbed from another SF question, how 'bout this?
You could use the AllowUsers directive in /etc/ssh/sshd_config e.g. AllowUsers [email protected]
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. ;-)