前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nginx代理出现403问题分析

Nginx代理出现403问题分析

作者头像
tunsuy
发布2023-08-19 09:45:47
1.7K0
发布2023-08-19 09:45:47
举报
文章被收录于专栏:有文化的技术人

背景

最近在处理一个业务场景问题: 项目需要调用某个系统的接口,但是那个系统因为比较历史了,对接口调用来源ip有严格限制,需要将来源ip添加为白名单,但是我们项目的这个工具是使用的serverless平台,无法知道具体的机器 ip,scf是即时性资源,因此来源ip肯定是变化的,因此决定通过一个代理来转发。

nginx配置

通过nginx来进行接口转发(nginx采用statefulset的固定ip部署),配置如下

代码语言:javascript
复制
user root;
worker_processes  auto;

error_log  /var/log/nginx/error.log;

pid        /var/log/nginx/nginx.pid;

events {
    worker_connections  1024;
}

http {
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    keepalive_timeout  65;


    upstream cmdb_server {
        server xxxx;
    }

    upstream xingyun_server {
        server xxxx;
    }

    server {
        listen 80;
        server_name xxxx;
        client_max_body_size 100M;
        proxy_read_timeout 120;

        location /cmdb {
            rewrite /cmdb/(.*)$ /$1 break;
            proxy_pass          http://cmdb_server;
        }

        location /xingyun {
            rewrite /xingyun/(.*)$ /$1 break;
            proxy_pass          http://xingyun_server;
        }
    }
}

问题描述

代码语言:javascript
复制
root@cmdb-proxy-0:/# curl -vvv http://9.139.61.234/xingyun/api/prm/prm_env_proxy/
*   Trying 9.139.61.234:80...
* Connected to 9.139.61.234 (9.139.61.234) port 80 (#0)
> GET /xingyun/api/prm/prm_env_proxy/ HTTP/1.1
> Host: 9.139.61.234
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Server: nginx/1.23.3
< Date: Fri, 03 Feb 2023 02:55:52 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 146
< Connection: keep-alive
< 
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host 9.139.61.234 left intact

测试发现访问该接口一直报403,

解决方法

经过了解,原来对端系统会校验请求header中的host(如果带了的话) 但是我这个访问明显没有带host啊,经过查阅资料,发现nginx会自动带上host字段,value为代理机器的ip,也就是访问url中的ip。

那就指定host试试:

代码语言:javascript
复制
root@cmdb-proxy-0:/# curl -vvv -H "Host:api.xingyun.tencentyun.com" http://9.139.61.234/xingyun/api/prm/prm_env_proxy/
*   Trying 9.139.61.234:80...
* Connected to 9.139.61.234 (9.139.61.234) port 80 (#0)
> GET /xingyun/api/prm/prm_env_proxy/ HTTP/1.1
> Host: api.xingyun.tencentyun.com
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Server: nginx/1.23.3
< Date: Fri, 03 Feb 2023 02:55:52 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 146
< Connection: keep-alive
< 
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host 9.139.61.234 left intact

结果还是报403,检查nginx配置才发现,没有设置host转发配置

更新配置如下:

代码语言:javascript
复制
location /xingyun {
    rewrite /xingyun/(.*)$ /$1 break;
    proxy_pass          http://xingyun_server;
    proxy_set_header Host $host;
}

加上proxy_set_header Host $host;这个

再次测试:

代码语言:javascript
复制
root@cmdb-proxy-0:/# curl -vvv -H "Host:api.xingyun.tencentyun.com" http://9.139.61.234/xingyun/api/prm/prm_env_proxy/
*   Trying 9.139.61.234:80...
* Connected to 9.139.61.234 (9.139.61.234) port 80 (#0)
> GET /xingyun/api/prm/prm_env_proxy/ HTTP/1.1
> Host:api.xingyun.tencentyun.com
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.3
< Date: Fri, 03 Feb 2023 02:55:25 GMT
< Content-Type: application/json
< Content-Length: 132
< Connection: keep-alive
< 
* Connection #0 to host 9.139.61.234 left intact
{"code": 6000, "message": "prm_env_proxy() missing 3 required positional arguments: 'interface', 'params', and 'env'", "data": null}root@cmdb-proxy-0:/# 
root@cmdb-proxy-0:/#

现在OK了。

知识点

变量

是否显示端口

值是否存在

host

"Host:value"显示值为a:b的时候,只显示a

http_host

"Host:value",value存在就显示

proxy_host

默认80不显示其他端口显示

"Host:value"显示

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有文化的技术人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • nginx配置
  • 问题描述
  • 解决方法
  • 知识点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档