【发布时间】:2019-12-13 08:32:18
【问题描述】:
对于以下配置,请求 2 没有反映在 nginx 中。没有错误日志,请求 2 的访问日志中也没有任何内容。
该问题仅在 100-Continue, 401 Unauthorized 作为初始响应引入后才开始出现。如果请求 1 得到代理服务器的 101 响应,则一切正常(结束 websocket 连接已建立)。
预期行为: 第二个请求应该成功到达代理,然后到达代理服务器。之后,它将被转换为 websocket 连接。
Nginx 配置
server {
listen 443 ssl;
server_name admin.example.com;
ssl_certificate /etc/nginx/server.pem;
ssl_certificate_key /etc/nginx/key.pem;
ssl_session_cache shared:SSL:5m;
ssl_protocols TLSv1.2;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ecdh_curve secp384r1;
server_name_in_redirect on;
client_max_body_size 100m;
location /my_line/ {
proxy_pass https://y.y.y.y/;
proxy_set_header Host y.y.y.y;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_ignore_client_abort on;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Origin '';
keepalive_timeout 100s;
proxy_set_header Expect $http_expect;
proxy_read_timeout 7200;
}
error_page 404 /index.html;
location / {
root /usr/share/nginx/html;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
}
}
请求 1:
GET /myserver/my_line/84620 HTTP/1.1
Connection: Upgrade
Authorization: Basic ODQ2MjA6c3MxOE1VRUs5UEF6RTB5eHoyVmpSZ0Roc3VyV0tCcA==
User-Agent: MyApp/WebSocketClient/
Host: x.x.x.x
Upgrade: websocket
Sec-WebSocket-Key: DhaIyjupEbTHXQvX3asVeA==
Sec-WebSocket-Protocol: Web_Proxy
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: mux
Expect: 100-continue
响应 1
HTTP/1.1 100 Continue
Server: nginx
Date: Mon, 09 Dec 2019 16:33:51 GMT
Connection: keep-alive
响应 2
HTTP/1.1 401 Unauthorized
Date: Mon, 09 Dec 2019 16:33:51 GMT
Expires: Mon, 09 Dec 2019 16:34:51 GMT
Cache-Control: private,max-age=60
WWW-Authenticate: Digest realm="WebSocket Group@myapp", domain="", nonce="f9beaf5521a1cdf078362b68a4332df5", algorithm=MD5
Server: MyServer/
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000
Content-Length: 0
请求 2
GET /myserver/my_line/84620 HTTP/1.1
Connection: Upgrade
Authorization: Digest username="84620", realm="WebSocket Group@myapp", nonce="f9beaf5521a1cdf078362b68a4332df5", uri="/myserver/my_line/84620", response="5d8bb7c396724bb840da698c06f19629", algorithm=MD5, nc=00000056
User-Agent: MyApp/WebSocketClient/
Host: x.x.x.x
Upgrade: websocket
Sec-WebSocket-Key: DhaIyjupEbTHXQvX3asVeA==
Sec-WebSocket-Protocol: Web_Proxy
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: mux
Issue -> nginx访问日志中没有反映第二个请求,错误日志中没有任何内容。
支持 nginx 将请求代理到代理服务器,而不做任何其他拥有它自己的事情。当从客户端触发 REQUEST2 时,客户端与代理、代理与代理服务器之间的 TCP 连接是完整的。我怀疑 nginx 的配置有问题 wrt 连接和升级标头。 我已经在 nginx 上捕获了所有的 wireshark,它清楚地表明 tcp 连接已经到位并且请求 2 是 nginx 的确认。只是 nginx 没有处理它——就好像它进入了黑洞而不是从中出来。
请求您的专家帮助。谢谢。
【问题讨论】:
-
这里要注意的一点是websocket代理的使用方式有所不同-nginx.com/blog/websocket-nginx。这里有多个HTTP请求在同一个tcp连接上流动,然后应该升级到ws。
-
为什么请求2中有不同的授权头和用户代理,你能解释一下原因吗?
-
这是用户代理的一种错字。我纠正了它,它们具有相同的价值。至于 Authorization 标头,值完全传递给代理服务器,是客户端和服务器之间设计的响应挑战机制。
标签: nginx websocket nginx-location nginx-config