HTTP/2 421 Misdirected Request
목차
HTTP/2 에서 프록시를 경유하는 네트워크 환경 구축 시 발생하는 문제에 대한 내용 및 해결한 방법을 기술한다.
Config Network Setting
- 도메인
serv1.iasdf.com
과serv2.iasdf.com
을 HAProxy에 연결한다. - HAProxy를 다음과 같이 설정한다.
- 아래 호스트의 연결은 HTTP/2 L7 Load Balancing으로 설정한다.
-
serv1.iasdf.com
호스트는10.0.1.43
서버로 접속 -
serv2.iasdf.com
호스트는10.0.1.48
서버로 접속
- 웹 서버 두 대를 HTTP/2 프로토콜 통신이 가능하도록 설정한다.
- 요청을 크롬 브라우저의 Secret Tab을 이용하여 탭을 열어 각각의 서버에 접속한다.
- 탭 하나 (tab1)을 열어서
serv1.iasdf.com
에 접속한다.
- 탭 하나 (tab1)을 열어서
- 탭을 하나 더 열어서 (tab2)
serv2.iasdf.com
에 접속한다.
- 탭을 하나 더 열어서 (tab2)
HAProxy 설정 내용
HAProxy 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
frontend webserver_front_http2_connection_test
mode http
bind 10.0.1.49:443 ssl crt /path/to/cert.pem alpn h2
use_backend webserver_backend_http2_1 if { ssl_fc_sni serv1.iasdf.com }
use_backend webserver_backend_http2_2 if { ssl_fc_sni serv2.iasdf.com }
# use_backend webserver_backend_http2 if { ssl_fc_alpn -i h2 }
default_backend webserver_backend_http2_1
backend webserver_backend_http2_1
mode http
balance roundrobin
server server1 10.0.1.43:443 ssl verify none alpn h2
backend webserver_backend_http2_2
mode http
balance roundrobin
server server1 10.0.1.48:443 ssl verify none alpn h2
설정 완료 후 크롬 접속 스크린샷
Expected Action
-
serv1.iasdf.com
에 접속한 탭(tab1)은serv1.iasdf.com
에 대한 커넥션을 만들고 유지한다. -
serv2.iasdf.com
에 접속한 탭(tab2)은serv2.iasdf.com
에 대한 커넥션을 만들고 유지한다.
시퀀스 다이어그램
Current Action
탭을 열어 serv1 접속 후, serv2 접속 시에도 serv1 커넥션을 재사용하여 serv1 서버로 요청된다.
이러한 문제로 serv2.iasdf.com
도메인으로 요청했으나 serv1 페이지가 응답된다.
크롬에서 탭을 2개 열어서 서로 다른 도메인에 접속했지만,
serv2.iasdf.com 도메인 요청 시 serv2.iasdf.com
스크린샷 과 달리 serv1.iasdf.com
스크린샷 페이지가 응답된다.
이러한 문제는 프록시가 중개하여 발생하는데, 프록시에서 호스트에 따라 커넥션을 분배하기 때문에
serv1.iasdf.com
, serv2.iasdf.com
모두 목적지가 프록시 (10.0.1.49) 를 가리킨다.
즉 클라이언트(크롬)은 serv1, serv2 모두 목적지가 같다고 판단하고 커넥션을 재사용한다.
WireShark 패킷 분석 내용
Modify Action
sni를 비교하여 호스트가 다를 경우 HTTP/2 421 Misdirected Request
응답을 하도록 소스를 변경했다.
나와 같은 문제를 겪는 사람이 이미 있었는데, 링크를 첨부한다.
- https://stackoverflow.com/questions/48701719/http2-different-domain-but-same-ip-multiple-connection-or-one-connection
- 421 Code : https://httpwg.org/specs/rfc7540.html#MisdirectedRequest
In the rare case where a server gets a resource request for an authority (or scheme) it can’t serve, there’s a dedicated error code 421 in HTTP/2 that it can respond with and the browser can then go back and retry that request on another connection.
이 링크를 보면, 잘못된 요청을 받았을 때 HTTP/2 421 Misdirected Request
응답을 하도록 하라고 한다.
우선은 HAProxy의 코드를 수정해서 HTTP/2 421 Misdirected Request
응답을 하도록 했는데, 421 에러코드의 내용을 보면 “이 에러코드는 프록시에 의해 생성되어서는 안된다.” 라고 한다. (따라서 PR은 못 할듯)
The 421 (Misdirected Request) status code indicates that the request was directed at a server that is not able to produce a response. This can be sent by a server that is not configured to produce responses for the combination of scheme and authority that are included in the request URI.
Clients receiving a 421 (Misdirected Request) response from a server MAY retry the request — whether the request method is idempotent or not — over a different connection. This is possible if a connection is reused (Section 9.1.1) or if an alternative service is selected [ALT-SVC].
This status code MUST NOT be generated by proxies.
A 421 response is cacheable by default, i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [RFC7234]).
동작 과정은 아래와 같다.
새로운 커넥션으로 serv2.iasdf.com
에 접속하게 되어, serv2.iasdf.com
페이지가 응답된다.