Apache默认不启用mod_cgi,必须显式加载模块、配置ScriptAlias或Directory权限、确保脚本有可执行权限及正确shebang路径、输出合法HTTP头,同时注意SELinux策略和日志调试。

Apache 默认不启用 mod_cgi,即使启用了,也必须显式授权执行权限,否则请求会返回 403 或直接下载脚本——这是最常卡住运维人员的地方。
确认模块已加载且无冲突
运行以下命令检查模块状态:
-
httpd -M | grep cgi(RHEL/CentOS)或apache2ctl -M | grep cgi(Debian/Ubuntu) - 输出含
cgi_module (shared)表示已加载;若无,需在httpd.conf或mods-enabled/cgi.load中补上:LoadModule cgi_module modules/mod_cgi.so - 切勿同时启用
mod_cgid(进程池模式),它与mod_cgi冲突,二选一即可
严格限定可执行目录与路径映射
不要把 CGI 脚本混在网站根目录下。推荐做法是只开放专用目录,并用 ScriptAlias 显式绑定:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 在虚拟主机或主配置中添加:
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" - 紧随其后配置对应目录块:
<Directory "/var/www/cgi-bin"><br> AllowOverride None<br> Options +ExecCGI<br> Require all granted<br></Directory>
- 注意:
/cgi-bin/末尾斜杠不可省;URL 访问时也必须带斜杠,如http://localhost/cgi-bin/backup.sh
脚本本身必须满足三项硬性条件
哪怕 Apache 配置全对,脚本也会静默失败(空响应、500 或下载)——问题几乎都出在这三处:
-
首行 shebang 必须准确:Perl 脚本写
#!/usr/bin/perl,Shell 脚本写#!/bin/bash或#!/bin/sh;路径必须真实存在,可用which perl或ls -l /bin/sh验证 -
文件必须有可执行权限:运行
chmod +x /var/www/cgi-bin/backup.sh;Apache 子进程以apache(RHEL)或www-data(Debian)用户运行,该用户必须能读+执行 -
输出必须含合法 HTTP 头且空行分隔:例如
print "Content-Type: text/plain\n\n";(Perl)或echo -e "Content-Type: text/plain\n"(Bash);头后必须紧跟一个空行,不能有多余 BOM、空格或换行
加固安全边界(尤其对 Shell 脚本)
运维类 Shell 脚本风险高,务必做最小权限隔离:
- 脚本内避免使用
eval、$()、未过滤的$QUERY_STRING或$REQUEST_METHOD直接拼接命令 - 如需解析参数,用白名单方式处理:
case "$1" in<br> "backup") /usr/local/bin/do-backup ;;<br> "status") /bin/systemctl is-active httpd ;;<br> *) echo "Invalid action"; exit 1;;<br>esac
- SELinux 启用时(如 CentOS/RHEL),运行:
setsebool -P httpd_execmem 1chcon -t httpd_exec_t /var/www/cgi-bin/* - 日志排查优先看
/var/log/httpd/error_log,常见错误如 “End of script output before headers” 或 “Permission denied” 可直接定位原因

















