내용 들어가기 전 용어 정의

Domain

domain

최상위 도메인(TLD: Top-Level Domain) : 인터넷 주소를 분류하는 역할을 한다.

ex) .com, .org, .net, .edu, .kr, .jp, .uk 

 

2차 도메인(SLD: Second-Level Domain) : 조직 또는 웹사이트의 고유 이름을 나타낸다.

ex) goole, naver, tistory, youtube

 

서브 도메인 : 주 도메인의 하위 영역을 나타낸다.

 

루트 도메인 : 도메인의 기본 주소로, 보통 SLD + TLD 조합으로 이루어진다.

 

SOP (Same-Origin Policy)

웹 브라우저가 보안을 위해 출처가 같은 리소스에 대해서만 요청을 허용하는 정책이다.

동일 출처는 프로토콜, 도메인, 포트가 모두 동일한 경우를 의미한다.

 

A 페이지: https://example.com

B 리소스: https://api.example.com

위 경우도 동일 출처가 아니다. 서브 도메인이 있어도 다른 출처로 여긴다. 

 

CORS (Cross-Origin Resource Sharing)

동일 출처 정책(Same-Origin Policy)을 우회할 수 있도록 설계된 메커니즘이다.

SOP는 웹 브라우저 정책이고, CORS는 서버 간 통신에서 발생하지 않는다.

 

포워드/리버스 프록시

특성 forward proxy reverse proxy
용도 클라이언트의 요청을 대신 전달 서버의 요청을 대신 처리
주요 목적 익명성 보호, 필터링, 차단 우회 부하 분산, 보안 강화, SSL 종료, 캐싱
대상 클라이언트 (사용자) 서버 (서비스 제공자)

forward는 인트라넷 생각하면 된다.

 

nginx 리버스 프록시로 CORS 해결하기

시스템 구성

도커로 구성한 시스템 예시

Host : 목표 지점 도메인

Origin : 출처 도메인

 

client <=> nginx

nginx에서 정적 파일(html, css...)을 서빙하고 있고, 클라이언트에서 자기 자신(nginx)으로 요청을 보내므로 Host와 Origin을 동일하게 할 수 있다.

 

nginx <=> 서버 (nginx.conf)

nginx 변수 예시

$http_host = 213.111.23.11:9999 (포트까지 포함한 host)

$host = 213.111.23.11 (포트 제외한 host)

# nginx.conf
        location /server {
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, PATCH' always;
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Vary' 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers' always;

            # Preflight 요청 처리 (OPTIONS)
            if ($request_method = 'OPTIONS') {
                add_header 'Content-Length' 0;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Access-Control-Max-Age' 7200;
                return 204;
            }

            proxy_pass http://server:9999;
            proxy_set_header Host $http_host;
            proxy_set_header Origin $scheme://$http_host;
            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;

            add_header Cache-Control "no-cache, no-store, max-age=0, must-revalidate";
            add_header Pragma "no-cache";
            add_header Expires "0";
            add_header Connection "keep-alive";
            add_header Keep-Alive "timeout=20";
            add_header X-Content-Type-Options "nosniff";
            add_header X-Frame-Options "DENY";
            add_header X-XSS-Protection "0";
            add_header Vary "Origin, Access-Control-Request-Method, Access-Control-Request-Headers";
        }

 

add_header는 클라이언트가 받을 응답에 대한 부분으로 서버에 전달되는 헤더 설정은 아니다.

 

정적 파일 서빙을 다른 origin에서 하고 리버스 프록시인 nginx로 요청을 보낸다면 다르겠지만,

클라이언트가 자신에게(nginx) 요청을 보낼 때, 위의 모든 add_header가 없어도 cors에 걸리는 건 없었다.

 

잘 동작한 proxy_set header 설정 방법들

X-aa-bb 헤더들은 CORS와 무관하다.

 

1. Origin 설정 없이 Host $http_host만

proxy_set_header Host $http_host;

 

1. Origin과 Host를 일치
    http_host를 사용하던, $host를 사용하던 Origin과 Host에 동일하게 적용하면 된다.

proxy_set_header Host $http_host;
proxy_set_header Origin $scheme://http_host;

==============================================
proxy_set_header Host $host;
proxy_set_header Origin $scheme://host;

 

1. Host를 설정하고 서버에서 설정한 allowOrigin도 가능하다.

proxy_set_header Host $http_host;
proxy_set_header Origin $scheme://abc:5555;

==========================================
proxy_set_header Host $host;
proxy_set_header Origin $scheme://abc:5555;

Origin 헤더를 제외하면 서버 간 통신으로 보고 CORS 메커니즘을 실행하지 않는 것 같고

모든 경우에서, 요청에 Host 헤더를 제외하면 Spring boot 다른 검증에서 400을 뱉는 것 같다.

 

( 추후에 이것저것 더 확인하고, 해당 포스팅 nginx.conf 수정, 보완 예정 )

 

 

'DevOps' 카테고리의 다른 글

docker-compose nginx load-balancing (spring, node, ws)  (0) 2023.08.28