SSH 登录而不是带有本地后备的 getty

SSH 登录而不是带有本地后备的 getty

我不知道如何确切地命名我的问题。

场景是我有一台服务器,其中有一套适合我需要的 TUI 程序。

我希望网络的其他用户打开一些较小的东西,例如 raspi 或恐龙计算机,并且当它启动时,用户不会像平常一样看到用于本地登录的 getty...而是显示 ssh到服务器。仅当服务器未应答时,才会向用户提供本地登录信息。

我想这种类型的场景并不新鲜或激进......在我看来,它基本上是通过 ssh 通过 tcp/ip 连接的瘦客户端的概念

答案1

这确实是可以实现的:大约在 1998 年左右,我在大学里就做过类似的事情。

基本上,您需要配置gettyRasPi 的进程来调用您自己的自定义版本的程序login而不是标准的/bin/login.那部分很容易。

login如果您不需要特别安全,或者只是进行原型设计,您的自定义替换甚至可以是脚本。但对于一个严肃的实现,我认为它应该是一个已编译的程序,为了安全:删除脚本解释器可以最大限度地减少要运行的代码量,因此更难设置竞争条件或针对它的其他攻击。

然而,我在你的设计中发现了一个可能的用户体验问题:当用户已经输入了他们的登录名时,他们可能会在密码提示出现后立即直接输入密码,几乎是一种反射动作,无需太多思考。如果 SSH 连接尝试不成功,并且自动重用相同的登录名进行本地登录尝试,则用户可能会认为自己已连接到服务器,并且当发现自己使用本地登录时会感到困惑。

最好需要进行深思熟虑的操作,例如切换到具有未修改getty配置的第二个虚拟控制台以进行本地登录。您可以添加有关所需击键的说明,/etc/issue以便getty在登录提示之前显示它。作为副作用,您的自定义login脚本或二进制文件可以大大简化为基本上:

#!/bin/sh
REMOTEUSER="$1"
exec ssh -oEscapeChar=none "$REMOTEUSER"@your.server.example

-oEscapeChar=none选项将阻止使用 OpenSSH 转义按键,因此用户将无法使用 SSH 客户端配置端口转发或执行其他恶作剧(感谢 Ferrybig 提醒我!)。

由于login(或其任何替代者)将以 root 身份运行,因此最好在exec()执行该ssh命令之前切换到某个非 root 用户。这是编译后的程序会更加灵活的地方。

如果您有一点编程经验,我建议您下载/bin/login您选择的 Linux 发行版的源代码包,看看是否可以破解它来执行此操作。

基本上,您需要进行两项更改:您可以让您的替代者使用仅为传出 SSH 连接保留的硬编码用户名,而不是使用提供给getty它的用户名作为参数来选择要登录的用户名。login。您无需exec()在登录过程结束时使用用户的 shell,而是使用exec()SSH 命令,将您获得的用户名getty和服务器名称作为参数提供给它。

答案2

我倾向于在 中/etc/profile使用类似的东西(假设用户的 shell 是 bash 或 ksh 或其他使用 的东西/etc/profile)来执行此操作:

if [[ $(ps h -o cmd $(ps h -o ppid $$)) =~ $(basename "$SHELL") ]] \
   || id | grep -q '(sshgroup)' \
   && fping -q remotehost; then
  set -e   # exit on any error, incl. user pressing ^C during
           # ssh-keygen or ssh-copy-id

  # generate a key if it doesn't already exist
  if [ ! -e ~/.ssh/id_rsa ] then
    ssh-keygen
  fi

  # install it on remote host if ~/.ssh/key-installed doesn't exist
  if [ ! -e ~/.ssh/key-installed ] ; then
    ssh-copy-id -i ~/.ssh/id_rsa.pub remotehost
    touch ~/.ssh/key-installed
  fi

  # rewrite the following if any users have a shell which doesn't
  # support arrays (ash, dash, posix sh, etc)
  ssh_args=(-oEscapeChar=none)
  exec ssh "${ssh_args[@]}" remotehost
fi

中文:如果父进程不是用户的shell该用户是以下组织的成员sshgroup 远程主机响应 ping,然后响应 ssh 到远程主机(并且因为sshexec-ed,一旦 ssh 会话结束,用户将立即注销)。否则登录将照常进行。组成员身份之前已进行测试fping,因此非成员不必等待“fping”结果。

本地和远程主机上的文件中的适当消息/etc/motd可用于突出显示它们最终位于哪台计算机上。

如果用户在远程主机上没有 ssh 密钥~/.ssh/authorized_keys,那么它也会要求输入密码。脚本片段中的ssh-keygen和内容ssh-copy-id是如何防止这种情况的最低限度示例。它可能也应该运行ssh-agent-t 86400这样他们只需每天输入一次密钥的密码,而不是每次登录时。

像这样检查组成员身份可以轻松排除某些用户(例如 root 或非 root 管理员帐户)自动 sshed 到远程主机。您可以反转测试并自动 ssh 任何用户不是特定群体的成员。

相关内容