| 
 | 
 
基本上 Linux 系统的大部份网络服务,都可以接听所有网络接口的连接端口。只要  
  把各种服务(例如 DNS 、 WWW )架设在拥有固定 IP 地址的内部网络接口上,即使您府  
  上是用电话拨接上网,您的系统服务激活、停止、关机应该都没有问题才对。  
  使用动态 IP 架站(据说即使没有中断联机 HiNet 的 ADSL 动态 IP 每天也会变  
  动),网际网络上的使用者要怎么样使用您的网络服务?我想这个不是问题,只要使用  
  免费动态网域名称服务(例如 Hammer Node - http://hn.org/ 、 myIP -  
  http://myip.org/ )即可解决。  
  问题是您不知道什么时候 IP 会被换掉,所以要使用客户端程序(例如 KVTek's  
  yiPost - http://www.kvtek.com/ 、 DynSite for Windows - http://noeld.com/ )  
  来侦测。  
  半数以上的动态网域名称服务客户端程序都是 Windows 平台,这样您要有另外一  
  台透过 Linux 上网的计算机来执行程序,定期(例如每 5-10 分钟)更新您的地址,但是  
  很多人只有一台计算机,想要使用 VMware - http://www.vmware.com/ 却又担心启用视  
  窗影响系统效能。  
  那么就用 Linux 来做吧,底下是使用 PERL 的动态网域名称地址更新程序范例:  
   
  #!/usr/bin/perl  
   
  $interface = "ppp0";  
  $id = "abc"; # 填上您的帐号  
  $pwd = "xxxx"; # 填上您的密码  
  $hostname = "abc.myip.org"; # 您的网域名称  
  $recordtype = "A"; # 据悉 NS record 尚未开放  
   
  $ipdata = `ifconfig $interface`;  
  $ipdata =~ /addr:(d+.d+.d+.d+)/;  
  $ipaddress = $1;  
  $myip_org_data = `lynx -dump  
  "http://www.myip.org/cgi-bin/Update.py?id=$id&pwd=$pwd&hostname=$hostname&i  
  p=$ipaddress&recordtype=$recordtype"`;  
  print "$myip_org_datan";  
   
  把上面这段程序存盘,就用 myip.org 为档名。给它执行属性(chmod 755  
  myip.org)然后加到工作排程。底下是定期(每 10 分钟)更新网域名称与 IP 地址对应  
  的排程范例:  
   
  5,15,25,35,45,55 * * * * /usr/local/bin/myip.org > /dev/null 2>&1  
   
  再把上面这段排程存盘,就用 cron.jobs 为档名。把它加到排程(crontab  
  cron.jobs)就解决了。现在从内部网络看来一切服务似乎没有问题,但是当您从网际网  
  路浏览虚拟主机的网站时,您将会发现所有虚拟主机的网页都变成与主网站相同的网页  
  了。怎么办?  
  由于 Apache 的 NameBase 虚拟主机只监听设定文件指定 NameVirtualHost 的 IP  
  地址,也就是说每当 ADSL 的 IP 变动时,您就要修改设定文件的 IP 地址然后重新激活  
  网站服务。  
  这工作也可以用排程来做,为了文字剖析语言程序的执行速度考量,我们先把虚拟  
  主机的设定文件部份另存新档,再从 Apache 的主设定档案  
  (/etc/httpd/conf/httpd.conf)中使用加载的方式 Include conf/vhosts.conf 进来。  
  底下是虚拟主机的设定文件(vhosts.conf)范例:  
   
  # If you want to use name-based virtual hosts you need to define at  
  # least one IP address (and port number) for them.  
  #  
  NameVirtualHost 172.16.0.66  
  #  
  ################# Named VirtualHosts  
    
  ServerAdmin root@dyn.hn.org  
  ServerName http://www.dyn.hn.org  
  DocumentRoot /var/www/html  
  # ErrorLog logs/host.some_domain.com-error_log  
  # CustomLog logs/host.some_domain.com-access_log common  
    
    
  ServerAdmin liu@dyn.hn.org  
  ServerName home.dyn.hn.org  
  DocumentRoot /home/liu/public_html  
  # ErrorLog logs/host.some_domain.com-error_log  
  # CustomLog logs/host.some_domain.com-access_log common  
    
    
  ServerAdmin root@dyn.hn.org  
  ServerName mail.dyn.hn.org  
  DocumentRoot /home/webmail/public_html  
  ScriptAlias /cgi-bin/ /home/webmail/public_html/cgi-bin/  
  # ErrorLog logs/host.some_domain.com-error_log  
  # CustomLog logs/host.some_domain.com-access_log common  
    
    
  ServerAdmin root@dyn.hn.org  
  ServerName imap.dyn.hn.org  
  DocumentRoot /var/www/html/horde/imp  
  # ErrorLog logs/host.some_domain.com-error_log  
  # CustomLog logs/host.some_domain.com-access_log common  
    
  #  
  ################# IP-based Virtual Hosts  
    
  # User jmdault  
  # Group jmdault  
  DocumentRoot /usr/share/doc/HOWTO/translations/zh/html  
  ServerName RedHat.dyn.yi.org  
  # Setenv VLOG /home/jmdault/logs  
  # ErrorLogs /home/jmdault/test2-error_log  
  # RewriteEngine On  
  # RewriteOptions inherit  
    
   
  除此之外,我们还要把 vhosts.conf 备份(cp vhosts.conf  
  vhosts.conf.default)一份,否则每当程序变动虚拟主机设定文件的 IP 地址之后,下次  
  程序就会找不到搜寻替换的目标了。底下是使用 PERL 变更虚拟主机设定文件之服务监听  
  地址的程序(dynsite.vhosts)范例:  
   
  #!/usr/bin/perl  
   
  # 拨号联机使用的适配卡  
  $interface = "ppp0";  
  # 没有联机使用的设定值  
  $vhosts = "172.16.0.66";  
  # 拨号联机使用的设定档  
  $filename = "/etc/httpd/conf/vhosts.conf";  
   
  # 下列程序没有必要修改  
  $ipconf = `/sbin/ifconfig $interface`;  
  $ipconf =~ /addr:(d+.d+.d+.d+)/;  
  $ipaddr = $1;  
  open (OLD_FILE,"$filename");  
  @lines =;  
  close(OLD_FILE);  
  open (NEW_FILE,">$filename");  
  foreach $line (@lines) {  
  $line =~ s/$vhosts/$ipaddr/eg;  
  print NEW_FILE ("$line");  
  }  
  close (NEW_FILE);  
   
  名称服务器的情况也极为类似,每当工作排程变动虚拟主机的 IP 地址之后,网站  
  的服务已重新加载,您的 DNS 解析内部网络虚拟主机地址,已经与虚拟主机设定文件的  
  IP 地址不同,从内部网络看来,所有虚拟主机的网页又变成与主网站相同的网页了。  
  怎么办?  
  为了内部网络与网际网络都能够正确浏览虚拟主机网页,名称服务器的设定当然也  
  要动态更新,底下是更新之前的内部网络名称服务器激活文件(/etc/named.conf)范例:  
   
  options {  
  directory "/var/named";  
  };  
  zone "." IN {  
  type hint;  
  file "named.ca";  
  };  
  zone "localhost" IN {  
  type master;  
  file "localhost.zone";  
  allow-update { none; };  
  };  
  zone "0.0.127.in-addr.arpa" IN {  
  type master;  
  file "named.local";  
  allow-update { none; };  
  };  
  zone "dyn.hn.org" IN {  
  type master;  
  file "named.hosts.ns";  
  };  
  zone "0.16.172.in-addr.arpa" IN {  
  type master;  
  file "named.rev.ns";  
  };  
   
  同样我们也要把 named.conf 档案备份(cp named.conf named.conf.default)一  
  份,否则每当程序变动 DNS 激活文件的反向对应区域之后,下次程序又将找不到搜寻替  
  换的目标了。底下是使用 PERL 变更名称服务器激活文件反向对应区域的程序  
  (dynsite.bind)范例:  
   
  #!/usr/bin/perl  
   
  # 拨号联机使用的适配卡  
  $interface = "ppp0";  
  # 没有联机使用的设定值  
  $zone = "0.16.172.in-addr.arpa";  
   
  # 下列程序没有必要修改  
  $filename = "/etc/named.conf";  
  $ipconf = `/sbin/ifconfig $interface`;  
  $ipconf =~ /addr:(d+.d+.d+.d+)/;  
  $ipaddr = $1;  
  ($addr1, $addr2, $addr3, $addr4)=split(/./, $ipaddr);  
  $ipaddr = $addr3 . "." . $addr2 . "." . $addr1 . ".in-addr.arpa";  
  open (OLD_FILE,"$filename");  
  @lines =;  
  close(OLD_FILE);  
  open (NEW_FILE,">$filename");  
  foreach $line (@lines) {  
  $line =~ s/$zone/$ipaddr/eg;  
  print NEW_FILE ("$line");  
  }  
  close (NEW_FILE);  
   
  底下是内部网络名称服务器的地址记录文件 (/var/named/named.hosts.ns) 范例:  
   
  @ IN SOA dyn.hn.org. root.dyn.hn.org. (  
  2001010100 ; Serial  
  28800 ; Refresh  
  14400 ; Retry  
  3600000 ; Expire  
  86400 ) ; Minimum  
  IN NS dns.dyn.hn.org.  
  IN MX 0 mail.dyn.hn.org.  
  dns IN A 172.16.0.66  
  www IN A 172.16.0.66  
  imap IN A 172.16.0.66  
  mail IN A 172.16.0.66  
  home IN A 172.16.0.66  
   
  我们也要把 named.hosts.ns 档案备份(cp named.hosts.ns  
  named.hosts.default)一份,否则每当程序变动 DNS 的地址记录文件之后,下次程序就  
  找不到搜寻替换的目标了。底下是使用 PERL 变更名称服务器地址记录文件的程序  
  (dynsite.hosts)范例:  
   
  #!/usr/bin/perl  
   
  # 拨号联机使用的适配卡  
  $interface = "ppp0";  
  # 没有联机使用的设定值  
  $address = "172.16.0.66";  
  # 拨号联机使用的设定档  
  $filename = "/var/named/named.hosts.ns";  
   
  # 下列程序没有必要修改  
  $ipconf = `/sbin/ifconfig $interface`;  
  $ipconf =~ /addr:(d+.d+.d+.d+)/;  
  $ipaddr = $1;  
  open (OLD_FILE,"$filename");  
  @lines =;  
  close(OLD_FILE);  
  open (NEW_FILE,">$filename");  
  foreach $line (@lines) {  
  $line =~ s/$address/$ipaddr/eg;  
  print NEW_FILE ("$line");  
  }  
  close (NEW_FILE);  
   
  底下是内部网络名称服务器的指针记录文件 (/var/named/named.rev.ns) 范例:  
   
  @ IN SOA dyn.hn.org. root.dyn.hn.org. (  
  2001010100 ; Serial  
  28800 ; Refresh  
  14400 ; Retry  
  3600000 ; Expire  
  86400 ) ; Minimum  
  IN NS dns.dyn.hn.org.  
  IN MX 0 mail.dyn.hn.org.  
  66 IN PTR dns.dyn.hn.org.  
   
  我们也同样把 named.rev.ns 档案备份(cp named.rev.ns named.rev.default)一  
  份,否则每当程序变动 DNS 的指针记录文件之后,下次程序又将会找不到搜寻替换的目  
  标了。底下是使用 PERL 变更名称服务器指针记录文件的程序(dynsite.rev)范例:  
   
  #!/usr/bin/perl  
   
  # 拨号联机使用的适配卡  
  $interface = "ppp0";  
  # 没有联机使用的设定值  
  $point = "66";  
  # 拨号联机使用的设定档  
  $filename = "/var/named/named.rev.ns";  
   
  # 下列程序没有必要修改  
  $ipconf = `/sbin/ifconfig $interface`;  
  $ipconf =~ /addr:(d+.d+.d+.d+)/;  
  $ipaddr = $1;  
  ($addr1, $addr2, $addr3, $addr4)=split(/./, $ipaddr);  
  open (OLD_FILE,"$filename");  
  @lines =;  
  close(OLD_FILE);  
  open (NEW_FILE,">$filename");  
  foreach $line (@lines) {  
  $line =~ s/$point/$addr4/eg;  
  print NEW_FILE ("$line");  
  }  
  close (NEW_FILE);  
   
  当然我们总不能只使用手动方式逐一更新吧,现在把上述所有动作整合起来,以便  
  使用于工作排程自动执行,底下是使用 Bourne Shell 整合的程序范例:  
   
  #!/bin/sh  
   
  # 拨号联机使用的适配卡  
  interface=ppp0  
  # 没有联机使用的设定档  
  named_hosts_default=/var/named/named.hosts.default  
  named_rev_default=/var/named/named.rev.default  
  named_conf_default=/etc/named.conf.default  
  httpd_vhosts_default=/etc/httpd/conf/vhosts.conf.default  
  # 拨号联机使用的设定档  
  named_hosts_dynamic=/var/named/named.hosts.ns  
  named_rev_dynamic=/var/named/named.rev.ns  
  named_conf_dynamic=/etc/named.conf  
  httpd_vhosts_dynamic=/etc/httpd/conf/vhosts.conf  
   
  # 下列程序没有必要修改  
  case "$1" in  
  'start')  
  IPADDR=`/sbin/ifconfig $interface | grep "inet addr" | awk '{print $2;}' |  
  awk -F':' '{print $2;}'`  
  if [ "${IPADDR}" = "" ] ; then  
  echo "$interface: error fetching interface information: Device not found"  
  exit 0  
  fi  
  cp $named_hosts_default $named_hosts_dynamic  
  cp $named_rev_default $named_rev_dynamic  
  cp $named_conf_default $named_conf_dynamic  
  /usr/local/bin/dynsite.hosts  
  /usr/local/bin/dynsite.rev  
  /usr/local/bin/dynsite.bind  
  /sbin/service named restart  
  cp $httpd_vhosts_default $httpd_vhosts_dynamic  
  /usr/local/bin/dynsite.vhosts  
  /sbin/service httpd restart  
  ;;  
  'stop')  
  cp $named_hosts_default $named_hosts_dynamic  
  cp $named_rev_default $named_rev_dynamic  
  cp $named_conf_default $named_conf_dynamic  
  /sbin/service named restart  
  cp $httpd_vhosts_default $httpd_vhosts_dynamic  
  /sbin/service httpd restart  
  ;;  
  *)  
  echo "Usage: $0 { start | stop }"  
  ;;  
  esac  
  exit 0  
   
  把上面这段 bash 程序代码存盘吧,档名就叫它 dynsite 好了,包括上述所有的  
  PERL 程序文件,都把它设定为可执行属性(chmod 755 dynsite*),现在可以用 dynsite  
  start 来手动更新名称服务器与虚拟主机的 IP 地址,如果您要中断联机 dynsite  
  stop 可以让您回到局域网络的设定值,这样我们无论从内部网络或网际网络都能够正  
  确地浏览虚拟主机的网页了。  
  现在就把 dynsite start 加到工作排程自动执行吧,底下是定期(每 10 分钟)更  
  新名称服务器与虚拟主机设定文件的排程范例:  
   
  6,16,26,36,46,56 * * * * /usr/local/bin/dynsite start > /dev/null 2>&1  
   
  把这段工作排程加入到刚才的 cron.jobs 档案里面,执行 crontab -r 移除原有  
  的排程,再重新执行一次 crontab cron.jobs 即可大功告成了。  
  关于使用 ADSL 动态 IP 建置虚拟主机,或许您有更好的解决方案,欢迎您给予指  
  正。 |   
 
 
 
 |