制作虚拟主机管理系统
前言
公司有两台服务器空着……没什么作用,打算明年拿来做虚拟主机业务。
网上找了一些虚拟主机的管理系统,没什么用,基本上都是数据库操作,非常少有对FTP、IIS、MAIL操作的考虑了半天 ,还是自己写一个算了!
第一部分 虚拟主机管理系统规划
程式需要的功能有:
(1)订单提交方式多样:非会员能直接提交产品订单,实时开通产品能定义为手工开通。
(2)试用时间自由设定:能针对某一具体产品设定试用时间,以天为单位。
(3)管理界面操作简化:比其他同类产品而言,该系统操作界面灵活,特别体目前财务上。
(4)域名接口选择更多:能同时容纳多个域名实时注册管理接口。
(4)独有产品赠送功能:每一产品能定义最多三个赠送品,如买主机送域名送邮局。
(5)独有套餐定义功能:能定义5个产品以内的任意组合套餐。
(6)系统查询功能强大:管理员后台拥有众多查询功能,能迅速定位到所需记录上。
(7)代理系统无限开设:利用系统递归,能开设无限级别的下级代理系统。
(8)支持后台在线重启服务器
系统模块可分为:
(1)顶级域名实时注册管理模块
(2)虚拟主机实时开设管理模块
(3)企业邮局实时开设管理模块
(4)MSSQL数据库开设管理模块
(5)非实时产品的订单提交模块(包括中文域名、通用网址、网站推广、租用托管、网站建设)
(6)财务管理模块
(7)日志查询模块(包括订单查询、操作查询及登录查询)
(8)会员管理模块
(9)系统设置模块
(10)服务器重要服务重启模块(包括FTP/SMTP/POP3/IIS/DNS/MSSQL等服务重启)
(11)信息通讯管理(包括行业新闻发布管理、本站通知发布管理、及邮件自动发送模版)
(12)英文域名、虚拟主机、企业邮局及MSSQL具有独立的控制面板
第二部分 技术难点及解决方案
一、技术难点
分析完整个系统的功能以后,我们来看一下关键的技术难点:
(1)在线实时开通FTP帐号;
(2)在线实时开通虚拟站点;
(3)在线实时开通EMAIL帐号;
(4)操作IIS/MSSQL/FTP/MAIL系统的启动、停止;
除以上难点以外,其他的功能无非就是简单的数据库录入、查询、修改、删除操作,所以,只要解决以上难点,系统即实现基本功能。
二、解决方案
(1)在线实时开通FTP帐号:
在这里,我们使用的FTP服务器端系统为Serv-U 6.0版,通过改写ServUDaemon.ini文件来增加、删除、修改用户。以下是增加FTP用户的原代码:
<%
'**************************************************
'* 原作者:awaysrain(绝对零度) *
'* 完成时间:2003-10-10 *
'* 修改时间:2005-01-11 *
'* 测试环境:WIN2000SERVER,SERV-U 6.0beta版 *
'**************************************************
Dim iniPath,iniFileName,iniStr,tmpStr,n
Dim userName,passWord,tmp
userName = "myfso222" '用户名
passWord = "awaysrain" '密码
'tmp = "ai" '随机生成两个小写字母,(应该是随机生成的,但是我这里省略了)
'passWord = tmp & UCase(md5(passWord)) '密码,是MD5加密过的,用动网的MD5加密程序,具体算法是随机生成两位小写字母,然后和你的密码连接后进行MD5加密,把随机生成的密码和MD5加密后的结果作为密码存放,举个例子来说比如下面的awaysrain用户,我的密码为awaysrain先随机生成两位小写字母ai,和我的密码awaysrain连接得到aiawaysrain把aiawaysrain进行MD5加密得到9118BFD94A9CE9CF37AE5BAA947ED596把随机生成两位小写字母ai和MD5加密后的结果9118BFD94A9CE9CF37AE5BAA947ED596连接得到密码ai9118BFD94A9CE9CF37AE5BAA947ED596
iniPath="D:/Program Files/Serv-U" 'ini文件的路径
iniFileName = "ServUDaemon.ini" 'ini的文件名
Set fso=Server.CreateObject("Scripting.FileSystemObject")
Set ServUIni = fso.OpenTextFile(iniPath & "/" & iniFileName,1,false)
iniStr = ""
n = 0
addedUserList = false
Set tf = fso.CreateTextFile(iniPath & "/" & iniFileName & "._awaysrain.tmp", True)
'生成新的临时INI文件
Do While not ServUIni.AtEndOfStream
tmpStr = ServUIni.ReadLine
If Instr("awaysrain||" & tmpStr,"awaysrain||User")>0 Then
'记录用户原来的数量
n = n+1
End If
If Instr("awaysrain||" & tmpStr,"awaysrain||[USER=")>0 and not addedUserList Then
'往用户列表的部分添加现在的用户
n = n +1
tf.WriteLine("User" & n & "=" & userName & "|1|0")
addedUserList = true
End If
tf.WriteLine(tmpStr)
Loop
ServUIni.Close
'添加新用户的信息,具体内容可以在SERV-U中新建用户并对照INI文件
tf.WriteLine("[USER=" & userName & "|1]") '用户名
tf.WriteLine("Password=" & passWord) '密码
tf.WriteLine("HomeDir=D:/temp") '主目录
tf.WriteLine("RelPaths=1") '是否锁定用户于主目录
tf.WriteLine("MaxUsersLoginPerIP=1") '相同IP同时登录数
tf.WriteLine("SpeedLimitDown=102400") '最大下载速度
tf.WriteLine("TimeOut=600") '空闲超时时间(秒)
tf.WriteLine("Access1=D:/Temp|RLP") '可访问目录,可以不是一个,比如 'Access2=E:/Temp1|RLP'
tf.Close
'--------------------备份原来的INI文件--------------------------
Set f1 = fso.GetFile(iniPath & "/" & iniFileName)
f1.Copy (iniPath & "/" & iniFileName & "._awaysrain.bak")
f1.Delete
'--------------------把生成的临时INI文件改为正式的INI--------------------------
Set f1 = fso.GetFile(iniPath & "/" & iniFileName & "._awaysrain.tmp")
f1.Copy (iniPath & "/" & iniFileName)
f1.Delete
Set fso = nothing
%>
这里我对原作者的程序进行了一点修改,把原有的对密码的加密去了,这样,存在INI文件中的密码是直接看见的,为什么要这样呢……因为6.0和4.2的加密算法好象不大一样(如果有知道加密算法的朋友请告诉我),而且,我们现在做虚拟主机管理系统的重点也不在这里,所以把这一部分舍去了。此处的SERV-U的设置有以下几点需要注意的:
1 必须已经有一个域,且有至少一个用户存在的情况下,才能成功。
2 因为去除了对密码的加密算法,所以在域的设置里的高级选项中的“将密码存储于加密的窗体中”选项去除。
(2)在线实时开通虚拟站点:
为了将来能满足域名转向功能,所以,我们这里要求在线实时开通“虚拟站点”,而不是开通“虚拟目录”,目录是不能控制转向的。
网上找了一些资料可以建立虚拟站点的,可是都失败了……不知道为什么,比如通过“ADSI修改IIS信息”,不行,提示“权限不够”。后来查了些资料,发现基本上都是通过c:/Inetpub/adminscript下的VBS脚本来实现对IIS的管理的,我通过ASP来调用时,出现了权限不够的问题,所有就换个思路,通过组件来调用这些脚本来控制IIS。
首先先些了个VB的组件:
一、建立一个ActiveX DLL工程
二、更改工程名ServerShell
三、更改类名:Cmd
四、修改类代码:
Public Function ServerCmd(strCMD)
Shell strCMD, vbHide
'就这么简单就行了!
End Function
五、生成并注册DLL文件
然后在ASP中调用这个组件
<%
set CMD = server.createobject("ServerShell.Cmd")
CMD.ServerCMD("cmd.exe /c C:/Inetpub/AdminScripts/mkw3site -r ""e:/inetpub"" -c ""db"" -o 88 -i 192.168.0.3 -h db -t ""testwebSite""")
'创建虚拟 Web 站点
'要创建虚拟 Web 站点,请在命令提示符下键入以下命令:
'Mkw3site -r 根目录 驱动器盘符:/文件夹名 -t 新服务器名 -h 主机名 www.我的新 Web 站点.com
%>
OK,现在可以通过“Internet 服务管理器”发现已经增加了一个testwebSite的虚拟站点了,这里对Adminscript下的脚本不做其他的解释了,有兴趣的朋友可以参考以下站点:
http://www.uudog.com/newscontent/IIS97.html
制作虚拟主机管理系统(三)
从命令提示符执行 IIS 中的管理任务
本文介绍如何从命令提示符执行 Internet 信息服务 (IIS) 中的管理任务。有几种工具可以帮助管理任务的执行。本文中,这些任务划分为三个独立的任务组;不过,所有任务都是由驱动器盘符:/Inetpub/AdminScripts 文件夹中 Administrator 组的组成员用户执行的。 备注:要打开命令提示符以执行本文介绍的任何任务,请按下列步骤操作: 单击开始,单击运行,键入 cmd,然后单击确定。 键入 cd Inetpub/AdminScripts 然后按 ENTER。 显示任务 可用来显示任务的两个命令是 findweb 和 disptree。另一个可用来显示树中某一特定管理节点中的相关域的命令是 dispnode。 查找虚拟 Web 站点 要查找虚拟 Web 站点,请在命令提示符下键入以下命令: findweb -c 计算机名 www.域名.com 显示管理树 要显示管理树,可在命令提示符下键入下列两个命令之一: disptree -a IIS://计算机名 或者 disptree -a IIS://本地主机/w3svc -n 创建任务 可用于创建任务的两个命令是 mkw3site 和 mkwebdir;不过,adsutil 命令行实用程序中包含几个设计用来创建进程内应用程序的命令。 创建虚拟 Web 站点 要创建虚拟 Web 站点,请在命令提示符下键入以下命令: Mkw3site -r 根目录 驱动器盘符:/文件夹名 -t 新服务器名 -h 主机名 www.我的新 Web 站点.com 创建虚拟 Web 目录 要创建虚拟 Web 目录,请在命令提示符下键入下面的命令: Mkwebdir -c 计算机名 -w "Web 站点名" -v 目录名, 驱动器盘符:/文件夹名 或者 Mkwebdir -c 本地主机 -w "Web 站点名" -v 目录名,驱动器盘符:/文件夹名 管理任务 有几个管理命令可用来执行从启动和停止服务到更改访问属性等各种任务。本文只为两个管理命令提供了分步指南,而下面列出了其他所有命令: chaccess contftp contsrv contweb dispnode disptree findweb mkw3site mkwebdir pauseftp pausesrv pauseweb startftp startsrv startweb stopftp stopsrv stopweb synciwam 在不中断整个 Web 服务的情况下停止虚拟站点 如想在不中断整个 Web 服务的情况下停止虚拟站点,请从命令提示符下键入下面的命令: adsutil STOP_SERVER W3SVC/服务器号 在本例中,对于 W3SVC/服务器号,可以键入 W3SVC/1 代表默认服务器,或者键入 W3SVC/2 代表 foobar 服务器。 在不中断整个 Web 服务的情况下启动虚拟站点 如想在不中断整个 Web 服务的情况下启动虚拟站点,请从命令提示符下键入下面的命令: adsutil START_SERVER W3SVC/服务器号 在本例中,对于 W3SVC/服务器号,可以键入 W3SVC/1 代表默认服务器,或者键入 W3SVC/2 代表 foobar 服务器。 疑难解答 在创建 Virtual Web Directory(虚拟 Web 目录)之前必须为该目录创建文件夹;进程不自动创建此文件夹。如果在创建文件夹之前创建目录,就会收到一条错误消息。 您可以在"Internet Information 服务"控制台检查您在命令提示符下执行的所有进程。如果在命令行进行更改时控制台打开着,则请单击操作,然后单击刷新以在控制台查看这些更改. |
制作虚拟主机管理系统(四)
以下是创建一个虚拟主机的代码:
config.xml(配置信息)
<Root_Element> <admin>Administrator</admin> <adminpass>xxxxxx</adminpass> <readuser>IUSR_MACHINE</readuser> <domain>cocoo.net</domain> <dnsadmin>dnsadmin</dnsadmin> <dnsadminpass>yyyyy</dnsadminpass> <dnsip>10.1.143.227</dnsip> <group>tryit</group> <webdir>http://hanhong.cocoo.net</webdir> </Root_Element>
global.asa(配置文件)
<SCRIPT LANGUAGE=vbscript RUNAT=Server> Sub Application_OnStart set ff=server.createobject("microsoft.xmldom") ff.async=false ff.load server.mappath("config.xml") set rootElem = ff.documentElement for e1=0 to rootElem.childNodes.length-1 application(trim(rootElem.childNodes.item(e1).nodeName))=trim(rootElem.childNodes.item(e1).text) next End Sub </script>
index.asp(申请页面)
<% user=trim(request("user")) pass=trim(request("pass")) email=trim(request("email")) if user<>"" then if pass="" or instr(email,"@")<2 then response.write "<font color='red'>填写错误</font>" else SET GG=SERVER.CREATEOBJECT("QWEB.USER") gg.logon application("admin") & "@" & application("domain"),application("adminpass") SET RR=GG.CREATE(user,application("group")) if gg.iserr then response.write "<font color='red'>不能创建用户:" & gg.errstring & "</font>" else gg.value("pwdLastSet",rr)=-1 gg.changepassword "", pass,rr response.write gg.errstring gg.value("accountdisabled",rr)=TRUE gg.value("accountexpirationdate",rr)=now()+2 gg.value("description",rr)=session.SessionID SET FF=CreateObject("QWEB.dns") domainn=right(email,len(email)-instr(email,"@")) SET cc=CREATEOBJECT("qmail.newmail") cc.sender="AA网络<anyone@anyone.net>" cc.receiver=email cc.sendashtml=true cc.subject="注册确认" cc.body="<a href='" & application("webdir") & "/active.asp?user=" & user & "&id=" & session.SessionID & "&pass=" & pass & "'>谢谢您的注册,请在24小时内(" & (now()+1) & ")激活您的帐户。</a>" vv=ff.mxrecord(application("dnsip"),domainn) HH=SPLIT(VV," ") FOR G=0 TO UBOUND(HH) cc.smtpsvr=hh(g) cc.send if cc.errcode=true then exit for next if cc.errcode=false then gg.delete rr response.write "<font color='red'>无法发送注册信息</font>" else response.write "<font color='red'>注册成功,请24小时内查看邮件,激活帐户.</font>" response.end end if set cc=nothing set ff=nothing end if set gg=nothing end if end if %> <h1 align="center">免费空间申请</h1> <form name="form1" method="post" action="<% =request.ServerVariables("SCRIPT_NAME") %>"> <p>用户名: <input type="text" name="user"> </p> <p>密 码: <input type="password" name="pass"> </p> <p>电子邮件: <input type="text" name="email"> </p> <p> <input type="submit" name="Submit" value="现在申请"> </p> </form> <p align="center"> </p>
active.asp(确认页面,建立站点、开通FTP、EMAIL、配置DNS纪录)
<% user=request("user") id=request("id") SET UU=SERVER.CREATEOBJECT("QWEB.MEMBER") SET GG=SERVER.CREATEOBJECT("QWEB.USER") SET z1=SERVER.CreateObject("QWEB.DIR") set bb=server.createobject("MDUsercom.MDUser") Set mUserInfo =server.createobject("MDUsercom.MDUserInfo") set ff=createobject("qweb.dns") UU.LOGON application("admin") & "@" & application("domain"),application("adminpass") gg.logon application("admin") & "@" & application("domain"),application("adminpass") SET RR=GG.user(user,application("group")) if gg.iserr then msg1= "获取用户资料时发生错误:" & gg.errstring else if gg.value("description",rr)<>id or (gg.value("accountdisabled",rr)=false) then msg1= "激活失败,请您从邮箱内提示的地址连接,或帐户在此之前已经被激活" else mpath=session.sessionid z1.CREATE SERVER.MapPath("free/" & mpath),user,application("readuser") if z1.iserr then msg1="在创建用户目录时发生错误:" & z1.errstring else z1.CREATE SERVER.MapPath("free/" & mpath & "/mail"),user,application("readuser") if z1.iserr then msg1="在创建用户邮件目录时发生错误:" & z1.errstring z1.delete SERVER.MapPath("free/" & mpath) else SET SS=z1.CREATESITE(user & "." & application("domain"),SERVER.MapPath("free/" & mpath)) if z1.iserr then msg1="在创建站点时发生错误:" & z1.errstring z1.delete SERVER.MapPath("free/" & mpath & "/mail") z1.delete SERVER.MapPath("free/" & mpath) else z1.createftpdir user,SERVER.MapPath("free/" & mpath) if z1.iserr then msg1="在创建FTP目录时发生错误:" & z1.errstring z1.delete SERVER.MapPath("free/" & mpath & "/mail") z1.delete SERVER.MapPath("free/" & mpath) set site1=z1.getsite(user & "." & application("domain")) z1.deletesite site1 else ff.logon application("domain"),application("dnsip"),application("dnsadmin"),application("dnsadminpass") ff.arecord(user & "." & application("domain"))=application("dnsip") if ff.iserr then msg1="在写入DNS记录时发生错误:" & ff.errstring z1.delete SERVER.MapPath("free/" & mpath & "/mail") z1.delete SERVER.MapPath("free/" & mpath) set site1=z1.getsite(user & "." & application("domain")) z1.deletesite site1 z1.deleteftpdir user else bb.LoadUserDll bb.inituserinfo muserinfo muserinfo.fullname=user muserinfo.mailbox=user muserinfo.domain=application("domain") muserinfo.MailDir=SERVER.MapPath("free/" & mpath & "/mail") muserinfo.password=request("pass") muserinfo.MaxDiskSpace=25000000 muserinfo.ApplyQuotas=true kk=bb.adduser(muserinfo) if kk<>"0" then msg1="在创建用户邮箱时发生错误:" & kk z1.delete SERVER.MapPath("free/" & mpath & "/mail") z1.delete SERVER.MapPath("free/" & mpath) set site1=z1.getsite(user & "." & application("domain")) z1.deletesite site1 z1.deleteftpdir user ff.arecord(user & "." & application("domain"))="" else gg.value("accountexpirationdate",rr)=gg.value("accountexpirationdate",rr)+366 gg.value("accountdisabled",rr)=false gg.value("EmailAddress",rr)=user & "@" & application("domain") gg.value("HomeDirectory",rr)=SERVER.MapPath("free/" & mpath) if gg.iserr then msg1="在设置用户属性时发生错误:" & gg.errstring z1.delete SERVER.MapPath("free/" & mpath & "/mail") z1.delete SERVER.MapPath("free/" & mpath) set site1=z1.getsite(user & "." & application("domain")) z1.deletesite site1 z1.deleteftpdir user ff.arecord(user & "." & application("domain"))="" bb.DeleteUser user & "@" & application("domain"),511 bb.FreeUserDll else bb.FreeUserDll session("isok")="true" msg1="激活成功,您站点的域名是http://" & user & "." & application("domain") & "<br>" msg1=msg1 & "FTP地址:ftp://" & user & "." & application("domain") & "<br>" msg1=msg1 & "用户名: " & user & "<br>" msg1=msg1 & "邮箱:" & user & "@" & application("domain") & "<br>" msg1=msg1 & "密码:是您注册时填写的密码。<br><a href='logon.asp'>登录</a><br>" end if end if end if end if end if end if end if end if end if UU.logoff set gg=nothing SET UU=nothing SET z1=nothing set bb=nothing Set mUserInfo =nothing set ff=nothing response.write msg1 %>
logon.asp(域名重指向)
<% user=trim(request("user")) pass=trim(request("pass")) IP=trim(request("IP")) if user<>"" then SET GG=SERVER.CREATEOBJECT("QWEB.USER") gg.logon application("admin") & "@" & application("domain"),application("adminpass") SET RR=GG.USER(user,application("group")) if gg.iserr then response.write "<font color='red'>用户不存在!</font>" else gg.changepassword pass,"mypass",rr if gg.iserr then response.write "<font color='red'>密码错误!</font>" else gg.changepassword "mypass",pass,rr set ff=createobject("qweb.dns") ff.logon application("domain"),application("dnsip"),application("dnsadmin"),application("dnsadminpass") if ip="" then ff.arecord(user & "." & application("domain"))=application("dnsip") else ff.arecord(user & "." & application("domain"))=ip end if if ff.iserr then response.write "设置失败,请重试!" else response.write "更新成功!" end if set ff=nothing end if end if set gg=nothing end if %> <h1 align="center">管 理</h1> <form name="form1" method="post" action="<% =request.ServerVariables("SCRIPT_NAME") %>"> <p>用户名: <input type="text" name="user"> </p> <p>密 码: <input type="password" name="pass"> </p> <p>把我的域名指向以下IP地址,如果为空则指向您的虚拟目录:</p> <p> <input type="text" name="IP"> </p> <p> <input type="submit" name="Submit" value="更改"> </p> </form> <p align="center"> </p> |