全面披露:
我写这个问题是为了自己回答。我在互联网上搜索了一整天的工作,但无法找到适合我的解决方案。我什至编译了自己的 GoogleAuthenticator PAM 模块来添加更多日志记录。甚至没有
strace
在 OpenVPN 进程及其子进程上运行,我就找到了解决方案。
使用案例
- 在 EC2 中使用 OpenVPN 启动 VPN
- 使用 PAM GoogleAuthenticator 模块
- 操作系统:CentOS
设置
- 登录EC2
- 创建一个客户端
- 使用提供的令牌生成器向用户(客户端)添加 MFA 令牌,同时将此令牌保存到正确的位置,以便 PAM 模块检测它
<user>.ovpn
为该用户创建文件
下面的脚本将创建一个 Linux 用户,然后创建一个 MFA 密钥,保存到 PAM 配置中指定的位置,注意权限600
,MFA_USER
是我创建的名为的预创建用户gauth
function generate_mfa() {
user_id=$1
if [ "$user_id" == "" ]; then
echo "ERROR: No user id provided to generate MFA token" >&2
exit 1
fi
echo "INFO: Creating user ${user_id}" >&2
useradd -s /bin/nologin "$user_id"
echo "> Please provide a password for the user" >&2
passwd "$user_id"
echo "INFO: Generating MFA Token" >&2
google-authenticator -t -d -r3 -R30 -f -l "${MFA_LABEL}" -s "${MFA_DIR}/${user_id}"
chown "${MFA_USER}:${MFA_USER}" "$MFA_DIR/${user_id}"
chmod 600 "${MFA_DIR}/${user_id}"
}
OpenVPN 的 PAM 配置
auth required /usr/lib64/security/pam_google_authenticator.so secret=/etc/openvpn/google-authenticator/${USER} user=gauth forward_pass
auth include system-auth use_first_pass
account include system-auth use_first_pass
password include system-auth use_first_pass
session include system-auth use_first_pass
auth required pam_deny.so
问题
- 使用配置了 my 的 Tunnelblick
client.ovpn
,然后系统会提示我使用我的用户名和密码登录。- 密码的格式是 inline: ,这被指令
<password><MFA_TOKEN>
删除forward_pass
- 密码的格式是 inline: ,这被指令
- 我输入了正确的凭据,但总是遇到未经授权的情况
日志
- 为了检查我的问题,我通过 ssh 登录到 VPN 实例并检查了我的 PAM/身份验证日志
tail /var/log/secure
Sep 10 22:33:43 ip-OMITTED openvpn(pam_google_authenticator)[12862]: Accepted google_authenticator for ryan
Sep 10 22:33:43 ip-OMITTED openvpn(pam_google_authenticator)[12862]: Failed to update secret file "/etc/openvpn/google-authenticator/ryan": Permission denied
啊哈! “没有权限”
然后检查我的权限:
[root@ip-OMITTED centos]# ls -lah /etc/openvpn/google-authenticator/
drwxr-xr-x. gauth gauth .
drwxr-xr-x. root root ..
-rw-------. gauth gauth ryan
- 嗯,这些权限
600
似乎是正确的。这些目录是可执行的,并且我gauth
在 PAM 配置中使用该用户。
我的配置到底有什么问题?
- 用户
gauth
存在:check:
- 权限是正确的
:check:
答案1
顿悟时刻
.
我的权限列表末尾的那些是什么?
[root@ip-OMITTED centos]# ls -lah /etc/openvpn/google-authenticator/
drwxr-xr-x. gauth gauth .
drwxr-xr-x. root root ..
-rw-------. gauth gauth ryan
...Searchin' the web...
- 显然有一个东西叫做SELinux(安全增强的Linux)
那是运行时文件权限末尾的那些点ls -lah
,它表明该文件存在特殊的上下文/ACL 内容。
因此,要查看上下文:
ls -Z
一次登录前
文件上下文是unconfined_u:object_r:openvpn_etc_t:s0
[root@ip-OMITTED centos]# ls -lahZ /etc/openvpn/google-authenticator/
drwxr-xr-x. gauth gauth unconfined_u:object_r:openvpn_etc_t:s0 .
drwxr-xr-x. root root system_u:object_r:openvpn_etc_t:s0 ..
-rw-------. gauth gauth unconfined_u:object_r:openvpn_etc_t:s0 ryan
- 然后我暂时禁用了selinux
setenforce 0
一次登录后
该文件能够被写入并且上下文被强制为 system_u:object_r:openvpn_etc_rw_t:s0
[root@ip-OMITTED centos]# ls -lahZ /etc/openvpn/google-authenticator/
drwxr-xr-x. gauth gauth unconfined_u:object_r:openvpn_etc_t:s0 .
drwxr-xr-x. root root system_u:object_r:openvpn_etc_t:s0 ..
-r--------. gauth gauth system_u:object_r:openvpn_etc_rw_t:s0 ryan
重新启用 SELinux:
setenforce 1
仍然可以登录。:)
打开 SELinux 时运行修复文件的命令:
semanage fcontext -a -t openvpn_etc_rw_t "${MFA_DIR}/${user}"
restorecon "${MFA_DIR}/${user}"
- 这允许
rw
位!