python ssh登录网络设备_Linux下使用pam_python实现SSH的双因子认证登录

Linux下使用pam_python实现SSH的双因子认证登录.md

关键字

Linux PAM Python SSH 2 Two Multi Factor Authentication Login 双因子 多因子 密保 TOKEN 一次性口令 PASSPOD OTP yubikey 认证 安全 登录

引言

Linux系统管理员(System Administrator,SA)经常碰到的问题就是放在公网的服务器经常被人猜测密码,每天都可以从系统日志里看到探测密码的信息,再加上最近很多厂商泄露了包含用户密码的数据库,撞库的行为也逐步开始转移到SSH上。

最初SA的防御手段一般是限制IP地址、修改SSH端口、部署失败一定次数就锁定或者封IP的程序或者脚本,更有极客想出了敲门3次端口才开放的办法,可谓无所不用其极。但是这些办法很多都不是很方便,改了端口,连接时需要指定端口;限制了IP地址,发现在家上网就登录不了了,封锁脚本可能把自己也锁定了。

在大公司里一般是采用的“RSA SecurID”方案,或者类似的技术。我们称其为双因子认证或者多因子认证(Two Factor Authentication;MFA,Multi Factor Authentication),在输入密码的同时需要输入一个一次性口令(OTP,One Time Password)。这种方案也有软件实现和硬件实现,软件例如google authenticator、Symantec Validation and ID Protection (VIP) ;硬件例如 RSA SecurID、飞天诚信的密保产品。

使用RSA SecurID的方案看起来虽然很好,但是他需要独立部署RSA Server,需要占用一台服务器,并且Server端软件是收费的,RSA SecurID密保也是收费的。

有没有免费的办法?

有啊,今天就来介绍一个。

实现方法

最简单的实现的方式,用户登录时需要输入用户名+PIN+密码方式才能登录。

这里的PIN是一个字符串,例如”ipcpu.com”,固定死的,不会变。

[root@IPCPU-0security]#ssh root@192.168.110.11

EnterYourPIN:

Password:

Lastlogin:MonMar2100:44:262016from192.168.110.11

[root@IPCPU-11~]#

安装pam_python模块

pam_python (注意不是python_pam)是一款开源的软件,将需要使用C语言编写的PAM模块转换成了可以使用python语言来写,顿时感觉方便多了。

安装方法比较简单

##@@安装编译依赖

yum install pam pam-devel-y

##@@解压进入src目录

make lib

##@@拷贝.so文件到/lib64/security/

cp build/lib.linux-x86_64-2.6/pam_python.so/lib64/security/

编写Python程序实现认证流程

我们进入到 /lib64/security/ 编写一个auth.py文件,内容如下

#!/usr/bin/env python

# -*- coding=utf-8 -*-

"""

#这个函数是本次的重点内容哦,判断用户输入的PIN是否为ipcpu.com

"""

defpam_sm_authenticate(pamh,flags,argv):

forattemptinrange(0,3):

msg=pamh.Message(pamh.PAM_PROMPT_ECHO_OFF,"Enter Your PIN: ")

resp=pamh.conversation(msg)

ifresp.resp=="ipcpu.com":

returnpamh.PAM_SUCCESS

else:

continue

returnpamh.PAM_AUTH_ERR

"""

#以下都是默认函数

"""

defpam_sm_setcred(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_acct_mgmt(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_open_session(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_close_session(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_chauthtok(pamh,flags,argv):

returnpamh.PAM_SUCCESS

配置SSHD,开启PAM模块

修改/etc/pam.d/sshd,新增一行,如下

#%PAM-1.0

auth requisite pam_python.so auth.py

auth required pam_sepermit.so

auth include password-auth

修改/etc/ssh/sshd_config,打开ChallengeResponse

ChallengeResponseAuthenticationyes

重启SSHD服务,接下来就可以测试了。

如果出现错误,日志会写到/var/log/secure里面。

进阶-独立的PIN

使用固定的PIN优点太low了,接下来我们介绍进阶的办法,每个人用自己的PIN。

首先PIN需要有个地方存放起来,我们就直接使用/etc/passwd的comment字段来存储。

可以通过命令 usermod来修改。如下,

[root@IPCPU2factor-with-PIN]#usermod-c',,15801581158,'ipcpu

[root@IPCPU2factor-with-PIN]#cat/etc/passwd|grep ipcpu

ipcpu:x:501:501:,,15801581158,:/home/ipcpu:/bin/bash

[root@IPCPU2factor-with-PIN]#

python的代码也需要修改下,如下

importrandom,string,hashlib,requests

importpwd,syslog

defauth_log(msg):

syslog.syslog("IPCPU-PAM-AUTH: "+msg)

defget_user_number(user):

"""Extract user's phone number for pw entry"""

try:

comments=pwd.getpwnam(user).pw_gecos

exceptKeyError:# Bad user name

auth_log("No local user (%s) found."%user)

return-1

try:

returncomments.split(',')[2]# Return Office Phone

exceptIndexError:# Bad comment section format

auth_log("Invalid comment block for user %s. Phone number must be listed as Office Phone"%(user))

return-1

defpam_sm_authenticate(pamh,flags,argv):

try:

user=pamh.get_user()

user_number=get_user_number(user)

exceptpamh.exception,e:

returne.pam_result

ifuserisNoneoruser_number==-1:

msg=pamh.Message(pamh.PAM_ERROR_MSG,"Unable to send one time PIN.\nPlease contact your System Administrator")

pamh.conversation(msg)

returnpamh.PAM_AUTH_ERR

forattemptinrange(0,3):# 3 attempts to enter the one time PIN

msg=pamh.Message(pamh.PAM_PROMPT_ECHO_OFF,"Enter Your PIN: ")

resp=pamh.conversation(msg)

ifresp.resp==user_number:

auth_log("user: "+user+" login successful with PIN.")

returnpamh.PAM_SUCCESS

else:

auth_log("user: "+user+" login failed with PIN.")

continue

returnpamh.PAM_AUTH_ERR

defpam_sm_setcred(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_acct_mgmt(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_open_session(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_close_session(pamh,flags,argv):

returnpamh.PAM_SUCCESS

defpam_sm_chauthtok(pamh,flags,argv):

returnpamh.PAM_SUCCESS

继续进阶-短信

上一步,我们使用了每个用户独立的PIN来进行双因子认证,如果我们把PIN换成自己的手机号,然后在登陆的时候先生成随机字符串,然后短信发送到用户的手机上,对比字符串是否一致,这样我们就实现了基于短信形式的双因子认证。

这部分代码就留给读者自行练习了。需要注意的是为了防止别人猜测密码时收到大量短信,这里最好连手机号也对比认证下。

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值