背景
最近在处理一个业务场景问题: 项目需要调用某个系统的接口,但是那个系统因为比较历史了,对接口调用来源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"显示 |