Secure SSH with Multi Factor authentication
Logging into a machine is essentially about proving your identity to the server. The human logging in needs to prove to the server that he/she is the holder of the account the session is trying to access.
Identity in general can be proved using the following methods
Something you have (like hardware token device, access card, public/private keys)
Something you know (like password, social security number, birth date)
Something you are (physically defines you, like fingerprint)
Most of the linux servers I deal with are headless and don't really have a bio-metric device attached to them to assert something you are. So, I will be focusing on the first 2 assertions.
Multi factor authentication essentially means asking user to verify his/her identity using two different methods like something you have and something you know.
The rest of the blog focuses on enabling various security mechanisms in a Linux server
a) Public/Private Key Authentication
Public key authentication falls in something you have but they have a weakness. Something you have should be tamper proof and hard to copy. However, private key files can be copied and can often be done without the user knowing that his/her key has been copied away. However, they offer better protection than password in attacks since we typically 2048 bit keys.
A private key can be generated easily using the following linux command
ssh-keygen -f file.rsa -t rsa -b 2048 -q -N ''
The command will produce a 2048 bit private RSA key and store that in a text file (file.rsa here). The private key can be potentially protected with a passphrase by either specifying it at command (-N '<passphrase>') or dropping -N parameter and specifying the passphrase as input in the tty session. The file created above is the private key and must be kept secure. The corresponding public key can be generated using
ssh-keygen -y -f file.rsa
The output is the public key which can be distributed freely. The public key is added/appended to ~<user>/.ssh/authorized_keys file on the server. This directs SSH server to accept the person in possession of the private key to log in as <user>.
Public Key Authentication can be enabled in a linux server by ensuring that the following is present in /etc/ssh/sshd_config
b) Password Authentication
Passwords are the oldest security mechanism. However, people choose simple passwords. Even a random 8 character case sensitive alphanumeric (a-zA-Z0-9) password has only 48 bits of entropy which isn't too hard (1 week) for a botnet to crack. However, most of us don't use random passwords and easy to remember passwords have much less entropy.
Standard password can be enabled in linux server by making sure that sshd config (/etc/ssh/sshd_config) contains the following
PasswordAuthentication yes
A better something you have example is a TOTP hardware device. A phone running TOTP app (like Google Authenticator) is not 100% tamper proof if running on a rooted Android device or if the underlying OS has security related bugs where other application might be able to steal the secret. A hardware key is more tamper proof and is a better choice but phone running TOTP app is also good.
Time based One Time Password (TOTP) algorithm generates a rolling password every X seconds (default 30). The password is based on 2 factors - a secret key which is known to both server and user and time. Given that time is a factor, it is critical that both server and client are using a synchronized clock.
While TOTP is a good something you have example, it has some flaws when it comes to a company wide deployment
a) The algorithm uses a shared secret. This means that the server knows the secret and hence it must be guarded on the server. Anyone who gains root access to the server can find out the secret for all the other users on the system.
b) The one time password is good for X seconds (default 30). This makes a man in the middle (MITM) attack easy. Anyone who intercepts or sees this password can use it for the next 30 seconds.
The flaws can be fixed by having a central TOTP authentication server which all the servers connect for TOTP validation. The central server can prevent MITM attack by enabling only login per verification code. This however limits the user to be able to log into a single server per X seconds.
TOTP authentication can be enabled on a linux server by running the following commands
# install pam module developed by google
# which enables TOTP validation apt-get install libpam-google-authenticator # Run the google authenticator command to create new secret google-authenticator # copy the QR code or secret to a smartphone running a TOTP app
# (like Google Authenticator)
Further, ssh pam configuration (/etc/pam.d/sshd) should be modified to add the following line
auth required pam_google_authenticator.so
This will require user to enter TOTP token (something you have) along with password (something you know)
Enabling combination of these methods
Openssh 6.2 added a new feature where user can be required to pass multiple validations before successful login. Here are some scenarios with the configuration
Its not a desirable configuration as both public key and TOTP fall under something you have. So, this is not a multi factor authentication. Imagine a user storing both of these on a phone and loses the phone. This configuration can be enabled by doing the following
Add the following line to sshd config (/etc/ssh/sshd_config)
AuthenticationMethods publickey,keyboard-interactive
The configuration above requires user to pass public key check and keyboard-interactive check. keyboard-interactive check passes the control to pam module. SSH pam configuration file should have the following changes
# Require TOTP auth required pam_google_authenticator.so
Default pam ssh configuration requires a password. That can be disabled by removing/commenting out the line indicated below
This is a good configuration since it mixes something you have and something you know. This can be enabled by adding the following to sshd config
AuthenticationMethods publickey,password
AuthenticationMethods publickey,keyboard-interactive
password authentication method is handled by sshd itself. While keyboard-interactive is handled by pam. So, in a default setting, they both appear to be the same to user but they are different under the surface. keyboard-interactive enables complex mechanisms possible via pam module. If the intention is use just password along with public key, its desirable to use "AuthenticationMethods publickey,password"
3) PublicKey + Password + TOTP
All 3 authentication methods listed here can be enabled by adding the following line to sshd config file
AuthenticationMethods publickey,keyboard-interactive
Further, pam ssh module should be modified to require totp code like mentioned in (c) above.