Apache 代理背后的詹金斯

Jenkins behind apache proxy

我的 Jenkins 运行 在 Kubernetes 中,服务类型为:LoadBalancer,并在下面添加了 azure 注释以获取内部子网私有 ip 地址以在内部公开服务。

  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    service.beta.kubernetes.io/azure-load-balancer-internal-subnet: subnetName

我有一台安装了 Apache 的 ubuntu 虚拟机。在 apache 配置中创建自签名证书并终止,我可以使用 HTTPS 访问 apache 主页。

然后我为 Jenkins 服务 IP 地址创建了代理规则。基本上我想从 Apache HTTPS 访问 Jenkins --> 到 kubernetes 服务的内部 HTTP 流量。

这是 Apache 配置:

xxxx@xxxx:/etc/apache2/sites-available$ ls -ltrh
total 28K
-rw-r--r-- 1 root root 1332 Jul 16 18:14 000-default.conf
-rw-r--r-- 1 root root 6338 Jul 16 18:14 default-ssl.conf
drwxr-xr-x 2 root root 4096 Dec 12 17:24 abc
-rw-r--r-- 1 root root  680 Dec 12 13:04 abc.conf
drwxr-xr-x 2 root root 4096 Dec 12 14:29 xyz
-rw-r--r-- 1 root root 1151 Dec 12 13:08 xyz.conf

cat abc/00-redirect-to-https.conf
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^jenkins$ login [L,R=302]


cat abc.conf
<VirtualHost *:80>
    ServerAdmin webmaster@localhost

    LogLevel warn
    ErrorLog ${APACHE_LOG_DIR}/abc_error.log
    CustomLog ${APACHE_LOG_DIR}/abc_access.log combined

    <IfModule mod_headers.c>
      RequestHeader unset X-Forwarded-For
      RequestHeader unset X-Forwarded-Host
      RequestHeader unset X-Forwarded-Server
      RequestHeader set X-Forwarded-Proto "http"
      RequestHeader set X-Forwarded-Port "80"
    </IfModule>

    # Apache will try to set application/json based on mime type
    # This behaviour casing problems with empty json responses from spring
    RemoveType json

    Include sites-available/abc/*.conf
</VirtualHost>


cat xyz/00-jenkins.conf
ProxyPass /jenkins balancer://jenkins/jenkins
ProxyPassReverse  /jenkins balancer://jenkins/jenkins
<Proxy balancer://jenkins>
    BalancerMember http://x.x.x.x:8080 loadfactor=1 keepalive=On retry=0
    ProxySet lbmethod=bytraffic
</Proxy>


cat xyz.conf
<VirtualHost *:443>
    ServerAdmin webmaster@localhost

    ServerName FQDN

    LogLevel warn
    ErrorLog ${APACHE_LOG_DIR}/xyz_error.log
    CustomLog ${APACHE_LOG_DIR}/xyz_access.log combined

    <IfModule mod_headers.c>
      RequestHeader unset X-Forwarded-For
      RequestHeader unset X-Forwarded-Host
      RequestHeader unset X-Forwarded-Server
      RequestHeader set X-Forwarded-Proto "https"
      RequestHeader set X-Forwarded-Port "443"
    </IfModule>

    SSLEngine on
    SSLProtocol -ALL +TLSv1 +TLSv1.1 +TLSv1.2
    SSLHonorCipherOrder On
    SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

    SSLCertificateFile    /etc/apache2/certs/ca.cert
    SSLCertificateKeyFile /etc/apache2/certs/ca.key


    # Apache will try to set application/json based on mime type
    # This behaviour casing problems with empty json responses from spring
    RemoveType json

    Include sites-available/xyz/*.conf

</VirtualHost>

如果我从本地 ubuntu VM 执行 curl -k https://localhost/jenkins,则响应显示需要身份验证,如下所示,但重定向 url 变为 window.location.replace('/login?from=%2F')

<html><head><meta http-equiv='refresh' content='1;url=/login?from=%2Fjenkins'/><script>window.location.replace('/login?from=%2Fjenkins');</script></head><body style='background-color:white; color:white;'>


Authentication required
<!--
You are authenticated as: anonymous
Groups that you are in:

Permission you need to have (but didn't): hudson.model.Hudson.Read
 ... which is implied by: hudson.security.Permission.GenericRead
 ... which is implied by: hudson.model.Hudson.Administer
-->

</body></html>       

但同样的情况,当我再次从浏览器 https://FQDN/jenkins 请求时 URL 变成 https://FQDN/login?from=%2F 但是浏览器抛出 URL 未找到错误

Not Found
The requested URL was not found on this server.

请在此协助更正配置..

谢谢..

更多来自日志的观察:

当我这样做时 curl -k https://localhost/jenkins apache 访问日志显示 403,这没问题,因为我没有通过凭据

127.0.0.1 - - [13/Dec/2019:13:37:40 +0000] "GET /jenkins HTTP/1.1" 403 3297 "-" "curl/7.58.0"

并且当从 Internet 浏览器尝试相同时 https://FQDN/jenkins apache 日志首先显示 403,这是需要的,但在 apache 尝试在同一个 VM 中找到更改 url 而不是重定向后不久,因此我'我没有得到詹金斯页面。

165.225.106.137 - - [13/Dec/2019:13:38:19 +0000] "GET /jenkins HTTP/1.1" 403 3446 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"

165.225.106.137 - - [13/Dec/2019:13:38:19 +0000] "GET /jenkins HTTP/1.1" 403 1564 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"

165.225.106.137 - - [13/Dec/2019:13:38:20 +0000] "GET /login?from=%2F HTTP/1.1" 404 541 "https://DNSname/jenkins" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"

更改以下配置后现在可以使用 --

(1) Set the context path by modifying the jenkins.xml configuration file and adding --prefix=/jenkins (or similar) to the <arguments> entry.

https://wiki.jenkins.io/display/JENKINS/Running+Jenkins+behind+Apache

(2) 最初 -- RewriteRule ^jenkins$ login [L,R=302] 现在 -- RewriteRule ^/jenkins(.*)$ /

(3) 最初--

ProxyPass /jenkins balancer://jenkins/jenkins
ProxyPassReverse  /jenkins balancer://jenkins/jenkins
<Proxy balancer://jenkins>
    BalancerMember http://x.x.x.x:8080 loadfactor=1 keepalive=On retry=0
    ProxySet lbmethod=bytraffic
</Proxy>

现在--

ProxyPass /jenkins balancer://jenkins
ProxyPassReverse  /jenkins balancer://jenkins
ProxyRequests     Off
AllowEncodedSlashes NoDecode
<Proxy balancer://jenkins>
    BalancerMember http://x.x.x.x:8080/jenkins loadfactor=1 keepalive=On retry=0
    ProxySet lbmethod=bytraffic
</Proxy>