为什么不建议在同一台机器上放置数据库和Web服务器?

152
听了Scott Hanselman与Stack Overflow团队的采访(第一部分第二部分),他坚持认为SQL服务器和应用程序服务器应该在不同的机器上。这样做只是为了确保如果一个服务器被攻破,两个系统都不会被入侵吗?对于小型应用程序,安全问题是否超过了两个服务器的复杂性(额外成本、两者之间的专用网络连接、更多维护等)尤其是当两个部件都没有使用太多的CPU或内存时?即使有两个服务器,如果其中一个服务器被攻破,攻击者仍然可以通过删除数据库或干扰应用程序代码来造成严重的损害。

如果性能不是问题,为什么这会成为一个大问题呢?


我相信这个帖子和问题完全忽略了一个非常重要的问题,这个问题会完全颠覆这个建议。如果你可以获得数据库凭证但无法访问服务器怎么办?如果数据库和应用程序都托管在同一台机器上,你可以禁止任何外部访问数据库,因此仅拥有数据库凭证并不能授予你任何访问权限,你需要服务器访问权限。如果你问我的话,这是少了一个安全问题。 - Tofandel
@Tofandel,我们可不可以在保留您提出的安全性好处的同时,通过告诉数据库仅接受来自Web服务器的连接,来保留本帖中其他地方概述的将DB/Web服务器分开的好处呢?这样,我们就有了两台机器和所有与此分离相关的好处,如果攻击者没有控制Web服务器,泄漏的DB凭据也只能用于恶意目的。 - Nick Muise
19个回答

188
  1. 安全性。您的Web服务器位于DMZ中,可由公共互联网访问,并从匿名用户接收不受信任的输入。 如果您的Web服务器被攻击并且您在连接到DB时遵循了最低特权规则,则最大暴露面是您的应用程序可以通过数据库API执行的操作。 如果您之间有一个业务层,则在攻击者和数据之间多了一步。 另一方面,如果您的数据库在同一台服务器上,则攻击者现在具有对您的数据和服务器的root访问权限。
  2. 可扩展性。使Web服务器无状态允许您轻松地水平扩展Web服务器。 要水平扩展数据库服务器非常困难。
  3. 性能。 2个盒子= 2倍的CPU,2倍的RAM和2倍的磁盘访问轮毂。

所有这些都说过后,我当然可以看出没有这些点真正重要的情况。


40
但使用2台机器会使硬件故障的概率增加一倍 ;) - TWith2Sugars
5
@TWith2Sugars - 与什么相反? - Kev
5
@Noelie - 您的 Web 层不能执行一些操作,如使用 xp_cmdshell 将数据库备份到文件并将该文件上传到 ftp.hackers.com,也不能删除数据库,修改配置值等。 - Mark Brackett
4
@MarkBrackett,但这就是我想说的:“最小权限”仍然足以控制您的数据库。为什么系统访问比数据库访问更有价值?数据库是每个人追求的目标:它包含私人用户信息,如密码、信用卡等。你想要系统访问而不是数据库访问的唯一原因是改变网站或者根据公司的不同情况下载私有源代码(但这是一个不同的问题)。我所描述的都不需要糟糕的设置,只需要泄露的数据库用户名/密码(和地址),如果Web服务器被攻击,则可获得这些信息。 - chacham15
7
@kirgy - 由于这两台机器是并联的,并且每台机器都是单点故障,因此整体可靠性较低;虽然不是技术上的翻倍(实际上是 1 - (r1 * r2)),但对于大型可靠性和小节点足够接近了... 在0.01%的情况下,它将是0.0199%。但对于100个节点,它将是36.6%,而不是翻倍声明所暗示的100%。 - Mark Brackett
显示剩余14条评论

68

它其实并不重要(你可以很愉快地在同一台机器上运行网站和数据库),这只是扩展的最简单步骤。

这正是StackOverflow所做的-从单台运行IIS/SQL Server的机器开始,然后当其开始承载大量负载时,购买第二台服务器并将SQL服务器迁移到其中。

如果性能不是问题,请不要浪费金钱购买/维护两个服务器。


5
我同意,当负载较低时可以完成...随着负载的增加,很容易将它们分成两台或更多台机器。 - E.J. Brennan
8
我来了,本来想评论同样的事情。在大多数情况下,切换数据库服务器只需更改连接字符串即可,非常容易。 - CitizenBane
1
哦,我喜欢这个。有人在提出解决方案之前考虑上下文! - demisx
这是正确的答案。从单个服务器开始,只有当您的服务器无法处理负载时才移动您的数据库。 - HamsterWithPitchfork

24

另一方面,提到不同的博客作者Scott(Telligent的Watermasyck),他们发现大多数用户可以通过将数据库放在与网站相同的机器上(使用Telligent的Community Server)来加速网站。然而,在他们客户的情况下,通常数据库和Web服务器是该机器上唯一的应用程序,并且网站并没有使机器过度紧张。然后,不需要跨网络发送数据的效率弥补了增加的压力。


4
直到并发使用增加,数据库服务器需要更多内存来有效利用缓冲区和缓存。一旦Web /应用程序和数据库服务器需要比单个服务器所能承受的内存更多的内存,分页和磁盘I/O就会增加,性能就会下降。 - kermatt
@MattK - 但是如果你有大量的内存怎么办?我们有一个应用程序,每个客户端都有自己的数据库,因此数据库和Web服务器都可以很容易地进行水平扩展。考虑到我们使用的内存比磁盘多(64GB vs. ~40GB),将它们全部放在同一台机器上是否更有利于性能? - Beep beep
1
如果您的工作集适合内存,则可能不会出现我提到的任何性能问题。更常见的情况是服务器的磁盘比内存大,但在您的情况下,您似乎有可以完全适合内存的数据库——只要共享服务器上的应用程序不会消耗太多内存。 - kermatt

17

Tom在这方面是正确的。其他一些原因是,它不具备成本效益,并且存在额外的安全风险。

Web服务器与数据库服务器有不同的硬件要求。数据库服务器需要大量内存和快速的磁盘阵列,而Web服务器只需要足够的内存来缓存文件和频繁的数据库请求(取决于您的设置)。关于成本效益,这两个服务器不一定会更便宜,但性能/成本比应该更高,因为您没有两个不同的应用程序竞争资源。因此,您可能需要花费更多的钱购买一个既适合两者又提供与两个专门服务器等效性能的服务器。

安全问题是,如果单台机器被攻击,Web服务器和数据库都容易受到攻击。有了两个服务器,您就有了一些喘息的时间,因为第二个服务器仍然是安全的(至少一段时间)。

另外,还有一些可扩展性好处,因为您可能只需要维护几个数据库服务器,由许多不同的Web应用程序使用。这样,您需要做的升级或修补程序以及性能调整的工作就会更少。我相信,在单台机器的情况下,有一些服务器管理工具可以使这些任务更容易。


3
如果你运行的不是存储过程,那么你的 Web 服务器很可能已经完全访问了你数据库中的数据。 - George Mauer
为什么它不具备成本效益?请具体说明。 - Robert Jeppesen
Robert,我进一步扩展了这个话题,并加入了关于可扩展性和维护方面的评论。 - Dana the Sane

16

我认为最重要的因素应该是性能。无论是Web服务器/应用程序代码还是SQL Server,都将在内存中缓存常请求的数据,如果它们在同一个内存空间中运行,则会降低缓存性能。


14
如果你有一个相对较小的数据库,但是内存很大呢?如果每次调用数据库都要通过网络传输,特别是当调用次数很多时,这样做的成本是否超过了收益? - Beep beep
1
@Tom Ritter 尽管性能是一个问题(根据这个答案和 Mark Brackett 答案中的第三点),但我知道有些人(包括我在内)可能会把不购买单独的数据库服务器所节省的钱投入到替代它的唯一服务器上的更多 CPU/RAM 等硬件资源中。因此,这应该考虑在内。至于分离的内存,IIS 和 SQL 可以配置以考虑它们之间的资源竞争。就我个人而言,“关键”的是 Mark 的第一点... 安全性。我喜欢受到攻击的 Web 服务器对单独的数据库服务器的有限访问权限的想法。 - Dylan - INNO Software
@Tom,你可以将内存空间分成两个独立的单元。一个用于服务器,另一个用于数据库。 - Pacerier

11
安全性是一个重要的问题。理想情况下,您的数据库服务器应该位于防火墙后面,并只开放执行数据访问所需的端口。您的Web应用程序应该使用一个SQL帐户连接到数据库服务器,该帐户具有足够的权限让应用程序正常运行,但不会赋予过多权限。例如,您应该删除允许删除对象的权限,肯定不应该使用像'sa'这样的帐户进行连接。
如果您失去了Web服务器(比如完整的特权升级为管理员权限),最坏的情况是您的应用程序数据库可能会受到影响,但不会影响整个数据库服务器(如果数据库服务器和Web服务器是同一台机器,则会出现这种情况)。如果您已加密您的数据库连接字符串并且黑客无法熟练解密它们,则您失去的仅是Web服务器。

但是你备份了数据库,对吧?否则,由于硬件故障或极少出现的错误,你将面临同样的风险。攻击会导致网站宕机。拥有足够的权限向表中添加记录就足以使网站无法使用。 - Daniel Earwicker
当然你会备份数据库,这是显而易见的,我在帖子中哪里暗示了相反的意思。 - Kev
1
是的,但因此得出的结论是,旨在使网站崩溃的攻击可以通过破坏Web服务器配置或数据库来实现,而解决方案对于两者都是相同的:从备份中恢复。特别保护数据库是不必要的,并且无论如何都是不可能的。 - Daniel Earwicker
@Earwicker - 那其他存储在数据库服务器上的所有其他数据库呢?你只丢失了一个数据库。 - Kev
8
Besides Daniel,你忽略了一个非常重要的问题。这不仅仅是关于数据库备份,而是关于被泄漏的数据。如果有人告诉你:“黑客偷走了你所有的客户和销售数据,但别担心,我有备份。”,你的客户会满意吗? :) - Dylan - INNO Software

10

还没有提到的一个因素是负载均衡。如果你把网页服务器和数据库视为两台不同的设备,你可以优化网络传输次数,并且在需要增加第二个网页服务器或第二个数据库引擎时也更容易操作。


9
我同意Daniel Earwicker的观点——安全问题基本上是有缺陷的。
如果您只在一个服务器上设置了一个Web服务器,并且只有该Web服务器的数据库,那么如果该Web服务器受到攻击,您将失去该特定应用程序的Web服务器和唯一的数据库。
这正好与在2台服务器设置中失去Web服务器时发生的情况相同。您会失去Web服务器和仅针对该特定应用程序的数据库。
在2台服务器设置中,“DB服务器的其余完整性得到维护”的论点是不相关的,因为在第一种情况下,与其他任何应用程序相关的每个其他数据库服务器(如果有的话)也保持不受影响,因为它们被托管在其他地方。
类似地,对于Kev提出的问题“关于驻留在DB服务器上的所有其他数据库怎么办?你失去的只是一个数据库。”:
如果您在一个服务器上托管应用程序和数据库,则只会在该服务器上托管与该应用程序相关的数据库。因此,在单服务器设置中,与多服务器设置相比,您不会失去任何其他数据库。
相比之下,在2个服务器设置中,如果攻击者可以访问Web服务器,并通过代理(在最佳情况下)访问数据库服务器的有限权限,则可以通过执行缓慢、占用内存的查询或最大化数据库服务器上的可用存储空间来使每个其他应用程序的数据库处于风险之中。通过将应用程序分离为其自己的问题,就像虚拟化一样,您还可以以积极的方式将它们隔离起来以保证安全性。

7

我可以从第一手的经验中讲述:将Web服务器和数据库放在不同的机器上通常是一个好主意。如果您有一个资源密集型的应用程序,它很容易导致机器的CPU周期峰值,从而基本上使机器停止运行。但是,如果您的应用程序对数据库的使用有限,那么它们共享一个服务器可能不是什么大问题。


7
哇,没有人提到这样一个事实:如果你真的花了5千美元购买SQL Server,那么你可能希望将其用于更多的应用程序。如果你使用的是Express版本,也许你不在意。我看到SQL Server运行20到30个应用程序的数据库,所以把它放在Web服务器上并不明智。
其次,这取决于服务器是为谁服务的。我为金融公司和政府工作,因此我们采用一种繁琐的方法,只使用存储过程并限制从Web服务器到SQL的端口。因此,如果Web应用程序被黑客攻击,黑客唯一能做的就是调用存储过程,因为Web服务器上的用户账户被锁定,只能查看/调用DB上的存储过程。现在黑客必须想办法进入数据库。如果它在Web服务器上,那么很容易接近它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接