金钱(警告)
** 状态:** 被贬值
如果您目前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议升级或迁移到支持的 Ubuntu 版本:
** 原因:** Ubuntu 12.04 已于 2017 年 4 月 28 日到期(EOL)并且不再收到安全补丁或更新。
** 参见相反:** 本指南可能仍然有用作为参考,但可能不会在其他Ubuntu版本上工作. 如果可用,我们强烈建议使用为您正在使用的Ubuntu版本撰写的指南。
介绍
Apache Web 服务器是世界上最受欢迎的 Web 服务器,可用于在各种不同的背景下向访问者提供静态和动态 Web 内容。
生成动态内容的最常见方法之一是通过使用CGI
或通用网关界面,这提供了执行编写各种编程语言的网页内容的脚本的标准方式。
在 Web 空间中运行任何类型的可执行代码都会带来一定的风险. 在本指南中,我们将展示如何使用suexec
模块实现 CGI 脚本,这允许您以不必要地提高权限的方式运行脚本。
前提条件
在本指南中,我们将配置Ubuntu 12.04 VPS,使用标准的LAMP(Linux,Apache,MySQL,PHP)安装。
要了解 如何在Ubuntu上安装LAMP堆栈,点击这里。
我们将参考该软件,因为它在其初始状态后,该教程。
如何启用 CGI 脚本
在Ubuntu的Apache配置中,CGI脚本实际上已经在特定CGI目录中配置了,该目录默认情况下是空的。
CGI脚本可以是任何具有输出HTML或其他对象或格式的能力的程序,而Web浏览器可以渲染。
如果我们进入Apache配置目录,并在mods-enabled
目录中查看Apache已启用的模块,我们会找到一个允许此功能的文件:
1less /etc/apache2/mods-enabled/cgi.load
1LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so
此文件包含启用 CGI 模块的指令,这使我们能够在我们的配置中使用此功能。
虽然该模块被加载,但它实际上不提供任何脚本内容,它必须在特定的 Web 环境中明确启用。
我们将看看默认的Apache虚拟主机文件,看看它如何做到这一点:
1sudo nano /etc/apache2/sites-enabled/000-default
虽然我们在这里,让我们设置服务器名称以参考我们的域名或IP地址:
<VirutalHost *:80> ServerName your_domain_or_IP_address ServerAdmin your_email_address . . .
我们可以在文件中看到适用于CGI脚本的部分:
1ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
2<Directory "/usr/lib/cgi-bin">
3 AllowOverride None
4 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
5 Order allow,deny
6 Allow from all
7</Directory>
让我们分解一下这个配置的部分正在做什么。
在这种情况下,目录是 /usr/lib/cgi-bin/
. 虽然第二个参数给出文件路径到脚本目录,第一个参数, /cgi-bin/
,提供URL路径。
这意味着位于 /usr/lib/cgi-bin
目录中的名为script.pl
的脚本将在您访问时执行:
your_domain.com/cgi-bin/script.pl
其输出将返回到网页浏览器来渲染页面。
目录
容器包含适用于/usr/lib/cgi-bin
目录的规则,您会注意到一个提到CGI的选项:
1Options +ExecCGI ...
这个选项实际上是不必要的,因为我们正在为已被ScriptAlias
宣布为CGI目录的目录设置选项,但它不会伤害,因此您可以保持它。
如果您想将 CGI 文件放到 ScriptAlias 以外的目录中,则必须将这两个选项添加到目录部分:
Options +ExecCGI
AddHandler cgi-script .pl .rb [extensions to be treated as CGI scripts]
当您完成检查文件时,保存并关闭它. 如果您做了任何更改,请重新启动 Web 服务器:
1sudo service apache2 restart
测试 CGI 脚本
我们将创建一个基本的、微不足道的 CGI 脚本,以显示必要的步骤来正确执行脚本。
正如我们在上一节所看到的那样,我们对 CGI 脚本的配置中指定的目录是 /usr/lib/cgi-bin
. 这个目录不能被非根用户编写,所以我们必须使用 sudo:
1sudo nano /usr/lib/cgi-bin/test.pl
我们给了该文件一个 ".pl" 扩展,因为这将是一个 Perl 脚本,但Apache 将尝试在该目录中运行任何文件,并根据其第一行将其传递给相应的程序。
我们将指定该脚本应该由 Perl 解释,以以下方式开始:
1#!/usr/bin/perl
接下来,脚本必须输出的第一件事是将生成的内容类型,这是必要的,以便Web浏览器知道如何显示所给出的输出,我们将打印出HTML内容类型,即文本/html
,使用Perl的常规打印功能。
1print "Content-type: text/html\n\n";
在此之后,我们可以做任何必要的函数或计算,以在我们的网站上生成我们想要的文本. 在我们的例子中,我们不会生成任何不像简单的HTML那样容易的事情,但你可以看到这允许动态内容,如果你的脚本更复杂。
前两个组件和我们的实际HTML内容相结合,形成以下脚本:
1#!/usr/bin/perl
2print "Content-type: text/html\n\n";
3
4print "<html><head><title>Hello There...</title></head>";
5
6print "<body>";
7
8print "<h1>Hello, World.</h1><hr>";
9print "<p>This is some regular text.</p>";
10print "<p>The possibilities are great.</p>";
11
12print "</body></html>";
保存并关闭文件。
现在,我们有一个文件,但它没有被标记为可执行的。
1sudo chmod 755 /usr/lib/cgi-bin/test.pl
现在,如果我们导航到我们的域名,然后是CGI目录(/cgi-bin/),然后是我们的脚本名称(test.pl),我们应该看到我们的脚本的输出。
点击您的浏览器:
your_domain.com/cgi-bin/test.pl
你应该看到一些看起来像这样的东西:
不是很激动人心,但表现正确。
如果我们选择查看页面的来源,我们只会看到给印刷函数的参数,减去内容类型标题:
如何允许成功
设置一个脚本可以由任何人执行时,存在一些隐含的安全问题。理想情况下,一个脚本只能由一个被锁定的用户执行。
我们实际上会安装一个修改的 suexec 模块,允许我们配置它运作的目录。
使用此命令安装替代模块:
1sudo apt-get install apache2-suexec-custom
现在,我们可以通过键入启用该模块:
1sudo a2enmod suexec
接下来,我们将创建一个新的用户,它将拥有我们的脚本文件. 如果我们有多个网站被服务,每个人都可以有自己的用户和组:
1sudo adduser script_user
请自由输入所有提示(包括密码提示)。
接下来,让我们在这个新的用户主目录中创建一个脚本目录:
1sudo mkdir /home/script_user/scripts
Suexec 需要对谁可以写入目录进行非常严格的控制. 让我们将所有权转移给 script_user 用户,并更改权限,以便其他人无法写入目录:
1sudo chown script_user:script_user /home/script_user/scripts
2sudo chmod 755 /home/script_user/scripts
接下来,让我们创建一个脚本文件,并从上面复制并粘贴我们的脚本:
1sudo -u script_user nano /home/script_user/scripts/attempt.pl
1#!/usr/bin/perl
2print "Content-type: text/html\n\n";
3
4print "<html><head><title>Hello There...</title></head>";
5
6print "<body>";
7
8print "<h1>Hello, World.</h1><hr>";
9print "<p>This is some regular text.</p>";
10print "<p>The possibilities are great.</p>";
11
12print "</body></html>";
我们只会让我们的 script_user 对文件有任何权限. 这是 suexec 模块允许我们做的事情:
1sudo chmod 700 /home/script_user/scripts/attempt.pl
接下来,我们将编辑我们的Apache虚拟主机配置,以允许我们的新用户执行脚本。
打开默认虚拟主机文件:
1sudo nano /etc/apache2/sites-enabled/000-default
首先,让我们创建我们的CGI目录,而不是使用ScriptAlias
指令,正如我们上面所做的,让我们展示如何使用常规的Alias
目录,结合ExecCGI
选项和SetHandler
指令。
添加此部分:
1Alias /scripts/ /home/script_user/scripts/
2<Directory "/home/script_user/scripts">
3 Options +ExecCGI
4 SetHandler cgi-script
5</Directory>
这允许我们通过进入/scripts
子目录来访问我们的 CGI 脚本. 要启用 suexec 功能,请在Directory
部分之外添加此行,但在VirtualHost
部分内:
1SuexecUserGroup script_user script_user
保存并关闭文件。
我们还需要指定 suexec 将视为有效目录的位置。这是我们可自定义的 suexec 版本允许我们做的事情。
1sudo nano /etc/apache2/suexec/www-data
在这个文件的顶部,我们只需要添加到我们的脚本目录的路径。
1/home/script_user/scripts/
保存并关闭文件。
现在,剩下的只是重新启动 Web 服务器:
1sudo service apache2 restart
如果我们打开我们的浏览器并导航这里,我们可以看到我们的脚本的结果:
your_domain.com/scripts/attempt.pl
请注意,在 suexec 配置时,您的正常 CGI 目录不会正常工作,因为它不会通过 suexec 所需的严格测试。
结论
您现在可以创建脚本并以相对安全的方式执行它们. CGI 脚本对快速将动态内容纳入您的网站非常有帮助。
使用 suexec 时要小心,因为如果配置不正确,它实际上可以创建更多的安全漏洞。