我按照https://ubuntu.com/tutorials/configure-ssh-2fa在我的 Ubuntu 22.04.5 系统上设置了 SSH 的 2FA 保护。我只启用了基于密钥的身份验证,因此这可能有点过度,但感觉更安全,即使我的私钥以某种方式丢失了,它本身也不够。
我不想在从 LAN 上的系统连接时输入 TOTP 代码,因此我的/etc/pam.d/sshd
代码如下:
auth [success=done default=ignore] pam_access.so accessfile=/etc/security/access-local.conf
auth required pam_google_authenticator.so
/etc/security/access-local.conf
有:
+ : ALL : 192.168.1.0/24
+ : ALL : LOCAL
- : ALL : ALL
一切正常。当我在局域网之外时,系统会提示我输入 TOTP 代码,而在局域网内时则不会。
我现在的问题是 tab 补全功能scp
不再起作用。例如,在另一个系统上,我尝试:
$ scp server:someth<TAB>
并且something
应该自动完成,假设该文件存在。当我没有启用 PAM 模块时,这可以正常工作,但启用后则不起作用。即使在我使用 LAN 并且没有提示输入 TOTP 代码的情况下,它也会失败。当我按 TAB 时,我会在服务器中收到如下消息/var/log/auth.log
:
Oct 26 17:08:13 server sshd[1136620]: Connection closed by authenticating user user 192.168.1.182 port 53145 [preauth]
Oct 26 17:08:13 server sshd[1136732]: Connection closed by authenticating user user 192.168.1.182 port 53146 [preauth]
每按一次 TAB 键,消息总是成对出现。
有人知道我可以做什么(如果有的话)来实现这个目标吗?
为了使制表符补全功能正常工作,ssh 必须在不需要交互式身份验证的情况下工作。
有两种方法可以做到这一点。常用的方法是使用创建的 ssh 密钥
ssh-keygen
,并将公共部分(使用ssh-copy-id
)复制到authorized_keys
远程 ssh 配置中的文件中。如果不绕过或禁用 2fa,这种方法很可能无法奏效,并且会破坏您的目标。另一种方法是使用启用了该
ControlMaster
选项的共享 ssh 连接,并使用其他几个选项进行了调整。这样实际上您只需使用 ssh 登录一次,所有后续 ssh 连接都使用原始连接,而无需重新进行身份验证。当第一个(“主”)连接关闭时,所有连接都将断开。或者,您可以设置超时来限制ControlPersist
在第一个连接关闭且其余连接处于空闲状态后后台连接保持打开的时间。(或者随时手动强制关闭它……)但请注意,使用 ControlMaster 选项时,所有 ssh 连接都通过单个 tcp 套接字进行多路复用,并共享该带宽。因此,如果您依靠多个 tcp 套接字来获得更大的带宽,则需要绕过这些流的主连接。
@user10489 的回答让我找到了解决方案。我的
sshd_config
hadAuthenticationMethods publickey,keyboard-interactive
和删除keyboard-interactive
解决了问题,但也导致不再调用 PAM 模块来请求 TOTP 代码。我像这样修改了它,并且必须将它移动到我的底部
sshd_config
,现在我不会在我的 LAN 上提示 TOTP,但在 LAN 外可以,并且制表符补全至少在我的 LAN 上有效,这确实是我想要的: