⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch03.htm

📁 Web_Programming_with_Perl5,一个不错的Perl语言教程。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
        AllowOverride : None



        Limit: GET POST



                require = valid-user







Options for Directory: /usr/local/etc/httpd/htdocs



        PerlHandler : main::handler



        AddType : text/html .shtml



        Options : Indexes SymLinksIfOwnerMatch IncludesNOEXEC



        AllowOverride : AuthConfig FileInfo Indexes Limit



        Limit:



</FONT></PRE>



<P>The <TT>&lt;Limit&gt;</TT> options for the test1 directory are now specified.



<CENTER>



<H4><A NAME="Heading11"></A><FONT COLOR="#000077">Whos There? Configuring Client



IP/Domain Restrictions</FONT></H4>



</CENTER>



<P>After you've configured the access rights on a per-directory basis, using either



the global access.conf or directory-specific access control files, you may decide



that you want to allow or deny access on a per-site basis, as well. You may, for



instance, only wish to allow connections from a particular domain, possibly for specific



directories. You can do this additionally within the global access.conf file using



additional entries within the <TT>&lt;Limit&gt;</TT> directive for a particular directory.</P>



<P>It's important to understand how the allow/deny directives are parsed within any



given <TT>&lt;Limit&gt;</TT> statement. You have three options to specify parse order



that give you the ability to override previous deny statements with allow statements,



using the order statement</P>



<PRE><FONT COLOR="#0066FF">order deny, allow



</FONT></PRE>



<P>Using this form lets you, for instance, deny from everywhere, then allow only



from a specific domain(s) or host(s), perhaps like this:</P>



<PRE><FONT COLOR="#0066FF">&lt;Limit GET&gt;



order deny,allow



deny from all



allow from .corp.adobe.com



&lt;/Limit&gt;



</FONT></PRE>



<P>Likewise, you can override allow statements with deny statements to allow everyone



and then deny a few specific domains or hosts like so:</P>



<PRE><FONT COLOR="#0066FF">&lt;Limit GET&gt;



order allow,deny



allow from all



deny from .bozo.com



&lt;/Limit&gt;



</FONT></PRE>



<P>You can also treat all connections as denied, unless the host appears in either



an allow or deny statement, using the following order option:</P>



<PRE><FONT COLOR="#0066FF">



&lt;Limit GET&gt;



order mutual-failure



allow from .metronet.com



allow from 130.248



deny from .bozo.com



&lt;/Limit&gt;



</FONT></PRE>



<P>This option is probably the safest, because it won't allow any connections from



anywhere, unless they're specifically allowed.</P>



<P>Running our script again now gives the following:</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



        AllowOverride : None



        Limit: GET POST



                require = valid-user







Options for Directory: /usr/local/etc/httpd/htdocs



        PerlHandler : main::handler



        AddType : text/html .shtml



        Options : Indexes SymLinksIfOwnerMatch IncludesNOEXEC



        AllowOverride : AuthConfig FileInfo Indexes Limit



        Limit: GET



                deny = from .bozo.com



                order = mutual-failure



                allow = from .metronet.com



</FONT></PRE>



<P>But note our <TT>&lt;Limit&gt;</TT> directive for <TT>DocumentRoot</TT> has not



limited retrievals in /cgi-bin. Because the cgi-bin directory isn't beneath <TT>DocumentRoot</TT>,



it's not affected by the <TT>&lt;Limit&gt;</TT> statement. You'll need to explicitly



limit anything outside, or above, the directory where you place <TT>&lt;Limit&gt;</TT>



statements if that is the intent.



<CENTER>



<H4><A NAME="Heading12"></A><FONT COLOR="#000077">Another IP Restriction Mechanism:



tcpwrapper</FONT></H4>



</CENTER>



<P>Another alternative, when you wish to restrict/verify connections from particular



hosts, is to run a site-wide tool like tcpwrapper. (This will work only if you're



starting httpd out of inetd.) You can get tcpwrapper from the COAST archive at</P>



<PRE><FONT COLOR="#0066FF">ftp://ftp.cs.purdue.edu/pub/tools/tcp_wrappers



</FONT></PRE>



<P>along with plenty of other security tools, papers, and packages. Using tcpwrapper,



you can configure certain actions based on the connecting site's domain, or hostname,



which are vastly more powerful than the options you have with httpd alone. Many sites



out on the open Internet use this tool, and it even ships with a couple of operating



systems. If your site has an open pipe to the Internet, it may well be worth investigating



this tool.



<CENTER>



<H4><A NAME="Heading13"></A><FONT COLOR="#000077">Whos There? User/Group Verification</FONT></H4>



</CENTER>



<P>Finally, you can use the http access.conf file, along with a couple of other files



and tools, to configure security for a specific directory or file on a per-user or



per-group basis. You'll need to create the .htpasswd file on a per-directory basis



and/or a global .htpasswd file. The <TT>HTTPD::UserAdmin</TT> module is the tool



of choice for manipulating passwd/group files. It knows about the various types of



user and group databases that the Apache, NCSA, and even CERN servers implement,



and provides you with a generic interface that hides the inconsistencies, simplifying



the maintenance of the databases.</P>



<P>The user/group databases may take various forms and use different internal formats,



depending on your preference and what tools are available on your system. The <TT>HTTPD::UserAdmin</TT>



module allows you to access databases implemented as DBM files or straight text files.



It also gives you the capability to talk to an SQL database and to get/put user information



to an SQL database. Its companion, <TT>HTTPD::Authen</TT>, knows about the various



formats of the entries in these files, including MD5 (Message Digest), as well as



standard (default) DES encryption and, of course, plaintext.</P>



<P>The <TT>HTTPD::UserAdmin</TT> module provides you with several useful methods



after you've created a new <TT>HTTPD::UserAdmin</TT> object. These include the following:







<TABLE BORDER="0">



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>add(</TT>name<TT>,</TT>passwd<TT>)</TT></TD>



		<TD ALIGN="LEFT">Add a new user to the database</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>delete(</TT>name<TT>)</TT></TD>



		<TD ALIGN="LEFT">Delete a user from the database</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>exists(</TT>name<TT>)</TT></TD>



		<TD ALIGN="LEFT">Check if the user exists in the database</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>password(</TT>name<TT>)</TT></TD>



		<TD ALIGN="LEFT">Return the encrypted password for the user</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>list</TT></TD>



		<TD ALIGN="LEFT">Return a list of all the usernames in the database</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>update(</TT>name<TT>,</TT>password<TT>)</TT></TD>



		<TD ALIGN="LEFT">Update the user with a new password</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>group</TT></TD>



		<TD ALIGN="LEFT">Create a new <TT>GroupAdmin</TT> object</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>lock([</TT>timeout<TT>])</TT></TD>



		<TD ALIGN="LEFT">Create a file lock for the database in anticipation of updating it</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><TT>unlock</TT></TD>



		<TD ALIGN="LEFT">Unlock the database</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD ALIGN="LEFT"><FONT COLOR="#000000">db(dbname)</FONT></TD>



		<TD ALIGN="LEFT"><FONT COLOR="#000000">Select a different database</FONT></TD>



	</TR>



</TABLE>



</P>



<PRE></PRE>



<P>There are several examples, provided as tests in the t/ directory, that accompany



the <TT>HTTPD::</TT> module suite. You can adapt these to suit your particular needs.



The simplest case might be one in which you wish to add a new user to an existing



database. The following simple script lets you do this, first by checking if the



specified user already exists in the database. If so, it updates the record with



the new password. If not, it creates the new entry for the user.</P>



<PRE><FONT COLOR="#0066FF">#!/usr/local/bin/perl



require HTTPD::UserAdmin;







$path = &quot;/usr/local/etc/httpd/conf&quot;;



$username = shift || &quot;josie&quot;;



$password = &quot;pussycats&quot;;







$user = new HTTPD::UserAdmin(DBType =&gt; &quot;Text&quot;, Path =&gt; $path, Server =&gt; &quot;apache&quot;);







if($user-&gt;exists($username)){



    print &quot;$username already exists in the database\n&quot;;



    print &quot;Updating with new password\n&quot;;



    $user-&gt;update($username, $password);



}



else{



    print &quot;Adding $username to database\n&quot;;



    $user-&gt;add($username, $password);



    if($user-&gt;exists($username)){



        print &quot;Successful\n&quot;;



    }



}



</FONT></PRE>



<CENTER>



<H4><A NAME="Heading14"></A><FONT COLOR="#000077">Changing Passwords from the Web</FONT></H4>



</CENTER>



<P>One of the most common requests I've seen for a CGI program is the one for a program



that allows the Web client to change his/her password. Certainly, it's reasonable



to want to be able to do this; unfortunately, it's more complicated and risky than



it seems.</P>



<P>Because the httpd is running as the user <TT>nobody</TT>, and because the passwd



file doesn't (or shouldn't) belong to that user, it's a bit of a quandary to have



an <TT>exec</TT>'d CGI program change that file. There are alternatives, however.



You can run a secondary server on a different port, under the <TT>www</TT> userid,



whose only purpose would be to execute the CGI program that changes the user's password,



for instance. Another alternative might be to implement something with <TT>SafeCGIPerl</TT>,



discussed later, and the <TT>HTTPD::UserAdmin</TT> module just introduced. Coding



it up is left as an exercise for the wary administrator. Be very, very careful.



<CENTER>



<H4><A NAME="Heading15"></A><FONT COLOR="#000077">Monitoring Userids</FONT></H4>



</CENTER>



<P>As a final note in this section, we'll add a bit more code to our ongoing example



to keep track of userids in the .htpasswd file for each <TT>&lt;Directory&gt;</TT>



entry in access.conf.</P>



<PRE><FONT COLOR="#0066FF">use HTTPD::Config;



require HTTPD::UserAdmin;



require &quot;stat.pl&quot;;



$conf =  `/usr/local/etc/httpd/conf';



@files = qw(httpd.conf srm.conf access.conf);



$V= new HTTPD::Config (SERVER =&gt; Apache,



                             SERVER_ROOT =&gt; $conf,



                             FILES =&gt; [@files]);







print &quot;Userid: &quot;, $V-&gt;user,&quot;\n&quot;;



print &quot;Group: &quot;, $V-&gt;group,&quot;\n&quot;;



print &quot;Administrator is: &quot;, $V-&gt;server_admin,&quot;\n&quot;;



print &quot;Running at port: &quot;, $V-&gt;port,&quot;\n&quot;;



print &quot;Access filename: &quot;,$V-&gt;access_file_name,&quot;\n&quot;;



print &quot;User Directory: &quot;, $V-&gt;user_dir,&quot;\n&quot;;



print &quot;Global Types:\t&quot;, join(&quot;\n\t\t&quot;,$V-&gt;add_type),&quot;\n&quot;;



print &quot;\n\n&quot;;







foreach $dir (keys %{$V-&gt;{`Directory'}}){



    print &quot;Options for Directory: $dir\n&quot;;



    while(($opt,$val) = each %{$V-&gt;{`Directory'}{$dir}{`OPTIONS'}}){



        print &quot;\t&quot;,$opt, &quot; : &quot;, @{$val},&quot;\n&quot;;



        if($opt eq &quot;AuthUserFile&quot;){



            ($path = join(`',@{$val})) =~ s/^(.*)\/.*/$1/;



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -