SSH - 即使没有Shell,也可以在登录时强制执行命令

Iac*_*hus 15 ssh sshd

我正在创建一个没有shell的受限用户,仅用于端口转发,我需要通过pubkey在登录时执行脚本,即使用户已连接ssh -N user@host,也不要求SSH服务器提供shell.

该脚本应警告管理员对使用pubkey进行身份验证的连接,因此用户连接不应该跳过脚本的执行(例如,通过连接ssh -N).

我试图无济于事:

  • 设置命令为/etc/ssh/sshrc.
  • .ssh/authorized_keys(man authorized_keys)中使用command ="COMMAND"
  • 使用命令设置脚本作为用户的shell.(chsh -s /sbin/myscript.sh USERNAME)
  • 匹配用户在/etc/ssh/sshd_config: Match User MYUSERNAME ForceCommand "/sbin/myscript.sh"

用户请求shell时所有工作,但如果只记录端口转发而没有shell(ssh -N)它不起作用.

Tod*_*obs 13

除非客户端请求,否则ForceCommand选项在没有PTY的情况下运行.因此,您实际上没有shell以您期望的方式执行脚本.此外,OpenSSH SSHD_CONFIG(5)手册页清楚地说:

使用用户的登录shell和-c选项调用该命令.

这意味着如果您已禁用用户的登录shell,或将其设置为类似/bin/false,则ForceCommand无法工作.假如说:

  1. 用户有一个合理的shell定义,
  2. 您的目标脚本是可执行的,以及
  3. 你的脚本有一个合适的shebang线

然后,在使用适当的用户名和自定义脚本的完全限定路径名正确修改后,以下内容应在您的全局 sshd_config文件中起作用:

Match User foo
    ForceCommand /path/to/script.sh
Run Code Online (Sandbox Code Playgroud)

  • 这只有在我不使用`ssh -N`标志进行连接时才有效.但无论如何你让我意识到只有使用sshd才能实现这个目标...脚本应该警告用pubkey进行身份验证的连接,因此用户连接不应该使用'ssh -N'跳过它. (3认同)

ema*_*maV 8

If you only need to run a script you can rely on pam_exec.

Basically you reference the script you need to run in the /etc/pam.d/sshd configuration:

session optional pam_exec.so seteuid /path/to/script.sh
Run Code Online (Sandbox Code Playgroud)

After some testing you may want to change optional to required.

Please refer to this answer "bash - How do I set up an email alert when a ssh login is successful? - Ask Ubuntu" for a similar request.

Indeed in the script only a limited subset on the environment variables is available:

LANGUAGE=en_US.UTF-8
PAM_USER=bitnami
PAM_RHOST=192.168.1.17
PAM_TYPE=open_session
PAM_SERVICE=sshd
PAM_TTY=ssh
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
PWD=/
Run Code Online (Sandbox Code Playgroud)

If you want to get the user info from authorized_keys this script could be helpful:

#!/bin/bash
# Get user from authorized_keys
# pam_exec_login.sh
# * [ssh - What is the SHA256 that comes on the sshd entry in auth.log? - Server Fault](https://serverfault.com/questions/888281/what-is-the-sha256-that-comes-on-the-sshd-entry-in-auth-log)
# * [bash - How to get all fingerprints for .ssh/authorized_keys(2) file - Server Fault](https://serverfault.com/questions/413231/how-to-get-all-fingerprints-for-ssh-authorized-keys2-file)

# Setup log
b=$(basename $0| cut -d. -f1)
log="/tmp/${b}.log"

function timeStamp () {
  echo "$(date '+%b %d %H:%M:%S') ${HOSTNAME} $b[$$]:"
}

# Check if opening a remote session with sshd
if [ "${PAM_TYPE}" != "open_session" ] || [ $PAM_SERVICE != "sshd" ] || [ $PAM_RHOST == "::1" ]; then
  exit $PAM_SUCCESS
fi

# Get info from auth.log
authLogLine=$(journalctl -u ssh.service |tail -100 |grep "sshd\[${PPID}\]" |grep "${PAM_RHOST}")
echo ${authLogLine} >> ${log}

PAM_USER_PORT=$(echo ${authLogLine}| sed -r 's/.*port (.*) ssh2.*/\1/')
PAM_USER_SHA256=$(echo ${authLogLine}| sed -r 's/.*SHA256:(.*)/\1/')

# Get details from .ssh/authorized_keys
authFile="/home/${PAM_USER}/.ssh/authorized_keys"
PAM_USER_authorized_keys=""

while read l; do
  if [[ -n "$l" && "${l###}" = "$l" ]]; then
    authFileSHA256=$(ssh-keygen -l -f <(echo "$l"))
    if [[ "${authFileSHA256}" == *"${PAM_USER_SHA256}"* ]]; then
      PAM_USER_authorized_keys=$(echo ${authFileSHA256}| cut -d" " -f3)
      break
    fi
  fi
done < ${authFile}

if [[ -n ${PAM_USER_authorized_keys} ]]
then
  echo "$(timeStamp) Local user: ${PAM_USER}, authorized_keys user: ${PAM_USER_authorized_keys}" >> ${log}
else
  echo "$(timeStamp) WARNING: no matching user in authorized_keys" >> ${log}
fi
Run Code Online (Sandbox Code Playgroud)


Iac*_*hus 5

我是 OP 的作者;我得出的结论是,仅使用 SSH 到日期 ( OpenSSH_6.9p1 Ubuntu-2, OpenSSL 1.0.2d 9 Jul 2015)不可能实现我需要实现的目标,但是我发现了一个很棒的软件,它使用加密的 SPAuthentication 打开 SSH 端口,并且它是新版本(截至本文发布之日) ,它是 GitHub 主分支)具有执行用户成功授权的命令的功能。

FWKNOP - 加密单包授权

FWKNOP 设置 iptables 规则,允许在通过 UDP 发送的单个加密数据包上访问给定端口。然后在授权之后,它允许授权用户在给定的时间内访问,例如 30 秒,在此之后关闭端口,保持连接打开。

1. 在 Ubuntu linux 上安装:

迄今为止,Ubuntu 存储库上的当前版本 (2.6.0-2.1build1) 仍然不允许在成功的 SPA 上执行命令;(请改用 GitHub 中的 2.6.8)

在客户端机器上:

sudo apt-get install fwknop-client

在服务器端:

sudo apt-get install fwknop-server

这是关于如何设置客户端和服务器机器的教程 https://help.ubuntu.com/community/SinglePacketAuthorization

然后,设置好后,在服务器端:

  1. 编辑 /etc/default/fwknop-server
  2. 将行更改START_DAEMON="no"START_DAEMON="yes"
  3. 然后运行:

    sudo service fwknop-server stop

    sudo service fwknop-server start

2. 成功 SPA 时警告管理员(电子邮件、pushover 脚本等)

因此,如上所述,Ubuntu 存储库 (2.6.0-2.1build1) 中的当前版本无法在成功的 SPA 上执行命令。如果您从 OP 开始需要此功能,但它将在 fwknop 版本(2.6.8)中发布,如此处所述:

https://github.com/mrash/fwknop/issues/172

因此,如果您现在需要使用它,您可以从具有CMD_CYCLE_OPEN选项的github 分支 master 构建。

3. 更多关于 fwknop 的资源

https://help.ubuntu.com/community/SinglePacketAuthorization

https://github.com/mrash/fwknop/(GitHub 上的项目)

http://www.cipherdyne.org/fwknop/(项目站点)

https://www.digitalocean.com/community/tutorials/how-to-use-fwknop-to-enable-single-packet-authentication-on-ubuntu-12-04(DO社区教程)