安全说明
TeamCity 是在考虑安全问题的前提下开发的。 我们会尽合理的努力确保该系统能抵御各种类型的攻击。 我们与第三方合作,使用安全扫描器和渗透测试来评估 TeamCity 的安全性。 新发现的安全问题会在最近的错误修复版本中得到及时解决(有关我们的发布周期的更多信息,请阅读更多)。 建议您一旦有新版本的 TeamCity 发布,尽快升级到最新发布的 TeamCity 版本。
但是,一般假设和推荐的设置是在受信任的环境中部署 TeamCity,确保无恶意用户能够访问它。
除了这些指导方针,请查阅有关配置 TeamCity 服务器以用于生产使用的 注意事项。 要查看已披露的安全相关问题清单,请参阅 JetBrains 安全公告 以及发布说明中的 "安全" 部分。
我们还建议您订阅 安全通知服务,以获取可能影响 TeamCity 或其他 JetBrains 产品的最新安全问题信息。
推荐的安全实践
这一部分包含了使用 TeamCity 时应遵循的主要安全建议。
凭据
使用强大的凭证,并且谨慎使用它们。
我们建议不仅对您的 TeamCity 服务器使用强大的凭证,而且对所有参与构建或者您的软件在生产中所需的其他服务也要使用强大的凭证。
确保尤其不要将您的凭证暴露在以下情况中:
代码库,例如 GitHub 和 GitLab。
环境变量,因为它们经常会被记录或与第三方监控系统共享。
确保您不会随意记录敏感信息的 构建日志。
如果您正在使用版本设置(在 Kotlin DSL 或 XML 格式中),请绝对不要在您的配置文件中储存您的认证信息。 相反,使用 tokens。
具有管理权限的 TeamCity 用户应该使用复杂的密码。
为了使用户密码存储更安全,TeamCity 使用了 BCrypt 散列算法。
考虑禁用超级用户访问权限。
在 TeamCity 中的 超级用户访问权限 功能,让用户可以使用在 <TeamCity_server_home>/logs/teamcity-server.log 文件中找到的令牌登录为系统管理员。
如果您将 TeamCity 日志发布到外部源,请添加 teamcity.superUser.disable=true
内部属性以禁用此授权选项并防止不必要的管理员访问。 修改 teamcity.superUser.disable
属性后,重启 TeamCity 服务器以使更改生效。
使用"password"类型的参数存储安全数据。
在 TeamCity 设置中存储密码或其他安全数据时,强烈建议您使用 typed parameters。 这将确保敏感值永远不会出现在网页用户界面中,并在构建日志中用星号替换。 请确保密码以 密码类型 的参数形式存储。
使用秘密管理工具。
尽管密码参数在用户界面中被掩盖,处于REST时被加密,且被保护,不会以明文形式暴露在构建日志中,但这往往无法提供足够高的安全级别。
您可以考虑使用像是 HashiCorp Vault 这样的工具,它可以让您管理并轮换在构建中将要使用的所有敏感凭证,同时 与 TeamCity 良好集成。
使用外部认证。
如果适用,请配置我们的其中一个外部认证模块,范围从 LDAP 和 Windows 域集成到通过 GitHub、GitLab 或其他方式进行认证。 您可以随后禁用 TeamCity 内置的身份验证,这样 TeamCity 就不再在内部数据库中保存哈希密码。
如果您的服务器上启用了任何 OAuth 认证模块(Bitbucket Cloud,GitHub.com,GitHub Enterprise,GitLab.com,GitLab CE / EE)并且您限制了对特定 Bitbucket 工作区,GitHub 组织或 GitLab 组的成员的认证,请注意以下内容:
一旦使用外部帐户登录到 TeamCity 服务器,用户可以创建密码或令牌,这将允许他们直接登录到此服务器,绕过 VCS 托管提供商的验证。 如果您从工作区/组织/组中删除了用户,请记得限制他们在 TeamCity 中的访问权限或删除他们的用户配置文件。
使用自定义加密密钥。
在外部系统(如版本控制系统、问题跟踪器等)中需要的密码以混淆的形式存储在 TeamCity Data Directory 中,也可以存储在数据库中。 然而,这些值只是被打乱,这意味着它们可以被拥有服务器文件系统或数据库访问权限的用户检索。
与其使用这种默认的混淆策略,您不妨考虑启用一个 自定义加密密钥。 在这种情况下,TeamCity将使用您独特的自定义密钥来加密所有安全值,而不是使用默认的混淆机制。
使用加密的 SSH 密钥。
当您向您的 TeamCity 服务器上传私人 SSH 密钥时,请注意,它们将以纯文本形式存储在磁盘上,没有任何额外的加密。 强烈建议只使用已使用密码短语加密的 SSH 密钥。
权限
使用预定义角色。
开箱即用,TeamCity 提供了几个预定义的 角色:
系统管理员
项目管理员
项目开发者
项目浏览者
您可以创建符合您组织结构的 用户组,并将上述角色分配给这些组。 然后将您的用户添加到各自的群组中,授予他们日常工作所需的最低权限。
我们强烈建议您创建具有额外权限的新角色,而不是立即将项目管理员角色分配给任何需要稍多些权限的人。 (如果您禁用了 每个项目的权限,这将无法工作。)
按项目授权。
为了进一步加强安全性,您还可以使用 每个项目的授权。 这样,您的开发人员例如,只能访问您构建链的编译部分,而运维人员可以访问并运行部署部分。
请勿启用 Guest Login。
默认情况下,匿名登录 TeamCity 是被禁用的。 确保不在暴露于互联网的生产 TeamCity 服务器实例上启用它,除非您希望外部用户能够查看所有的构建和相关的日志文件 / 工件。 如果启用,应仔细审查访客和 All Users 组的用户角色。
为 REST 请求创建一个独立的用户。
如果您从外部脚本或程序访问 TeamCity REST API,我们建议您为其创建一个权限有限的单独用户。 也许您应该创建 自动过期访问令牌,而不是使用用户名/密码来访问 API。
限制部署构建权限。
确保您的部署构建链不允许 personal builds。 限制能触发这些构建的开发者数量,并为这些构建使用一个单独的干净代理池。
彻底管理授予用户和用户组的权限。
请注意以下细微差别:
能够更改在 TeamCity 运行的构建中所使用的代码的用户(包括在任何分支 / 拉取请求中的提交者,如果它们在 TeamCity 上构建):
可以执行系统用户可以执行的所有操作,该系统用户正在运行 TeamCity 代理;可以访问操作系统资源和安装在代理机器上的其他应用程序,他们的构建可以在这些机器上运行。
可以访问和更改在同一代理上构建的其他项目的源代码,修改 TeamCity 代理代码,将任何文件作为代理上运行的构建的工件发布(这意味着这些文件可以随后在 TeamCity 网络界面中显示并暴露网络漏洞,或可以在其他构建中使用)等等。
可以模仿 TeamCity 代理(运行一个对 TeamCity 服务器看起来相同的新代理)。
可以执行所有服务器上所有项目的"查看构建配置设置"权限的用户可以执行的操作(参见 下文)。
能够检索运行构建的构建配置的设置,包括密码字段的值。
您可以从服务器上的任何构建中下载制品。
拥有“查看构建配置设置”权限的用户(默认为项目开发者角色)可以查看服务器上的所有项目。 为了限制这个,您可以使用
teamcity.buildAuth.enableStrictMode=true
内部属性。拥有 "编辑项目" 权限的用户(默认为 "项目管理员" 的 TeamCity 角色)可以在一个项目中更改设置,从他们只有查看权限的任何构建配置中检索制品并触发构建(TW-39209)。
拥有“更改服务器设置”权限的用户(默认为 "System Administrator" TeamCity 角色):我们假定这些用户也能够访问运行 TeamCity 服务器的计算机,并使用运行服务器进程的用户帐户登录。 因此,用户可以获得对该操作系统用户帐户下的机器的完全访问权限:浏览文件系统,更改文件,运行任意命令等等。
TeamCity 服务器计算机管理员:具有对 TeamCity 存储数据的全部访问权限,并能影响 TeamCity 执行的进程。 需要在外部系统(如 VCS、问题跟踪器等)中进行身份验证的密码以混淆的形式存储在 TeamCity Data Directory 中,也可以存储在数据库中。 然而,这些值只是被打乱了,这意味着任何有权访问服务器文件系统或数据库的用户都可以取回它们。
拥有阅读 TeamCity 服务器日志(TeamCity 服务器主目录)访问权限的用户可以将其权限提升为 TeamCity 服务器管理员。
拥有
<TeamCity 数据目录>
读取权限的用户可以访问服务器上的所有设置,包括配置的密码。拥有
<TeamCity 数据目录>/system/artifacts
构建工件读取权限的用户将获得与拥有 "查看构建运行时参数和数据" 权限的用户相同的权限(尤其是可以访问构建中使用的所有密码参数的值)。TeamCity 代理计算机管理员:与“能够更改 TeamCity 构建运行所用代码的用户”一样。
当启用 在 VCS 中存储设置 功能时:
服务器和数据
定期更新您的 TeamCity 服务器。
我们强烈建议您定期将 TeamCity 更新到 最新发布的版本。
TeamCity 将会在有新的更新可用时,通过 UI 自动通知您。 您也可以手动检查新的 TeamCity 版本,检查 TeamCity 本身的方法是在 服务器管理 | 更新 下查看,检查任何可用插件更新的方法是在 服务器Administration | Plugins 下查看。
从技术角度来看,同一主要 / 次要版本内的错误修复发布之间的升级是向后兼容的(例如,2021.1.1 → 2021.1.2),并支持相对简单的回滚。 对于所有其他主要的升级,我们尽力确保其运行尽可能地顺畅,尽管强烈推荐进行备份以便于轻松回滚。
从许可证的角度来看,升级到错误修复版本也是安全的。 如果您的许可证涵盖 2021.2,那么您将能够升级到任何 2021.2.x 版本。
保护 TeamCity 数据目录。
拥有 TeamCity Data Directory 读取权限的用户可以访问服务器上的所有设置,包括配置的密码。 因此,您需要确保只有操作系统用户(实际上是服务的管理员)才能读取此目录。
TeamCity Windows 安装程序修改了 TeamCity 安装目录 的权限,不再使用继承的权限,而是明确授予管理员用户组和配置为运行服务的帐户对该目录的访问权限。 强烈推荐您以相同的方式限制对 TeamCity Data Directory(TeamCity 数据目录)
的权限。
保护您的服务器设备。
限制访问运行您的 TeamCity 服务器的机器。 启用访问日志并定期进行审查。
一般来说,不要在 TeamCity 服务器机器上运行 构建代理(至少在允许读取 <TeamCity 安装目录>
和 <TeamCity 数据目录>
的用户下)。
TeamCity 服务器(及代理)的进程是在具有最少所需 权限 的用户下运行的。 安装目录只能由一部分操作系统用户读取和写入。 conf\buildAgent.properties
文件和服务器日志,以及 Data Directory,只有代表服务管理员的操作系统用户才能阅读,因为阅读这些位置可能允许接管代理或服务器。
请注意,已安装在服务器上的 agent 插件的二进制文件对于任何能够访问服务器 URL 的人都是可用的。
在任何地方使用 HTTPS。
访问 TeamCity 网页界面是通过 HTTPS 加密 的(例如,利用像 NGINX 这样的 代理服务器)。 确保在 TeamCity 网页界面中应用了保护网络应用程序的最佳实践:例如,不能用 HTTP 协议访问服务器。 反向代理不会剔除 Referer 请求头。
要了解如何配置 TeamCity 代理和 TeamCity 服务器之间的连接,请参阅 本节。
防御 DoS。
TeamCity 没有内置的防御 DoS(Denial-of-service,即服务拒绝)攻击的保护措施:高频率的请求可能会使服务器超负荷运转,使其无法响应。 如果您的 TeamCity 实例部署在允许此类服务滥用的环境中,应在反向代理级别实施保护。
保护您的数据库。
确保为您的 TeamCity 服务器的数据库模式使用具有强凭证的专用数据库用户帐户。 如果支持,请考虑加密数据库。
请考虑将 teamcity.installation.completed=true
行添加到 <TeamCity 安装目录>\conf\teamcity-startup.properties
文件中 —— 这将阻止以空数据库启动的服务器为首个访问用户授权访问该机器。
安全构建文件。
TeamCity 开发团队会尽其所能修复一旦被发现的任何重大漏洞(例如跨站脚本攻击的可能性)。 请注意,任何能影响构建文件的用户(“可以修改 TeamCity 运行构建使用的代码的用户”或“TeamCity 代理计算机管理员”)都可以将恶意文件作为构建工件提供,然后利用这个产物来利用跨站点脚本漏洞。
构建代理
运行干净的生产构建。
我们建议您为生产构建 执行清理检出,以防止代理上的源代码被篡改。
使用一次性的、网络保护的构建代理。
请注意,运行在同一构建代理上的构建并不是隔离的,它们可能会相互影响,从而可能提供执行恶意操作的机会。
如果可能,尝试使用一次性的、可丢弃的构建代理。 代理的生命周期越短,其被破解的可能性就越小。 另外,请确保使用依赖于操作系统的防火墙规则来禁用对您的云代理的入站网络访问。
为不同的项目使用代理池。
通常,建议将项目在代理间分配,这样一个 TeamCity 代理就不会运行多个项目的构建,而这些项目的开发者和管理员不应该获得对彼此项目的访问权限。
如果您在同一台机器上运行了多个代理,并且没有启用清理检出,请注意,受损的代理或不受信任的项目可能会在"邻近"工作目录中修改源代码。 为了减轻这种风险,考虑在每台机器上只运行一个代理,并为不同的 ( 私有 / 公开 ) 项目使用不同的 代理池。 确保 "Default" 代理池没有任何代理,因为在某种重配置(即没有其他池被分配给项目时)后,项目可以被分配给 Default 池。
控制运行 TeamCity 代理 的操作系统用户的权限。
建议在只具有必要权限集的操作系统帐户下运行 TeamCity 代理。
只将代理连接到可信的服务器。
TeamCity 代理完全受 TeamCity 服务器控制:由于 TeamCity 代理支持从服务器自动下载更新,所以代理应只连接到受信任的服务器。 请注意,服务器计算机的管理员可以强制执行与连接的代理相关的任意代码。
版本控制
使用较新版本的 Git。
请确保始终在您的 构建代理 上使用最新稳定的操作系统和 Git 版本。 定期更新。
妥善管理您的 SSH 密钥。
如果您正在使用 SSH 密钥来访问您的仓库,不要在您的构建代理上存储它们。 反而,使用 TeamCity 的 SSH 密钥管理 将它们上传到 TeamCity 服务器。
而不是禁用已知的主机检查,请确保在服务器和每个您要连接的主机的构建代理上维护一个 .ssh/known_hosts
文件。
使用一个专用的 VCS 用户。
如果您不使用诸如 Kotlin DSL 这样的高级功能,或者通常情况下,如果您不需要在构建过程中提交到您的仓库,我们建议保留一个专用的 VCS 用户而不赋予其写入权限以连接到您的仓库。
构件存储
禁用匿名访问。
无论您在何处存储您的构建工件(例如 S3),一定要禁止对您的存储位置进行匿名访问。
使用正确的访问策略。
使用适当的访问策略来保护您的 S3 或其他存储位置 / 存储库以储存制品。 如果可能,也请使用加密。 检查,监控,并定期回顾您的存储位置的访问日志。
不要将敏感数据放入工件中。
请不要在您的构建工件中以明文形式存储凭证或其他敏感信息。
构建历史和日志
保持您的构建历史。
将您的构建历史和日志保存更长的时间,尤其是对于进行关键部署的构建,通过为您的项目指定相应的 清理规则来实现。 另外,请确保不要向开发者授予 "remove build" 权限,因为这可能会阻止存档。
这两项措施都有助于追踪恶意活动,即使这些活动在很长时间前就发生了。
归档服务器和代理日志。
将 TeamCity 服务器 和 构建代理 logs 收集到一个存档中,并把它们放在一个安全性良好的存储中。
集成
在构建公共拉取请求时请谨慎。
如果您构建来自未知用户或组织外用户的 pull requests,请注意,pull requests 可能包含恶意代码,这些代码将在您的构建代理上运行。
禁止构建公开的拉取请求,或使用独立、隔离、一次性的代理。 TeamCity 还提供了一个 内置健康报告,它能检测并报告拉取请求构建。
使用版本设置时,请注意安全性的影响。
当您使用 版本化设置(Kotlin DSL,XML)并将这些设置放在与源代码相同的存储库中时,任何恶意开发者都可能会修改并泄漏项目配置设置。 例如,可以通过添加一个构建步骤来完成这个操作,该步骤将打印出密码或将它们作为文件发送到某个地方。
作为一种选择,您可以使用一个只有少数用户可以提交的独立仓库来存放您的版本控制设置。
小心使用第三方插件。
在安装插件时,务必确保它们来自可信赖的来源,并且其源代码是可获得的。 插件可能能访问 TeamCity 服务器上的所有信息,包括敏感信息。
TeamCity 使用的加密
TeamCity 尝试不通过网络用户界面(从浏览器到服务器)以明文传递密码值:而是使用 1024 位密钥的 RSA 进行加密。 然而,推荐仅通过 HTTPS 使用 TeamCity 网页 UI,所以这项预防措施应该并不重要。 TeamCity 在设置中以混淆的形式存储密码(在其他系统中执行身份验证时需要原始密码值)。 混淆是通过使用固定密钥的 3DES 或 使用自定义密钥 来完成的。
第三方软件漏洞
此部分描述了与第三方软件公布的安全漏洞相关的影响以及必要的保护步骤。
Heartbleed , ShellShock
JetBrains 提供的 TeamCity 分发版本不包含受 Heartbleed 和 Shellshock 漏洞影响的软件/库,也不使用受这些漏洞影响的技术。 可能仍需要评估的是特定的 TeamCity 安装实现,这可能使用了 JetBrains 提供/推荐的那些组件背后的组件,并且可能会对所提到的漏洞攻击存在脆弱性。
POODLE
如果您已经配置了对 TeamCity 服务器的 HTTPS 访问,请检查用于 HTTPS 的解决方案,因为该解决方案可能会受到影响(例如,Tomcat 似乎会受到 影响)。 在这一点上,TeamCity 的所有版本默认都不包含 HTTPS 访问,而调查 / 消除与 HTTPS 相关的漏洞超出了 TeamCity 的范围。
根据所使用的设置,TeamCity 服务器(和代理)可以与其他服务器(例如,Subversion)建立 HTTPS 连接。 根据服务器设置,这些连接可能会退回使用 SSL 3.0 协议。 推荐的解决方案不针对 TeamCity,而是在目标 SSL 服务器端禁用 SSLv3。
GHOST
CVE-2015-0235 漏洞被发现在 glibc 库中,而这个库并未直接被 TeamCity 代码使用。 它被 TeamCity 在 *nix 平台下使用的 Java/JRE 所使用。 由于 Java 并未与 TeamCity Unix 发行版(Docker 镜像使用较新的 glibc 版本)捆绑在一起,您应执行 Java 供应商推荐的安全措施。 目前还没有发布任何与 Java 相关的特定安全建议,因此更新操作系统应该足够消除漏洞利用的风险。
FREAK
在 OpenSSL 的实施中发现了 CVE-2015-0204 漏洞。 TeamCity 并未捆绑 OpenSSL 产品的任何部分,因此并不易受攻击。 您可能仍需要审查设置 TeamCity 服务器和代理的环境,以及为可能的漏洞缓解步骤额外安装的 TeamCity 工具。
Apache Struts
TeamCity 可以下载包含 Apache Struts 1.x 和 Apache Struts 2.x 的 JARs 的 IntelliJ IDEA 。 这些 JARs 仅被 IntelliJ IDEA Struts 插件在 IntelliJ IDEA 在 TeamCity 代理 上收集项目的检查时使用。
TeamCity 并不使用 Apache Struts 来处理任何 HTTP 请求。 因此,无论是 TeamCity 服务器还是 TeamCity 代理,都不会受到相关 Struts 漏洞(CVE-2016-1181、CVE-2017-5638、CVE-2023-50164 等)的影响。