Nginx
Nginx(엔진 x라 읽는다)는 웹 서버 소프트웨어로, 가벼움과 높은 성능을 목표로 한다. 웹 서버, 리버스 프록시 및 메일 프록시 기능을 가진다.
Netcraft의 2011년 1월 웹서버 설문조사에 따르면, nginx는 전체 도메인에서 4번째(7.50%)로 많이 쓰이는 웹서버이며, 활성화된 웹 사이트에 대한 통계에서도 역시 4번째(8.23%)로 많이 사용된다.
Nginx는 요청에 응답하기 위해 비동기 이벤트 기반 구조를 가진다. 이것은 아파치 HTTP 서버의 스레드/프로세스 기반 구조를 가지는 것과는 대조적이다. 이러한 구조는 서버에 많은 부하가 생길 경우의 성능을 예측하기 쉽게 해준다.
Categories
ETC
- OpenSSH
- Certbot (SSL)
- Web cache
- bunkerized-nginx - 보안 강화된 Nginx 도커 이미지
- Gixy - Nginx 보안 설정 분석 도구
- BunkerWeb - 클라우드 네이티브 웹 방화벽 오픈소스
How to install
Ubuntu 14.04
PGP 서명을 추가한다.
/etc/apt/sources.list파일에 아래 저장소를 추가한다.
deb http://nginx.org/packages/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/ubuntu/ trusty nginx
그리고 아래와 같이 설치한다.
Files
- Document Root
-
/usr/share/nginx/html/
- 설정 파일
-
/etc/nginx/
- 로그파일
-
/var/log/nginx/
Configuration
- Understanding the Nginx Configuration File Structure and Configuration Contexts
- NGINX - Alphabetical index of directives
Keepalive
요약하면,
client_max_body_size
Proxy
- Stackoverflow: NGinx config for redirecting domain
- Stackoverflow: route different proxy based on subdomain request in nginx
- Joinc: Proxy에 대하여
http {
server {
listen 80;
server_name service1.domain.com;
location / {
proxy_pass http://192.168.0.2:8181;
proxy_set_header host service1.domain.com
}
}
server {
listen 80;
server_name service2.domain.com;
location / {
proxy_pass http://192.168.0.3:8080;
proxy_set_header host service2.domain.com;
}
}
}
전달되는 서버에서 Redirect할 경우 URL 또는 포트번호가 달라진다면 아래와 같이 설정한다.
HTTPS
- How To Configure Nginx with SSL as a Reverse Proxy for Jenkins
- How To Create a SSL Certificate on Apache for Ubuntu 14.04
- OpenSSL 참조.
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name jenkins.domain.com;
ssl_certificate /etc/nginx/cert.crt;
ssl_certificate_key /etc/nginx/cert.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/jenkins.access.log;
location / {
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;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://localhost:8080;
proxy_read_timeout 90;
proxy_redirect http://localhost:8080 https://jenkins.domain.com;
}
}
HTTP Authentication
- How To Set Up HTTP Authentication With Nginx On Ubuntu 12.10
- How to use nginx to proxy to a host requiring authentication?
- Nginx - Forward HTTP AUTH - User?
Create User and Password:
Update Nginx configuration:
(Optional) Proxy forward:
Example
server {
listen portnumber;
server_name ip_address;
location / {
root /var/www/mywebsite.com;
index index.html index.htm;
auth_basic "Restricted"; #For Basic Auth
auth_basic_user_file /etc/nginx/.htpasswd; #For Basic Auth
}
}
NginX Cache
Reverse proxy항목을 우선적으로 참조.
NginX WebSocket Proxy
API 프록시 HTTPS 업스트림 지원
증상
BACKEND_ORIGIN=https://dhmc-api-dev.unwiki.net (Cloudflare 뒤 도메인)으로 배포하자 모든 /api/ 요청이 502 를 반환했다.
[error] SSL_do_handshake() failed (SSL: error:0A000410:SSL routines::ssl/tls
alert handshake failure:SSL alert number 40) while SSL handshaking to upstream,
request: "GET /api/status HTTP/1.1", upstream: "https://172.67.196.41:443/api/status",
host: "dhmc.unwiki.net"
백엔드 자체는 정상이었다. 직접 호출하면 200 과 {"db":"success","modbus":"success","health":"success"} 를 반환했다.
진단 시 주의점
로그의 업스트림 IP(172.67.196.41, 104.21.68.142)는 프론트엔드 도메인 dhmc.unwiki.net 의 IP 와 동일하다. 그러나 이는 자기참조가 아니다 — Cloudflare 가 여러 고객 도메인에 같은 anycast IP 를 배정하기 때문이다. IP 일치만으로 설정 오류를 단정하면 안 된다.
원인 (두 가지)
- 원인 1 — SNI 미전송
- nginx 의
proxy_ssl_server_name기본값은off다. SNI 없이 핸드셰이크하면, 한 IP 로 여러 도메인을 받는 엔드포인트(Cloudflare 등)는 어느 인증서를 내줄지 결정할 수 없어handshake failure(alert 40) 로 연결을 끊는다. nginx 는 이를 502 로 변환한다.proxy_ssl_name의 기본값이proxy_passURL 의 호스트이므로, 플래그만 켜면 올바른 SNI 가 나간다.
- 원인 2 — Host 헤더가 원본 도메인
-
proxy_set_header Host $host는 브라우저가 본 도메인(dhmc.unwiki.net)을 그대로 업스트림에 보낸다. 프론트엔드와 백엔드가 같은 리버스 프록시 뒤에 있으면, 그 프록시는 요청을 백엔드가 아닌 프론트엔드로 되돌린다 — 자기참조 루프가 되어 SNI 를 고친 뒤에도 502 가 유지된다.
검증
실제 nginx 컨테이너를 띄워 배포된 백엔드를 상대로 세 가지 설정을 비교했다.
| 설정 | |
| 수정 전 | 502 (운영 로그와 동일) |
| SNI 만 켜고 | 502 (원인만 바뀜 — 루프) |
| 수정 후 | 200 |
openssl 로 SNI 가설도 직접 재현했다.
| 명령 | 결과 |
| | |
| | 정상 ( |
수정 내용
location /api/ {
set $backend "${BACKEND_ORIGIN}";
proxy_pass $backend$request_uri;
proxy_http_version 1.1;
# 업스트림이 기대하는 호스트를 보낸다($proxy_host = BACKEND_ORIGIN 의 host[:port]).
proxy_set_header Host $proxy_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;
# BACKEND_ORIGIN 이 https 일 때 SNI 를 보낸다. http 업스트림에는 영향이 없다.
proxy_ssl_server_name on;
# ... (SSE 관련 설정은 기존 유지)
}
회귀 없음
- 목 백엔드로
http://업스트림을 테스트해 200 응답과/api접두어 유지를 확인했다. - 백엔드 FastAPI 는
Host도X-Forwarded-*도root_path도 읽지 않으므로, 원본 Host 를 잃어도 영향이 없다.
Load Balancing
아래 항목을 참조.
Performance Tunning
- 고성능 Nginx를위한 튜닝 - (1) 디스크의 I/O 병목 줄이기
- 고성능 Nginx를위한 튜닝 - (2) 프로세스 처리량 늘리기
- 고성능 Nginx를위한 튜닝 - (3) TCP 관련 처리량 늘리기
- [고성능 Nginx를위한 튜닝 - (4) 메모리 및 CPU 튜닝하기 (Processor)]
무중단 배포
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream docker-express {
server express1:3000;
server express2:3000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_http_version 1.1;
proxy_pass http://docker-express;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
Live Streaming
See also
- Upgrade - 실행중에 실행파일 업그레이드하기 (Nginx 가 사용하는 업그레이드 방식)
Favorite site
- NGINX web site
- Wikipedia (en) NGINX에 대한 설명
- Github - NginX - read-only mirror
- [추천] NGINX 소개
- 우분투에서 nginx 설치부터 무료 SSL 적용까지
- HTTP/2 성능 향상을 위한 NGINX 구조 개선 3
Documentation
- Module ngx_http_core_module Embedded Variables (내장변수) 포함.
Online tools
- nginx playground - Nginx 설정을 웹에서 테스트하고 공유할 수 있다.