본문 바로가기

리눅스

[draft] NGINX에서 응답 헤더를 추가하는 방법

728x90

NGINX에서 응답 헤더를 추가하는 방법

NGINX는 웹 서버로서 클라이언트에게 응답을 보낼 때 다양한 정보를 포함하는 헤더를 함께 전송합니다. 이 헤더에 추가적인 정보를 포함시켜 서버의 동작을 조절하거나 클라이언트에게 특정한 정보를 제공할 수 있습니다.

왜 응답 헤더를 추가해야 할까요?

  • 캐싱 : 캐싱 지시를 추가하여 브라우저나 CDN에서 콘텐츠를 캐싱하도록 유도할 수 있습니다.
  • 보안 : 보안 관련 헤더를 추가하여 XSS, CSRF 등의 공격을 방어할 수 있습니다.
  • CORS : CORS 헤더를 추가하여 다른 도메인에서 자원을 요청할 수 있도록 허용할 수 있습니다.
  • 커스텀 정보 : 응용 프로그램에서 필요한 커스텀 정보를 추가할 수 있습니다.

1. 가상 호스트에서 헤더 추가하기(server 블록)

가상 호스트에 헤더를 추가하려면 server 블록 내에 add_header 지시어를 사용합니다.

vim /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name sangchul.kr www.sangchul.kr;

    # 보안 헤더 추가
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";

    location / {
        root /var/www/html;
        index index.html;
    }
}

2. 전역 설정에 헤더 추가하기(http 블록)

NGINX 전역 설정(/etc/nginx/nginx.conf)에서 모든 서버와 위치에 헤더를 적용하려면 http 블록에 추가합니다.

vim /etc/nginx/nginx.conf
http {
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";

    # 기타 설정
}

3. 특정 위치에 헤더 추가하기(location 블록)

특정 경로에만 헤더를 추가하고자 할 때는 location 블록에 추가할 수 있습니다.

vim /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name server_name sangchul.kr www.sangchul.kr;

    location /secure {
        add_header X-Frame-Options "DENY";
        add_header Cache-Control "no-store";
    }

    location / {
        # 다른 설정
    }
}

4. 설정 테스트 및 적용

NGINX를 재시작하여 변경사항을 적용합니다.

sudo nginx -t
sudo systemctl restart nginx

5. 적용된 헤더 확인

curl을 사용하여 응답 헤더를 확인할 수 있습니다.

curl -I http://sangchul.kr

(또는)

curl --resolve sangchul.kr:80:127.0.0.1 -I http://sangchul.kr
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Wed, 30 Oct 2024 00:36:27 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 12 Aug 2024 14:28:31 GMT
Connection: keep-alive
ETag: "66ba1c0f-267"
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Accept-Ranges: bytes
728x90

캐싱 관련 헤더 추가하기

캐싱을 통해 웹 페이지의 로딩 시간을 줄이고 서버 부하를 감소시킬 수 있습니다.

location /static {
    add_header Cache-Control "public, max-age=31536000"; # 캐싱 기간 1년
    expires 30d; # 만료 기간 설정
}
  • Cache-Control : public 설정을 통해 모든 사용자가 캐싱할 수 있도록 하고 max-age는 캐싱 유효기간을 초 단위로 지정합니다.
  • expires : 캐싱 기간을 지정하는 또 다른 방식입니다.

보안 관련 헤더 추가하기

보안 헤더는 XSS, 클릭재킹, MIME 타입 스니핑 등을 방지하는 데 도움이 됩니다.

add_header X-Frame-Options "SAMEORIGIN"; # 동일 출처에서만 iframe 허용
add_header X-Content-Type-Options "nosniff"; # MIME 타입 스니핑 방지
add_header X-XSS-Protection "1; mode=block"; # XSS 방지
  • X-Frame-Options : SAMEORIGIN을 설정하여 동일한 출처 내에서만 iframe 사용을 허용합니다.
  • X-Content-Type-Options : nosniff를 설정하여 브라우저가 MIME 타입을 강제로 변경하는 것을 방지합니다.
  • X-XSS-Protection : 브라우저의 XSS 필터를 활성화하여 탐지된 XSS 공격을 차단합니다.

CORS 허용 헤더 추가하기

CORS 헤더를 통해 다른 출처의 웹 애플리케이션이 현재 서버의 리소스에 접근할 수 있도록 허용할 수 있습니다.

add_header Access-Control-Allow-Origin "*"; # 모든 출처 허용 (보안상 필요에 따라 특정 출처만 허용)
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; # 허용할 HTTP 메서드
add_header Access-Control-Allow-Headers "Authorization, Content-Type"; # 허용할 헤더
  • Access-Control-Allow-Origin : CORS를 허용할 출처를 설정합니다. 보안상 가능한 특정 출처로 제한하는 것이 좋습니다.
  • Access-Control-Allow-Methods : 허용할 HTTP 메서드를 지정합니다.
  • Access-Control-Allow-Headers : 클라이언트에서 사용할 수 있는 헤더를 지정합니다.

HSTS (HTTP Strict Transport Security) 헤더 추가하기

HSTS 헤더는 HTTPS를 통한 보안을 강화하고 브라우저가 항상 HTTPS를 사용하도록 요구합니다.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

Strict-Transport-Security: HTTPS 연결을 강제하는 데 사용됩니다.

  • max-age : 브라우저가 HSTS 정책을 적용할 기간(초 단위).
  • includeSubDomains : 모든 하위 도메인에 대해 HSTS를 적용.
  • preload : HSTS 프리로드 리스트에 추가될 수 있도록 요청.

커스텀 정보 헤더 추가하기

서버에서 원하는 커스텀 정보를 응답 헤더로 추가할 수 있습니다. 예를 들어, 서버 버전이나 빌드 정보 등을 제공할 수 있습니다.

add_header X-Custom-Info "Server version 1.0";
  • X-Custom-Info: 사용자 정의 헤더로 서버의 특정 정보를 담을 수 있습니다.

적용된 헤더 확인

$ curl --resolve sangchul.kr:80:127.0.0.1 -I http://sangchul.kr
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Wed, 30 Oct 2024 00:47:17 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 12 Aug 2024 14:28:31 GMT
Connection: keep-alive
ETag: "66ba1c0f-267"
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Custom-Info: Server version 1.0
Accept-Ranges: bytes
$ curl --resolve sangchul.kr:80:127.0.0.1 -I http://sangchul.kr/static/gg
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Wed, 30 Oct 2024 00:47:23 GMT
Content-Type: application/octet-stream
Content-Length: 0
Last-Modified: Wed, 30 Oct 2024 00:46:43 GMT
Connection: keep-alive
ETag: "672181f3-0"
Expires: Fri, 29 Nov 2024 00:47:23 GMT
Cache-Control: max-age=2592000
Cache-Control: public, max-age=31536000
Accept-Ranges: bytes

각 설정에 따라 헤더가 올바르게 추가되었는지 확인할 수 있습니다.

 

참고URL

- Nginx Documentation : ngx_http_headers_module(add_header)

 

728x90