MOTP stands for mobile one time password which provides one time password services.
Download and install otp server
- Login to DS as root
- mkdir -p /opt/usr/local/bin
- cd /opt/usr/local/bin
- Download otp server script
# wget http://motp.sourceforge.net/bash/otpverify.sh
- Install necessary library
# ipkg install findutils
# ipkg install md5deep
# ipkg install bash - Edit otpverify.sh
# vi /opt/usr/local/bin/otpverify.sh
Changes highlighted in red.
#!/opt/bin/bash # # Mobile One Time Passwords (Mobile-OTP) for Java 2 Micro Edition, J2ME # written by Matthias Straub, Heilbronn, Germany, 2003 # (c) 2003 by Matthias Straub # # Version 1.05a # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # arguments: $1 $2 $3 $4 $5 # $1 - username # $2 - one-time-password that is to be checked # $3 - init-secred from token (to init token: #**#) # $4 - user PIN # $5 - time difference between token and server in 10s of seconds (360 = 1 hour) # # one-time-password must match md5(EPOCHTIME+SECRET+PIN) # # # otpverify.sh version 1.04b, Feb. 2003 # otpverify.sh version 1.04c, Nov. 2008 # changed line 1 to ksh because of problems with todays bash an sh # otpverify.sh version 1.05a, Jan. 2011 # changed back to bash and added in shopts line to ensure aliases handled # correctly (bash is always available on any modern *nix unlike ksh) # PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/usr/local/bin:/opt/bin:/opt/sbin # ensure aliases are expanded by bash shopt -s expand_aliases if [ -e "`which md5 2>/dev/null`" ] then alias checksum=md5 have_md5="true" fi if [ -e "`which md5sum 2>/dev/null`" ] then alias checksum=md5sum have_md5="true" fi alias checksum=md5deep have_md5="true" if [ $have_md5 != "true" ] then echo "No md5 or md5sum available on server!" exit 16 fi function chop { num=`echo -n "$1" | wc -c | sed 's/ //g' ` nummin1=`expr $num "-" 1` echo -n "$1" | cut -b 1-$nummin1 } if [ ! $# -eq 5 ] ; then echo "USAGE: otpverify.sh Username, OTP, Init-Secret, PIN, Offset" exit 14 fi mkdir /opt/var/motp 2>/dev/null mkdir /opt/var/motp/cache 2>/dev/null mkdir /opt/var/motp/users 2>/dev/null chmod og-rxw /opt/var/motp 2>/dev/null || { echo "FAIL! Need write-access to /opt/var/motp"; exit 17; } chmod og-rxw /opt/var/motp/cache chmod og-rxw /opt/var/motp/users USERNAME=`echo -n "$1" | sed 's/[^0-9a-zA-Z._-]/X/g' ` PASSWD=`echo -n "$2" | sed 's/[^0-9a-f]/0/g' ` SECRET=`echo -n "$3" | sed 's/[^0-9a-f]/0/g' ` PIN=`echo -n "$4" | sed 's/[^0-9]/0/g' ` OFFSET=`echo -n "$5" | sed 's/[^0-9]/0/g' ` EPOCHTIME=`date +%s` ; EPOCHTIME=`chop $EPOCHTIME` # delete old logins /opt/bin/find /opt/var/motp/cache -type f -cmin +5 | xargs rm 2>/dev/null if [ -e "/opt/var/motp/cache/$PASSWD" ]; then echo "FAIL" exit 15 fi # account locked? if [ "`cat /opt/var/motp/users/$USERNAME 2>/dev/null`" == "8" ]; then echo "FAIL" exit 13 fi I=0 EPOCHTIME=`expr $EPOCHTIME - 18` EPOCHTIME=`expr $EPOCHTIME + $OFFSET` while [ $I -lt 36 ] ; do # 3 minutes before and after OTP=`printf $EPOCHTIME$SECRET$PIN|checksum|cut -b 1-6` if [ "$OTP" = "$PASSWD" ] ; then /bin/touch /opt/var/motp/cache/$OTP || { echo "FAIL! Need write-access to /opt/var/motp" ; exit 17; } echo "ACCEPT" rm "/opt/var/motp/users/$USERNAME" 2>/dev/null exit 0 fi I=`expr $I + 1` EPOCHTIME=`expr $EPOCHTIME + 1` done echo "FAIL" NUMFAILS=`cat "/opt/var/motp/users/$USERNAME" 2>/dev/null` if [ "$NUMFAILS" = "" ]; then NUMFAILS=0 fi NUMFAILS=`expr $NUMFAILS + 1` echo $NUMFAILS > "/opt/var/motp/users/$USERNAME" exit 11In case there is a newer version of this server script released in the future, here is the summary of changes:
- line 1 should point to optware bash: /opt/bin/bash
- The script will only looks for md5 and md5sum binary, however, we are using md5deep from optware instead. Add two lines to assign md5deep as checksum binary.
- Add 10 to all error code, otherwise it will fail the FreeRadius server
- Basically I’ve appended /opt to every path inside the script.
- It need the find binary. We should use the binary provided by optware instead of using the system default binary.
- # chmod 755 /opt/usr/local/bin/otpverify.sh
Download and setup Android motp client
Since I’ve an Android phone, I install the motp client to my phone.
- Download the android motp client ‘Mobile-OTP’ from url below
http://motp.sourceforge.net/Mobile-OTP.apk
- Install the apk to the phone
- Run the Mobile-OTP.
- Input #**# and click ‘Calculate OTP’ button. An init-secret value will be generated. Copy the init-secret and paste it to somewhere, i.e. notepad.
- Input 1234 and click ‘Calculate OTP’ button again. An one time password will be generated.
- Now test the setup, SSH to the DiskStation as root and run the command as below:
# /opt/usr/local/bin/otpverify.sh testuser [one-time-password] [Init-secret] 1234 0
If you run the command fast enough, the script should return “ACCEPT”. If you got a “FAIL”, repeats again by generating a new one-time-password and execute the command again couple times until you got “ACCEPT”. Make sure the Init-secret and One-time-password is input correctly.
FreeRadius changes
- SSH to DS as root
- # cd /opt/etc/raddb
- # wget http://motp.sourceforge.net/dictionary.motp
- Edit /opt/etc/raddb/dictionary, add following line to the end of the file
$INCLUDE dictionary.motp
- Although I don’t think this step is needed, but it is suggested by the official installation guide.
# wget http://motp.sourceforge.net/execparams - Add a test user by editing /opt/etc/raddb/users file. Add following lines to the end of the file.
testuser Auth-Type = Accept Exec-Program-Wait = "/opt/usr/local/bin/otpverify.sh %{User-Name} %{User-Password} 123412341234 1234 0", Fall-Through = Yes, Reply-Message = "Hello, %{User-Name}"where 123412341234 is the init-secret and 1234 is the pin of the test user. Replace the value of init-secret with the one generated by the Android OTP client.
- Generate a new One-time-password using the Android OTP client (input 1234 and click ‘Calculate OTP’ button), then test the freeradius setup by executing the command below:
# radtest testuser [one-time-password] localhost 0 [FreeRadius shared secret password]
If success, you should got a response similar to below:
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=48, length=46
Reply-Message = "Hello, testuser "
Now my services like OpenVPN and Squid accept OTP login
Resources
Hi,
did you chose anything else ? I’m trying to do it on a DS411j and it doesn’t work ….
TIA