2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 使用otp动态口令ssh登录linux

使用otp动态口令ssh登录linux

时间:2021-03-31 11:02:32

相关推荐

使用otp动态口令ssh登录linux

linux上各应用的权限认证使用pam机制(http://www.linux-//linux-pam/linux-pam)。

这里需要一个支持otp验证的pam模块,可以直接用pam_script模块,通过编写脚本实现。

1. 安装pam_script

yum install pam_script或从/jeroennijhof/pam_script编译安装。

这里直接yum安装,会安装下面几个文件:

[root@localhost root]# ll /lib64/security/pam_script.so

-rwxr-xr-x. 1 root root 15416 8月 23 /lib64/security/pam_script.so

[root@localhost root]# ll /etc/pam_script*

-rwxr-xr-x. 1 root root 3836 2月 13 12:21 /etc/pam_script

lrwxrwxrwx. 1 root root 10 2月 10 14:59 /etc/pam_script_acct -> pam_script

lrwxrwxrwx. 1 root root 10 2月 10 14:59 /etc/pam_script_auth -> pam_script

lrwxrwxrwx. 1 root root 10 2月 10 14:59 /etc/pam_script_passwd -> pam_script

lrwxrwxrwx. 1 root root 10 2月 10 14:59 /etc/pam_script_ses_close -> pam_script

lrwxrwxrwx. 1 root root 10 2月 10 14:59 /etc/pam_script_ses_open -> pam_script

另外还会生成/etc/pam-script.d/目录。

2. 修改/etc/pam.d/sshd文件,最前面增加下面一行配置,表示使用pam_script认证,只要通过pam_script认证成功就通过,否则,则使用原来的方式验证。

auth sufficientpam_script.so

3. 参考pam_script的资料和源码可知,使用pam_script进行认证,会调用/etc/pam_script_auth,实际调用的是/etc/pam_script,进一步调用/etc/pam-script.d/*_auth。

/etc/pam-script.d/*_auth里能得到请求认证的用户名密码等,exit的值为1即为认证失败。

所以只需要在/etc/pam-script.d/下增加一个*_auth的文件,能以otp方式判断用户名密码是否正确,相应返回exit值即可。

文件:/etc/pam-script.d/totp_auth

#! /bin/shstamp=`/bin/date +'%Y-%m-%d %H:%M:%S'`script=`basename $0`LOGFILE=/tmp/pam-script.logecho ============= >> $LOGFILEecho $stamp $script $PAM_SERVICE $PAM_TYPE\user=$PAM_USER ruser=$PAM_RUSER rhost=$PAM_RHOST\tty=$PAM_TTY \args=["$@"] \>> $LOGFILEecho check $PAM_USER >> $LOGFILE#if [[ "x$PAM_AUTHTOK" == "123456" ]]; then# exit 0#fi#exit 1python3 /root/check_totp.py $PAM_USER $PAM_AUTHTOKexit $?

这里进一步使用python脚本检查otp动态口令是否正确。

totp密钥配置在认证用户的个人目录下的.pam_totp.conf中,以一行一组k=v格式配置key、key_format、window、interval参数,文件所有者需要为认证用户,读写权限为0600。

文件:/root/check_totp.py

# -*- coding: utf-8 -*-import timeimport os,sysimport pwd,statfrom otp import *# 日志def logprint(*msg):pass#print(*msg)# 读取配置,格式每行一组k=vdef get_config(path):logprint('load config: ', path)config = {}with open(path, 'r') as f:while True:line = f.readline()if not line:breakif line.startswith('#'):continueidx = line.find("=")if idx >= 0:a = line[0:idx]b = line[idx+1:]config[a.strip()] = b.strip()logprint('config: ', config)return config# 检查totp口令def check(username, token):if not username or not token:return 1#### 获取用户uu = pwd.getpwnam(username)if not uu:logprint('用户没找到')return 1#### 获取路径if not uu.pw_dir:logprint('用户目录没找到')return 1path = uu.pw_dir + '/.pam_totp.conf'### 获取totp配置文件信息,要求文件权限为0600,文件所属为当前认证用户fst = os.stat(path)mode = fst.st_modeif not stat.S_ISREG(mode):logprint('totp配置文件不是普通文件')return 1if fst.st_size <= 0 or fst.st_size > 1024 * 10:logprint('totp配置文件为空或文件大小超过10KB')return 1if stat.S_IMODE(mode) != (0o600):logprint('totp配置文件权限不是0600')return 1uid = fst.st_uidif fst.st_uid != uu.pw_uid:logprint('totp配置文件所有者不是当前认证用户')return 1#### 获取配置config = get_config(path)key = config.get('key')key_format = config.get('key_format')window = config.get('window')interval = config.get('interval')if not key:logprint('otp参数项key为空')return 1if not key_format:key_format = "string"if not window:window = 3if not interval:interval = 30#### 验证totpt = TOTP(None, int(window), int(interval))t.setSecret(key, key_format)if t.verify(token) != True:logprint('totp检测失败')return 1else:logprint('totp检查成功')return 0def main(argv):#time.sleep(3)if len(argv) < 3:logprint('参数个数错误')exit(1)username = argv[1]token = argv[2]ret = check(username, token)logprint('检测结果:', ret)exit(ret)if __name__ == "__main__":main(sys.argv)

文件:/root/otp.py

# 参看/superzlc/otp

文件:.pam_totp.conf

key=02191234567890qwertyuiopkey_format=stringwindow=3interval=30

4. 其他

totp动态口令,可以用微信小程序“动态口令”生成。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。