能否从 NGINX 执行具有根权限的 bash 脚本并获取输出?

我正在使用启用了 Lua 脚本功能的 Openresty 构建下的 Nginx。我想创建一个 URI 位置(它将通过 SSL +身份验证加上 IP 白名单进行保护),它允许来自授权来源的 Webhook 调用使用根权限在服务器上执行 bash 脚本。例如:

https://someserver.com/secured/exec?script=script.sh&param1=uno&param2=dos

NGINX 将使用 'script' 和 'param#' GET 请求参数在 shell 中执行 "script.sh uno dos"。它捕获脚本输出和 bash 返回码(如果可能的话)。

我理解以 root 身份运行 NGINX 和运行任意命令的安全隐患,但是如上所述,访问 URI 将受到保护。

是否可以通过本机 NGINX 模块或 Lua 脚本实现?有没有一些示例代码可以让我了解怎么开始?

谢谢。

点赞
用户2830850
用户2830850

有另一种可能的解决方案,不需要额外的 nginx lua 插件。这是使用 socat。您可以在端口 8080 上启动一个 socat ,在每个连接时执行一个 bash 脚本

socat TCP4-LISTEN:8080,reuseaddr,fork EXEC:./test.sh

test.sh

#!/bin/bash

recv() {
    echo "< $@" >&2;
}

read line
line=${line%%$'\r'}
recv "$line"

read -r REQUEST_METHOD REQUEST_URI REQUEST_HTTP_VERSION <<<"$line"

declare -a REQUEST_HEADERS

while read -r line; do
    line=${line%%$'\r'}
    recv "$line"

    # 如果我们到达标题的结尾,就退出。
    [ -z "$line" ] && break

    REQUEST_HEADERS+=("$line")
done
eval $(echo $REQUEST_URI | awk -F? '{print $2}' | awk -F'&' '{for (i=1;i<=NF;i++) print $i}')

cat <<END1
HTTP/1.1 200 OK
Content-Type: plain/text

REQUEST_METHOD=$REQUEST_METHOD
REQUEST_URI=$REQUEST_URI
REQUEST_HTTP_VERSION=$REQUEST_HTTP_VERSION
REQUEST_HEADERS=$REQUEST_HEADERS
script=$script
param1=$param1
param2=$param2
END1

在 curl 上的测试如下所示

$ curl "localhost:8080/exec?script=test2.sh&param1=abc&param2=def"
REQUEST_METHOD=GET
REQUEST_URI=/exec?script=test2.sh&param1=abc&param2=def
REQUEST_HTTP_VERSION=HTTP/1.1
REQUEST_HEADERS=Host: localhost:8080
script=test2.sh
param1=abc
param2=def

因此,您可以轻松地在 nginx 中使用此方法进行 proxy_pass

要以 bash 中的 socat 查看完整的服务器,可以查看 https://github.com/avleen/bashttpd/blob/master/bashttpd

2017-09-28 20:53:29