首页 >> 编程知识

DirectoryEntry使用方法大全、搜索引擎优化的核心:关键字策略

DirectoryEntry使用方法大全



说明:本文中所需环境为2003Server + iis6.0 + ms sql2000 

  曾经很早就在网上看到一篇关于的文章,当时并不在意,做过asp虚拟主机的朋友可能都知道,即对每一个用户都设置一个独立的服务器用户和单个目录的操作权限,能够基本上解决asp的fso问题。 

  在网上无意中发现了一个叫做webadmin的asp.net-webshell,对自己的服务器进行测试的时候,让我大吃一惊,居然对我服务器的c盘有读取的权限。以及对整个硬盘的修改删除权限。这样的话,那么我的服务器的安全…… 

  为了进一步证实,本人曾在国内一些著名的虚拟主机提供商上作过测试,均有和我一样的问题。 

  有必要先介绍一下漏洞的原因。 

  ASP中常用的标准组件:FileSystemObject,这个组件为 ASP 提供了强大的文件系统访问能力,可以对服务器硬盘上的任何有权限的目录和文件进行读写、删除、改名等操作。FSO对象来自微软提供的脚本运行库scrrun.dll中。 

  在ASP.NET中我们发现这一问题仍然存在,并且变得更加难以解决。这是因为.NET中关于系统IO操作的功能变得更加强大,而使这一问题更严重的是ASP.NET所具有的一项新功能,这就组件不需要象ASP那样必须要使用regsvr32来注册了,只需将Dll类库文件上传到bin目录下就可以直接使用了。这一功能确实给开发ASP.NET带来了很大的方便,但是却使我们在ASP中将此dll删除或者改名的解决方法失去效用了,防范此问题就变得更加复杂。需要进一步了解的朋友可以看一文,本文就不再重复。只针对此问题引出虚拟主机的安全设置。 

  网上提出针对此问题用Microsoft .NET Framework Configration设置System.io的对目录读取的权限,经过我们长时间的测试没有成功,可能是.net framework1.1机制改革了? 

  废话不说。先说说解决的思路:在 IIS 6 中,Web 应用程序的工作进程设置为以进程标识"Network Service"运行。在 IIS 5 中,进程外 Web 应用程序则设置为以 IWAM_<服务器名> 帐户运行,这个帐户是普通的本地用户帐户。 

  Network Service 是 Windows Server 2003 中的内置帐户。了解 IIS 5 上的本地用户帐户(IUSR 和 IWAM)与这个内置帐户之间的区别是非常重要的。Windows 操作系统中的所有帐户都分配了一个 SID(安全标识,Security ID)。服务器是根据 SID,而不是与 SID 相关的名称来识别服务器上所有帐户的,而我们在与用户界面进行交互时,则是使用名称进行交互的。服务器上创建的绝大部分帐户都是本地帐户,都具有一个唯一的 SID,用于标识此帐户隶属于该服务器用户数据库的成员。由于 SID 只是相对于服务器是唯一的,因此它在任何其他系统上无效。所以,如果您为本地帐户分配了针对某文件或文件夹的 NTFS 权限,然后将该文件及其权限复制到另一台计算机上时,目标计算机上并没有针对这个迁移 SID 的用户帐户,即使其上有一个同名帐户也是如此。这使得包含 NTFS 权限的内容复制可能出现问题。 

  内置帐户是由操作系统创建的、一类较为特别的帐户或组,例如 System 帐户、Network Service 和 Everyone 组。这些对象的重要特征之一就是,它们在所有系统上都拥有一个相同的、众所周知的 SID。当将分配了 NTFS 权限的文件复制到内置帐户时,权限在服务器之间是有效的,因为内置帐户的 SID 在所有服务器上都是相同的。Windows Server 2003 服务中的 Network Service 帐户是特别设计的,专用于为应用程序提供访问网络的足够权限,而且在 IIS 6 中,无需提升权限即可运行 Web 应用程序。这对于 IIS 安全性来说,是一个特大的消息,因为不存在缓冲溢出,怀有恶意的应用程序无法破译进程标识,或是对应用程序的攻击不能进入 System 用户环境。更为重要的一点是,再也不能形成针对 System 帐户的"后门",例如,再也无法通过 InProcessIsapiApps 元数据库项利用加载到 Inetinfo 的应用程序。 

  Network Service 帐户在创建时不仅仅考虑了在 IIS 6 中的应用。它还具有进程标识 W3WP.exe 的绝大部分(并不是全部)权限。如同 ASPNET 用户为了运行 ASP.net 应用程序,需要具有 IIS 5 服务器上某些位置的访问权限,进程标识 W3WP.exe 也需要具有类似位置的访问权限,而且还需要一些默认情况下没有指派给内置组的权限。 

  为了管理的方便,在安装 IIS 6 时创建了 IIS_WPG 组(也称为 IIS 工作进程组,IIS Worker Process Group),而且它的成员包括 Local System(本地系统)、Local Service(本地服务)、Network Service(网络服务)和 IWAM 帐户。IIS_WPG 的成员具有适当的 NTFS 权限和必要的用户权限,可以充当 IIS 6 中工作进程的进程标识。 

  因此,Network Service 帐户提供了访问上述位置的权限,具有充当 IIS 6 工作进程的进程标识的充足权限,以及具有访问网络的权限。 

  Msdn上说:在 Windows Server 2003 中,用户上下文称为 NETWORK SERVICE。这些用户帐户是在 .NET Framework 安装过程中创建的,它具有唯一的不易破解的密码,并仅被授予有限的权限。ASPNET 或 NETWORK SERVICE 用户只能访问运行 Web 应用程序所需的特定文件夹,如 Web 应用程序存储已编译文件的 /bin 目录。 

  要将进程标识设置为特定用户名,以取代 ASPNET 或 NETWORK SERVICE 用户标识,您提供的用户名和密码都必须存储在 machine.config 文件中。 

  但是根据实际情况,asp.net的system.io可以无限制访问不设防的服务器路径。不知道这算不算一个ms的重大漏洞。而且根本不能使iis以machine.config的用户执行asp.net程序。J 

  如何解决呢?答案就是—应用程序池。 

  IIS 6.0 在被称为应用程序隔离模式(隔离模式)的两种不同操作模式下运行,它们是:工作进程隔离模式和 IIS 5.0 隔离模式。这两种模式都要依赖于 HTTP.sys 作为超文本传输协议 (HTTP) 侦听程序;然而,它们内部的工作原理是截然不同的。 

  工作进程隔离模式利用 IIS 6.0 的重新设计的体系结构并且使用工作进程的核心组件。IIS 5.0 隔离模式用于依赖 IIS 5.0 的特定功能和行为的应用程序。该隔离模式由 IIs5IsolationModeEnabled 配置数据库属性指定。 

  您所选择的 IIS 应用程序隔离模式对性能、可靠性、安全性和功能可用性都会产生影响。工作进程隔离模式是 IIS 6.0 操作的推荐模式,因为它为应用程序提供了更可靠的平台。工作进程隔离模式也提供了更高级别的安全性,因为运行在工作进程中的应用程序的默认标识为 NetworkService。 

  以 IIS 5.0 隔离模式运行的应用程序的默认标识为 LocalSystem,该标识允许访问并具有更改计算机上几乎所有资源的能力。 
500)this.width=500" border=0> 
 由此可见,我们只能使用工作进程隔离模式解决.net的安全问题。 
  默认情况下,IIS 6.0在工作进程隔离模式下运行,如图五所示。在这种模式中,对于每一个Web应用,IIS 6.0都用一个独立的w3wp.exe的实例来运行它。w3wp.exe也称为工作进程(Worker Process),或W3Core。 
500)this.width=500" border=0> 
可靠性和安全性。可靠性的提高是因为一个Web应用的故障不会影响到其他Web应用,也不会影响http.sys,每一个Web应用由W3SVC单独地监视其健康状况。安全性的提高是由于应用程序不再象IIS 5.0和IIS 4.0的进程内应用那样用System帐户运行,默认情况下,w3wp.exe的所有实例都在一个权限有限的"网络服务"帐户下运行,如图六所示,必要时,还可以将工作进程配置成用其他用户帐户运行。 
500)this.width=500" border=0> 
对,这里,这里就是我们解决的核心。 

  我们把每一个网站都分配一个独立的应用程序池,并赋予不同的权限。不就能解决这个问题了吗? 

  具体如何做呢,下面我就针对建立一个网站来做一个示范: 

  首先,我们为网站创建两个用户(一个是app_test_user、密码为appuser,一个是iis_test_user、密码为iisuser) 

  1. 打开 计算机管理器 

  2. 单击控制台树中的用户→计算机管理→系统工具→本地用户和组→用户 

  3. 单击"操作"菜单上的"新用户"输入用户名为。app_test_user、密码为appuser 

  4. 在对话框中键入适当的信息。 

  5. 选中复选框: 

   用户不能更改密码 

   密码永不过期 

  6. 单击"创建",然后单击"关闭"。 
500)this.width=500" border=0> 
按照此方法在创建iis_test_user账户 

  然后分别把app_test_user添加到iis_wpg组,把iis_test_user添加到Guests组。删除其他组。 
500)this.width=500" border=0> 
500)this.width=500" border=0> 
然后,建立相应的应用程序池。 

  依次打开Internet 信息服务→本地计算机→应用程序池→新建→应用程序池 

  新建一个名字为test的应用程序池 
500)this.width=500" border=0> 
编辑test应用程序池的属性→标示→配置→用户名→浏览→把用户名改为我们刚才建立的app_test_user并输入相应的密码 
500)this.width=500" border=0> 
 其次建立相应的网站。 

  依次打开Internet 信息服务→本地计算机→网站→新建→test的网站,目录为d:/test →编辑test网站的属性→主目录→应用程序池→app_test_user →目录安全性→身份验证和访问控制→编辑,选择我们刚才建立的iis_test_user,并输入相应的密码iisuser→保存并退出。 
500)this.width=500" border=0> 
最后设定服务器的安全。 

  C:只给administrators和system完全控制的权利,删除掉其他所有的权限,不替换子目录 
500)this.width=500" border=0> 
C:/Documents and Settings继承父项,并替换子目录。 

  C:/Program Files继承父项,并替换子目录,并把C:/Program Files/Common Files/Microsoft Shared继承属性删除并复制现有属性,增加users的读取权限并替换子目录(这样做是为了能够让asp,asp.net使用access等数据库)。 

  C:/windows删除继承,并复制现有属性,只给予administrators,system完全控制和users读取的权限并替换子目录。 
500)this.width=500" border=0> 
其余所有的盘都只给于administrators和system用户的完全控制权限,删除其他所有用户并替换子目录。 

  D:/test(用户网站目录)继承现有属性并增加app_test_user和iis_test_user完全控制的权限并替换子目录。 

  以后每增加一个网站都以此类推。 

  但是,至此,system.io还是对c:/windows又读取权限的,(怀疑network servers用户属于users组,但是好多服务都要使用users组来执行的,所以不能把c:/windwos去掉users组的读取权限)但必须知道系统路径,有两种方案解决。 

  1、 再安装系统的时候使用无人值守安装,更换c:/windows默认安装路径,如更改为c:/testtest(要符合dos的命名规则,不能超过8个字符)。这个是必需的 

  2、 以下位置具有指派给 IIS_WPG 的权限: 

  %windir%/help/iishelp/common – 读取 
  %windir%/IIS Temporary Compressed Files – 列出、读取、写入 
  %windir%/system32/inetsrv/ASP Compiled Template – 读取 
  Inetpub/wwwroot(或内容目录)- 读取、执行 

  此外,IIS_WPG 还具有以下用户权限: 

  忽略遍历检查(SeChangeNotifyPrivilege) 

  作为批处理作业登录(SeBatchLogonRight) 

  从网络访问此计算机(SeNetworkLogonRight) 

  当然两种方法结合起来算是最安全的方案,一般使用第一种方案已经算是很安全的,毕竟是用一个webshell来猜测8位字符的目录还是需要花费时间的。使用防火墙很容易就能察觉出来,并加以控制。 

  第二种可能根据所安装软件不同还要相应增加目录的读取权限,详细情况要根据软件来确定。 

  如果主机用户比较多,这将是一个相当大的劳动量,推荐使用程序来解决问题,下面给出网上不常见的针对iis应用程序池操作的代码和针对iis虚拟目录的操作代码。 

操作iis应用程序池 
using System; 
using System.DirectoryServices; 
using System.Reflection; 

namespace ADSI1 

 /// 
 /// Small class containing methods to configure IIS. 
 /// 
 class ConfigIIS 
 { 
  /// 
  /// The main entry point for the application. 
  /// 
  [STAThread] 
  //主程序入口,可以选择用哪些,我为了方便,全部功能都写上去了。 
  static void Main(string[] args) 
  { 
   string AppPoolName = "MyAppPool"; 
   string newvdir1 = "MyVDir"; 
   DirectoryEntry newvdir = createVDir(newvdir1); 

   createAppPool(AppPoolName); 
   AssignAppPool(newvdir, AppPoolName); 

   ConfigAppPool("Stop",AppPoolName); 
  } 

  //创建虚拟目录 
  static DirectoryEntry createVDir (string vdirname) 
  { 
   DirectoryEntry newvdir; 
   DirectoryEntry root=new DirectoryEntry("IIS://localhost/W3SVC/1/Root"); 
   newvdir=root.Children.Add(vdirname, "IIsWebVirtualDir"); 
   newvdir.Properties["Path][0]= "c://inetpub//wwwroot"; 
   newvdir.Properties["AccessScript][0] = true; 
   newvdir.CommitChanges(); 
   return newvdir; 
  } 

  //创建新的应用程序池。 
  static void createAppPool(string AppPoolName) 
  { 
   DirectoryEntry newpool; 
   DirectoryEntry apppools=new DirectoryEntry("IIS://localhost/W3SVC/AppPools"); 
   newpool=apppools.Children.Add(AppPoolName, "IIsApplicationPool"); 
   newpool.CommitChanges(); 
  } 

  static void AssignAppPool(DirectoryEntry newvdir, string AppPoolName) 
  { 
   object[] param={0, AppPoolName, true}; 
   newvdir.Invoke("Appcreate3", param); 
  } 

  //method是管理应用程序池的方法,有三种Start、Stop、Recycle,而AppPoolName是应用程序池名称 
  static void ConfigAppPool(string method,string AppPoolName) 
  { 
   DirectoryEntry appPool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools"); 
   DirectoryEntry findPool = appPool.Children.Find(AppPoolName,IIsApplicationPool"); 
   findPool.Invoke(method,null); 
   appPool.CommitChanges(); 
   appPool.Close(); 
  } 

  //应用程序池的列表 
  static void AppPoolList() 
  { 
   DirectoryEntry appPool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools"); 
   foreach(DirectoryEntry a in appPool.Children) 
   { 
    Console.WriteLine(a.Name); 
   } 
  } 

  private void VDirToAppPool() 
  { 
   DirectroryEntry VD = new DirectoryEntry("IIS://localhost/W3SVC/1/ROOT/ccc"); 
   Console.WriteLine(VD.Properties["AppPoolId].Value.ToString()); 
  } 
 } 




iis6操作的例子 
using System; 
using System.DirectoryServices; 
using System.Collections; 
using System.Text.RegularExpressions; 
using System.Text; 

namespace Wuhy.ToolBox 

 /// 

 public class IISAdminLib 
 { 
  #region UserName,Password,HostName的定义 
  public static string HostName 
  { 
get 
   { 
    return hostName; 
   } 
   set 
   { 
    hostName = value; 
   } 
  } 

 public static string UserName 
 { 
  get 
  { 
   return userName; 
  } 
  set 
  { 
   userName = value; 
  } 
 } 

 public static string Password 
 { 
  get 
  { 
   return password; 
  } 
  set 
  { 
   if(UserName.Length <= 1) 
   { 
    throw new ArgumentException("还没有指定好用户名。请先指定用户名"); 
   } 
  password = value; 
 } 


public static void RemoteConfig(string hostName, string userName, string password) 

 HostName = hostName; 
 UserName = userName; 
 Password = password; 


private static string hostName = "localhost"; 
private static string userName; 
private static string password; 
#endregion 

#region 根据路径构造Entry的方法 

/// 
/// 根据是否有用户名来判断是否是远程服务器。 
/// 然后再构造出不同的DirectoryEntry出来 
/// 
/// DirectoryEntry的路径 
/// 返回的是DirectoryEntry实例 

public static DirectoryEntry GetDirectoryEntry(string entPath) 

 DirectoryEntry ent; 
 if(UserName == null) 
 { 
  ent = new DirectoryEntry(entPath); 
 } 
 else 
 { 
  // ent = new DirectoryEntry(entPath, HostName+"//"+UserName, Password, AuthenticationTypes.Secure); 
  ent = new DirectoryEntry(entPath, UserName, Password, AuthenticationTypes.Secure); 
 } 
 return ent; 


#endregion 
#region 添加,删除网站的方法 

/// 
/// 创建一个新的网站。根据传过来的信息进行配置 
/// 
/// 存储的是新网站的信息 

public static void createNewWebSite(NewWebSiteInfo siteInfo) 

 if(! EnsureNewSiteEnavaible(siteInfo.BindString)) 
 { 
  throw new DuplicatedWebSiteException("已经有了这样的网站了。" + Environment.NewLine + siteInfo.BindString); 
 } 
 string entPath = String.Format("IIS:///w3svc", HostName); 
 DirectoryEntry rootEntry = GetDirectoryEntry(entPath); 
 string newSiteNum = GetNewWebSiteID(); 
 DirectoryEntry newSiteEntry = rootEntry.Children.Add(newSiteNum, "IIsWebServer"); 
 newSiteEntry.CommitChanges(); 
 newSiteEntry.Properties["ServerBindings].Value = siteInfo.BindString; 
 newSiteEntry.Properties["ServerComment].Value = siteInfo.CommentOfWebSite; 
 newSiteEntry.CommitChanges(); 
 DirectoryEntry vdEntry = newSiteEntry.Children.Add("root", "IIsWebVirtualDir"); 
 vdEntry.CommitChanges(); 
 vdEntry.Properties["Path].Value = siteInfo.WebPath; 
 vdEntry.CommitChanges(); 


/// 
/// 删除一个网站。根据网站名称删除。 
/// 
/// 网站名称 

public static void deleteWebSiteByName(string siteName) 

 string siteNum = GetWebSiteNum(siteName); 
 string siteEntPath = String.Format("IIS:///w3svc/", HostName, siteNum); 
 DirectoryEntry siteEntry = GetDirectoryEntry(siteEntPath); 
 string rootPath = String.Format("IIS:///w3svc", HostName); 
 DirectoryEntry rootEntry = GetDirectoryEntry(rootPath); 
 rootEntry.Children.Remove(siteEntry); 
 rootEntry.CommitChanges(); 


#endregion 
#region Start和Stop网站的方法 

public static void StartWebSite(string siteName) 

 string siteNum = GetWebSiteNum(siteName); 
 string siteEntPath = String.Format("IIS:///w3svc/", HostName, siteNum); 
 DirectoryEntry siteEntry = GetDirectoryEntry(siteEntPath); 
 siteEntry.Invoke("Start", new object[] {}); 


public static void StopWebSite(string siteName) 

 string siteNum = GetWebSiteNum(siteName); 
 string siteEntPath = String.Format("IIS:///w3svc/", HostName, siteNum); 
 DirectoryEntry siteEntry = GetDirectoryEntry(siteEntPath); 
 siteEntry.Invoke("Stop", new object[] {}); 


#endregion 
#region 确认网站是否相同 

/// 
/// 确定一个新的网站与现有的网站没有相同的。 
/// 这样防止将非法的数据存放到IIS里面去 
/// 
/// 网站邦定信息 
/// 真为可以创建,假为不可以创建 

public static bool EnsureNewSiteEnavaible(string bindStr) 

 string entPath = String.Format("IIS:///w3svc", HostName); 
 DirectoryEntry ent = GetDirectoryEntry(entPath); 
 foreach(DirectoryEntry child in ent.Children) 
 { 
  if(child.SchemaClassName == "IIsWebServer") 
  { 
   if(child.Properties["ServerBindings].Value != null) 
   { 
    if(child.Properties["ServerBindings].Value.ToString() == bindStr) 
    { 
     return false; 
    } 
   } 
  } 
 } 
 return true; 


#endregion 
#region 获取一个网站编号的方法 
/// 
/// 获取一个网站的编号。根据网站的ServerBindings或者ServerComment来确定网站编号 
/// 
/// 
/// 返回网站的编号 
/// 表示没有找到网站 

public static string GetWebSiteNum(string siteName) 

 Regex regex = new Regex(siteName); 
 string tmpStr; 
 string entPath = String.Format("IIS:///w3svc", HostName); 
 DirectoryEntry ent = GetDirectoryEntry(entPath); 
 foreach(DirectoryEntry child in ent.Children) 
 { 
  if(child.SchemaClassName == "IIsWebServer") 
  { 
   if(child.Properties["ServerBindings].Value != null) 
   { 
    tmpStr = child.Properties["ServerBindings].Value.ToString(); 
    if(regex.Match(tmpStr).Success) 
    { 
     return child.Name; 
    } 
   } 
   if(child.Properties["ServerComment].Value != null) 
   { 
    tmpStr = child.Properties["ServerComment].Value.ToString(); 
    if(regex.Match(tmpStr).Success) 
    { 
     return child.Name; 
    } 
   } 
  } 
 } 

 throw new NotFoundWebSiteException("没有找到我们想要的站点" + siteName); 


#endregion 
#region 获取新网站id的方法 
/// 
/// 获取网站系统里面可以使用的最小的ID。 
/// 这是因为每个网站都需要有一个唯一的编号,而且这个编号越小越好。 
/// 这里面的算法经过了测试是没有问题的。 
/// 
/// 最小的id 

public static string GetNewWebSiteID() 

 ArrayList list = new ArrayList(); 
 string tmpStr; 
 string entPath = String.Format("IIS:///w3svc", HostName); 
 DirectoryEntry ent = GetDirectoryEntry(entPath); 
 foreach(DirectoryEntry child in ent.Children) 
 { 
  if(child.SchemaClassName == "IIsWebServer") 
  { 
   tmpStr = child.Name.ToString(); 
   list.Add(Convert.ToInt32(tmpStr)); 
  } 
 } 
 list.Sort(); 
 int i = 1; 
 foreach(int j in list) 
 { 
  if(i == j) 
  { 
   i++; 
  } 
 } 
 return i.ToString(); 

#endregion 


#region 新网站信息结构体 

public struct NewWebSiteInfo 

 private string hostIP; // The Hosts IP Address 
 private string portNum; // The New Web Sites Port.generally is "80" 
 private string descOfWebSite; // 网站表示。一般为网站的网站名。例如"www.dns.com.cn" 
 private string commentOfWebSite;// 网站注释。一般也为网站的网站名。 
 private string webPath; // 网站的主目录。例如"e:/tmp" 
 public NewWebSiteInfo(string hostIP, string portNum, string descOfWebSite, string commentOfWebSite, string webPath) 
 { 
  this.hostIP = hostIP; 
  this.portNum = portNum; 
  this.descOfWebSite = descOfWebSite; 
  this.commentOfWebSite = commentOfWebSite; 
  this.webPath = webPath; 
 } 
 public string BindString 
 { 
  get 
  { 
   return String.Format("::", hostIP, portNum, descOfWebSite); 
  } 
 } 
 public string CommentOfWebSite 
 { 
  get 
  { 
   return commentOfWebSite; 
  } 
 } 
 public string WebPath 
 { 
  get 
  { 
   return webPath; 
  } 
 } 

#endregion 




  至此,一个相对安全的.net主机就建立起来了,随着.net2.0的发布越来越逼近,希望ms能针对此问题作一个妥善的防范。 

  我们已经简单的介绍了一下ASP.NET中关于文件IO系统的漏洞的防治方法,这一方法有些繁琐,但是却可以从根本上杜绝一些漏洞,我们讨论的只是很少的一部分,更多的解决放法需要大家共同来探索、学习. 


搜索引擎优化的核心:关键字策略



搜索引擎优化的核心:关键字策略
根据潜在客户或目标用户在搜索引擎中找到你的网站时输入的语句,产生了关键字
(Keywords)的概念,这不仅是搜索引擎优化的核心,也是整个搜索引擎营销都必须围绕的
核心。

                                   关键字的选择

首先确定你的核心关键字,再围绕核心关键字进行排列组合产生关键词组或短句。对企业、
商家而言,核心关键字就是他们的经营范围,如产品/服务名称、行业定位,以及企业名称
或品牌名称等。总结起来,选择关键字有以下技巧:


1、站在客户的角度考虑
潜在客户在搜索你的产品时将使用什么关键词?这可以从众多资源中获得反馈,包括从你的
客户、供应商、品牌经理和销售人员那里获知其想法。


2、将关键词扩展成一系列词组/短语
毋用单一词汇,而是在单一词汇基础上进行扩展,如:营销→网络营销→网络营销管理。英
文关键词可以采用搜索引擎 overture 的著名工具 Keyword Suggestion Tool 对这些关键词
组进行检测,可查看你的关键词在过去 24 小时内被搜索的频率,最好的关键词是那些没有
被广泛滥用而又很多人搜索的词。中文工具可以通过百度的“相关搜索”和 Google 提供的
KeywordSandbox 工具进行关键词匹配和扩展。


工具推荐:
Google AdWords 关键字工具:查询特定关键词的常见查询及扩展匹配
https://adwords.google.com/select/KeywordToolExternal
百度关键字工具:查询特定关键词的常见查询、扩展匹配及查询热度
http://www2.baidu.com/inquire/dsquery.php


3、进行多重排列组合
改变短语中的词序以创建不同的词语组合。使用不常用的组合。组合成一个问句。包含同义
词、替换词、比喻词和常见错拼词。包含所卖产品的商标名和品名。使用其它限定词来创建
更多的两字组合,三字、四字组合。


4、 毋用意义太泛的关键字。
如果你从事包装机械制造,则选择“机械”作为你的核心关键字就无益于吸引到目标客户。
实际上,为了准确找到需要的信息,搜索用户倾向使用具体词汇及组合寻找信息(尤其是二
词组合),而不是使用那些大而泛的概念。此外,使用意义太广的关键字,也意味着你的网
站要跟更多的网站竞争排名,难以胜出。


5、用自己的品牌做关键词
如果是知名企业,则别忘了在关键词中使用你的公司名或产品品牌名称。


6、使用地理位置
地理位置对于服务于地方性的企业尤其重要。如果你的业务范围以本地为主,则在关键词组
合中加上地区名称如“深圳网站建设”。


7、回顾竞争者使用的关键词
查寻竞争者的关键词可让你想到一些你可能漏掉的词组。但不要照抄任何人的关键词,因为
你并不清楚他们如何要使用这些关键词——你得自己想关键词。寻找别人的关键词只是对你
已经选好的关键词进行补充。


8、不用与自己无关的关键字
总是会有人将热门的词汇列入自己的 META 关键字中——尽管这个热门关键字跟自己网站内
容毫不相干。甚至有人把竞争对手的品牌也加入到自己的关键字中,这不仅侵权,可能被起
诉(国外多起类似案例),并且由于这些所谓“热门”词汇并未在网站内容中出现,因此对
排名并无实质帮助,过多的虚假关键词还可能受到处罚降低排名。


9、控制关键词数量
一页中的关键词最多不要超过 3 个为佳,然后所有内容都针对这几个核心关键词展开,才能
保证关键词密度合理。搜索引擎也会认为该页主题明确。如果确实有大量关键词需要呈现,
可以分散写在其它页面并针对性优化,让这些页面也具有“门页(entry)”的效果。这也是
为什么首页和内页的关键词往往要有所区分的原因。最典型的情况是拥有不同的产品和服务
的情况下,对每个产品进行单网页优化,而不是罗列在一个首页上。


DirectoryEntry使用方法大全、搜索引擎优化的核心:关键字策略(本文完毕)
下一篇:Ajax基础之Javascript篇
上一篇:vbscript函数之语法速查