使用OATH Toolkit实现ssh登录时进行TOTP双因子认证

前言

什么是双因子认证

双因子认证(英语:Two-factor authentication,缩写为2FA),又译为双重验证、双因子验证、双因素验证、二元认证,是多重要素验证中的一个特例,使用两种不同的元素,合并在一起,来确认用户的身份。

传统的单一密码认证(即知识要素,如用户名和密码)容易受到攻击,因此,为了增强安全性,双因子认证引入了至少还需要第二种形式的认证。这种方式通常结合以下两种或更多种验证要素:

知识要素:用户知道的东西,例如密码、PIN码。

持有的物件:用户拥有的东西,如安全令牌、智能卡、手机(通过短信或认证应用生成的一次性代码)。

固有要素(在双因子认证中通常不同时使用):生物特征,例如指纹、虹膜扫描、面部识别。

HOTP和TOTP

HOTP(HMAC-Based One-Time Password,基于HMAC的一次性密码)和TOTP(Time-Based One-Time Password,基于时间的一次性密码)都是实现一次性密码(OTP)的技术,常用于双因素认证中,以增强账户的安全性。它们的主要区别在于生成密码的方式和同步机制:

生成机制

  • HOTP:基于事件同步。HOTP使用一个计数器(counter,简称ctr)作为移动因子(moving factor),每次认证时,计数器递增,服务器和客户端都需要知道当前的计数器值来生成匹配的密码。密码是通过将计数器值与一个共享密钥一起通过HMAC算法计算得出的。
  • TOTP:基于时间同步。TOTP利用当前时间作为移动因子,通常以30秒为一个时间步长(time step),在这个时间间隔内生成的密码是相同的。密码是通过将当前时间戳(通常是自1970年1月1日以来的秒数,经过特定偏移和时间步长调整)与共享密钥一起通过HMAC算法计算得出的。

同步需求

  • HOTP:要求客户端和服务器上的计数器保持同步。如果计数器不同步(例如,客户端错过或重复了一个计数器值),则需要通过额外的机制(如手动调整计数器)来重新同步。
  • TOTP:依赖于精确的时间同步。客户端和服务器必须有大致相同的时间,否则会因为时间偏差导致密码不匹配。不过,大多数实现都允许一定的时间偏移以应对时钟漂移。

应用场景

  • HOTP:更适合于网络不稳定或时钟不同步的环境,因为它不依赖于绝对时间,但需要解决计数器同步问题。
  • TOTP:在大多数现代系统中更为常见,尤其是那些能够维持时间同步的环境,因为它实现简单且用户体验较好,用户无需手动管理计数器。

安装和配置OATH Toolkit

安装OATH Toolkit中的工具和相关库

dnf install pam_oath oathtool qrencode

生成随机种子(令牌)

方法一

openssl rand -hex 32

方法二

head -10 /dev/urandom | sha512sum | cut -b 1-30

可以用以下命令将随机种子(令牌)导出为图片,以下的secret仅仅作为示例,不要在实际的工作环境中使用,注意这里的secret要根据实际情况调整,这里为了在freeotp平台添加所以使用了Base32格式,默认算法是SHA1

qrencode -o /tmp/user.png 'otpauth://totp/MFAtest?otpauth://totp/MFAtest?issuer=myexample&secret=GWSR5NIPEGJTVGGVCSM3O22F&Algorithm=SHA1&digits=6&period=30'

写入配置文件/etc/users.oath

写入以下内容,表示使用TOTP方式,时间窗口为30s,pin码为6位,用户名是hj,令牌为c7878cdbcf95d729967e7877a7a990

users.oath中需要定义所有使用该服务的用户(可以包含root),如果没有在文件中定义,会直接判定验证结果为失败

HOTP/T30/6 hj - c7878cdbcf95d729967e7877a7a990

配置ssh相关参数并重启服务

按照以下配置来修改/etc/ssh/sshd_config

PasswordAuthentication yes
ChallengeResponseAuthentication yes
UsePAM yes

修改/etc/pam.d/sshd,新增以下内容,指定从/etc/users.oath读取配置,如果加在auth的第一行则表示先验证OTP,再验证用户密码,如果加在auth的最后一行则反之

auth required pam_oath.so usersfile=/etc/users.oath window=30 digits=6

修改后的内容如下

#%PAM-1.0
auth       substack     password-auth
auth       include      postlogin
auth       required     pam_oath.so    usersfile=/etc/users.oath window=30 digits=6
account    required     pam_sepermit.so
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    optional     pam_motd.so
session    include      password-auth
session    include      postlogin

重启sshd服务

systemctl restart sshd

验证

计算实时pin码

[root@localhost ~]# oathtool -v --totp c7878cdbcf95d729967e7877a7a990 -w 5
Hex secret: c7878cdbcf95d729967e7877a7a990  
Base32 secret: Y6DYZW6PSXLSTFT6PB32PKMQ  
Digits: 6  
Window size: 5  
TOTP mode: SHA1  
Step size (seconds): 30  
Start time: 1970-01-01 00:00:00 UTC (0)  
Current time: 2024-05-11 07:51:09 UTC (1715413869)  
Counter: 0x368812E (57180462)  
  
135923  
459844  
361657  
706010  
728960  
160225

在登录时输入正确的pin码即可完成登录

PS C:\Users\12058> ssh hj@192.168.15.171  
  
Authorized users only. All activities may be monitored and reported.  
(hj@192.168.15.171) Password:  
(hj@192.168.15.171) One-time password (OATH) for `hj':  
  
Authorized users only. All activities may be monitored and reported.  
Last login: Sat May 11 11:36:45 2024 from 192.168.105.1  
  
  
Welcome to 4.19.90-2312.1.0.0255.oe2003sp4.x86_64  
  
System information as of time: Sat May 11 11:37:20 CST 2024  
  
System load: 0.00  
Processes: 138  
Memory used: 7.8%  
Swap used: 0.0%  
Usage On: 7%  
IP address: 192.168.15.171  
Users online: 3  
To run a command as administrator(user "root"),use "sudo <command>".

验证失败

解决方案一

需要查看selinux策略

getenforce

如果不为Permissive,则需要设置为Permissive

setenforce 0
解决方案二

查询缺失规则

audit2allow -a /var/log/audit/audit.log*

根据缺失规则生成一个策略模块

audit2allow -a /var/log/audit/audit.log* -M pam_oath

加载策略模块

semodule -i pam_oath.pp

附录

linux-pam

模块类型

Linux-PAM有四种模块类型,分别代表四种不同的任务,它们是:
认证管理(auth),账号管理(account),会话管理(session)和密码(password)管理,一个类型可能有多行,它们按顺序依次由PAM模块调用

  1. 认证管理(auth)

    • 负责验证用户的身份。
    • 检验用户输入的凭证(比如密码、一次性密码、证书等)是否正确。
    • 常见的模块有pam_unix.so(用于UNIX密码认证)、pam_ldap.so(用LDAP服务认证)等。
  2. 账号管理(account)

    • 一旦用户身份验证成功,账号管理用于进一步检查账号状态。
    • 它用来确认用户账号的有效性,比如确认账号没有过期、时间段内是否允许登录、用户是否有访问请求资源的权限等。
    • 常见模块比如pam_nologin.so(检查是否有nologin文件,决定系统是否关闭登录)。
  3. 会话管理(session)

    • 开始和结束用户的登录会话。
    • 负责设置和清除用户登录后的会话环境,如用户环境变量、挂载用户的文件系统、日志记录等。
    • 会话管理模块包括pam_mkhomedir.so(用于创建用户家目录)或pam_lastlog.so(更新/显示最后一次登录的时间)。
  4. 密码(password)

    • 用于更新用户凭证,如密码。
    • 当用户需要更改密码时,这一类别的模块会被调用。
    • 包括切换密码,确保新密码的复杂度和安全性,关联的模块如pam_cracklib.so(用于检查密码的复杂度和安全性)。

控制标记

  • required

    • 这个模块必须执行成功。即使该模块失败了,PAM会继续执行后续的模块来收集更多失败信息,但最终的认证结果将是失败。其他required模块仍会执行,以便提供完整的日志记录。
  • requisite

    • 类似于required,但如果此类模块失败,那么整个认证过程会立即终止,并返回一个失败的结果,后续的模块将不会被执行。这对于避免不必要的处理非常有用,比如在明确知道认证会失败时。
  • sufficient

    • 如果此类模块成功,并且在它之前的所有required模块也成功了,那么认证过程将成功,后续的模块将不会被执行。如果一个required模块在sufficient模块之前失败了,即使sufficient模块成功了,认证也会失败。如果sufficient模块本身失败了,那么这并不会导致立即认证失败,而是继续执行后续模块。
  • optional

    • 此类模块不是绝对必需的,对认证过程成功与否没有直接的决定性影响。一般来说,要通过多个optional模块的聚合结果或者其他required模块的结果来决定认证结果。
  • include

    • 这不是一个控制标志,而是一种引用其他PAM配置文件的方法。你可以在一个PAM服务的配置文件中使用include引用另一个通用配置的集合,这样可以复用和共享认证配置模块,避免重复配置同样的模块。

服务端方案

服务器需要配置双因子认证服务,一般有以下方案

OATH-Toolkit

Google Authenticator

Yubico Authenticator

客户端方案

客户端录入令牌以及根据令牌获取OTP,一般有以下方案

OATH-Toolkit

Google Authenticator

Microsoft Authenticator

Authy

FreeOTP

Yubico Authenticator

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值