![在容器化流行之前,共享主机提供商如何确保用户隔离?](https://linux22.com/image/753886/%E5%9C%A8%E5%AE%B9%E5%99%A8%E5%8C%96%E6%B5%81%E8%A1%8C%E4%B9%8B%E5%89%8D%EF%BC%8C%E5%85%B1%E4%BA%AB%E4%B8%BB%E6%9C%BA%E6%8F%90%E4%BE%9B%E5%95%86%E5%A6%82%E4%BD%95%E7%A1%AE%E4%BF%9D%E7%94%A8%E6%88%B7%E9%9A%94%E7%A6%BB%EF%BC%9F.png)
在 2000 年至 2010 年左右,共享主机作为一种廉价的解决方案(有时每月几美元,有时甚至免费,仅几 MB)对于开始使用博客、小型网站(例如使用 Wordpress)的人来说非常流行。
通常有:
- 仅 Apache + PHP + MySQL
- 没有 SSH,只有 (s)FTP 访问
- 大约 100 MB
- 据我记得,他们可能没有为每个帐户创建一个新的虚拟机
问:在容器化/Docker流行之前,各大主机商是如何保证用户隔离的?
他们是否只是ChrootDirectory
在 sshd_config 中使用了不同的用户,例如如何创建隔离/监禁的 SFTP 用户?
+<VirtualHost>
配置如何open_basedir
防止 PHP 代码访问其他账户的文件?
更一般地说,主要的隔离技术是什么,可以防止使用某些恶意 PHP 代码user1234
访问user5678
同一服务器上的文件?
答案1
简而言之,他们很挣扎!
有时,了解一点进化史可以很好地帮助我们了解我们来自哪里以及我们现在在哪里......
简单的网络服务器必须绑定到 IP 地址。
因此,这实际上意味着,如果您将自己限制在一个端口 (80),那么每个 IP 地址 (机器) 只能有一个真实域。但是,您可以指定内容所在的目录,可能是用户 $HOME 目录。
文件访问仅通过用户帐户权限来强制执行。
您的唯一用户标识 (UUID) 将被视为足以区分帐户。
由于 Web 服务器的架构方式,它实际上并不使用传统的用户帐户权限和许可方式,Web 服务器通常以 root 身份运行(在最坏的情况下)或在最好的情况下以低权限用户身份运行。(www-data/nobody)。
网络服务器最好的一点是它可以通过网络传输您想要在浏览器中呈现的文件,而网络服务器的坏处是它也可以传输您可能不想要的文件。(/etc/passwd)。
https://cwiki.apache.org/confluence/display/httpd/PrivilegeSeparation。
然后出现了 apache 虚拟主机指令。这允许 Web 服务器识别客户端 Web 浏览器需要哪个域。
Vhosts 的发明,使得 Web 服务器能够根据主机头名称而不是服务器的 IP 地址来提供文件。
https://httpd.apache.org/docs/current/vhosts/examples.html
FTP/SSH 等文件传输服务通过您的用户名链接到您有权限写入的区域......(这些系统也有自己的安全问题)。
PHP 流行起来的同时,客户对编写活动脚本的需求也迅速增长。他们希望能够在 Web 服务器上动态运行,而且他们现在就想要!
所以,这是一个试图保护 unix 系统的问题,其中所有内容都有效地以相同的 UUID 运行......您是否看到问题开始发生?
这引发了网络服务器安全军备竞赛!!!
发现攻击后,就会部署补丁或处理方法......这通常意味着生产中需要更多的代码......或者在配置方面限制 Web 服务器可以做的事情。
有时这可能是实际代码中的错误,有时配置会导致漏洞被利用。最糟糕的情况是阻止用户访问他们所依赖的某种功能!
Apache 上的 followsymlinks 为什么存在安全风险
因此,主机部署了一个又一个修复程序、一个又一个补丁。与所有安全控制一样,您开始通过配置进行限制,或修补代码以在安全方面“做正确的事情”,您开始破坏兼容性,并开始出现集成问题。
添加更多像 SELINX 这样的军备竞赛技术,尽管您可以创建一个安全的 Web 服务器,但您破坏了太多软件,以至于它变得毫无用处……它要么有效,要么变得难以管理,变得无法管理。现在,将其乘以同一台机器上的 X 个用户……添加的每一层安全性都可能破坏现有的 PHP 脚本,使调试它们变得极其困难。
您可以达到超级安全的程度,但实际上什么都无法运行..... ;-)。
允许客户将自己的脚本上传到机器或存在攻击可以做到同样的事情的漏洞,可能会导致该服务器被控制,允许攻击者不仅控制该帐户,还可以通过将其升级到该机器的 root 权限。
即使是本地权限提升错误也是问题,因为当你运行像 PHP 这样的活动脚本语言时,你实际上是在机器上本地运行。
坏消息是,这一切仍然存在。
好消息是 Docker 和其他容器/虚拟机技术只是将问题转移了。但是,你可以使用更简单的配置,在容器中使用更少的代码来做同样的事情。
此外,配置可以变得更加简单,并且可以实际上有效地管理。
您或许已经明白为什么现在人们不再使用大型的“厨房水槽”网络服务器,也不再在同一台机器上设置数千个账户。
答案2
在共享主机上,你通常只有一个FTP 访问
。您从未获得并且仍然没有获得对实际文件服务器的 SSH 访问权限。数据库如果您购买了,则将分配给您另一台数据库服务器,该服务器不保证位于同一物理主机上。
如果您购买了电子邮件帐户这也不能保证位于任何特定的物理主机上。
托管提供商目前和往常一样管理托管客户的所有流量转发。
大多数情况下,您需要购买领域与您的文件托管一起。
在管理面板您为主机配置了根目录和子域。
如果您的文件位于物理主机上,主机提供商永远不会告诉您该主机的规范名称(如果有的话)。
直到今天它仍然如此运作。
容器化被透明地引入到服务器端的托管客户端。
仍然是经典的 Web 应用程序,例如“WordPress“在此架构上构建。
他们只需要你提供一个FTP 帐户和一个数据库帐户。
容器化主要只会使托管服务提供商受益,因为这样他就可以快速将客户内容透明地移动到客户认为合适的任何地方。
我发现这些安全强化实践即使在容器化的互联网中也始终有效。
在服务器端也有一些安全强化配置系统级别,应该属于任何服务器设置。
互联网攻击的第一道防线是
- 能见度:
和阿帕奇您可以在主配置文件中更改目录浏览功能httpd.conf
:
<Directory "/var/www/html">
AllowOverride None
#Disabling it by commenting
#Options Indexes
</Directory>
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
# "denied" will restrict any call to it from the internet
Require all denied
</Directory>
# Disable Aliases you don't use
<IfModule alias_module>
# ScriptAlias: This controls which directories contain server scripts.
#Disabling it by commenting
#ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
- 访问系统来自 Web 应用
程序PHP您可以使用以下选项禁用允许引擎在系统级别运行的功能disable_functions
:
; This directive allows you to disable certain functions for security reasons.
; It receives a comma-delimited list of function names. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
; http://php.net/disable-functions
disable_functions = escapeshellarg,escapeshellcmd,exec,passthru,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,system
最好的办法是避免克罗恩系统级别的作业。
如果您无法完全避免它们,则它们必须在用户级别作为 FTP 用户运行,sudo ftp_user
或在其自己的定时任务和crontab -u ftp_user
:
# pwd
/var/spool/cron
# ls -alh
insgesamt 12K
drwx------. 2 root root 29 feb 12 18:59 .
drwxr-xr-x. 15 root root 4,0K may 3 2019 ..
-rw-------. 1 ftp_user ftp_user 698 feb 5 10:17 ftp_user
在Web应用程序这一级别还存在一个经常被 Web 开发人员低估的安全风险。
- 在公共目录中写入磁盘
正如@the-unix-janitor之前所指出的以及在引用的答案中提到的那样: https://serverfault.com/a/244612/460989
任何缓存文件必须在目录级别上创建无法访问来自互联网,例如:
-- ftp_user
|-- public_html
|-- index.php
|-- cache
|-- cache_file.txt
这属于 Web 开发人员的职责,因为您可以从 FTP 帐户更改和创建它。
通常WordPress插件开发人员鼓励你给予写访问到目录中的插件wp-content
。但这确实是一种糟糕的做法和糟糕的风格。
- 将缓存内容写入PHP文件
像
cache_file.php
:
<?php
$cache_content = "my cache data";
?>
如果cache_file.php
缓存文件可写,攻击者可以用以下方式替换内容恶意代码您的应用程序将其直接加载到内存中并执行。
已编译枝条模板是PHP应用程序动态生成的代码。它们一定不驻留在您的public_html
目录中。