doc:l:lighttpd

启用Lighttpd的port-based Virtual Host功能,以防火墙和目录密码双重保护网管的后台控制程序

yes298 2008/01/25 09:41


欢迎转载,但必须注明以下信息:

  • 此文由 http://www.freebsdchina.org 的yes298原创于2007年1月25日
  • Yes298座右铭: 热心帮助他人, 即是帮助自己 …
  • 对新手, 尽可能去扶持一下, 又有何妨呢?
  • 非常鄙视那些有点技术,就自以为是, 沾沾自喜的人, 不帮人也罢, 还出言讽刺新手, 别忘了, 你亦曾为新手 …

前言:

在FreeBSD v6.2上安装完lighttpd, 想用port-based的功能, 却找不到相关的文章.经不断尝试, 终于找到了可行的方法, 现将完整的安装过程写出来供大家参考:

一般浏览用户可以用http://10.1.1.1https://10.1.1.1去访问. 预设的port为: 80 和 443 (SSL)

但一些网管的后台控制程序若果同样用port 80或443去访问,若只是用密码去保护,始终不是安全之策,

现时实在有太多无聊人会不断去尝试登入密码: 比例: 你若开放了server-status功能, 人人都会用:

http://10.1.1.1/server-status

去撞密码或其它破解方法企图登入. 如果可以用到port-based的功能, 将网管的后台控制程序放在document-root之外的目录,

用port-based的virtual host链接至后台控制程序的目录, 如此一来, 除了密码保护外, 亦会多了一层防火墙去保护,

因为可以写一些防火墙规则去允许特定的IP访问该virtual host的port , 这样则可完全杜绝无聊人去撞密码企图登入了.

安装环境:

 OS: FreeBSD v6.2 
 Lighttpd Version: v1.4.18  
 server IP: 10.1.1.1 
 一般用户可浏览的网页储在: /var/local/www 
 网管的后台控制程序储在: /var/local/protectArea/webadminData 

注解: 在webadminData之上必须至少还需一层的目录, 因为网管的SSL port实施在protectArea目录. 而lighttpd的密码验证则实施在webadminData目录. 详情如下:

修改/usr/local/etc/lighttpd.conf 為以下设定:

(修改之后需要用/usr/local/etc/rc.d/lighttpd restart重新启动)

移除server.modules中mod_auth和server-status前面的# 号. 
server.document-root        = "/var/local/www/" 
server.port = 80 
# 一般用户可用到的SSL port, 如无需要则用#去disable. 
$SERVER["socket"] == "0.0.0.0:443" { 
ssl.engine                  = "enable" 
ssl.pemfile                 = "/etc/ssl/lighttpd.pem" 
server.document-root        = "/var/local/www" 
} 
# 所有网管的后台控制程序都需要SSL联机,加强安全, port为45678 
$SERVER["socket"] == "0.0.0.0:45678" { 
ssl.engine                  = "enable" 
ssl.pemfile                 = "/etc/ssl/lighttpd.pem"  
 # 下面一项不能设为 /var/local/protectArea/webadminData, 因为在网址见到 /webadminData则表示需输入密码. 
server.document-root        = "/var/local/protectArea"    
} 

# status.status-url此项必须更改为如下才能受防火墙的保护: 
status.status-url          = "/webadminData/server-status" 
auth.debug = 1        # Enable only for logging only. 
auth.backend               = "htdigest" 
auth.backend.htdigest.userfile = "/usr/local/protectArea/webadminData/.lighttpdPassword" 
 # 因为status.status-url已设定server-status在webadminData目录下,而进入webadminData是需要密码,因以以下无需再设定server-status的保护 
  # 所有网管的后台控制程序都储在/webadminData目录, 因此设定此目录受密码保护,无需要设为/var/local/protectArea/webadminData 
auth.require               = ( "/webadminData" => 
                             ( "method"  => "digest", 
                               "realm"   => "Enter Password", 
                               "require" => "valid-user" 
                             ), 
                           ) 

创建储存网页和网管的后台控制程序的储存目录:

 mkdir -R /usr/local/protectArea/webadminData && touch /usr/local/protectArea/webadminData/.lighttpdPassword 
 chmod 0500 /usr/local/protectArea/webadminData && chown -R www:www /usr/local/protectArea/webadminData 
 mkdir -R /var/local/www && chmod 0500 /var/local/www && chown -R www:www /var/local/www 

以下程序用来产生进入受保护目录的密码:

 touch /root/genDigestPwd.sh && chmod 0700 /root/genDigestPwd.sh 
 vi /root/genDigestPwd.sh 加入以下内容去产生密码: (shell是用bash,你若不是用bash, 请自行更改) 
    #!/usr/local/bin/bash 
    user=$1 
    realm=$2 
    pass=$3 
    hash=`echo -n "$user:$realm:$pass" | md5 | cut -b -32` 
    echo "$user:$realm:$hash" >/usr/local/protectArea/webadminData/.lighttpdPassword 
    cat /usr/local/protectArea/webadminData/.lighttpdPassword 

注解: realm 也是认证方式, 所以genDigestPwd.sh中的第2个参数realm字符串值必须跟 lighttpd.conf 内中auth.require部份的 realm 是完全相同的字符, 且字符不能含有冒号.

用以下指令去产生密码: (peter是虚拟用户名,与系统账号是完全不相关的,亦切勿用真实的系统账号)

 /root/myScript/genDigestPwd.sh "peter" "Enter Password" "peterPassword" ; history -c 

产生SSL

 cd /etc/ssl && openssl req -new -x509 -keyout lighttpd.pem -out lighttpd.pem -days 9999 -nodes 
 chmod 0400 lighttpd.pem 

设定防火墙规则只允许网管员IP进入后台程序

 ipfw -q add 001 allow tcp from 11.22.33.44 to me 45678 in setup limit src-addr 3 
 ipfw -q add 002 allow tcp from me 45678 to 11.22.33.44 out keep-state  

注解:

 (1) 001和002是规则号码,请按实际情况更改,必须放在deny all之前. 
 (2) 11.22.33.44是網管的IP, limit src-addr 3是限制每个IP只允许3个联机. 
 (3) 若网管计算机无固定IP,可用需密码进入的PHP程序去取得IP,写入某档案,再写script去读取该档,
     用该IP去更新防火墙规则.这些程序可就要考考你的功夫了, 不是太困难的 ... 

创建测试档案

 touch /var/local/www/index.html 
 echo "my Home Page for public" >/var/local/www/index.html 
 chmod 0500 /var/local/www && chown -R www:www /var/local/www 
 touch /var/local/protectArea/webadminData/admin.html 
 echo "private file for web admin only" >/var/local/protectArea/webadminData/admin.html 
 chmod 0500 /usr/local/protectArea/webadminData && chown -R www:www /usr/local/protectArea/webadminData 

好了, 基本上己设定好了, 现在测试一下了: 一般用户可用 http://10.1.1.1/index.htmlhttps://10.1.1.1/index.html 去访问储在: /var/local/www 目录下的网页. 网管则必须用:

 https://10.1.1.1:45678/webadminData/admin.html 
 https://10.1.1.1:45678/webadminData/server-status 

去访问储在 /var/local/protectArea/webadminData 目录下的后台控制程序.


请留意以下几点:

 (1) /var/local/www 目录下最好不要再有webadminData和server-status目录. 
 (2) lighttpd所有受htdigest方式保护的目录,若果遇上目录下的程序本身又以 
      basic authentication方式, 弹出窗口要求输入账号和密码, 此时lighttpd会非常 
      奇怪,一直处正在登入中的状态, 打不开网页,而在log档中则出现大量auth OK 
     的信息, 应该是lighttpd的bug. 比如eAccelerator的后台控程序control.php
     若放在webadminData目录下就会出现这种现象. 
      **********    解决方法   **********
     (a) 改用其他lighttpd保护目录的验证方式,除了htdigest, 还有其他方式的,详情看官方网站的Docs 
     (b) 删除control.php文件中要求登入密码的部份,已有防火墙(port)和htdigest双重保护已足够了. 
       
          /*    这样就可以停用eAccelerator自身的登入验证了. 
               if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_USER']) || 
               $_SERVER['PHP_AUTH_USER'] != $user || $_SERVER['PHP_AUTH_PW'] != $pw) { 
               header('WWW-Authenticate: Basic realm="eAccelerator control panel"'); 
               header('HTTP/1.0 401 Unauthorized'); 
               exit; 
              } 
          */ 
      (c) 若程序自身的登入密码部份不能删除,好像phpMyAdmin, 则只需在/var/local/protectArea/目录下 
            再创建另一目录phpmyadmin2114来储存,在lighttpd.conf就不要再对目录phpmyadmin2114进行保护了, 
          这样同样有防火墙(port)和程序自身的验证双重保护.


yes298 2008/01/25 09:41

/data/vhosts/wiki-data/pages/doc/l/lighttpd.txt · 最后更改: 2008/02/18 09:22 由 delphij