1. 前言
随着.NET技术日新月异的发展和Windows2003的推出,越来越多的人开始熟悉和使用.NET开发的产品。我们的程序员在开发.NET的程序的过程中往往忽略了安全的重要性,认为只要能运行就是好产品,或者盲目的把安全推给.NET环境来解决。这是完全错误的。.NET环境提供了一整套安全防护措施,我们必须合理的运用这些安全措施并贯穿于开发和部署的每一个环节,才能达到所预期的安全效果。
本文中我们所提到的安全主要是针对于利用.NET技术开发的、基于三层架构的应用程序(3-tier application)。先简单介绍一下利用三层架构开发的应用程序。
本文适合于熟悉.NET开发,熟悉SQL Server 2000,并装配Windows 2003的读者。
2. 三层架构应用
三层架构的全称是“Three-Tier Application Using an XML Web Service”详情请见MSDN。究竟三层是指哪三层?第一层:客户端应用层(包括浏览器页面)。第二层:Web Service层。第三层:数据库层。详见图一。
(图1)
这样做的好处是:
1.开发者可以快速简单的开发程序。
2.使用者可以在任何可以连接到Internet的地方适用应用程序。
3.数据访问层集中在Web Service上便于更新维护,不用升级客户端。
4.数据访问与前台实现隔开。
3. 本文演示程序简述
由于本文讲述的是如何安全的部署.NET三层应用,而不是如何开发。所以这个演示程序就不做详细介绍了。这是从数据库中列出所有顾客并能查询每个顾客订单的小演示程序。
文件目录:
根目录 \demo
子目录 \demo\demo_Client Application 客户端应用
\demo\demo_Database 数据库
\demo_WebService Web 服务
注:由于强调安全性,所以与数据库的交互全部由存储过程实现。点击此处下载演示程序。
客户端如下图二:
(图2)
4. 配置你的系统
4.1. 总述
安全的体系结构,访问权限要责任明确,尽量使用专用身份进行访问,而且应该将权限设置为“恰好够用”的最小授权。主要从四个方面考虑。
(1).客户端匿名用户以IUSR_MACHINENAME的身份访问IIS。
(2).IIS以Application Pool设定的身份(默认情况下,NT AUTHORITY\Network Service)的身份执行Web Service。
(3).如果没有发生新的角色扮演,或者在web.config中进行配置,则Web Service以执行它的身份访问SQL Server。
(4).SQL Server以某个特定的受限用户身份(在我们的例子中,_SQLSERVER_)访问资源。
4.2. 为SQL Server 2000单独建一个用户
4.2.1. 原因
在Windows中系统为IIS建了两个帐户,IUSR_MACHINENAME(Internet 来宾帐户)、IWAM_MACHINENAME(启动IIS进程帐户)。这样做的好处是,由于这两个帐户的权限很低(通常只能访问IIS)所以即使IIS被入侵,可以把损失降到最低。
在SQL Server中却没有类似的专用帐户,在安装SQL Server的时候通常设定SQL Server的访问资源的帐户是以本地系统(NT AUTHORITY\LOCAL SYSTEM)身份,这一身份拥有比Administrator更多的特权。这样给SQL Server的权限实在太高了,一旦被攻陷,后果不堪设想。
我们可以手动为SQL Server建立一个用户并给它最低的权限(指给它访问数据库文件的权限)。现在我将从头开始建立。
4.2.2. 新建用户
新建用户如图三所示:
(图3)
注:
1. 这是标准的Windows 2003 的新建用户对话框
2. 用户名可以随便起,这里用_SQLSERVER_,全称是SQL Server Jail User意思是这个专用用户被关进了“监狱”。
3. 密码应该尽量长(64字节以上),尽量复杂(包含大小写、数字、特殊符号等,最好是随机生成)。Don’t panic这个密码一共只用一次,所以最好先记在文档里。
4. 同时选择用户不能更改密码和密码永不过期两项。
4.2.3. 给这个用户配权限
修改权限如图四:
(图4)
注:
1.右键点击_SQLSERVER_用户,选择属性。
2.进入“隶属于”页,将Users组删除。这样_SQLSERVER_就不属于任何组了,这个用户没有任何权限。注意:对于Windows 2000来说,由于所有驱动器上默认的Everyone完全控制授权,需要进行一些额外的配置。
4.3. 建议重装你的SQL Server
4.3.1. 原因
重新建立安全的SQL Server。确保SQL Server以SQL Server Jail User 身份访问计算机资源。确保SQL Server只信任命名管道等。所以建议重装SQL Server。
4.3.2. 修改SQL Server服务帐户
在安装SQL Server的过程中有一步是指定SQL Server 服务是以什么身份运行。如图五:
(图5)
注:
1.这里把我们刚才添加的SQL Server Jail User 添加为Services Accounts。
2.在Username中填入“_SQLSERVER_”;在Password中将密码复制过来。
3.彻底删除记录密码的文件,这个密码只用一次。这个用户就像被关进了SQLSERVER监狱中了,除了SQL Server没有程序可以使用它。
4.点击Next
4.3.3. 指定SQL Server登录验证模式和网络连接方式
如图六、图七所示:
(图6)
注:
1.我们不信任SA的登录模式,只信任windows身份验证模式
2.SA身份有很多缺点:(1).SA身份没有过期时效。(2).SA身份没有用户锁定,这样SA口令最终总能被穷举出来。(3).SA身份的权限太高,一但SA密码被获取,则可以以SQL Server的身份运行任何程序。
(图7)
注:
1.不信任除命名管道以外的任何网络连接
2.将默认选中的TCP/IP Sockets取消(如果需要在分布式环境中运行,则应配置Active Directory域)。
3.原则是除非必须需要其他的连接,否则请不要选
4.3.4. 安装SQL Server SP3
在安装SP3的时候有一步会提示你必须指定SA密码,因为在安装SQL Server的时候不允许以SA身份登录,所以SA密码为空。SP3认为SA密码为空是不安全的(即使SA不能用作登录)。我们要做的就是输入一串尽可能长且复杂的密码。
5. 开始部署demo程序(将权限配的最小)
5.1. 部署之前
5.1.1. 将demo目录复制到“C:\sample\”目录下
5.1.2. 先配最小权限
修改sample目录的安全,使sample目录及所有子目录和文件只能被administrators组的成员完全控制。其他默认访问控制删除。如图八。
(图8)
注:
1.右键单击sample文件夹,点“属性”;选择“安全”页。默认有四种身份可以访问该文件夹。再点击“高级”如图八。
2.将“允许父项的继承权…… ……”复选框的勾取消。这样会弹出一个对话框,点击“删除”按钮。
3.这样就将所有从父目录继承的权限删除了。只剩Administrators组有访问权限。
如图九:
(图9)
5.1.3. 附加数据库(attach database)
在SQL Server企业管理器中附加数据库,在选择数据库的时候会发现,File Browser无法遍历进Sample文件夹。这是由于SQL Server 是以_SQLSERVER_身份运行的,而_SQLSERVER_身份无法访问Sample文件夹和数据库文件,接下来要给_SQLSERVER_遍历文件夹的权限和完全控制数据库文件的权限。
同样,在sample“属性”的“安全”中,点击“高级”,弹出“Sample的高级安全设置”的对话框,点击“添加”,输入“_SQLSERVER_”点击“确定”按钮 ,在权限项目表中选择“_SQLSERVER_”,点击“编辑”按钮,弹出“权限项目”设置对话框。在“应用到”下拉框中选择“只有该文件夹”;在“列出文件夹/读取数据”复选框后选择“允许”。按“确定”退出。如图十。
按照此方法依次将sample,demo,demo_Database文件夹配权限。
最后给数据库文件“demo_DB_Data.MDF”和“demo_DB_Log.LDF”配权限,在这里由于SQL Server需要对这两个文件进行各种操作,所有应给_SQLSERVER_身份配完全访问权。与上述分配权限方法雷同,在最后一步选择“完全控制”。如图十一。
回到SQL Server 企业管理器中就可以附加数据库了。将Special Database Owner设为_SQLSERVER_。如图十二。
(图10)
(图11)
(图12)
5.2. 部署Web Service
5.2.1. 为Web Service新建一个应用程序池(application pool)
我推荐至少为每一个Web Service建立一个应用程序池。在IIS 6.0中建立一个应用程序池非常简单。启动IIS6.0,右键单击“应用程序池”,选择“新建”“应用程序池”,则弹出添加应用程序池对话框,输入应用程序池名称。如图十三。
(图13)
给AppPool-Demo应用程序池配权限,右键单击“AppPool-Demo”选“属性”弹出属性对话框。在这里可以设置一些应用属性。我们关心的是“标识”页,确保应用程序池安全帐户的预定义帐户是“网络服务”(即Network Service帐户)。如图十四。
(图14)
5.2.2. 给Web Service添加虚拟目录
虚拟目录名为demo,对应的路径是“C:\sample\demo\demo_Webservice”。新建虚拟目录就不再详述了。
现在给虚拟目录配权限,由于IIS以Application Pool 设定的身份(Network Service)的身份执行Web Service。所以应该给Network Service访问和运行虚拟目录的权限。
在IIS中右键单击demo虚拟目录,选择“权限”,则弹出该目录的安全设置对话框。添加“Network Service”帐户。并选择“读取和运行”的权限。如图十五。
给Web Service一个应用程序池,右键单击demo虚拟目录,选择“属性”。在“应用程序池”下拉框选择刚才建立的应用程序池(AppPool-Demo)。
现在试试Web Service是否可以正常工作了。在IIS中单击“demo”虚拟目录,在右边的文件列表中,右键单击“demo.asmx”选择“浏览”。检查Web Service是否正常。如图十六表示Web Service正常。若不正常请检查上述的每一步。
(图15)
(图16)
5.3. 配置数据库
5.3.1. 添加访问数据库用户
打开SQL Server企业管理器,展开Demo_DB树,右键点击“User”。选择“New Database User”,则弹出新建用户对话框,在“Login Name”下拉框中选择“New”,则又弹出一个对话框,手动向“Name”下拉框中填入“NT Authority\Network Service”。(说明:在SQL Server中必须手动填写全称,不能搜索此用户。对此,我也表示不解)。选择数据库为“demo_DB”。点击“确定”按钮。如图十七
则退到第一个对话框中,在“Login Name”下拉框中选择“NT Authority\Network Service”并给与“Public”权限。点击“确定”按钮。
(图17)
5.3.2. 为这个用户配权限
在SQL Server 企业管理器中展开“demo”数据库目录,点击“Users”,在右边的用户列表中右键单击“NT Authority\Network Service”,选择“属性”弹出对话框,点击“Permissions”按钮,则弹出权限对话框,将程序的两个用户定义的存储过程的“EXEC”权限点成“允许”。如图十八。
说明:一个安全的应用程序,所有对数据库表和视图的访问都应该由存储过程来处理。所以我们在设置权限的时候应该只给访问存储过程的权限,不给访问表和视图的权限。在数据库中认为只要不画勾,就认为没有权限访问,所以,只给两个存储过程画勾。
(图18)
6. 运行客户端程序
6.1. 运行
这个时候会发现程序无法运行,弹出一个error对话框,如图十九。
(图19)
这是由于客户端程序是以IUSR_MACHINENAME的身份访问的网络资源,在Web Server以Application Pool所指定的身份运行前,IIS是以IUSR_MACHINENAME的身份读取服务器资源的,直到IIS发现所请求的资源是Web Server程序,便以Application Pool所指定的身份执行Web Server。所以我们要向Web Server加入IUSR_MACHINENAME的可读取权限。如图二十。
(图20)
注:
1.在IIS中右键单击demo虚拟目录,选择“权限”,则弹出该目录的安全设置对话框。添加“IUSR_MACHINENAME”(每台计算机的名称会有所不同,一般是IUSR_加上主机名)帐户。并选择“读取”的权限
2.运行客户端。看看是不是可以运行了,若有错误,请详细检查上述的每一步。