Pam-Python实现SSH的短信双因素认证

2023-12-29 07:08

本文主要是介绍Pam-Python实现SSH的短信双因素认证,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

谈及到双因子认证或多因子认证时,解决方案有很多,可能会想到短信验证码、RSA动态令牌、Google Authenticator或者Duo,在国内由于某些限制的原因,Google Authenticator和Duo的应用案例较少,而RSA动态令牌主要常见于一些大公司里面,而且使用RSA动态令牌需要独立独立部署RSA 服务器,并且软件需要收费,RSA SecurID密保也是要收费的,如何实现一种经济实惠的双因素认证呢?这里介绍利用python的pam_python模块实现SSH的短信双因素认证。

首先需要简单了解一下Linux中的PAM模块。PAM(PluggableAuthentication Module,可插拔认证模块)机制,采用模块化设计和插件功能,使用户可以轻易地在应用程序中插入新的认证模块或替换原先的组件,同时不必对应用程序做任何修改。详细的PAM介绍可参考:http://www.infoq.com/cn/articles/linux-pam-one 。Pam_python是一款开源的python模块,它将需要使用C语言编写的PAM模块转换成了可以使用python语言编写。

接下来就介绍如何利用pam_python模块实现SSH的短信双因素认证。首先需要编译和安装pam_python模块。依次执行以下命令:

yum install pampam-devel -y   #安装编译需要的依赖wget -Opam-python_1.0.6.tar.gz https://sourceforge.net/projects/pam-python/files/latest/download?source=files --no-check-certificate   #下载pam_python模块tar xvfpam-python_1.0.6.tar.gzcd pam-python_1.0.6make libcp  src/build/lib.linux-x86_64-2.7/pam_python.so/lib64/security/.
接下来就是编写python脚本实现SSH登陆的短信双因素认证。既然是短信双因素认证,就需要一个短信接口用来发送短信。

 image.png

生成随机验证码并调用短信发送接口发送给用户手机号码。

 image.png

最后是SSH登陆与用户交互过程并校验验证码的准确性。

 image.png

完整代码内容如下:

# -*- coding: utf-8 -*-import random, string, hashlib, requestsimport urllib,urllib2import pwd, syslogclass SMSOperation:"""短信发送接口"""def__init__(self, pin, phone_num):self.pin = pinself.phone_num = phone_numself.url = "短信服务地址"self.params = {"account":"短信服务用户名","pswd":"短信服务密码","msg":"One Time Pin:"+str(pin),"mobile":str(phone_num),"needstatus":"false","extno":""}defparse_number(self):"""设置用户手机号参数"""try:self.params['mobile'] =self.phone_numreturn 1except:auth_log("Invalidphone number %s. Please check." % (user))defsend_text(self,pamh):"""发送请求"""try:self.parse_number()except:auth_log("Invalidphone number %s. Please check." % (user))#msg = pamh.Message(pamh.PAM_ERROR_MSG,"The params are : (%s)"% (self.params))#pamh.conversation(msg)resp = requests.post(self.url, data=self.params)temp =resp.content.split(',')[1]if(temp!=0):auth_log("Message cannot be sentto (%s), please check." %(self.phone_num) )def auth_log(msg):"""保存日志到/var/log/messages"""syslog.openlog(facility=syslog.LOG_AUTH)syslog.syslog("MultiFactors Authentication: " + msg)syslog.closelog()def get_hash(plain_text):"""获取短信验证码的sha512字符串,与用户输入的验证码进行校验"""key_hash = hashlib.sha512()key_hash.update(plain_text)return key_hash.digest()def get_user_number(user):"""获取用户手机号码"""try:comments = pwd.getpwnam(user).pw_gecosexcept:auth_log("No local user (%s) found." % user)return -1try:return comments.split(',')[2] # 返回用户手机号except:auth_log("Invalid comment block for user %s. Phone number must belisted as Office Phone" % (user))return -1def gen_key(pamh, user, user_number, length):"""生成短信验证码并发送到用户手机"""pin= ''.join(random.choice(string.digits) for i in range(length))msg= pamh.Message(pamh.PAM_ERROR_MSG, "The pin is: (%s)" % (pin)) # 登陆界面输出验证码,测试目的,实际使用中注释掉即可pamh.conversation(msg)sms= SMSOperation(pin, user_number)try:sms.send_text(pamh)except:if not user_number:auth_log("No phonenumber listed for user (%s)." % (user))else:auth_log("Errorsending PIN to the given SMS number. (%s)" % (user_number))return -1return get_hash(pin)def pam_sm_authenticate(pamh, flags, argv):PIN_LENGTH = 6 # 短信验证码长度try:user = pamh.get_user()user_number = get_user_number(user)except pamh.exception, e:return e.pam_resultifuser is None or user_number == -1:msg = pamh.Message(pamh.PAM_ERROR_MSG,"[1]Unable to get user's phone number.\nPlease check.")pamh.conversation(msg)return pamh.PAM_ABORTpin= gen_key(pamh, user, user_number, PIN_LENGTH)ifpin == -1:msg = pamh.Message(pamh.PAM_ERROR_MSG, "[2]One time PIN could notbe generated.\nPlease check (%s)" % (user_number))pamh.conversation(msg)return pamh.PAM_ABORTforattempt in range(0,3): # 仅允许三次错误尝试msg = pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, "Enter one time PIN:")resp = pamh.conversation(msg)if get_hash(resp.resp) == pin: #用户输入与生成的验证码进行校验return pamh.PAM_SUCCESSelse:continuereturn pamh.PAM_AUTH_ERRdef pam_sm_setcred(pamh, flags, argv):return pamh.PAM_SUCCESSdef pam_sm_acct_mgmt(pamh, flags, argv):return pamh.PAM_SUCCESSdef pam_sm_open_session(pamh, flags, argv):return pamh.PAM_SUCCESSdef pam_sm_close_session(pamh, flags, argv):return pamh.PAM_SUCCESSdef pam_sm_chauthtok(pamh, flags, argv):return pamh.PAM_SUCCESS

保存脚本文件到/lib64/security/目录下,这里将脚本命名为:Multiauth.py。

接下来是配置SSHD,启用PAM的短信认证模块。

 vi /etc/pam.d/sshd 添加一行内容如下:

 

       auth      requisite    pam_python.so   Multiauth.py

 

image.png

同时需要启用ChallengeResponseAuthentication,修改/etc/ssh/sshd_config,将ChallengeResponseAuthentication设置为yes即可。

image.png

在上面的代码里面,获取用户手机号码的时候使用的方法是:pwd.getpwnam(user).pw_gecos,这里我将用户的手机号码信息存放在/etc/passwd文件中,当然可以根据需要存放在其他地方,这里只是用作演示。

 image.png

一切配置完成之后,需要重启ssh服务:systemctl restart sshd.service

重启完成之后,使用gary账号ssh登陆目标主机时,就启用了短信双因素认证了。

image.png

如果在运行过程中发生错误,异常日志信息记录在/var/log/secure文件中,正常的运行日志记录在/var/log/messages中。

这里简单介绍了如何利用pam_python模块实现ssh登陆的短信验证码双因素认证,在实际的安全场景中,实现业务主机的双因素安全认证,可根据实际的安全需求进行调整,例如针对不同用户开启短信验证码,用户手机号码的存储,短信验证码的发送频率限制,短信接口访问的限制。

更多Python视频、源码、资料加群683380553免费获取

*本文作者:yuegui_2004,转载请注明FreeBuf.COM

这篇关于Pam-Python实现SSH的短信双因素认证的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/548719

相关文章

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

python使用watchdog实现文件资源监控

《python使用watchdog实现文件资源监控》watchdog支持跨平台文件资源监控,可以检测指定文件夹下文件及文件夹变动,下面我们来看看Python如何使用watchdog实现文件资源监控吧... python文件监控库watchdogs简介随着Python在各种应用领域中的广泛使用,其生态环境也

el-select下拉选择缓存的实现

《el-select下拉选择缓存的实现》本文主要介绍了在使用el-select实现下拉选择缓存时遇到的问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录项目场景:问题描述解决方案:项目场景:从左侧列表中选取字段填入右侧下拉多选框,用户可以对右侧

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

python 字典d[k]中key不存在的解决方案

《python字典d[k]中key不存在的解决方案》本文主要介绍了在Python中处理字典键不存在时获取默认值的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录defaultdict:处理找不到的键的一个选择特殊方法__missing__有时候为了方便起见,

使用Python绘制可爱的招财猫

《使用Python绘制可爱的招财猫》招财猫,也被称为“幸运猫”,是一种象征财富和好运的吉祥物,经常出现在亚洲文化的商店、餐厅和家庭中,今天,我将带你用Python和matplotlib库从零开始绘制一... 目录1. 为什么选择用 python 绘制?2. 绘图的基本概念3. 实现代码解析3.1 设置绘图画

Python pyinstaller实现图形化打包工具

《Pythonpyinstaller实现图形化打包工具》:本文主要介绍一个使用PythonPYQT5制作的关于pyinstaller打包工具,代替传统的cmd黑窗口模式打包页面,实现更快捷方便的... 目录1.简介2.运行效果3.相关源码1.简介一个使用python PYQT5制作的关于pyinstall

使用Python实现大文件切片上传及断点续传的方法

《使用Python实现大文件切片上传及断点续传的方法》本文介绍了使用Python实现大文件切片上传及断点续传的方法,包括功能模块划分(获取上传文件接口状态、临时文件夹状态信息、切片上传、切片合并)、整... 目录概要整体架构流程技术细节获取上传文件状态接口获取临时文件夹状态信息接口切片上传功能文件合并功能小

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur