如何在自定义PAM模块中获取入站连接的IP地址
在PAM Python模块中获取SSH入站连接IP的方法
核心解决方案:通过PAM API或配置传递环境变量
你遇到的问题根源在于认证阶段未正确获取PAM传递的环境变量,以及who这类工具无法捕捉未完成登录的连接。以下是两种可行的实现方式:
方式一:直接通过Python PAM API读取环境变量
在你的Python PAM认证模块中,无需调用Bash命令,直接通过PAM会话对象的API获取PAM_RHOST变量——这是PAM为SSH认证场景原生提供的远程IP字段:
def pam_sm_authenticate(pamh, flags, argv): # 直接从PAM上下文获取远程IP remote_ip = pamh.getenv("PAM_RHOST") if remote_ip: # 这里接入你的人脸识别/双因素认证逻辑,可传入remote_ip做关联校验 print(f"当前入站连接IP: {remote_ip}") return pamh.PAM_SUCCESS else: # 无法获取IP时的异常处理 return pamh.PAM_AUTH_ERR
方式二:配置PAM保留环境变量后通过Bash获取
如果你必须通过Bash命令获取,需要先修改PAM配置文件(比如/etc/pam.d/sshd),显式保留相关环境变量,确保子shell能读取到:
# 在/etc/pam.d/sshd中添加该行,保留SSH相关环境变量 session required pam_env.so env_keep="PAM_RHOST SSH_CLIENT SSH_CONNECTION"
之后在Python中执行Bash命令即可读取:
import subprocess # 执行Bash命令获取PAM_RHOST result = subprocess.run(['bash', '-c', 'echo $PAM_RHOST'], capture_output=True, text=True) remote_ip = result.stdout.strip() if remote_ip: # 后续认证逻辑 pass
为什么之前的尝试无效?
who命令仅能显示已成功建立的登录会话,而你是在SSH连接建立前的认证阶段,此时会话尚未创建,因此无法获取。- 直接执行
echo $PAM_RHOST失败,是因为默认情况下PAM不会将认证上下文的环境变量传递给子shell,必须通过pam_env.so显式配置保留。
内容的提问来源于stack exchange,提问作者Charlotte Harper
相关产品推荐
相关产品推荐

