我在虚拟机 (OS:Debian 8) 中运行 Jenkins CI 服务器。我从前任管理员手中接管了这台虚拟机。由于我决定通过 TLS/SSL 保护正在运行的 Jenkins,因此我申请了证书并设置了 Apache (2.4.10) 作为反向代理。
我参考了这个 Jenkins Wiki 说明进行配置:https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache
正如该页面上的完整示例一样,我按如下方式配置了我的 Apache 反向代理:
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerName myhostname.tld
Redirect permanent / https://myhostname.tld/
</VirtualHost>
<VirtualHost *:443>
ServerName myhostname.tld:443
SSLEngine on
SSLCertificateFile /path-to-my-cert/cert.pem
SSLCertificateKeyFile /path-to-my-key/keyfile.key
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ nocanon
ProxyPassReverse / http://localhost:8080/
ProxyPassReverse / http://myhostname.tld/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>
据我所知,根据文档,这似乎是使用 TLS/SSL 的反向代理的正确设置。我可以通过 HTTPS 完美访问 Jenkins 服务器,但是唯一行不通的事情,是从 HTTP 重定向到 HTTPS。
我确实设置了另一台 Apache 服务器,它不充当反向代理,其中类似的重定向从 HTTP 到 HTTPS 运行正常,没有任何问题。因此,我推测,这似乎是我的 vhost 配置文件中的反向代理命令的配置问题。
我搜索了很多答案,并在这里发现了类似的问题:为 Jenkins 和 Sonar 使用 SSL 更正 Apache 反向代理配置
不幸的是,那里发布的解决方案是我已包含在配置中的内容,因为那里接受的答案似乎是来自 Jenkins wiki 网站的代码。我还发现了很多其他建议的解决方案,它们似乎都是不同方法的混合体(有些更好,有些更差),因此我感到困惑的提示和错误的配置让我相当迷茫。
我还发现了 Apache wiki 网站:https://wiki.apache.org/httpd/RedirectSSL
官方的重定向解决方案似乎也是我已经在使用的。
我还检查了 Jenkins 内部的后端配置,并找到了“Jenkins URL”字段,其中 URL 为 http://。但将其更改为 https:// 也没有任何效果。
我一次又一次地检查了我的配置,并且还考虑检查我的域名尾部的斜杠,但似乎一切都正确。
如有任何帮助或进一步的资源我将不胜感激。
谢谢。
编辑:
因此,我再次对最近因长期患病而导致的延误深感抱歉。
无论如何,我克隆了虚拟机,并设置了新证书。有相同的干净的虚拟主机配置和相同的重定向。我能够完美地使用 HTTPS 调用网站,没有任何错误。但 HTTP -> HTTPS 重定向仍然不起作用。
以下是我得到的输出curl -I -H "Host:..." http://...
HTTP/1.1 200 OK
Date: Mon, 06 Mar 2017 14:29:44 GMT
X-Content-Type-Options: nosniff
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache,no-store,must-revalidate
X-Hudson-Theme: default
Content-Type: text/html;charset=UTF-8
Set-Cookie: JSESSIONID.8d3ecf0e=47s4cwdffsf4t3qnwix3n2;Path=/;HttpOnly
X-Hudson: 1.395
X-Jenkins: 2.49
X-Jenkins-Session: 67e643e
X-Hudson-CLI-Port: 56889
X-Jenkins-CLI-Port: 56889
X-Jenkins-CLI2-Port: 56889
X-Frame-Options: sameorigin
X-Instance-Identity: MIIBIjANBgkqhk....
X-SSH-Endpoint: jenkinsdomain.tld:47955
Transfer-Encoding: chunked
Server: Jetty(9.2.z-SNAPSHOT)
我非常确定,浏览器缓存问题不会影响这一点。我使用了不同的浏览器,清除了所有缓存,使用了私人会话等。但都不起作用。
编辑2:
经过一番挖掘和各种尝试后,我距离失败又近了一步。
关于不同的来源(我无法在这里发布所有这些链接,因为我的声誉点数不够),我所做的是:
我发现詹金斯config 文件并编辑了JENKINS_ARGS
行,其中包含用于启动 Jenkins 服务器的不同参数。我添加了这个参数:
--httpListenAddress=127.0.0.1
因此我的启动行如下所示:
JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpPort=$HTTP_PORT --httpListenAddress=127.0.0.1 --ajp13Port=$AJP_PORT"
在哪里:
$HTTP_PORT=8080
$AJP_PORT
已禁用(在配置文件中设置为 -1)
我找到了不同的教程(例如来自 Jenkins 网站本身以及 Digital Ocean 和其他网站),它们都以同样的方式进行。更进一步的是,Jenkins 现在提供仅有的HTTPS!当我尝试通过 HTTP 访问网站时,出现错误,我的连接被拒绝。
因此,我可以验证 Jenkins 是通过 HTTPS 上的 Apache 反向代理提供服务的,并且 Apache 似乎尝试转发 HTTP。这让我有点困惑,因为 vhost 配置非常干净,那里的指令似乎被执行了(如果没有,HTTPS 将不起作用)。此外,这是首选方法,必须如何完成,参考官方 Apache 文档。
我尝试了一些其他方法,只是想看看它是否有任何效果。我添加了一个像这样的标题重写:
<Location />
ProxyPassReverse /
Order deny,allow
Allow from all
</Location>
Header edit Location ^http://www.example.com/ https://www.example.com/
这是 Hudson 服务器文档中提出的建议(因为 Jenkins 基于 Hudson)。没有用。
我尝试将 HTTP 重写为 HTTPS,正如 Apache 官方文档所指出的那样,但mod_rewrite
也没有用(这也是另一个用户在这里提出的)。
在任何其他配置和尝试重写 URL 时,我都会遇到完全相同的错误(ERR_CONNECTION_REFUSED
)。
因此,现在,我试图了解,是什么让 Apache 拒绝重定向到 Jenkins?Jenkins 正在监听端口 8080 和地址 127.0.0.1(之前是 0.0.0.0,我按照我已经描述的方式进行了更改)。
添加一些调试输出。当我localhost
从服务器本身 curl 时,我确实得到了:
# curl -I http://localhost
HTTP/1.1 301 Moved Permanently
Date: Wed, 08 Mar 2017 10:04:31 GMT
Server: Apache/2.4.10 (Debian)
Location: https://jenkins.domain.tld/
Content-Type: text/html; charset=iso-8859-1
这似乎是正确的,因为这似乎是我对 HTTPS 网站的重定向。
localhost:8080
当我从服务器本身curl (Jenkins 绑定到的位置)时,我确实得到了正确的答案:
# curl -I http://localhost:8080
HTTP/1.1 200 OK
Date: Wed, 08 Mar 2017 10:07:41 GMT
X-Content-Type-Options: nosniff
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache,no-store,must-revalidate
X-Hudson-Theme: default
Content-Type: text/html;charset=UTF-8
Set-Cookie: JSESSIONID.9e9c97x3=2wx6r12gl694bf51b7ln8vymm;Path=/;HttpOnly
X-Hudson: 1.395
X-Jenkins: 2.49
X-Jenkins-Session: 66c04def
X-Hudson-CLI-Port: 39397
X-Jenkins-CLI-Port: 39397
X-Jenkins-CLI2-Port: 39397
X-Frame-Options: sameorigin
X-Instance-Identity: MVIBIjAN....
X-SSH-Endpoint: jenkins.domain.tld:46063
Transfer-Encoding: chunked
Server: Jetty(9.2.z-SNAPSHOT)
错误发生在远程客户端:
# curl -I http://jenkins.domain.tld
curl: (7) Failed to connect to jenkins.domain.tld port 80: Connection refused
另外,为了确保万无一失:
# a2enmod proxy_http
Considering dependency proxy for proxy_http:
Module proxy already enabled
Module proxy_http already enabled
答案1
我遇到了重定向问题(HTTP 到 HTTPS) 用于我的 drupal 网站。我已通过在 .htaccess 中添加这些行解决了此问题。您尝试添加此 httpd.conf 或您的 vhost.conf 怎么样?
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
这应该将所有 HTTP 重定向到 HTTPS。
答案2
从 http 到 https 的重定向是完美的并且将始终有效。
确保您没有在浏览器中看到某些缓存行为,请尝试:
curl -I myhostname.tld
还要为该虚拟主机定义 customlog 并查看发生了什么,在发送 curl 时检查 access.log,确保您着陆在您认为着陆的位置(没有其他具有相同服务器名称的虚拟主机干扰,您可以使用“apachectl -S”检查)。
另一件事是“NameVirtualHost”在 2.4 中已被弃用,请将其删除。
另外,删除反向代理中无用的部分以及其中包含不必要的 2.2 指令的部分。