我正在设置一个 Jenkins 服务器,在 Apache 后面的 Tomcat 下运行。我使用带 SSL 的虚拟主机,使用 SNI,因此我可以在https://jenkins.example.com,然后上其他东西,比如说,http://www.example.com。
我已经启动并运行了,但是当我点击“管理 Jenkins”时,它告诉我你的反向代理设置似乎已损坏。
请注意,我使用的是自签名 SSL 证书,并且 jenkins.example.com 不是默认虚拟主机。
相关的 apache 配置如下所示:
<VirtualHost *:80>
ServerName jenkins.example.com
Redirect / https://jenkins.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName jenkins.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/jenkins.example.com.crt
SSLCertificateKeyFile /etc/ssl/private/jenkins.example.com.key
<Location />
AuthType Digest
AuthName "Jenkins"
AuthUserFile "/etc/htpasswords"
Require valid-user
</Location>
ProxyRequests Off
ProxyPreserveHost On
<Proxy http://localhost:8080*>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
ProxyPassReverse / https://jenkins.example.com
</VirtualHost>
如果我做:
curl --user "username:password" --digest -k https://jenkins.example.com/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/test -L
然后我看到输出:
<div/>
如果我使用调试运行 wget,那么我会看到在某个时候 wget 会获取指向 http 而不是 https 的指针,不确定为什么会发生这种情况或者是否相关,但它确实正确重定向:
---response begin---
HTTP/1.1 302 Moved Temporarily
Date: Tue, 17 Jan 2012 19:47:16 GMT
Server: Apache-Coyote/1.1
Location: http://jenkins.example.com/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/test-for-reverse-proxy-setup
Content-Length: 0
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Content-Type: text/plain
我在 Ubuntu 11.04、Apache 2.2.17、Tomcat 6.0.28 和 Jenkins 1.448 上运行。
答案1
我发现您的配置存在一个问题:
ProxyPassReverse / https://jenkins.example.com
应该:
ProxyPassReverse / https://jenkins.example.com/
似乎服务正在发送http://
而不是https://
位置标头(可能是因为您从 Apache 到其侦听器的连接在本地主机侦听器上未加密),在这种情况下您需要添加:
ProxyPassReverse / http://jenkins.example.com/
因此,目前可能发生的情况是 API 调用失败,因为它在重定向的标头中获取了一个http://
地址(由于不是,因此在取消翻译时遗漏了该地址)。Location:
ProxyPassReverse
http
它将请求发送到该位置并获取其他重定向响应,来自您的<VirtualHost *:80>
。其有效性检查器知道这是不正确的,并且会产生错误,而 则curl
继续进行一次重定向并获取有效响应。
如果我没记错的话,添加上面的ProxyPassReverse
内容http://
应该可以解决问题。
答案2
如果使用 Apache 作为反向代理,则需要至少为 2.2.18 并设置选项AllowEncodedSlashes NoDecode
(早期版本只有值 On 和 Off,这两个值都是错误的);以及nocanon
在ProxyPass
指令中。
两者都需要在 VirtualHost 中设置,因为 AllowEncodedSlashes 不会被继承。
<VirtualHost *:80>
AllowEncodedSlashes NoDecode
ServerName build.example.org
ProxyPass / http://localhost:8080/ nocanon
ProxyPassReverse / http://localhost:8080/
ProxyRequests Off
</VirtualHost>
答案3
通过https://stackoverflow.com/a/33179008/923560:
确保系统配置中配置的 Jenkins URL 与您用于访问 Jenkins 的 URL 匹配。
要进入系统配置:
- 转到您的 Jenkins 页面
- 点击管理詹金斯
- 单击“配置系统”
- 滚动到詹金斯位置并找到 Jenkins URL。
确保端口值<arguments>
与詹金斯.xml位于您机器上的 Jenkins 文件夹中的文件。