使用 Jenkins 和 TLS/SSL 的 Apache 反向代理

使用 Jenkins 和 TLS/SSL 的 Apache 反向代理

我在虚拟机 (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 指令的部分。

相关内容