PAM module for sending One-Time Passwords (OTP) via SMS
WARNING! I take no responsibility for any security holes or other potential problems or malfunctions in the pam_otpsms module. It is provided “as is”. However, any feedback or suggestions for improvements are very welcome.
Background
Sometimes when out travelling I have found a need for accessing resources in our internal network. When VPN is not possible (from internet cafés or other public computers) SSH can be an option. However, normal username and password authentication can feel a bit too weak as the only means of authentication if you open up your SSH server to the world. Therefore I thought I would add an extra layer of security through an extra password sent out via SMS. This can be done via a PAM (Pluggable Authentication Modules) module using “Challenge-Response”-style authentication.
Trusted vs non-trusted users
The idea is checking the remote IP of the SSH client and if not within a defined “trusted” IP address range require an extra password / pin code before allowing access. Only users that are defined in pam_otpsms.conf, the configuration file, are prompted for the password, others are rejected. In the configuration file the user’s mobile phone number needs to be specified as well.
PAM and remote host / IP address
One thing about PAM is that the “remote host” (PAM_RHOST) exposed to the PAM module is set by the application (OpenSSH sshd in this case) and can basically be set to anything. We use OpenSSH on Linux as SSH server and luckily OpenSSH sets this attribute to the hostname (if available) or the IP address. We can even “force” the IP address by setting “UseDNS no” in sshd_config. However, if we would use another SSH server (or a telnet server or whatever) we would need to check what values can be set for PAM_RHOST or we could be in for a surprise.
Sending SMS (via SMS Submit)
Since we offer a commercial SMS service (SMS Submit), that is the service I use in pam_otpsms. It is based on a simple protocol using HTTP POST, so it can definitely be modified to connect to another SMS provider fairly easy. cURL (or rather libcurl) is used for the HTTP communication and since cURL supports SSL as well we can use an encrypted connection in order to keep our extra password as safe as possible.
Installation
WARNING! When experimenting with PAM modules and PAM configuration files it is very possible to lock oneself out of the system. If the PAM configuration for the “sshd” application becomes invalid it may not be possible to login via SSH. Therefore it is vital to have access to the system console or some other way of access. Of course I take no responsibility for any problems arising from the use of pam_otpsms. If you do not feel 100% comfortable with this, don’t continue!
Quick install guide (Linux)
- Download source code
wget http://www.smssubmit.se/files/pam_otpsms-0.90.tar.gz - Unpack it
tar xvzf pam_otpsms-0.90.tar.gz - Compile it
cd pam_otpsms-0.90
make - Copy the library to /lib/security (as root)
cp pam_otpsms.so /lib/security - Copy the config file to /etc and edit it (as root)
cp pam_otpsms.conf /etc
vi /etc/pam_otpsms.conf - Modify /etc/pam.d/sshd to use pam_otpsms.so
See “PAM configuration” below. - Enable challenge-response for sshd
See “OpenSSH configuration” below. - Try it!
Configuration file
This is a sample configuration file (/etc/pam_otpsms.conf):
smssubmit.url=https://smssubmit.infoflex.se:9025/bin/send
smssubmit.username=12345678
smssubmit.password=mysecret
message=Your password:
user=john:46701234567
trustedip=192.168.1.0/24
trustedip=10.0.0.1/32
PAM configuration
A normal /etc/pam.d/sshd file can look like this:
#%PAM-1.0
auth required pam_stack.so service=system-auth
auth required pam_nologin.so
account required pam_stack.so service=system-auth
password required pam_stack.so service=system-auth
session required pam_stack.so service=system-auth
session required pam_loginuid.so
We change that into this:
#%PAM-1.0
auth requisite pam_stack.so service=system-auth
auth required /lib/security/pam_otpsms.so debug conf=/etc/pam_otpsms.conf logfile=/var/log/pam_optsms.log
account required pam_stack.so service=system-auth
password required pam_stack.so service=system-auth
session required pam_stack.so service=system-auth
session required pam_loginuid.so
The change of “required” into “requisite” means that PAM should not proceed to next step unless the “requisite” step passes ok. So, if normal authentication with username and password fails, user is immediately rejected. Then we add the pam_otpsms module to the PAM stack, together with a couple of arguments which points out the configuration and log files. Also we set the loglevel to “debug”.
OpenSSH configuration
When installing CentOS 4.4 “out of the box”, (OpenSSH 3.9p1) the following directives should be added/changed in /etc/ssh/sshd_config:
ChallengeResponseAuthentication yes
UsePAM yes
UseDNS no
Also we always should make use of the “AllowUsers” directive in order to control which users may login via ssh at all. This minimizes the risk of having “guest” accounts with poor passwords lying around.
Getting help
You can always drop me an e-mail, stefan@norlin.se.