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
...