본문 바로가기
서버 인프라 실무

Nginx 서버 블록(server_name)로 도메인 연결: WWW/비WWW 선택과 301 리다이렉트, HTTP→HTTPS까지

by yamoojin83 2025. 10. 20.

Nginx 서버 블록(server_name)로 도메인 연결: WWW/비WWW 선택과 301 리다이렉트, HTTP→HTTPS까지

도메인을 연결하는 가장 깔끔한 방법은 Nginx 서버 블록(server block)을 분리하고, 하나의 대표 호스트(예: example.com)만 정식 서비스로 두며 나머지는 301 영구 리다이렉트로 통일하는 겁니다. 이 글은 Ubuntu 24.04 기준으로 DNS 설정 → 서버 블록 작성 → www/비www 리다이렉트 → HTTP→HTTPS 전환까지 현업에서 바로 쓰는 템플릿과 점검 루틴을 제공합니다.


1) 준비물 체크: DNS에 A/AAAA 레코드 추가

  • A 레코드(IPv4) : example.com → YOUR_SERVER_IPv4
  • AAAA 레코드(IPv6) : example.com → YOUR_SERVER_IPv6 (있다면)
  • 선택 : www.example.com도 동일 IP로 A/AAAA 설정

확인

# 로컬에서
dig +short A example.com
dig +short AAAA example.com

2) Nginx 설치와 폴더 구조

sudo apt update
sudo apt install -y nginx
# 표준 폴더
# ├─ /etc/nginx/nginx.conf
# ├─ /etc/nginx/sites-available/   (개별 서버 블록 정의)
# └─ /etc/nginx/sites-enabled/     (여기에 심볼릭 링크)

3) 대표 호스트를 먼저 정한다(예: 비WWW를 대표로)

SEO/브랜딩 관점에서 보통 비WWW(example.com)를 대표로 두고 www.example.com은 301 리다이렉트로 통합합니다. 반대로 운영 중인 서비스가 이미 www로 고정되어 있다면 대표를 www로 하고 비www를 리다이렉트하면 됩니다. 핵심은 “하나만 정식 서비스”라는 점입니다.


4) 서버 블록 템플릿(HTTP 단계) — 비WWW를 대표로

4-1) 서비스 서버 블록(비WWW)

sudo tee /etc/nginx/sites-available/example.com > /dev/null <<'NGINX'
server {
  listen 80;
  listen [::]:80;
  server_name example.com;

  # 애플리케이션(프록시) 또는 정적 루트 중 택1

  # (A) 리버스 프록시 예시
  location / {
    proxy_pass         http://127.0.0.1:8080;
    proxy_set_header   Host $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;
    proxy_http_version 1.1;
    proxy_set_header   Connection "";
    client_max_body_size 20m;
  }

  # (B) 정적 파일 서빙 예시 (A와 중복 사용 금지)
  # root /var/www/example.com/public;
  # index index.html;
}
NGINX

4-2) www 리다이렉트 전용 서버 블록

sudo tee /etc/nginx/sites-available/www.example.com > /dev/null <<'NGINX'
server {
  listen 80;
  listen [::]:80;
  server_name www.example.com;

  return 301 http://example.com$request_uri;
}
NGINX

4-3) 활성화 및 문법 검사

sudo ln -s /etc/nginx/sites-available/example.com     /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/www.example.com /etc/nginx/sites-enabled/

sudo nginx -t
sudo systemctl reload nginx

테스트

curl -I http://example.com
curl -I http://www.example.com    # 301로 example.com 이동 확인

5) HTTPS로 올리기(무료 인증서, Certbot)

실서비스는 HTTPS가 기본입니다. Nginx 플러그인으로 서버 블록을 자동 변환하면 HTTP → HTTPS 리다이렉트까지 한 번에 정리됩니다.

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# 이메일, 약관 동의, 리다이렉트(redirect) 선택 → 자동 구성

Certbot이 완료되면 /etc/nginx/sites-available/example.com443(SSL) 서버 블록HTTP→HTTPS 301으로 업데이트됩니다. 아래는 수동 설정 시 참고용 템플릿입니다.

5-1) 수동 템플릿(핵심만)

# HTTP → HTTPS 리다이렉트
server {
  listen 80;
  listen [::]:80;
  server_name example.com www.example.com;
  return 301 https://example.com$request_uri;
}

# HTTPS 서비스 (비WWW 대표)
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;

  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  # 보안 헤더(스니펫로 관리 권장)
  add_header X-Content-Type-Options "nosniff" always;
  add_header X-Frame-Options "SAMEORIGIN" always;
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;

  # 프록시 or 정적 선택
  location / {
    proxy_pass         http://127.0.0.1:8080;
    proxy_set_header   Host $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;
    proxy_http_version 1.1;
    proxy_set_header   Connection "";
    client_max_body_size 20m;
  }

  # 정적 예시(필요 시)
  # root /var/www/example.com/public;
  # index index.html;
}

테스트

curl -I http://example.com           # 301 → https://example.com
curl -I https://example.com          # 200 OK
curl -I https://www.example.com      # 301 → https://example.com

6) 대표 호스트를 WWW로 쓰는 경우(역전 템플릿)

www가 대표라면 반대로 작성하세요.

# HTTP → HTTPS 리다이렉트(두 호스트 모두 수신)
server {
  listen 80;
  listen [::]:80;
  server_name example.com www.example.com;
  return 301 https://www.example.com$request_uri;
}

# HTTPS 서비스 (www 대표)
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name www.example.com;

  ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

  # 이하 프록시/정적 동일
}

7) 다중 서비스 운영(서브도메인 분리)

API와 웹을 분리할 때는 api.example.com 서버 블록을 별도 파일로 만들어 독립 운영합니다.

sudo tee /etc/nginx/sites-available/api.example.com > /dev/null <<'NGINX'
server {
  listen 80;
  listen [::]:80;
  server_name api.example.com;

  location / {
    proxy_pass http://127.0.0.1:9000;
    proxy_set_header Host $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;
  }
}
NGINX

sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

8) 운영 팁(헤더·업로드·타임아웃 정합)

  • 업로드 제한: client_max_body_size 20m; (서비스 요구에 맞게 조정)
  • 타임아웃: 백엔드/프록시가 서로 다른 값이면 499/504가 증가합니다. proxy_read_timeout / keepalive_timeout / 백엔드 타임아웃을 표로 관리하세요.
  • 보안 헤더: X-Content-Type-Options, X-Frame-Options, Referrer-Policy 등은 스니펫로 묶어 재사용.

9) 점검 루틴(릴로드 전후 반드시 수행)

# 1) 설정 문법 검사
sudo nginx -t

# 2) 적용
sudo systemctl reload nginx

# 3) 열려 있는 포트 확인
ss -lntup | grep nginx

# 4) 외부에서 헤더/리다이렉트 검증
curl -I http://example.com
curl -I https://example.com

10) FAQ

Q1. www와 비www를 모두 서비스로 두면 안 되나요?
A. 권장하지 않습니다. 중복 콘텐츠로 간주될 수 있고, 쿠키·캐시·CORS 정책이 꼬일 수 있습니다. 하나를 대표로 두고 나머지는 301로 통일하세요.

Q2. HSTS는 바로 켤까요?
A. 검증 완료 후에 켜세요. 잘못 켜면 HTTP 접근이 완전히 차단되어 복구가 번거롭습니다. 운영 안정화 뒤에 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;를 적용하세요.

Q3. 인증서 자동 갱신은 어떻게 확인하죠?
A. Certbot은 시스템 타이머로 자동 갱신합니다. sudo systemctl status certbot.timer, sudo certbot renew --dry-run으로 점검하세요.


11) 최종 체크리스트

  • DNS A/AAAA가 서버 IP를 가리키는지
  • 대표 호스트 1개만 서비스, 나머지는 301 리다이렉트
  • HTTP→HTTPS 전환(301), 인증서 정상
  • 프록시/정적 중 하나만 사용, 업로드/타임아웃 합리값
  • nginx -t & reloadcurl -I로 최종 검증

이 구조로 올리면 도메인 라우팅이 단순·명확해지고, SEO/캐시/보안 정책도 한결 정리됩니다. 다음 글에서는 무료 SSL(HTTPS) 적용과 갱신 오류 트러블슈팅을 자세히 다루겠습니다.