我必须为我的公司设置一个生产环境,但我在新架构的一个组件上遇到了问题。
我快速绘制了一张图,向您展示今天是如何完成的,以及我认为明天应该如何完成。
一切都使用 Debian。
编辑:所有内容都存储在云中,实际上是在一个小的托管商中,但我计划迁移到 DO
1. 今天
服务器可以访问互联网,并且位于 NAT 后面。
服务器安装了安全堆栈,如该文章末尾所述。
服务器直接在 VM 中安装了软件。
imgur 上的架构
2. 明天
服务器位于私有网络中。Apache
和 MySQL 在 docker 容器内运行。
服务器位于负载平衡器/代理/防火墙后面。
如果需要,我可以运行一组 PHP 容器。
编辑-imgur 上的新架构根据答案
3. 我在哪里
老问题
入口点是我的问题,我不知道要使用哪种软件进行代理/负载平衡。
我真的不明白我是否应该在 Swarm 模式下使用 docker,因为我有两个不同的容器。
我不知道是否应该使用 nginx,因为我已经有 Apache 处理 HTTP 请求。
我不明白容器如何访问互联网以下载配置文件(例如存储在外部 git repo 上的 puppet 文件)。
我实际上读了很多这方面的资料,并试图学习好的做法(如将数据存储在容器之外),但仍然有点不清楚。
我有另一个使用节点运行的应用程序,我想应用相同的模式,只是用 PM2/Node 容器替换 Apache/PHP 容器,这就是我询问负载平衡的原因。我也可能需要为 PHP 应用程序进行负载平衡。
也许我对架构更新完全错了,我应该坚持它今天的工作?但我觉得管理 2 台服务器的安全性更危险,因为我的攻击面更大。
我还听说 CSF 默认会阻止 docker,所以我必须编写额外的规则,我想避免这种情况,但它能在 swarm 模式下与 docker 一起开箱即用吗?
编辑:答案帮助我得出了这一点,如果我错了,请纠正我
安全
如果我理解了您的信息,我应该按照 2 中的模式进行设置。
首先,我用防火墙过滤所有传入的 TCP/UDP 连接,阻止尝试扫描端口的 IP 等……
然后我得到了我的代理,它将根据我访问的端口将 SSH/HTTP/SFTP 路由到正确的容器。
由于 traefik 可以监控群,我猜它足以关注正在发生的事情。
我希望仅通过 SSH 隧道对我的 DB VM 进行 SSH 访问,以避免暴露从代理到 DB VM 的路由。(我知道如何做到这一点)
扩展
通过使用 traefik,我现在能够添加一个协调器服务器并添加我需要扩展的任意数量的 Apache + PHP 容器。
监控
Traefik 提供了监控管理服务的好方法。
日志被发送到 ELK 堆栈进行可视化。我还考虑将安全日志发送到 ELK 堆栈。
听起来不错 ?
4. 附录 - 安全堆栈
请原谅我在安全方面的知识匮乏,我已尽力而为。
- CSF + LFD
- 无人值守升级
- clamav
- rkhunter
- logwatch
- fail2ban
- psad
- 无 ssh root 登录 + 端口敲击
答案1
你的主要目标是什么?
表现
如果您的目标是性能,并且可以节省一些离线时间,那么您当前的设置就没问题,Quintiliano 关于在容器中使用数据库的评论可能成立。虽然使用 Apache 作为反向代理很容易管理,但为了获得更好的性能,您可以检查 HAProxy(这并不难,但需要时间来习惯它)。为了提高性能,您可能需要 2 个或更多服务器和一个负载均衡器(对于单个服务器,负载均衡器毫无意义)。如果您的连接良好,则可以使用网络接口绑定来加倍连接速度。
安全
您可以在代理前添加路由器来提高安全性(专业版 - 昂贵 - 或经济但功能齐全,例如 ubiquiti、mikrotik 等)。您需要知道如何设置它并保护您的私人网络。在安全性方面,最好在容器中运行数据库并牺牲一些性能。您也可以在容器中设置代理。我建议检查特雷菲克这是一个易于使用的代理/负载平衡器。你说得对,单台服务器比两台服务器更容易维护。
冗余(故障安全)
如果您想要的是零停机时间,则需要更改设计。您至少需要 2 个路由器并设置 VRRP。您需要设置网络接口绑定并至少拥有 2 台服务器(越多越好)。您在路由器中设置将奇数 IP 发送到其中一个服务器,将偶数 IP 发送到另一个服务器(这样您就不需要同步会话),并将负载平衡您的连接。您需要一种方法将文件从一台服务器同步到另一台服务器(以防文件上传等)。我建议使用齐奏,但我使用的是 LXD 而不是 docker,所以我不确定这是否适用于你的情况。对于数据库,最好将它们放在集群中,检查加莱拉和最大尺度。通常至少需要 3 台服务器,但如果您使用加莱拉仲裁员
这只是其中一种方法,还有很多条路可走,这是我个人的解决方案。
更新(关于安全)
说真的,如果这些业务数据泄露,会有多严重?您说会“致命”,但事实确实如此?我之所以问您这个问题,是因为如果事情真的那么重要,那么您就不应该自己做,而应该找一个专业团队或安全顾问。无论您多么严格,如果经验不足,总会犯错(如果您在这个网站上提问,是因为您没有经验,对吗?)。别误会我的意思,如果这些数据泄露,谁会为此负责?就我个人而言,我不管理绝密,所以只要我尝试遵循并应用高于标准的安全措施,我认为就足够了。从我在您的安全列表中看到的内容来看,您几乎涵盖了我通常所做的工作,到目前为止,我还没有遇到任何安全漏洞(据我所知:P)。
我还有一些可以改善您的设置的建议:
1)数据保护:请查看使用 MariaDB 加密静态数据。这是一种非常简单的数据加密方法。它的主要好处是,如果您的数据库文件被泄露,没有密钥它们就毫无用处。如果将密钥存储在内存中会更好,因为它不会存储在快照或备份中,缺点是您每次启动数据库时都必须输入该密钥。如果有人可以访问正在运行的实例(这是入侵数据库的最常见方式),这种加密方法对您没有帮助。
2)应用:我猜你最薄弱的环节是在应用程序层。你必须确保你的代码得到很好的保护,并且不容易受到XSS、SQL注入或类似攻击。如果你不能100%地做到这一点,最好将非常重要的数据尽可能远离你的应用程序。确保你添加更多的保护层(如额外的身份验证、数据库中的值加密等)。
3)加密目录:加密目录通常对服务器被盗或有人以非 root 用户身份获得访问权限的情况很有帮助。
4)备份:留意备份和快照的存储位置。它们和数据库一样重要。如果您的服务器感染了勒索软件(是的它可能发生在 Linux 中(同样),您的备份可以帮助您挽救局面。最好将它们保存在安全的位置(受限制、加密,如果可能的话,不可更改)。
5)本地网络:确保您的服务器与本地网络隔离。不要假设您的本地网络是安全的,因此不要为本地客户端授予特殊权限。将您的服务器视为隔离在远程位置并且只能通过互联网访问,这样您就只能保护单个入口点。
6)SSH:如果您仍在使用 ssh 端口 22,请更改它。我建议除了使用 ssh 密码外,还使用客户端密钥(以及用于敲击端口)。
7)密码:确保使用经过充分测试的密码管理器应用程序来保护所有服务器密码的安全。如果您的个人计算机被黑客入侵并且这些密码被泄露,那么无论您在这个安全方案中添加多少内容都没有用。因此,请保护您的个人计算机和服务器。(您使用的是强密码,对吗?)
8)后门:我被锁定的情况已经发生过好几次了!所以请记住,这也可能发生在你身上。如果你打开了访问服务器的其他方式,请确保这些方式与主要方式一样强大。如果你可以物理访问服务器,你就不必太担心。
9)防病毒:不要太过信任clamAV
。这不是一个糟糕的软件,但你不会得到与商业解决方案相同的保护。我在我的邮件服务器和一些文件服务器(Samba)中使用它来阻止众所周知的 Windows 病毒,但当遇到新威胁时,我不会指望它。最好不要假设它会保护你。正如你所知,只有很小的已知 Linux 恶意软件列表,因此,如果您因 clamAV 而遇到性能问题,那么没有它可能不会对您的安全性产生太大影响(如果您已经通过许多其他方式保护您的服务器)。如果您想要一个商业解决方案,Sophos 和 ESET 是不错的选择。如果您真的想掌控服务器的所有威胁,您可以尝试 AlienVault(但您需要一台额外的服务器才能实现这一点)。
关键问题:(如果有人……会发生什么情况)
* gains access to the DB through my applications?
* gains access the containers?
* gains access to the servers as user?
* gains access to the servers as root? <-- usually this is gameover
* stole the server?
* has access to the local network?
* gains access to my 'development' computer?
我知道这里提到的很多要点您已经做到了,但我不想假设任何事情。我希望您觉得我的见解有用,如果您有任何其他我在这里没有提到的建议,我希望听到。
答案2
这是我的意见。
首先,我认为第二种方法很好。您只有一个暴露的服务器,从安全角度来看,更容易维护您的环境。此外,使用第二种方法,也更容易扩展。
我不会做什么。
在容器中使用 MySQL。我知道 docker 是部署的绝佳解决方案,用它完成任务非常快,但我对 Docker + 数据库的体验并不好。当您使用 Docker 部署 MySQL 节点时,您应该确保 MySQL DB 文件的外部持久性存储,如果磁盘和网络硬件不正确,在应用程序高负载时很容易出现问题。我更喜欢为 DB 专用一个好的 VM(如果需要,可以有多个),并使用 docker 生成大量连接到此 DB 的应用程序服务器。它还可以解决 docker swarm 中 2 种 VM 类型的问题。此外,由于您使用的是 puppet,因此您可以像 docker 一样轻松地提供一个新的 DB 节点。
我会做什么。
这只取决于你对工具的熟悉程度和学习新事物的时间。如果您的网站流量较低 < 10k 请求/秒,那么开箱即用的 Apache 是一个不错的工具。它易于配置和维护,几乎每个人都知道如何处理它。随着负载的增加,您应该寻找更强大的解决方案。我是 HAproxy 的忠实粉丝。已经使用了近 6 个月,我爱上了它。它既可以用作 L7(作为 HTTP 代理),也可以用作 L4(作为 TCP 代理,例如:MySQL 负载平衡器)代理/平衡器,具有大量选项,并且比 Apache 轻量级得多。只要您掌握了窍门,它就不会太难,并且您可以轻松地扩展它以处理大量连接。
Apache 和 HAproxy 都支持负载均衡算法,在 PHP 节点之间共享负载。您可能需要 Memcache/Redis 来进行会话/缓存分配,但这并不难实现。使用代理作为瓶颈,您还可以将其用作 TLS 卸载,从而减少 PHP 节点的使用。
就像在您的 PHP 节点中一样,使用 Apache 和 Ngnix 完全取决于您。同样,使用您有知识和经验的工具。两者都是适用于 PHP 的出色服务器。
至于节点获取配置的问题,您的代理也可以作为内部网络的网关。负载的增加将是最小的(通常您在生产时间后对站点进行更改)。如果您确实需要传输大量文件/配置,我建议您安装 GIT/SVN 或您在站点内使用的其他存储库。使用这种方法,您只需将文件从 DEV -> PRODUCTION 传输一次,然后让 puppet 或任何其他工具为您 LAN 内的服务器提供服务。根据您的环境规模,这是一个巨大的胜利。
最后,关于安全方面。你总是可以使用老牌的 Iptables 来控制代理和内部服务器,再加上一些 WAF(Web 应用程序防火墙)。由于 iptables 只允许在 Web 端口进行连接(我会过滤 ssh 以用于 VPN 内的特定来源/隧道),因此你的攻击面将是应用程序。WAF 实施起来可能真的很麻烦,但这是一种可行的方法。你也可以为此寻找设备和专有解决方案。将你的应用程序日志集中在 ELK 或 Gray Log 之类的东西中,最重要的是,监控所有事物的性能和问题,从磁盘、内存和磁盘使用情况,到每个代理和服务器上的链接和连接。这样,你可以在客户开始抱怨之前评估你的网站性能并预测任何需要的升级(始终为最高负载做好准备)。我喜欢 Zabixx 来扮演这个角色。
我希望它对你有帮助。
[]`
答案3
给出的两个答案都很棒。
我想在这里补充一点关于安全方面的信息。
主要问题是DOCKER。
使用 docker,安全责任就从你转移到开发团队。这称为DevOps。
问题可能在于开发团队对补丁、当前 Java 版本等的安全意识不够(所有这些都是管理员关心的东西,但没人注意到)。
解决方案就是培训开发人员适应他们的新角色。
由于这是一个容易出错且耗时较长的过程,因此最好使用相应的技术支持。这在 Docker 上下文中称为DevSecOps。
市场上有一些产品可以与 Docker 集成并寻求安全性(完全自动化),直到它们丢弃不提供指南所设置的安全性的 Docker 容器。
这可能有助于过渡过程。