【问题标题】:Bash command not running in Apache CGI ShellBash 命令未在 Apache CGI Shell 中运行
【发布时间】:2014-01-02 15:17:26
【问题描述】:

当我在我的 linux 机器上单击 http 服务器上的按钮时,我有一个脚本会运行。 该文件在 cgi-bin 中并且是可执行的。

但这个脚本的两行似乎不起作用

#!/bin/bash

IPADDR=`echo "$QUERY_STRING" | sed -n 's/^.*IPADDR=\([^&]*\).*$/\1/p' | sed "s/+/ /g"`
SUBNET=`echo "$QUERY_STRING" | sed -n 's/^.*SUBNET=\([^&]*\).*$/\1/p' | sed "s/+/ /g"`
DHCP=`echo "$QUERY_STRING" | sed -n 's/^.*DHCP=\([^&]*\).*$/\1/p' | sed "s/+/ /g"`

(2行不工作)

sed -i.bak "s/IPADDR=.*/IPADDR=$IPADDR/g" test
sed -i.bak "s/NETMASK=.*/NETMASK=$SUBNET/g" test

echo "Content-type: text/html"
echo ""
DHCP=`echo "$QUERY_STRING" | sed -n 's/^.*DHCP=\([^&]*\).*$/\1/p' | sed "s/+/ /g"`
echo "<html><head><title>IP CHANGED</title></head>"
echo "<body>IP changed to: "
echo "$IPADDR <br>"
echo "<body>SUBNET changed to: "
echo "$SUBNET <br>"
echo "DHCP $DHCP"
echo "</body></html>"

文件测试内容

DEVICE=p32p1
BOOTPROTO=static
DHCPCLASS=
HWADDR=00:01:2e:48:f0:f3
IPADDR=3333333333
NETMASK=4444444444
ONBOOT=yes

sed 从不更改文件。

这也是我的 HTML

<form action="cgi-bin/IPChange.sh" method="get">
Enter an IP Address: <input type="text" name="IPADDR"></input><br>
Enter a Subnet Mask: <input type="text" name="SUBNET"></input><br>
<input type="radio" name="DHCP" value="on">Enable DHCP
<input type="radio" name="DHCP" value="off">Disable DHCP<br>
<input type="submit" name="subbtn" value="Submit">
<form>

【问题讨论】:

  • Apache 无权编辑您的文件。除此之外,让 bash 脚本由 Web 进程运行听起来很可怕
  • 这是一个我试图实现的简单案例,我怎样才能给 apache 权限?
  • 您可能只想为所有用户授予test文件写入权限,而不是增加apache的权限:chmod a+x /path/to/test
  • 顺便说一句:这个脚本看起来很容易受到命令行注入攻击。如果用户提交如下查询字符串:"; rm /* -rf; echo ",他们可能会清除您的文件系统。
  • 修改写权限也没有用

标签: linux apache bash shell sed


【解决方案1】:

这一定是文件系统权限和SELinux配置问题的结合。

文件系统部分更容易修复。您的 Web 服务器进程可能以 apache 用户身份运行,因此请确保它对您要重写的文件具有正确的权限。要确认文件系统权限正常,请暂时禁用 SELinux 并检查写入是否正常:

echo 0 >/selinux/enforce

如果可行,请重新打开 SELinux:

echo 1 >/selinux/enforce

然后修复您的 SELinux 设置。以下是来自this other answer 的一些提示,尤其是:

您必须为目录结构提供httpd_sys_rw_content_t 的上下文,或者为它们提供public_content_rw_t 的上下文并启用allow_httpd_anon_write 和/或allow_httpd_sys_script_anon_write。有关详细信息,请参阅 httpd_selinux(8) 手册页。

另外,我会这样重写你的脚本:

#!/bin/bash
config=/var/www/net.config

while IFS== read name value; do
    case $name in
        IPADDR) IPADDR=$value ;;
        SUBNET) SUBNET=$value ;;
        DHCP) DHCP=$value ;;
    esac
done < <(sed -e 's/&/\n/g' <<< $QUERY_STRING)

is_valid() {
    # todo: validate the input params
    return 1
}

if is_valid; then
    sed -i.bak e "s/IPADDR=.*/IPADDR=$IPADDR/g" -e "s/NETMASK=.*/NETMASK=$SUBNET/g" $config
    title='IP CHANGED'
    body=$(cat << EOF
IP changed to: $IPADDR <br>
SUBNET changed to: $SUBNET <br>
DHCP $DHCP
EOF
)
else
    body='What are you trying to pull, mister?'
fi

cat << EOF
Content-type: text/html

<html><head><title>$title</title></head>
<body>$body</body></html>
EOF

【讨论】:

  • 我已将文件的权限更改为任何人都可以编辑的地方,但它仍然无法正常工作
  • 如果你将配置文件复制到/tmp/net.config 并更改我给你的脚本以使用config=/tmp/net.config 那么它应该可以工作。
  • 是的,还是不行,apache需要root权限吗?
  • 问题是脚本可以在我的命令行中运行,但是当我从 apache 服务器运行它时它不会
  • 好的,这很可能是 SELinux 设置问题。查看我更新的答案,我重写了第一部分。
猜你喜欢
  • 2015-09-03
  • 2011-11-03
  • 2018-11-09
  • 1970-01-01
  • 2020-01-02
  • 1970-01-01
  • 2015-02-19
  • 2014-01-11
  • 1970-01-01
相关资源
最近更新 更多