安装 jenkins 并启动后,此时访问地址是:http://localhost:8080
默认占用的是8080端口,且启动的是 http 服务,出于安全考虑,我打算改成 https。
采用的方案是:使用已经配置好 https 的 Ngixn 反向代理 Jenkins 服务。
下面是配置步骤:
修改 Jenkins 端口和根目录
修改配置文件中的下面两项配置即可
#启动端口修改为8899
JENKINS_PORT = "8899"
#根目录修改为/jenkins
JENKINS_ARGS="--prefix=/jenkins"
重启 Jenkins,此时 Jenkins 的访问地址是:http://localhost:8899/jenkins
配置 Nginx 代理
server {
listen 443 ssl;
server_name YOU_DOMAIN_NAME;
charset utf-8;
ssl_certificate YOU_CA;
ssl_certificate_key YOU_CA_KEY;
location /jenkins/ {
proxy_pass http://localhost:8899;
proxy_http_version 1.1;
http2_push_preload on; # Enable http2 push
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
}
}
重启 Nginx,此时直接访问 https://localhost/jenkins
也可以访问到 Jenkins 了。
ok,正常情况下到这里就配置完成了。但是我却多踩了两个坑。。。
因为我的Nginx 和 Jenkins 是部署在家里的电脑上(有公网ip),运营商80和443端口是关闭的,没法用!所以只能用路由器的端口转发功能。
路由器端口映射如下:
nginx监听端口 | 路由器转发端口 |
---|---|
443 | 2443 |
所以此时我访问 Jenkins 的地址就变成了:https://xxx.com:2443/jenkins/
,请求转发的路线如下图所示:
graph LR
A[用户] -->|https://xxx.com:2443/jenkins/ | B[路由器]
B -->|https://xxx.com/jenkins/ | C[Nginx]
C -->|http://localhost:8899/jenkins/| D[Jenkins]
第一个坑:
直接访问 https://xxx.com:2443/jenkins/
也没问题,也能访问到,但是!
一但 Jenkins 向前端返回302重定向,Nginx 会把重定向的地址设置成:https://xxx.com/jenkins/
。
端口没了,,,
首先想到的是这个配置:proxy_redirect 。
这个配置项的官方文档地址是:
Module ngx_http_proxy_module 。
这个配置的默认值是:proxy_redirect default,默认行为是:将后端返回的重定向 host 地址修改为 Nginx 服务器的 host 地址,端口变成 Nginx 的端口,所以重定向的地址是不带端口号的。
所以,解决思路也很简单了,就是在 Jenkins 返回重定向的时候要把 2443 端口号带上,修改 location 配置如下:
location /jenkins/ {
proxy_pass http://localhost:8001/jenkins/;
proxy_http_version 1.1;
http2_push_preload on; # Enable http2 push
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;#这个加上的话,jenkins返回的重定向地址会变成https://localhost:8001
#下面是解决重定向问题的配置
proxy_redirect http://localhost:8001 https://$http_host;
}
重新访问 https://xxx.com:2443/jenkins/
,登录后跳转没问题了!但是。。
第二个坑
但是,在管理台会有一个“反向代理设置有误”的提示。
打开浏览器控制台也会看到有请求报错,点击提示框中的“更多信息”按钮,会跳转到一个 Jenkins 文档地址:
原来,Jenkins 会自动识别 X-Forwarded-Proto、X-Forwarded-Host、X-Forwarded-Port 这些请求头,返回 302 重定向的时候会自动重定向到正确地址。
所以我参考 Jenkins 的 文档,修改 location 配置如下:
location /jenkins/ {
access_log logs/access.log;
proxy_pass http://localhost:8001/jenkins/;
proxy_http_version 1.1;
http2_push_preload on; # Enable http2 push
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
#下面是解决重定向问题的配置
# proxy_redirect http://localhost:8001 https://$http_host;
proxy_set_header X-Forwarded-Host $http_host;#这里用$http_host,$http_host包含端口,就不用了设置X-Forwarded-Port
}
重启 Nginx 后访问:https://xxx.com:2443/jenkins/
,登录成功。但是,控制台“反向代理设置有误”的提示依然存在。。。
面向搜索引擎一番之后,终于明白了这个问题的所在:
在 Jenkins 的管理台的 Configure System 配置模块中有一项 Jenkins URL 配置:
默认配置是什么我忘了,我之前已经顺手把它改成了:https://xxx.com:2443/jenkins/
,也就是我的 Jenkins 外网访问的根目录。
jenkins判断“反向代理设置有误”的依据就是:向这个 Jenkins URL 配置的地址发送一个请求,请求的末尾会携带 Jenkins 控制台的地址。完整请求示例如下:
https://xxx.com:2443/jenkins/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fxxx.com%3A2443%2Fjenkins%2Fmanage/
后端接到请求会对比请求的 host 和参数中控制台地址,如果一样就返回200,不一样就返回404错误,前端就根据返回结果是不是200来控制“反向代理设置有误”的提示框是否显示。所以 Jenkins URL 如果配置的不正确,也是会有“反向代理设置有误”的提示框的。
可是我配置的 Jenkins URL 是正确的,为什么也会有提示框?查看浏览器控制台的请求结果如下:
仔细看这个红框中的地址,原来 Jenkins 接收到的参数中少了个斜线,https://xxx.com:2443/jenkins/manager/
变成了 https:/xxx.com:2443/jenkins/manager/
。。。
造成斜线丢失的原因就是 当 proxy_pass 以 / 结尾时,Nginx 会对 request_url 进行处理,默认会合并 request_url 中相连的多个斜线为一个。
解决方案就是把 proxy_pass http://localhost:8001/jenkins/
修改为 proxy_pass http://localhost:8001
。
重启 Nginx 后,刷新页面,提示框消失。
另外我还根据 Jenkins Reverse proxy - Nginx 文档 增加了下面的配置:
#其他配置
proxy_max_temp_file_size 0;
#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
第三个坑
第三个坑同样是因为路由器端口映射造成的,也跟重定向有关。
现象是这样的,访问 http://xxx.com:2443/jenkins/
没问题,但是访问 http://xxx.com:2443/jenkins
的时候后 Nginx 发现没有匹配的文件 location 但是有匹配的目录 /jenkins/。此时 Nginx 会返回一个301 重定向,重定向的地址是:http://xxx.com/jenkins/
。端口又没了。。。
解决方案是在 server 中增加这条配置:absolute_redirect off; 加完后重定向的地址会变成相对地址:/jenkins/
可以用 curl 测试下:curl -v https://xxx.com:9443/jenkins
如果不生效可能是浏览器缓存原因,清下缓存就行了。
具体逻辑不想写了,累。。。看下面三个配置项的文档就明白了。
理论上还可以通过增加这样一个 location 来解决:
location /jenkins {
return 302 $scheme://$http_host/jenkins/;
}
没测试,不想试了。。。
总结
没有总结,累。
原文:https://blog.fengxiuge.top/2021/2021-05-08-nginx-reverse-proxy-jenkins.html