YubiKey是一种新型USB密钥,它通过双因素验证简化了登录过程,用户只要轻触一下设备,它就会在任意电脑或平台上生成一个一次性的密码(OTP),而不需要任何客户端软件。
YubiKey工作原理:通过轻触按钮,YubiKey会发送一个随机的安全登录密码。这一***的密码由YubiKey配套的Web服务或软件应用验证,此文中则是BIG-IP 访问策略管理器。
什么是YubiCloud:YubiCloud是一款免费的基于云技术的YubiKey验证服务,它将有力的双要素验证于网站或在线服务结合在一起。
使用APM的YubiKey 2-Factor 验证进程
验证进程可以分解为几个简单步骤,如下:
步骤一:用户会看到一个登录页面。笔者遇到的登录页面要求填写用户名,密码和YubiKey OTP。在输入用户名和密码后,你可以把YubiKey插入USB端口,再按下按钮。YubiKey将会生成一个***的一次性密码供登录者输入进行验证。
步骤二和三:用户名和密码都由Active Directory验证。
步骤四和五:检查以确保YubiKey已经分配好用户。笔者将8字节的YubiKey序列号保存到了Active Directory属性:“employeeID”。显然,你可以使用你喜欢的任何属性域或是数据群组。
步骤六:确保生成的一次性密码与YubiKey序列号匹配。YubiKey 一次性密码使用修改后的十六进制输出(MODHEX)。可在Yubico论坛找到MODHEX表(http://forum.yubico.com/viewtopic.php?f=6&t=96 )笔者创建了一个iRule,它使用一个YubiKey序列号,并将其转换为MODHEX,然后再把它保存到一个APM对话变量。下一步,从步骤一到MODHEX序列号比较OTP值,如果字符存在,就可以往下了。
步骤7,8,9——把YubiKey一次性密码发送到YubiCloud验证服务。如果YubiCloud API返回“Status=OK”,然后用户就可以访问资源。#p#
BIG-IP APM 配置
APM配置是直观的,假设:
1. 你已经有一个目录服务器,上面有配置好的用户,你可以把YubiKey序列号添加给LDAP/AD属性。
2. 你的YubiKey通过YubiCloud服务注册。
3. 你已经从https://upgrade.yubico.com/getapikey/ 处获得了一个Auth ID和API 密钥可以验证YubiKey。
4. 你此前使用过BIG-IP,且具备适当的LTM知识。
那么可以用BIG.-IP v11.2.0创建此配置。让我们进入APM配置。
验证服务器
活动目录
访问策略>>AAA服务器>>>活动目录>>>“创建”
如下:
1. 名称:dc1.test.lab
2. 域名:test.lab
3. 域控制器:或 (AD服务器)
4. 管理员名称及密码
选择“完成”以保存。
#p#
YubiCloud API
HTTP AAA服务器对象不支持HTTPS连接,所以我们需要创建一个虚拟服务器代理BIG-IP到YubiCloud API的数据流。这个虚拟服务器会听取HTTP,但是我们可以使用一个创建HTTP的Server SSL 配置文件-——>HTTPS 代理。
本地数据>>节点>>节点列表>>“创建”
如下:
1. 名称:api.yubico.com
2. 地址:api.yubico.com
3. 监测
选择“完成”以保存。
本地数据>>池>>池列表>>“创建”
如下:
1. 名称:pool_yubicloud
2. 描述:YubiCloud 代理池 (可选项)
3. 监测 (可选项)
4. 地址:api.yubico.com
5. 服务端口:HTTPS
选择“完成”以保存。
本地数据>>虚拟服务器>>虚拟服务器列表>>“创建”
如下:
1. 名称:vs_yubicloud
2. 描述:YubiCloud 代理 VS (可选项)
3. 目的地:
4. 服务端口:HTTP
5. HTTP配置文件:http
6. SSL 配置文件(服务器):clientssl
7. SNAT池:Auto Map
8. 默认池:pool_yubicloud
选择“完成”以保存。
访问策略>>AAA服务器>>HTTP
如下:
1. 名称:aaa_yubicloud
2. 表单方法:GET
3. 表单活动:http://
4. 用户名称的表单参数:id
5. 密码的表单参数:otp
6. 成功登录检测匹配类型:指定响应字符
7. 成功登录检测匹配数值:status=OK
表单活动使用上文配置的虚拟服务器IP,而不是YubiCloud服务器FQDN。你至少要为没有签名的响应提供id和otp参数。Id参数是用于YubiCloud服务的Auth ID,otp是YubiKey生成的代码。
选择“完成”以保存。
#p#
MODHEX 编码iRule
本地数据>>iRules>>iRules 列表>>“创建”
复制粘贴下列iRule,它们可以把YubiKey序列号转换成MODHEX格式。在本文示例中,笔者检索了与Active Directory用户相关的YubiKey序列号,该Active Directory使用employeeID 属性。如果序列号已经保存在备用处,如一个数据群组或一个自定义LDAP/AD属性,那么就需要修改此iRule。
when ACCESS_POLICY_AGENT_EVENT { if { [ACCESS::policy agent_id] eq "irule_apm_yubikey_modhex_encode" } {
# yubikey serial number
set yubikey_serial [ACCESS::session data get session.ad.last.attr.employeeID]
# modhex alphabet
array set modhex_alphabet { 0 c 1 b 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k A l B n C r D t E u F v }
# remove leading zeros from serial number
set yubikey_serial [string trimleft $yubikey_serial 0]
# convert serial to hex and pad with zeros
set yubikey_serial [format %012X $yubikey_serial]
# split the string
set yubikey_serial [split $yubikey_serial ""]
# for each HEX change to MODHEX using alphabet
set yubikey_modhex ""
foreach index $yubikey_serial {
append yubikey_modhex $modhex_alphabet($index)
}
ACCESS::session data set session.custom.yubikey.modhex $yubikey_modhex
}
}
访问配置文件和策略
访问策略>>访问配置文件>>访问配置文件列表>>“创建”
提供如下信息:
1. 姓名:profile_yubicloud
2. 语言:English
3. 使用默认设置。
选择“完成”以保存。
访问策略>>访问配置文件>>访问配置文件列表>>“编辑”
在“start”对象后的“fallback”上,添加“logon page”对象。
添加第三个域:
1. 类型:文本。
2. 贴出变量名称:yubiotp
3. 会话变量名称:yubiotp
4. 只读:否
在“自定义”部分,将“表单标头文本”设置为你需要的效果,并把“登录页面输入区域#3”改成有意义的值,如下。“Branch Rules”设为默认状态。别忘了点“保存”。
#p#
在“Logon Page”对象后面的“fallback”分支,添加一个“AD Auth”对象
这一步可以验证姓名和密码。
提供如下信息:
1. 姓名:AD Auth
2. AAA服务器:/Common/dc1.test.lab (选择你的AD 服务器)
“Branch Rules”为默认。结束后选择“保存”。
“AD Auth”对象之后的操作成功分支上,添加一个“AD Query”对象
这一步检查用户的Active Directory账号是否有YubiKey。我们已经为每位用户把YubiKey的序列号添加到Active Directory。以前笔者出于方便会使用employeeID,但这里,推荐大家创建一个用于YubiKey序列号的自定义AD属性。
提供如下属性:
1. 姓名:YubiKey Provisioned
2. 搜索过滤:sAMAccountName=%{session.logon.last.username}
在“Branch Rules”下,删除默认,选择“添加Branch Rule”
更新Branch Rule设置:
姓名:Yes
表达式:expr{[mcgt{session.ad.last.attr.employeeID}]!=””}
选择“完成”,然后保存。
在“YubiKey Provisioned”对象的“Yes”分支里,添加“iRule Event”对象
这一步可以把“session.ad.last.attr.employeeID”(YubiKey 序列)从AD Query发送到名为“irule_apm_yubikey_modhex_encode”的iRule。iRule会返回一个用MODHEX编码的字符,并将其保存在“session.custom.yubikey.modhex”。我们需要MODHEX格式的YubiKey序列号,这样我们就可以把它与登录页面输入的原始YubiKey OTP进行比对。
提供如下信息:
1. 姓名:YubiKey MODHEX Encode
2. ID:irule_apm_yubikey_modhex_encode
#p#
现在,我们把MODHEX格式的YubiKey序列号与登录页面输入的YubiKey OTP进行比较。这一步可以验证用户是否正在使用他们的YubiKey抑或是被盗用。这个YubiKey OTP的前面12个字符是YubiKey序列号,这样就可以用“字符优先”的TCK命令进行验证。
在“Branch Rules”下选择“Add Branch Rule”
更新Branch Rule的设置:
1. 名称:YubiKey Serial Match
2. 表达式“expr { [string first [mcget {session.custom.yubikey.modhex}] [mcget {session.logon.last.yubiotp}]] == 0 }
选择“完成”,然后保存。
在YubiKey MODHEX Encode对象后面的YubiKey Serial Match上,添加一个Variable Assign对象。
这一步会把YubiCloud Auth ID 分配到“session.logon.last.username”,并把登录页面上的YubiKey OTP分配给“session.logon.last.password”。这些会话变量随后被分配到之前创建的HTTP Auth AAA对象aaa_yubicloud所使用的id和otp HTTP参数。
提供下列属性:
名称:Assign YubiCloud Variables
选择“Add new entry”>>”change” 添加变量分配。
变量赋值1:
1. 自定义变量:session.logon.last.username
2. 自定义表达式:expr{“1111”} (把1111改为你的YubiCloud Auth ID)
变量赋值2:
1. 自定义变量:session.logon.last.password
2. 自定义表达式:expr { [mcget {session.logon.last.yubiotp}] }
选择“完成”,然后保存。Branch Rules使用默认设置。
在“Assisign YubiCloud Variables”对象的“fallback”分支上,添加一个“HTTP Auth”对象
这样可以把HTTP Get发送到YubiCloud API 以验证登录页面的YubiKey OTP。
提供下列属性:
1. 名称:YubiCloud Auth
2. AAA Server:/Common/aaa_yubicloud
Branch Rules使用默认设置。保存退出。
这样就媲美访问策略了。它应该和下图类似:
接下来把“访问配置文件”附加到虚拟服务器做测试。
结论
这是通过APM轻松添加双因素验证的典型案例。F5提供了一个10人同时使用的APM试验版本,且每个BIG-IP都颁发了LTM许可证。