Light Up OpenSSH with Matches

Posted: August 31, 2018 in Cool Projects, Security, Software

SSH is a great tool for accessing systems remotely to perform system management tasks.  It can also be a security risk if it is not configured properly. Many administrators start with the best intentions.  Password complexity rules are put in place that require long passwords with a robust mixture of uppercase, lowercase, numbers and special characters.  Alternatively, a policy of using SSH public keys is implemented. In most, cases this is a great setup. However, there are times when a single method for authentication does not fit well.  

Take for example, services or other systems that must utilize SSH but only support username and password authentication.  All of the other user accounts on the same network utilize public keys. Configuring the SSH server enforce a policy where different interfaces support different authentication methods, or where users must use one method while services us another would be ideal in these scenarios.  This is where the match parameter in the SSH configuration file can come into play.

Matchmaking in SSH

Let’s take a look at an SSH configuration file to see how the match parameter can be configured.  In this scenario there is a single SSH server with the hostname of “sshserver” that is configured with two network interfaces.  SSH is installed and configured in it’s default state which allows both public key and password based authentication.

Besides root, there are two other accounts on the system.  The user account for Bill does not have a public key created on the server and can only authenticate using a password.  The account for Ted has a public key established on the SSH server and can log in with either the public key of a password.  Once the SSH server configuration is complete, it is expected that Ted will be able to log in to either network while Bill is only allowed to login to the internal network since that account is not configured with a public key for SSH.

The network configuration is configured as follows.  The external interface is on the 192.168.122.0 network will be configured as the default for SSH.  It needs to be configured to only allow public key based authentication and not permit the root account to directly login.  Below are the settings from /etc/ssh/sshd_config that need to be changed and the effect that each has on how SSH functions.

PermitRootLogin no
PermitRootLogin determines if the root user and login interactively through SSH.

PubkeyAuthentication yes
PubkeyAuthentication sets the SSH server to allow keys to used for logging in to the server.

PasswordAuthentication no
Setting PasswordAuthentication to no means that the SSH server will not accept any connections that are not presenting an ssh key.

Once the configuration is in place, restart the SSH service

systemctl restart sshd

On a client that has Ted’s private key on it, try to login to the external interface of the SSH server using both Bill and Ted’s accounts.

$ ssh ted@192.168.122.4
Last login: Fri Aug 31 13:22:48 2018 from gateway
[ted@sshserver ~]$ exit
logout
Connection to 192.168.122.4 closed.

$ ssh bill@192.168.122.4
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Now lets try the same thing using the internal interface for both accounts.

$ ssh ted@192.168.10.194
Last login: Fri Aug 31 13:23:15 2018 from gateway
[ted@sshserver ~]$ exit
logout
Connection to 192.168.10.194 closed.

$ ssh bill@192.168.10.194
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

As expected, Ted and use the public key associated with the account to login to either of the SSH servers interfaces while Bill is denied access on both interfaces.

The internal LAN is connected to the 192.168.10.0 network.  We want to change the behavior of SSH on this interface to allow password based login.  This should allow Bill access to the server despite not having a public key. To complete the configuration, add the following lines to the end of the sshd_config file.

Match Address 192.168.10.0/24
PasswordAuthentication yes
PubkeyAuthentication no
PermitRootLogin yes

And restart the SSH server

Systemctl restart sshd

Here is what each of those lines do:

Match Address 192.168.10.0/24
This introduces a conditional block of configuration items.  If all of the items on the match line are met, in this case the IP network that the request is from, then the listed parameters override the values that are specified in the configuration file.

PasswordAuthentication yes
This option overrides the ability to authenticate via a password so that it is allowed.

PubkeyAuthentication no
PubkeyAuthentication is overridden so the public keys are not allowed on the internal network.

PermitRootLogin yes
Setting PermitRootLogin to “yes” enables the root user to log in to the server on the internal network.

Once the configuration is set, try to login to the external interface of the SSH server again with Bill and Ted’s accounts.  Make sure to use the client where Ted’s private key is located.

$ ssh ted@192.168.122.4
Last login: Fri Aug 31 13:48:31 2018 from gateway
[ted@sshserver ~]$ exit
logout
Connection to 192.168.122.4 closed.

$ ssh bill@192.168.122.4
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

As expected, Ted can log in to the external interface, but Bill cannot.  Now let’s try the internal interface that should work with the match parameter that was configured.

$ ssh ted@192.168.10.194
ted@192.168.10.194's password:
Last login: Fri Aug 31 13:48:44 2018 from gateway
[ted@sshserver ~]$ exit
logout
Connection to 192.168.10.194 closed.

$ ssh bill@192.168.10.194
bill@192.168.10.194's password:
[bill@sshserver ~]$ exit
logout
Connection to 192.168.10.194 closed.

For fun, let’s also try the root user.  Remember, the configuration file was configured to prevent root logins as a default, but the match parameter included and override for that configuration item if the user is initiating the connection from the internal network.

$ ssh root@192.168.10.194
root@192.168.10.194's password:
Last login: Fri Aug 31 13:22:11 2018
[root@sshserver ~]# exit
logout
Connection to 192.168.10.194 closed.

$ ssh root@192.168.122.4
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Everything is working as expected!  We now have a SSH server that expects to use public key based authentication on one network, and password authentication on another.

More Advanced Matches

In the above example, the match criteria only listed the address however, the match criteria can include usernames, groups, IP addresses and ports.  Each criteria just has to be separated by a space. For example, if the match criteria needed to be changed to add a rule that applies to all users except “ted” the example would be changed to:

Match Address 192.168.10.0/24 User *,!ted

The result is that the user named Ted would not be allowed to override the default configuration parameters with those that follow the match parameter.  Instead Ted would still be login with public key based authentication. Note that the syntax has to be “*,” meaning to allow all before we negate the the individual user.

Once a pattern is matched, there are a large number of configuration parameters that can be overridden.  These parameters include the following:

AcceptEnv, AllowAgentForwarding, AllowGroups, AllowStreamLocalForwarding, AllowTcpForwarding, AllowUsers, AuthenticationMethods, AuthorizedKeysCommand, AuthorizedKeysCommandUser, AuthorizedKeysFile, AuthorizedPrincipalsCommand, AuthorizedPrincipalsCommandUser, AuthorizedPrincipalsFile, Banner, ChrootDirectory, ClientAliveCountMax, ClientAliveInterval, DenyGroups, DenyUsers, ForceCommand, GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes, HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS, KbdInteractiveAuthentication, KerberosAuthentication, KerberosUseKuserok, MaxAuthTries, MaxSessions, PasswordAuthentication, PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY, PermitTunnel, PermitUserRC, PubkeyAcceptedKeyTypes, PubkeyAuthentication, RekeyLimit, RevokedKeys, StreamLocalBindMask, StreamLocal BindUnlink, TrustedUserCAKeys, X11DisplayOffset, X11MaxDisplays, X11Forwarding and X11UseLocalHost.

There are a ton of choices!

Conclusion

SSH is a flexible and important part of security in the datacenter and the match parameter is an important part of that service.  The SSH server can be configured to allow for multiple different criteria that allow different users, systems or services access to a system using different authentication mechanisms without unnecessarily decreasing the overall security posture of the server itself.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s