# @MAIL_HOST@ — 웹 메일함과 Resend 웹훅. POP3·IMAP·SMTP 포트는 Node 프로세스가 직접 엽니다. # # DNS: @MAIL_HOST@ 는 이 서버를 직접 가리키는 A 레코드여야 합니다(Cloudflare 를 쓰면 프록시 끔, 회색 구름). # 메일 프로그램 포트는 프록시를 지나지 못하고 공개 CA 인증서를 요구하므로 Let's Encrypt 인증서를 원본 서버에 둡니다. # # 인증서: certbot certonly --webroot -w @ACME_WEBROOT@ -d @MAIL_HOST@ (아래 경로가 만들어집니다) server { listen 80; listen [::]:80; server_name @MAIL_HOST@; location /.well-known/acme-challenge/ { root @ACME_WEBROOT@; } location / { return 301 https://@MAIL_HOST@$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name @MAIL_HOST@; ssl_certificate /etc/letsencrypt/live/@MAIL_HOST@/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/@MAIL_HOST@/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; server_tokens off; charset utf-8; client_max_body_size 32m; # 로그인 전용 화면: 색인·캐시·프레임 금지. 응답 헤더는 Node 도 같이 붙이지만 nginx 레벨에서도 보장합니다. add_header X-Content-Type-Options nosniff always; add_header Referrer-Policy no-referrer always; add_header X-Frame-Options DENY always; add_header X-Robots-Tag "noindex, nofollow" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always; add_header Cache-Control "no-store, no-transform" always; # 대용량 첨부파일 업로드(0.9.5): 본문 크기 제한을 두지 않고(크기는 Node 가 관리자·시스템 설정으로 거부) 버퍼링 없이 바로 흘려보냅니다. # 예전에는 server 블록의 client_max_body_size 32m 에 걸려 32MB 가 넘는 파일이 nginx 의 413(HTML)으로 끊겼고 화면에는 일반 오류만 보였습니다. # 버퍼링을 끄는 이유: 켜 두면 nginx 가 1GB 를 임시 파일에 다 받은 뒤 넘기므로 브라우저의 진행률은 100% 인데 서버 저장은 한참 뒤에 끝나고 디스크를 두 번 씁니다. location = /api/files { client_max_body_size 0; proxy_request_buffering off; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_pass http://127.0.0.1:@PORT@; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Prefix ""; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header CF-Connecting-IP ""; proxy_no_cache 1; proxy_cache_bypass 1; } # 대용량 첨부파일 다운로드 링크: 큰 파일을 오래 흘려보내므로 응답 버퍼링을 끄고 시간 제한을 넉넉히 둡니다. location /dl/ { proxy_buffering off; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_pass http://127.0.0.1:@PORT@; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Prefix ""; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header CF-Connecting-IP ""; proxy_no_cache 1; proxy_cache_bypass 1; } location / { proxy_pass http://127.0.0.1:@PORT@; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Prefix ""; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header CF-Connecting-IP ""; proxy_read_timeout 180s; proxy_no_cache 1; proxy_cache_bypass 1; } access_log /var/log/nginx/@APP_NAME@.access.log; error_log /var/log/nginx/@APP_NAME@.error.log; }