📄 ch03.htm
字号:
drwxr-xr-x 2 root www 512 Feb 17 00:32 support/
</FONT></PRE>
<P>In this case, the restrictions on the logs directory or the conf directory may
be excessive, again depending on the level of access you wish to provide. If the
person who has the root password can't be bothered to create new directories under
the htdocs directory, to truncate/archive the logfiles periodically, or to modify
the configuration options within the config files, then these files or directories
may need to have write-perms for the group <TT>www</TT>, or possibly ownership by
the userid, <TT>www</TT>. The most important thing is that <TT>root</TT> owns the
server binary itself, <TT>httpd</TT>, and that the userid the server runs under (<TT>nobody</TT>)
has no write permissions to anything within this hierarchy.</P>
<P>It's a good idea to use some sort of security package, like TripWire or COPS,
to occasionally verify that these permissions haven't been changed. Such a practice
is also useful for the detection of unwanted files or changed files within your archive.
This will be discussed further in the next section. We'll take a closer look at these
tools at the end of the chapter. For now, we can add a few lines to the previous
script to check some of the most important of these permissions for us:</P>
<PRE><FONT COLOR="#0066FF">use HTTPD::Config;
require "stat.pl";
$conf = `/usr/local/etc/httpd/conf';
@files = qw(httpd.conf srm.conf access.conf);
$V= new HTTPD::Config (SERVER => Apache,
SERVER_ROOT => $conf,
FILES => [@files]);
print "Userid: ", $V->user,"\n";
print "Group: ", $V->group,"\n";
print "Administrator is: ", $V->server_admin,"\n";
print "Running at port: ", $V->port,"\n";
print "Access filename: ",$V->access_file_name,"\n";
print "User Directory: ", $V->user_dir,"\n";
print "Global Types:\t", join("\n\t\t",$V->add_type),"\n";
print "\n\n";
foreach $dir (keys %{$V->{`Directory'}}){
print "Options for Directory: $dir\n";
while(($opt,$val) = each %{$V->{`Directory'}{$dir}{`OPTIONS'}}){
print "\t",$opt, " : ", @{$val},"\n";
}
}
# rudimentary permissions checking
$webuser = (getpwnam($V->user))[2];
opendir(ROOT,$V->server_root);
@files = grep(!/\.\.?/,readdir(ROOT));
closedir(ROOT);
foreach $f (@files){
@s = Stat($V->server_root."/$f");
if($s[$ST_UID] == $webuser){
print "Warning: ",$V->server_root,"/$f is owned by ",
$V->user,"\n\n";
}
if($f eq "httpd"){
if(($s[$ST_MODE] != 0100700) or ($s[$ST_UID] != 0)){
print "\tWarning: ",$V->server_root,"/httpd may have\n";
print "\tpermission problems. Recommend root ownership\n";
print "\tand readable, writable and executable only by\n";
print "\troot user\n";
}
}
}
</FONT></PRE>
<P>Now, when we run our simple security script, we'll get a warning if anything in
the <TT>RootDir</TT> is owned by the userid that runs the server, or if the httpd
itself isn't owned by root with the permissions specified in the preceding code.
Note that we used the old stat.pl library in this example, as well. It provides a
simplified interface to the <TT>stat(2)</TT> function.
<CENTER>
<H3><A NAME="Heading8"></A><FONT COLOR="#000077">Data Security</FONT></H3>
</CENTER>
<P>A Web archive may have a specific intent for any or all of its elements. The contents
of your archive may be entirely intended for public access, without any constraints
at all, or you may wish to have specific permissions set up for each and every element.
In this section, we'll take a look at how you can do either.
<CENTER>
<H4><A NAME="Heading9"></A><FONT COLOR="#000077">General ConsiderationsGlobal versus
Local Configuration of Permissions</FONT></H4>
</CENTER>
<P>Obviously, if you don't care who accesses your archive's contents, you won't need
to worry too much about data security, with the exception of general permissions
being correctly set. If your archive provides documents that are intended for a specific
audience, such as registered users or paying customers, then you'll need to use the
additional features of the httpd server to limit access to those documents to the
audience you intend them for. Additionally, you may use CGI scripts, Netscape cookies,
hidden variables, or other state-retention mechanisms to assure proper access. These
topics will be discussed in Chapter 16, "Advanced CGI/HTML."</P>
<P>Most http servers provide you with the capability to give access to specific files
and directories on an individual basis, using one of two methods. The files and tools
you'll be configuring to enable this capability differ in format, depending on which
server you're running, but generally are
<TABLE BORDER="0">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT">conf/access.conf</TD>
<TD ALIGN="LEFT">Global access configuration file</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT"><FONT COLOR="#000000">htaccess</FONT></TD>
<TD ALIGN="LEFT"><FONT COLOR="#000000">Directory-specific access file</FONT></TD>
</TR>
</TABLE>
</P>
<PRE></PRE>
<P>when using the Apache or NCSA servers. In the examples that follow, we'll assume
you're using one or the other of these servers. The other Web server, from CERN,
won't be discussed or used in the examples here for the sake of brevity.</P>
<P>For simplicity and portability, it's probably easier to use the per-directory
.htaccess files, but this technique is generally not favored as strongly as using
the global access-control file, presumably because it's easier to control all rights
and permissions from one place. If you do decide to use the per-directory method,
then be aware that the .htaccess file can be specified in the conf/srm.conf file
to be whatever name you specify, and it is recommended that you use a name other
than .htaccess in order to avoid arbitrary retrievals of your access configuration
files themselves. (There is a bug in some servers that allows the client to fetch
your access-configuration files directly.)
<CENTER>
<H4><A NAME="Heading10"></A><FONT COLOR="#000077">Directory Access Configuration</FONT></H4>
</CENTER>
<P>If you decide to allow per-directory configuration files, you'll need to enable
them in the global access.conf file with a good deal of consideration and care. Assuming
you have a <TT><Directory></TT> entry for the <TT>DocumentRoot</TT>, you can
enable certain capabilities for individual directories beneath the <TT>DocumentRoot</TT>
on an as-needed basis.</P>
<P>Let's suppose, for the purpose of demonstration, that your archive consists of
the <TT>DocumentRoot</TT>:</P>
<PRE><FONT COLOR="#0066FF">/usr/local/etc/httpd/htdocs
</FONT></PRE>
<P>And beneath <TT>DocumentRoot</TT>, you have a subdirectory:</P>
<PRE><FONT COLOR="#0066FF">/usr/local/etc/httpd/htdocs/test1
</FONT></PRE>
<P>Now assume that there exists, for <TT>DocumentRoot</TT>, an entry in the access.conf
file that looks something like this:</P>
<PRE><FONT COLOR="#0066FF"><Directory /usr/local/etc/httpd/htdocs>
AuthType Basic
AuthName PasswordAdmin
AuthUserFile /usr/local/etc/httpd/conf/.htpasswd
AccessFileName .myhtaccess
AddType text/html .shtml
Options Indexes SymLinksIfOwnerMatch IncludesNOEXEC
AllowOverride AuthConfig FileInfo Indexes Limit
</Directory>
</FONT></PRE>
<P>This entry allows any directory beneath <TT>DocumentRoot</TT> to have its own
.privaccess files, which can then override any of the directives specified for <TT>DocumentRoot</TT>
except the <TT>Options</TT> directive, which we don't want to let anyone specify
beyond what is already allowed. Note that the <TT>Options</TT> directive is already
used to turn on the automatic directory indexes (when index.html doesn't exist) and
to follow symlinks if the owner of the symlink and what it points to match, as well
as allowing server-side includes, but not the <TT>#exec</TT> and <TT>#include</TT>
directives within server-side includes files.</P>
<P>Now, assume that the directory test1 has some proprietary or confidential information
within it. You could assure that nothing is left to chance by configuring its directory
entry in the global access.conf to disallow any overrides or options, like this:</P>
<PRE><FONT COLOR="#0066FF"><Directory /usr/local/etc/httpd/htdocs/test1>
AllowOverride None
Options None
<Limit GET POST>
require valid-user
</Limit>
</Directory>
</FONT></PRE>
<P>Note that we also specify here that any access to this directory also be validated
from the valid users in the <TT>AuthUserFile</TT>, inherited from the directives
for <TT>DocumentRoot</TT>. We'll look more at user/group authentication in a bit.</P>
<P>You can use Perl and the HTTPD modules to verify that your access configurations
for any given file in the archive are what you expect them to be. Here we'll modify
our previous script to give us some additional information on the configuration directives
for each directory specified in access.conf:</P>
<PRE><FONT COLOR="#0066FF">use HTTPD::Config;
require "stat.pl";
$conf = `/usr/local/etc/httpd/conf';
@files = qw(httpd.conf srm.conf access.conf);
$V= new HTTPD::Config (SERVER => Apache,
SERVER_ROOT => $conf,
FILES => [@files]);
print "Userid: ", $V->user,"\n";
print "Group: ", $V->group,"\n";
print "Administrator is: ", $V->server_admin,"\n";
print "Running at port: ", $V->port,"\n";
print "Access filename: ",$V->access_file_name,"\n";
print "User Directory: ", $V->user_dir,"\n";
print "Global Types:\t", join("\n\t\t",$V->add_type),"\n";
print "\n\n";
foreach $dir (keys %{$V->{`Directory'}}){
print "Options for Directory: $dir\n";
while(($opt,$val) = each %{$V->{`Directory'}{$dir}{`OPTIONS'}}){
print "\t",$opt, " : ", @{$val},"\n";
}
print "\tLimit: @{$V->{Directory}{$dir}{LIMIT}{METHODS}}\n";
while(($key,$val) = each %{$V->{Directory}{$dir}{LIMIT}{OPTIONS}}) {
print "\t\t$key = @{$val}\n";
}
print "\n";
}
# rudimentary permissions checking
$webuser = (getpwnam($V->user))[2];
opendir(ROOT,$V->server_root);
@files = grep(!/\.\.?/,readdir(ROOT));
closedir(ROOT);
foreach $f (@files){
@s = Stat($V->server_root."/$f");
if($s[$ST_UID] == $webuser){
print "Warning: ",$V->server_root,"/$f is owned by ",
$V->user,"\n\n";
}
if($f eq "httpd"){
if(($s[$ST_MODE] != 0100700) or ($s[$ST_UID] != 0)){
print "\tWarning: ",$V->server_root,"/httpd may have\n";
print "\tpermission problems. Recommend root ownership\n";
print "\tand readable, writable and executable only by\n";
print "\troot user\n";
}
}
}
</FONT></PRE>
<P>Note that we added a few lines to the <TT>foreach</TT> loop, which loops over
the <TT><Directory></TT> entries in access.conf, to tell us about any <TT><Limit></TT>
directives and how they're configured. Now when we run the script against our existing
hierarchy, we get the following output:</P>
<PRE><FONT COLOR="#0066FF">Userid: nobody
Group: nogroup
Administrator is: wmiddlet@adobe.com
Running at port: 80
Access filename: .privaccess
User Directory: public_html
Global Types: text/html .shtml
Options for Directory: /usr/local/etc/httpd/cgi-bin
Options : None
AllowOverride : None
Limit:
Options for Directory: /usr/local/etc/httpd/htdocs/test1
Options : None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -