配置代理服务器
这篇文章提供了关于配置以下代理类型的一般建议:
tip
现在,TeamCity 允许 轻松配置 HTTPS 访问。 这些设置会影响内置的 Tomcat 服务器配置,并可能破坏您现有的代理配置。
对于面向大众的大型 TeamCity 安装,我们仍然建议您在代理后面设置 TeamCity。
考虑以下示例:
TeamCity 服务器安装在一个 本地 URL http://teamcity.local:8111/tc
。
它对外界是以一个 公共 URL http://teamcity.public:400/tc
可见的。
为确保 TeamCity "了解" 客户端用于访问资源的实际绝对 URL,您需要:
按照以下描述设置反向代理。
配置与 TeamCity 绑定的 Tomcat server。
这些 URL 被用于在客户端重定向和其他响应中生成绝对 URL。
配置代理后,您还需要更改 TeamCity 全局设置中的服务器 URL值为代理 URL。
注意:内部的 TeamCity 服务器应在与从外部地址可见的 相同上下文(即主机名后的 URL 部分)下工作。 请参阅 TeamCity 服务器的 上下文更改指令。
如果您需要在不同的上下文下运行服务器,请注意,上下文更改代理应该对 TeamCity 隐藏这一事实:例如,它应将服务器重定向的 URL 以及 cookies 设置路径映射到原始(外部)上下文。
代理应该考虑到通用网络安全进行配置。 像 引用来源
和 来源
这样的头部,以及所有未知的头部,都应以未修改的形式传递给 TeamCity 网络应用程序。 例如,TeamCity 依赖客户端添加的 X-TC-CSRF-Token
头。
建议使用 2.4.5 或更高版本。 早期版本不支持 WebSocket 协议。
当使用 Apache 时,请确保使用 专用的 "Connector" 节点方法 来配置 TeamCity 服务器。
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so
LoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /tc/app/subscriptions ws://teamcity.local:8111/tc/app/subscriptions connectiontimeout=240 timeout=1200
ProxyPassReverse /tc/app/subscriptions ws://teamcity.local:8111/tc/app/subscriptions
ProxyPass /tc http://teamcity.local:8111/tc connectiontimeout=240 timeout=1200
ProxyPassReverse /tc http://teamcity.local:8111/tc
## The following entries are required to allow the Agent Terminal feature to function with websockets
ProxyPass /tc/plugins/teamcity-agent-terminal/ ws://teamcity.local:8111/tc/plugins/teamcity-agent-terminal/ connectiontimeout=240 timeout=1200
ProxyPassReverse /tc/plugins/teamcity-agent-terminal/ ws://teamcity.local:8111/tc/plugins/teamcity-agent-terminal/
ProxyPass /tc/app/agentTerminal/ ws://teamcity.local:8111/tc/app/agentTerminal/ connectiontimeout=240 timeout=1200
ProxyPassReverse /tc/app/agentTerminal/ ws://teamcity.local:8111/tc/app/agentTerminal/
请注意 ProxyPass 规则 的顺序:冲突的 ProxyPass 规则必须以最长的 URL 为首进行排序。
默认情况下,Apache 只允许有限的并行连接,这可能在使用 WebSocket 协议时不足够。 例如,当大量客户端打开网页 UI 时,可能导致 TeamCity 服务器无响应。 为了修复它,您可能需要微调 Apache 配置。
例如,在 Unix 上,您应该切换到 mpm_worker 并配置最大的同时连接数:
<IfModule mpm_worker_module>
ServerLimit 100
StartServers 3
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxClients 2500
MaxRequestsPerChild 0
</IfModule>
在 Windows 上,您可能需要按照 Apache 文档 中的描述增加 ThreadsPerChild 的值。
建议使用 1.3 或更高版本。 早期版本不支持 WebSocket 协议。
http {
... default settings here
proxy_read_timeout 1200;
proxy_connect_timeout 240;
client_max_body_size 0; # maximum size of an HTTP request. 0 allows uploading large artifacts to TeamCity
map $http_upgrade $connection_upgrade { # WebSocket support
default upgrade;
'' '';
}
server {
listen 400; # public server port
server_name teamcity.public; # public server host name
location / { # public context (should be the same as internal context)
proxy_pass http://teamcity.local:8111; # full internal address
proxy_http_version 1.1;
proxy_set_header Host $server_name:$server_port;
proxy_set_header X-Forwarded-Host $http_host; # necessary for proper absolute redirects and TeamCity CSRF check
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade; # WebSocket support
proxy_set_header Connection $connection_upgrade; # WebSocket support
}
}
}
要在 IIS 反向代理后配置 TeamCity 服务器:
为您的 TeamCity 服务器创建一个规范名称(CNAME)记录。
发行一个证书,以确保 TeamCity 服务器与外部用户之间的安全连接。 如果证书不是由知名证书颁发机构颁发的,您可能需要在每台连接到 TeamCity 的机器上手动将其添加到 Java 证书存储中:
keytool -importcert -file <cert file> -keystore <path to JRE installation>/lib/security/cacerts
将 server URL 更改为代理 URL。
编辑 <TeamCity 安装目录>/conf/server.xml 文件,按照 TeamCity Tomcat 配置 小节中的描述来设置所需的 TeamCity Tomcat 服务器属性。
步骤5到8在Powershell中执行。 使用 Get-IISConfigSection 和 Set-IISConfigAttributeValue 命令来启动 SSL 标志:
$ConfigSectionTC = Get-IISConfigSection -SectionPath "system.webServer/security/access" -Location "<IIS Website name>"; Set-IISConfigAttributeValue -AttributeName sslFlags -AttributeValue Ssl -ConfigElement $ConfigSectionTC;
使用 Set-WebConfigurationProperty cmdlet 添加一个服务器变量,允许从web请求中传递HTTP转发的IP:
Set-WebConfigurationProperty -pspath "IIS:/" -Location "<IIS Website name>" -filter "system.webServer/rewrite/allowedServerVariables" -name "." -value @{name="HTTP_FORWARDED"} -FORCE
启用代理设置:
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -filter "system.webServer/proxy" -name "." -value @{ enabled="true" } -FORCE
如果您使用外部存储来保存 TeamCity 的工件,请禁用
reverseRewriteHostInResponseHeaders
参数:Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -filter "system.webServer/proxy" -name "." -value @{ reverseRewriteHostInResponseHeaders="false" } -FORCE
按照以下方式修改 IIS web.config 文件:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.web> <httpRuntime requestPathInvalidCharacters="" /> </system.web> <system.webServer> <rewrite> <rules useOriginalURLEncoding="true"> <rule name="teamcity" enabled="true" patternSyntax="Wildcard" stopProcessing="true"> <match url="*" /> <action type="Rewrite" url="http://localhost:80/{R:0}" /> <serverVariables> <set name="HTTP_FORWARDED" value="for={REMOTE_ADDR};by={LOCAL_ADDR};host="{HTTP_HOST}";proto="https"" /> </serverVariables> </rule> </rules> </rewrite> <security> <requestFiltering allowDoubleEscaping="true"> <fileExtensions> <remove fileExtension=".config" /> </fileExtensions> <hiddenSegments> <remove segment="bin" /> </hiddenSegments> </requestFiltering> </security> </system.webServer> </configuration>
确保使用性能高效的代理,并适当(高)限制请求(上传)和响应(下载)的大小以及超时(至少几十分钟和一千兆字节,根据代码库和工件的大小)。
建议使用能够支持 WebSocket 协议的代理,因为这有助于 UI 更快地刷新。
一般来说,您需要配置 TeamCity 服务器,以便它“知道”客户端使用的原始 URL,并且可以为客户端生成正确的绝对 URL。 实现该目标的首选方式是将原始的 主机
头文件传递给 TeamCity。 一种替代方法是将 X-Forwarded-Host
头设置为原始的 主机
头的值。
请注意,每当代理更改了 主机
标题的值(虽然建议保留原始的 主机
标题值)并且没有提供具有原始 主机
值的 X-Forwarded-Host
标题时,如果 来源
和 引用来源
标题含有原始的 主机
标题值,则应相应地映射这些值(如果它们没有,则不应设置,以免绕过 TeamCity 的 CSRF保护)。
从下面的部分中选择一个合适的方法,并相应地配置代理。
请检查您的反向代理(或类似工具)是否符合以下要求:
以点(
.
)开头的路径的 URLs 受到支持(隐藏工件的路径开始包含.teamcity
目录)。支持带有冒号(
:
)的 URLs (许多 TeamCity 资源使用冒号)。 相关的 IIS 设置。 症状:即使有构建工件,构建也没有带有“此构建中没有用户定义的构建工件”字样的构建工件。设定限制最大请求名称、响应长度和响应时间的设置并不过于严格。 请参阅此文章以获取更多信息:IIS 相关问题。
gzip 内容编码得到了全面的支持。 例如,某些 IIS 配置可能导致用户界面出现 "正在加载数据...",并产生 500 HTTP 响应(请参阅相关的 问题)。
IIS 相关问题:
如果出现 "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target" 错误,将您的证书添加到 TeamCity 使用的相同的 Java 密钥库中。
如果在 HTTP 404 或 50x 错误中返回了错误的服务器名称,请检查您的重定向规则和转发的头部。
对于 TeamCity Tomcat 配置,您需要在服务器配置中使用带有硬编码公共 URL 详情的专用 "Connector" 节点,并确保连接器中配置的端口仅被配置的公共 URL 的请求所使用。
此方法可用于任何代理配置,只要配置的端口仅接收到配置的公共 URL 的请求。
您需要在 <TeamCity 安装目录>/conf/server.xml
文件中按照以下方式更改 "Connector" 节点。
<Connector port="8111" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="60000"
useBodyEncodingForURI="true"
socket.txBufSize="64000"
socket.rxBufSize="64000"
tcpNoDelay="1"
secure="false"
scheme="http"
/>
当公共服务器地址为 HTTPS 时,使用 secure="true"
和 scheme="https"
属性。 如果缺少这些属性,TeamCity 将会显示相应的健康报告。
如果一个 TeamCity 服务器是在 IIS 反向代理后配置的:
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="60000"
redirectPort="8543"
useBodyEncodingForURI="true"
socket.txBufSize="64000"
socket.rxBufSize="64000"
tcpNoDelay="1"
proxyName="<your_CNAME_value>"
proxyPort="443"
secure="true"
scheme="https"
/>
<Valve
className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for"
protocolHeader="x-forwarded-proto"
portHeader="x-forwarded-port"
internalProxies="<internal_proxy_ip>"
/>
这个部分描述了如何配置 TeamCity 以使用代理服务器进行出站 HTTP 连接。 要将位于代理服务器后的 TeamCity 连接到 Amazon EC2 云代理,请查看 此部分。
TeamCity 服务器可以使用代理服务器进行某些对其他服务(如问题跟踪器)的出站 HTTP 连接。
要将 TeamCity 指向您的代理服务器,请设置以下 内部属性:
# For HTTP protocol
## The domain name or the IP address of the proxy host and the port:
teamcity.http.proxyHost=proxy.domain.com
teamcity.http.proxyPort=8080
## The hosts that should be accessed without going through the proxy, usually internal hosts. Provide a list of hosts, separated by the '|' character. The wildcard '*' can be used:
teamcity.http.nonProxyHosts=localhost|*.mydomain.com
## For an authenticated proxy add the following properties:
### Authentication type. "basic" and "ntlm" values are supported. The default is basic.
teamcity.http.proxyAuthenticationType=basic
### Login and Password for the proxy:
teamcity.http.proxyLogin=username
teamcity.http.proxyPassword=password
# For HTTPS protocol
## The domain name or the IP address of the proxy host and the port:
teamcity.https.proxyHost=proxy.domain.com
teamcity.https.proxyPort=8080
## The hosts that should be accessed without going through the proxy, usually internal hosts. Provide a list of hosts, separated by the '|' character. The wildcard '*' can be used:
teamcity.https.nonProxyHosts=localhost|*.mydomain.com
## For an authenticated proxy add the following properties:
### Authentication type. "basic" and "ntlm" values are supported. The default is basic.
teamcity.https.proxyAuthenticationType=basic
### Login and Password for the proxy:
teamcity.https.proxyLogin=login
teamcity.https.proxyPassword=password
warning
对于外部 Git 仓库,只有切换到捆绑的 JGit,上述设置才能解决连接问题。 如果 TeamCity 使用的是 native Git,您需要在 Git 配置中手动设置代理。 请参阅以下文章以获取更多信息:
构建代理通常需要进行各种出站连接:连接到 TeamCity 服务器,S3 文档存储,VCS 主机等等。 这个章节描述了如何配置构建代理,以便在构建代理部署在代理服务器后,出站连接能够继续工作。
在 TeamCity 代理端,使用 buildAgent.properties
文件中的以下属性来指定连接到 TeamCity 服务器的代理:
## The domain name or the IP address of the proxy host and the port
teamcity.http.proxyHost=123.45.678.9
teamcity.http.proxyPort=8080
## If the proxy requires authentication, specify the login and password
teamcity.http.proxyLogin=login
teamcity.http.proxyPassword=password
如果代理有 HTTPS 端点,您也可以配置 teamcity.https.*
属性。
tip
代理必须配置为不缓存任何 TeamCity 服务器的响应。 例如,如果您使用 Squid,将 "cache deny all" 这行添加到
squid.conf
文件中。如果您正在使用 自定义工件存储,请确保 agent 可以连接到所需的服务。 例如,如果您使用 S3 buckets 存储工件,代理应允许
*.amazonaws.com
流量。
TeamCity 服务器可以配置为使用多个节点(或服务器)以实现高可用性和灵活的负载分配。 参考此文章以获取 NGINX 和 HAProxy 配置的示例:高可用性的多节点设置。
感谢您的反馈!