我需要使用 NGINX 设置一个透明的 HTTP/HTTPS 服务器(代理 X),以便将具有所需授权的流量代理到代理端点(代理 Y)。代理端点 (B) 需要基本授权才能接受流量。
类比如下:
客户端C
请求URL(例如ifconfig.co)->自定义 DNS 将请求解析为代理X
->代理(X)
接受请求并操纵标头以添加基本身份验证->代理X
将请求转发到代理端点Y
它应该实现与以下 cURL 完全相同的结果:在这里我使用https://ifconfig.co检查端点 IP。
HTTP
curl -x http://proxy_endpoint:proxy_port -U 'username':'password' -k https://ifconfig.co
HTTPS
curl -x http://proxy_endpoint:proxy_port -U 'username':'password' -k https://ifconfig.co
测试:
为了测试设置,我在我的 Proxy X 服务器中添加了一条记录/etc/hosts
来解析ifconfig.co
然后我做了一个 cURL
#http
curl http://ifconfig.co
#https
curl https://ifconfig.co
成功的结果应该会给我端点代理的 IPY
HTTP 流量:
我已在网上广泛搜索使用 NGINX 模块的解决方案,并且在这里找到了一个非常有用的答案:https://serverfault.com/a/345244/954119
但是,这个答案只帮助我发送 HTTP 流量,而不是 HTTPS。以下是我在 nginx.conf 中为端口 80 上的 HTTP 配置的内容:
http {
include /etc/nginx/mime.types;
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;
sendfile on;
#tcp_nopush on;
keepalive_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
server {
listen *:80;
access_log /var/log/nginx/nginx.access.log;
error_log /var/log/nginx/nginx.error.log;
location / {
proxy_pass http://proxy_endpoint_Y:PORT;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy-Authorization "Basic base64-encoded-string";
}
}
}
因此我设置了监听端口 80 的http
指令,并配置了bas64 编码的用户名/密码。server
location
proxy_set_header Proxy-Authorization
这实际上非常有效,并将代理 HTTP(端口 80)流量代理到代理端点,但是 HTTPS 流量不起作用。
HTTPS 流量
因此,当我listen
改为443
:
http {
include /etc/nginx/mime.types;
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;
sendfile on;
keepalive_timeout 300;
server {
listen *:443;
access_log /var/log/nginx/nginx.access.log;
error_log /var/log/nginx/nginx.error.log;
location / {
proxy_pass http://proxy_endpoint_Y:PORT;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy-Authorization "Basic base64-encoded-string";
}
}
}
我的客户端上出现 cURL 错误C
:
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
在我的访问日志中,我收到一个非常奇怪的日志:
xx.xxx.xx.x - - [26/Mar/2022:21:43:54 +0000] "\x16\x03\x01\x00\xE1\x01\x00\x00\xDD\x03\x03W\x87>\x1E+1\xDFb\x13\x1E,\xC0\xE9\xEF\x07\xAB[\xEA!\xBE\x17\xC23\x8D\xBD\xA4\xEA\xB5\xD5s\x8AO\x00\x00\x5C\xC00\xC0,\xC0(\xC0$\xC0\x14\xC0" 400 157 "-" "-"
我只需要操纵 HTTPS 流量来添加授权标头?这可能吗?或者还有其他方法吗?
笔记:
我尝试使用stream
以前使用过的模块将 HTTPS 流量发送到端点,但没有授权,但在 NGINXstream
模块文档中我没有看到任何操作请求标头的选项。http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html
系统环境:
nginx 版本:nginx/1.21.6 由 gcc 9.3.0(Ubuntu 9.3.0-10ubuntu2)构建,使用 OpenSSL 1.1.1f 构建,2020 年 3 月 31 日启用 TLS SNI 支持