Nginx 리다이렉트 설정 가이드

목차

Nginx는 가장 널리 사용되는 웹 서버 중 하나이며, 리다이렉트 설정은 운영의 기본입니다. 주요 도구인 returnrewrite는 자주 혼동되어 비효율적이거나 잘못된 설정의 원인이 됩니다.

return과 rewrite 비교

return (권장)

return 301 https://example.com;

rewrite (강력하지만 느림)

rewrite ^/old-path/(.*)$ /new-path/$1 permanent;

💡 기본 원칙

가능한 한 return을 사용하세요. 정규식 캡처 그룹이나 복잡한 URL 변환이 필요한 경우에만 rewrite를 사용합니다.

기본 예제

301 영구 리다이렉트

server {
    listen 80;
    server_name old-domain.com;
    return 301 https://new-domain.com$request_uri;
}

302 임시 리다이렉트

server {
    listen 80;
    server_name example.com;
    location /maintenance {
        return 302 /maintenance.html;
    }
}

단일 페이지 리다이렉트

location = /old-page.html {
    return 301 /new-page.html;
}

HTTP→HTTPS

권장: 별도의 server 블록

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    # 사이트 설정...
}

⚠️ if 디렉티브 사용 자제

Nginx 커뮤니티에는 "if는 악이다"라는 격언이 있습니다. if 디렉티브는 특정 컨텍스트에서 예상치 못한 동작을 일으킬 수 있습니다. HTTPS 리다이렉트에는 별도의 server 블록을 사용하세요.

www 정규화

non-www → www

server {
    listen 80;
    listen 443 ssl http2;
    server_name example.com;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    return 301 https://www.example.com$request_uri;
}

www → non-www

server {
    listen 80;
    listen 443 ssl http2;
    server_name www.example.com;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    return 301 https://example.com$request_uri;
}

경로 리다이렉트

# 디렉토리 리다이렉트 (접두사 제거)
location /blog/ {
    rewrite ^/blog/(.*)$ /articles/$1 permanent;
}

# map을 사용한 대량 리다이렉트 (대규모 목록에 효율적)
map $uri $new_uri {
    /old-page-1 /new-page-1;
    /old-page-2 /new-page-2;
}
server {
    if ($new_uri) { return 301 $new_uri; }
}

정규식 리다이렉트

# .html 확장자 제거
location ~ ^(.+)\.html$ {
    return 301 $1;
}

# 날짜 기반 URL 접두사 제거
location ~ ^/\d{4}/\d{2}/\d{2}/(.+)$ {
    return 301 /$1;
}

흔한 실수

1. rewrite 루프

# ❌ 무한 루프
location /old/ {
    rewrite ^/old/(.*)$ /new/$1;
}

# ✅ permanent 플래그 또는 return 사용
location /old/ {
    return 301 /new$request_uri;
}

2. 쿼리 문자열 손실

# ❌ 쿼리 문자열이 사라짐
location /old { return 301 /new; }

# ✅ 쿼리 문자열 유지
location /old { return 301 /new$is_args$args; }

3. HTTPS 대상의 SSL 설정 누락

HTTP → HTTPS로 리다이렉트하더라도 HTTPS server 블록에 유효한 인증서가 설정되어 있지 않으면 사용자는 연결 오류를 겪게 됩니다. 리다이렉트를 활성화하기 전에 반드시 HTTPS 블록의 존재와 인증서 유효성을 확인하세요.

성능 팁

리다이렉트 설정 후 301check.com으로 검증하세요.