nginx.conf 설정
문서 루트를 정의하고 php 와의 연동을 위한 설정을 한다.
root@wl ~ # vi /usr/local/nginx/conf/nginx.conf
...
thread_pool default threads=32 max_queue=65536; 1)
events {
use eventport; 2)
...
}
http {
server {
...
# 문서의 루트를 정의. /usr/local/nginx/html
location / {
...
root html;
...
}
# NGINX 상태 보기(http_stub_status_module 사용) 3)
location /nginx_status {
stub_status on;
access_log off;
allow w.x.y.z;
deny all;
}
...
# Fast-CGI로 PHP와 연동한다.
location ~ \.php$ { 4)
try_files $uri =404;
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
...
root@wl ~ #
1) thread_pool 을 사용하도록 한다. NGINX는 솔라리스 AIO를 지원하지 않기 때문에 aio threads구문은 지원하지 않는다.
2) 솔라리스 10에 추가된 Event Port를 사용하도록 해준다. 하지만 솔라리스 10의 커널 패치(102485이상)를 하지 않으면 커널 패닉이 일어날 수 있으니 반드시 패치한다. (솔라리스 10 u10을 사용하고 있다면 이미 패치 되어있다. Sun Alert 102485 Security Vulnerabilities in The Solaris Event Port API May Result in a Denial of Service (DoS) Condition을 읽어보자) 이 옵션을 지정하지 않으면 /dev/poll 을 사용한다. 이외에도 리눅스에서는 epoll, BSD계열은 kqueue 를 사용할 수 있다. 자세한 사항은 Optimizations - Nginx Community을 참고하자.
3) http://w.x.y.z/nginx_status 에 접속해보면 아래와 유사한 화면을 볼 수 있다.
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106
text/plain 형식으로 제공되기 때문에 커맨드라인 툴로 잘라내서 원하는 곳에서 사용할 수 있다. 의미는 다음과 같다.
- Active connections: 활성 커넥션 수
- accepts: 접속 승인 개수
- handled: 접속 처리 개수. 오류가 발생한 것이 아니라면, 일반적으로 accepts 와 동일하다.
- requests: 총 요청 건수. keep-alive 가 off 인경우 handled 와 requests 가 동일하다.
- 커넥션 수 상세
- Reading: 읽기(클라이언트에서 요청을 받음)중인 활성 커넥션 수
- Writing: 쓰기(클라이언트로 응답을 전송)중인 활성 커넥션 수
- Waiting: 대기중인 활성 커넥션 수
따라서 Active connections = Reading + Writing + Waiting 이 성립한다.
4) location블록이 여러개 있는 경우, 가장 긴 프리픽스에 매칭된 블록 한개만 실행된다. Beginner’s Guide를 읽어보자. 아파치 웹 서버의 Location 해석되는 방식과 다르다.
특정 국가의 IP 블록
GeoIP, GeoLiteCity 를 사용해 특정 국가를 블록할 수 있다. 속도는 생각만큼 느리지 않은 것으로 생각한다.
root@wl ~ # mkdir /usr/local/geoip
root@wl ~ # cd /usr/local/geoip
root@wl /usr/local/geoip # wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
root@wl /usr/local/geoip # gunzip GeoIP.dat.gz
root@wl /usr/local/geoip # wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
root@wl /usr/local/geoip # gunzip GeoLiteCity.dat.gz
nginx.conf 는 아래와 같은 설정을 추가한다. 이 설정은 중국IP를 블록한다.
root@wl ~ # vi /usr/local/nginx/conf/nginx.conf
...
http {
...
geoip_country /usr/local/geoip/GeoIP.dat;
geoip_city /usr/local/geoip/GeoLiteCity.dat;
...
map $geoip_country_code $ip_allow {
default yes;
cn no;
}
server {
...
if ($ip_allow = no) {
return 403;
}
}
}
root@wl ~ #
리버스 프록시(Reverse Proxy)
- 서문에도 나와있듯, 필자는 nginx 를 주로 리버스 프록시로 사용한다.
- nginx 를 웹 서버로 사용하기 보단 리버스 프록시 서버로 사용하고, 프록시 서버에서 gzip 압축을 통해 외부로 나가는 트래픽을 줄이도록 설정하자. 웹 서버는 '같은 호스트의 81번 포트'에서 서비스하고 있다고 가정한다. 설정 파일을 수정해야 할 곳이 많기 때문에 nginx의 전체 conf 파일을 싣는다. 그리고 이 설정은 필자가 사용하고 있는 설정과 비슷하다.
- proxy 로 설정한후, proxy_pass 지시자를 사용하는게 핵심이다. 단 프록시를 사용하는 곳이 더 비효율적인 경우에는 nginx 가 직접 호스트하도록 한다.
root@wl ~ # cat /usr/local/nginx/conf/nginx.conf
user nobody;
worker_processes 2;
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log logs/access.log;
sendfile on;
tcp_nopush on;
keepalive_timeout 5;
server_tokens off;
limit_conn_zone $binary_remote_addr zone=zoneone:10m;
gzip on;
gzip_comp_level 5;
gzip_http_version 1.0;
gzip_min_length 0;
gzip_types text/plain text/css image/x-icon application/x-javascript;
gzip_vary on;
geoip_country /usr/local/geoip/GeoIP.dat;
geoip_city /usr/local/geoip/GeoLiteCity.dat;
map $geoip_country_code $ip_allow {
default yes;
cn no;
}
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
client_header_buffer_size 64k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
proxy_busy_buffers_size 64k;
server {
listen 80;
server_name www.xxx.com;
access_log logs/www.xxx.com.access.log;
error_log logs/www.xxx.com.error.log debug;
location / {
proxy_pass http://localhost:81/;
limit_conn zoneone 10;
}
location = /_.gif {
empty_gif;
}
location /admin {
proxy_pass http://localhost:81/admin;
allow 127.0.0.1;
deny all;
}
location /images {
proxy_pass http://localhost:81/images;
expires max;
}
location /thumbimages {
proxy_pass http://localhost:81/images;
image_filter resize 150 100;
image_filter_buffer 1M;
image_filter_jpeg_quality 75;
error_page 415 = /_.gif;
}
location /share {
root /share/;
expires max;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
if ($ip_allow = no) {
return 403;
}
}
}
root@wl ~ #
아파치 로그파일에는 접속IP가 모두 nginx 가 설치된 서버의 IP로 저장된다. 따라서 http.conf 의 로그 포맷을 바꿔야 한다.
root@wl ~ # vi /usr/local/apache2/conf/httpd.conf
...
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
LogFormat "%{X-Real-IP}i:%{X-Real-PORT}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio-forward
...
SetEnvIf X-Real-IP "^.*\..*\..*\..*" forward
CustomLog "/var/log/httpd-access.log" combinedio-forward env=forward
CustomLog "/var/log/httpd-access.log" combinedio env=!forward
...