PDA

View Full Version : Sử dụng nginx chống Slowloris HTTP DoS



canvu
23-08-2010, 10:33 PM
Đầu tiên làm cái này đã:
-reboot server
-log ssh
-chạy:

httpd stop

Nginx (tức là EngineX) là gì?


nginx [engine x] is a HTTP server and mail proxy server written by me (Igor Sysoev).

Thông tin chi tiết:
http://nginx.net/
Vậy chúng ta dùng Nginx( và module mod_rpaf của apache) chống dos như thế nào? Lý thuyết là sẽ dùng nginx như 1 proxy listen ở port 80 (mặc định http) ở server, apache sẽ listen ở 1 port khác chứ không phải port 80 như mặc định. Request đi vào port 80 sẽ đc nginx tiếp nhận, chuyển qua apache, sau đó nginx nhận dữ liệu trả về và gửi về client. Có thể nói nginx đóng vai trò như 1 proxy.

Bài viết mình test trên CentOS/WHM nhá ^-^
Đầu tiên, cài nginx:


rpm -Uvh http://download.fedora.redhat.com/pub/epel/5Server/x86_64/epel-release-5-3.noarch.rpm
yum install nginx

tiếp theo cài mod_rpaf

cd /usr/src
wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
tar -zxf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
/usr/local/apache/bin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

Sau đó vào WHM==> Service Configuration ==> Apache Configuration ==> Include Editor ==> Pre Main Include ( chọn version apache bạn đang dùng ở dưới)

LoadModule rpaf_module modules/mod_rpaf-2.0.so

RPAFenable On
# Enable reverse proxy add forward
RPAFproxy_ips 127.0.0.1 [Các ip mà server bạn dùng]
# which ips are forwarding requests to us
RPAFsethostname On
# let rpaf update vhost settings
# allows to have the same hostnames as in the "real"
# configuration for the forwarding Apache
RPAFheader X-Real-IP
# Allows you to change which header mod_rpaf looks
# for when trying to find the ip the that is forwarding
# our requests
Chỗ [các ip mà server bạn dùng] bạn lần lượt điền các ip mà sv bạn dùng, vd đối với X là

LoadModule rpaf_module modules/mod_rpaf-2.0.so

RPAFenable On
# Enable reverse proxy add forward
RPAFproxy_ips 127.0.0.1 74.55.113.71
# which ips are forwarding requests to us
RPAFsethostname On
# let rpaf update vhost settings
# allows to have the same hostnames as in the "real"
# configuration for the forwarding Apache
RPAFheader X-Real-IP
# Allows you to change which header mod_rpaf looks
# for when trying to find the ip the that is forwarding
# our requests

Kế tiếp tạo file config cho nginx



mkdir -p /usr/local/nginx/conf/
touch /etc/nginx/vhost.conf
ln -s /etc/nginx/vhost.conf /usr/local/nginx/conf/vhost.conf
ln -s /etc/nginx/nginx.conf /usr/local/nginx/conf/nginx.conf

Taọ 1 file /scripts/nginx.sh với nội dung:



#!/bin/sh

cat > "/usr/local/nginx/conf/nginx.conf" <<EOF
user nobody;
# no need for more workers in the proxy mode
worker_processes 1;

error_log /var/log/nginx/error.log info;

worker_rlimit_nofile XXX92;

events {
worker_connections 512; # increase for more busy servers
use epoll; # you should use epoll here for Linux kernels 2.6.x
}

http {
server_names_hash_max_size 2048;
server_names_hash_bucket_size 512;

include mime.types;
default_type application/octet-stream;

sendfile on;
tcp_nopush on;
tcp_nodelay on;

keepalive_timeout 10;

gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain text/html application/x-javascript text/xml text/css;
ignore_invalid_headers on;

client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 4k;
large_client_header_buffers 4 32k;
request_pool_size 4k;
output_buffers 4 32k;
postpone_output 1460;

include "/usr/local/nginx/conf/vhost.conf";
}

EOF

/bin/cp /dev/null /usr/local/nginx/conf/vhost.conf

cd /var/cpanel/users
for USER in *; do
for DOMAIN in `cat $USER | grep -a ^DNS | cut -d= -f2`; do
IP=`cat $USER|grep -a ^IP|cut -d= -f2`;
ROOT=`grep ^$USER: /etc/passwd|cut -d: -f6`;
echo "Converting $DOMAIN for $USER";

cat >> "/usr/local/nginx/conf/vhost.conf" <<EOF
server {
access_log off;

error_log /var/log/nginx/vhost-error_log warn;
listen 80;
server_name $DOMAIN www.$DOMAIN;

# uncomment location below to make nginx serve static files instead of Apache
# !WARNING!
# it will make the bandwidth accounting incorrect as these files won't be logged!
#location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html| js|css)$ {
# root $ROOT/public_html;
#}

location / {
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_send_timeout 90;
proxy_read_timeout 90;

proxy_buffer_size 4k;
# you can increase proxy_buffers here to suppress "an upstream response
# is buffered to a temporary file" warning
proxy_buffers 16 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

proxy_connect_timeout 30s;

proxy_redirect http://www.$DOMAIN:XXX http://www.$DOMAIN;
proxy_redirect http://$DOMAIN:XXX http://$DOMAIN;

proxy_pass http://$IP:XXX/;

proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
}
EOF
done
done


với XXX là port bạn muốn chạy apache (tất nhiên khác port 80), ví dụ nếu muốn apache listen ở 8080:

Code:


#!/bin/sh

cat > "/usr/local/nginx/conf/nginx.conf" <<EOF
user nobody;
# no need for more workers in the proxy mode
worker_processes 1;

error_log /var/log/nginx/error.log info;

worker_rlimit_nofile 808092;

events {
worker_connections 512; # increase for more busy servers
use epoll; # you should use epoll here for Linux kernels 2.6.x
}

http {
server_names_hash_max_size 2048;
server_names_hash_bucket_size 512;

include mime.types;
default_type application/octet-stream;

sendfile on;
tcp_nopush on;
tcp_nodelay on;

keepalive_timeout 10;

gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain text/html application/x-javascript text/xml text/css;
ignore_invalid_headers on;

client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 4k;
large_client_header_buffers 4 32k;
request_pool_size 4k;
output_buffers 4 32k;
postpone_output 1460;

include "/usr/local/nginx/conf/vhost.conf";
}

EOF

/bin/cp /dev/null /usr/local/nginx/conf/vhost.conf

cd /var/cpanel/users
for USER in *; do
for DOMAIN in `cat $USER | grep -a ^DNS | cut -d= -f2`; do
IP=`cat $USER|grep -a ^IP|cut -d= -f2`;
ROOT=`grep ^$USER: /etc/passwd|cut -d: -f6`;
echo "Converting $DOMAIN for $USER";

cat >> "/usr/local/nginx/conf/vhost.conf" <<EOF
server {
access_log off;

error_log /var/log/nginx/vhost-error_log warn;
listen 80;
server_name $DOMAIN www.$DOMAIN;

# uncomment location below to make nginx serve static files instead of Apache
# !WARNING!
# it will make the bandwidth accounting incorrect as these files won't be logged!
#location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html| js|css)$ {
# root $ROOT/public_html;
#}

location / {
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_send_timeout 90;
proxy_read_timeout 90;

proxy_buffer_size 4k;
# you can increase proxy_buffers here to suppress "an upstream response
# is buffered to a temporary file" warning
proxy_buffers 16 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

proxy_connect_timeout 30s;

proxy_redirect http://www.$DOMAIN:8080 http://www.$DOMAIN;
proxy_redirect http://$DOMAIN:8080 http://$DOMAIN;

proxy_pass http://$IP: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;
}
}
EOF
done
done

sau đó chạy:

/etc/init.d/nginx condrestart

chmod 755 /scripts/nginx.sh

/scripts/nginx.sh


Test xem file config của nginx cho nginx.sh tạo ra có dùng dc ko +_+

nginx -t

Gần xong gòi

Log vào WHM ==> Server Configuration ==> Tweak Settings==> The port on which Apache listens for HTTP connections ==> sửa 80 lại thành port bạn đã điền trong file config ở trên. (ví dụ port 8080).

Xong thì:


httpd restart
nginx

Bước cuối( cần làm nhá): dùng CSF (nếu pro thì iptables) chặn cái port apache listen lại ko cho incoming meo mèo méo (vd ở đây, chặn port 8080 lại).



http://teenkhanhhoa.com/forum/threads/820-Security-S%E1%BB%AD-d%E1%BB%A5ng-nginx-ch%E1%BB%91ng-Slowloris-HTTP-DoS

http://www.hvaonline.net/hvaonline/posts/list/20/29851.hva