ssh – SSH with MAC-Based Filtering Using iptables: Recommended?

iptablesmac addressSecurityssh

I have a server in an internal network (login there via VPN) from where I login to the server via SSH with OpenSSH public/private key authentication. From a security point of view, I want to tie the MAC addresses of my three used clients via iptables on the server so that only these clients can login with it.

iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source xx:xx:xx:xx:xx:xx -j ACCEPT
iptables -A INPUT -p tcp --destination-port 22 -j DROP

However, is it recommended though to do it this way? What other (better) methods can I use to tie the SSH login to the used clients?

(If someone wants to request 2FA, unfortunately 2FA is not possible as potential solution.)

Thanks.

Best Answer

I am supposing that you want to prevent your SSH server from accepting connections from untrusted hosts even though they supply valid user credentials. Is it right?

A possible solution to tie users' public key authentication to selected client hosts is via host-based authentication. By setting up host-based authentication and defining AuthenticationMethods parameter in /etc/ssh/sshd_config to either:

AuthenticationMethods hostbased,publickey hostbased,keyboard-interactive hostbased,password

Or:

AuthenticationMethods hostbased,publickey

That will instruct SSH daemon to request clients to authenticate the hosts they are connecting from before checking users' keys or passwords. The former alternative allows password-based authentication, while the latter restricts it to public keys only. Since host-based authentication is based on keypairs, SSH server will be able to authenticate clients with dynamic IP addresses.


Here follows complete instructions. The documentation of how SSH performs host-based authentication is written in ssh(1) man-page. Please note how SSH identifies users and check whether it is applicable to your case.

Host-based authentication works as follows: If the machine the user logs in from is listed in /etc/hosts.equiv or /etc/ssh/shosts.equiv on the remote machine, and the user names are the same on both sides, or if the files ~/.rhosts or ~/.shosts exist in the user's home directory on the remote machine and contain a line containing the name of the client machine and the name of the user on that machine, the user is considered for login. Additionally, the server must be able to verify the client's host key for login to be permitted. This authentication method closes security holes due to IP spoofing, DNS spoofing, and routing spoofing. [Note to the administrator: /etc/hosts.equiv, ~/.rhosts, and the rlogin/rsh protocol in general, are inherently insecure and should be disabled if security is desired.]

To enable host-based authentication in OpenSSH:

# /etc/ssh/sshd_config

HostbasedAuthentication yes
IgnoreUserKnownHosts yes
IgnoreRhosts yes

# AuthenticationMethods hostbased,publickey hostbased,keyboard-interactive hostbased,password
AuthenticationMethods hostbased,publickey
  • To perform host-based authentication, you can trust the hostname information supplied by clients by setting HostbasedUsesNameFromPacketOnly yes in /etc/ssh/sshd_config:
# /etc/ssh/sshd_config

HostbasedUsesNameFromPacketOnly yes
  • Or, alternatively, you can configure SSH daemon to identify hostnames via resolution of clients' IP addresses using information stored in either /etc/hosts file or PTR records in network's DNS server:
# /etc/ssh/sshd_config

HostbasedUsesNameFromPacketOnly no
UseDNS yes
# /etc/ssh/shosts.equiv

ssh-client-alpha
ssh-client-bravo
ssh-client-charlie
  • List the public keys of the authorized hosts in /etc/ssh/ssh_known_hosts file. A convenient way to do so is via ssh-keyscan:
[root@ssh-server ~]# ssh-keyscan ssh-client-alpha >> /etc/ssh/ssh_known_hosts
[root@ssh-server ~]# ssh-keyscan ssh-client-bravo >> /etc/ssh/ssh_known_hosts
[root@ssh-server ~]# ssh-keyscan ssh-client-charlie >> /etc/ssh/ssh_known_hosts

After configuring OpenSSH server to accept host-based authentication requests, clients must also be configured to request host-based authentication:

# /etc/ssh/ssh_config

Host *
    HostbasedAuthentication yes
    EnableSSHKeySign yes
  • Ensure that SUID/SGID bits in ssh-keysign executable grant read permission to host's private key files:
[root@ssh-client-alpha ~]# find /usr -name ssh-keysign -ls
 16517300    616 -r-xr-sr-x   1  root     ssh_keys   630344 Feb  4 16:01 /usr/libexec/openssh/ssh-keysign

[root@ssh-client-alpha ~]# ls -l /etc/ssh/ssh_host_*key
-rw-r----- 1 root ssh_keys  480 Apr 13 06:51 /etc/ssh/ssh_host_ecdsa_key
-rw-r----- 1 root ssh_keys  387 Apr 13 06:51 /etc/ssh/ssh_host_ed25519_key
-rw-r----- 1 root ssh_keys 2578 Apr 13 06:51 /etc/ssh/ssh_host_rsa_key
Related Question