امن سازی سرویس دهنده وب nginx قسمت اول

در این مقاله به بررسی نحوه امن سازی سرویس دهنده وب nginx بر روی لینوکس می پردازیم.

nginx-logo

 

توجه داشته باشید که شما میتوانید این مقاله را بر روی centos و debian مورد استفاده قرار دهید.

در ابتدای کار و قبل از شروع به امن سازی سرویس نیاز به امن سازی خود سیستم عامل است که شما میتوانید مقالات ۳ گانه آن را بتریتب قسمت اول , دوم و سوم را در سایت مطالعه کنید.

بعد از امن سازی سیستم عامل و مشخص کردن ماشنی که بر روی آن سرویس دهنده nginx نصب شده است نوبت به امن سازی آن میرسد.

۱- ابتدا nginx را با آخرین نسخه ارتقاع میدهیم .

yum update nginx (centos)

apt-get upgrade nginx

نکته: قبل از اجرای دستورات بالا یاید repository های خود را با استفادهاز دستور update  در yum و apt-get آپدیت کنید.

۲- مطمئن شوید که سرویس دهنده وب nginx با استفاده از کاربر nginx در حال اجراست و فایل هایی هم که اجرا میکند به همان کاربر متعلق است. برای این منظور دستورات زیر را اجرا کنید.

برای اطمینان از اینکه کاربر nginx وجود دارد یا نه از دستور زیر استفاده کنید .

id nginx

و برای عوض کردن صاحب یا ownership فایل ها بصورت زیر عمل کنید.

chown -R nginx:nginx /path/to/your/document

نکته: در صورتی که از پارتیشن جداگانه ای برای نکهداری قایل های nginx استفاده میکنید, آن پارتیشن را بصورت محدود و کنترل شده Mount کنید.

LABEL=/nginx    /nginx    ext3    defaults,nosuid,noexec,nodev 1 2

۳- در این مرحله باید کرنل سیستم را برای یک سرویس دهنده وب امن و tune کنیم . برای این منظور فایل /etc/sysctl.con را با ویرایشگر باز میکنیم و موارد زیر را در آن کپی میکنیم .

vi /etc/sysctl.conf

# Avoid a smurf attack
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Turn on protection for bad icmp error messages
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Turn on syncookies for SYN flood attack protection
net.ipv4.tcp_syncookies = 1
# Turn on and log spoofed, source routed, and redirect packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# No source routed packets here
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Turn on reverse path filtering
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Make sure no one can alter the routing tables
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Don’t act as a router
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Turn on execshild
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# Tune IPv6
net.ipv6.conf.default.router_solicitations = 0
net.ipv6.conf.default.accept_ra_rtr_pref = 0
net.ipv6.conf.default.accept_ra_pinfo = 0
net.ipv6.conf.default.accept_ra_defrtr = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.default.dad_transmits = 0
net.ipv6.conf.default.max_addresses = 1
# Optimization for port usefor LBs
# Increase system file descriptor limit
fs.file-max = 65535
# Allow for more PIDs (to reduce rollover problems); may break some
programs 32768
kernel.pid_max = 65536
# Increase system IP port limits
net.ipv4.ip_local_port_range = 2000 65000
# Increase TCP max buffer size setable using setsockopt()
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 87380 8388608
# Increase Linux auto tuning TCP buffer limits
# min, default, and max number of bytes to use
# set max to at least 4MB, or higher if you use very high BDP paths
# Tcp Windows etc
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_window_scaling = 1

نکته: شما میتوانید تمام ماژول های غیر ضروری nginx را که به آن احتیاج ندارید را از سرور پاک کنید.

۴- در این مرحله version header مربوط به سرویس دهنده nginx را تغییر میدهیم . برای این منظور بصورت زیر عمل میکنیم .

vi +48 src/http/ngx_http_header_filter_module.c

بعد از باز کردن فایل بالا بدنبال خطوط زیر در این فایل میگردیم.

static char ngx_http_server_string[] = “Server: nginx” CRLF;
static char ngx_http_server_full_string[] = “Server: ” NGINX_VER CRLF;

و بعد از پیدا کردن خطوط بالا آنها را بضورت زیر ویرایش میکنیم .

static char ngx_http_server_string[] = “Server: NowLearn Web Server” CRLF;
static char ngx_http_server_full_string[] = “Server: NowLearn Web Server” CRLF;

بعد از انجام کارهای بالا فایل /etc/nginx/nginx.conf را با ویرایشگرمان باز میکنیم و عبارت زیر را در سکشن server آن قرار میدهیم تا هر کسی که خواست از سرویس دهندده وب ما درخواست شماره نسخه آن را کند با خطا مواجه شود.

vi /etc/nginx/nginx.conf

server_tokens off

۵- در این مرحله با استفاده از iptables به بستن تمام پورت ها به جر پورت هایی را که نیاز است تا سرویس دهنده ما دیده شود می پردازیم.

برای این منظور اسکریپ زیر را در سیستم خود کپی و اجرا کنید.

توجه: باید آدرس IP های مربوط به سازمان خودتان را در آن قرار دهید و یا نام کارت شبکه خود را در آن با توجه به سیستمتان ویرایش کنید.

#!/bin/bash
IPT=”/sbin/iptables”
#### IPS ######
# Get server public ip
SERVER_IP=$(ifconfig eth0 | grep ‘inet addr:’ | awk -F’inet addr:’ ‘{
print $2}’ | awk ‘{ print $1}’)
LB1_IP=”<YOUR WEB SERVER PUBLIC IP>”
LB2_IP=”<YOUR WEB SERVER PUBLIC IP>”
# Do some smart logic so that we can use damm script on LB2 too
OTHER_LB=””
SERVER_IP=””
[[ “$SERVER_IP” == “$LB1_IP” ]] && OTHER_LB=”$LB2_IP” || OTHER_LB=”$LB1_IP” [[ “$OTHER_LB” == “$LB2_IP” ]] && OPP_LB=”$LB1_IP” || OPP_LB=”$LB2_IP”
### IPs ###
PUB_SSH_ONLY=”122.xx.yy.zz/29″
#### FILES #####
BLOCKED_IP_TDB=/root/.fw/blocked.ip.txt
SPOOFIP=”127.0.0.0/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 169.254.0.0/16 0.0.0.0/8 240.0.0.0/4 255.255.255.255/32 168.254.0.0/16 224.0.0.0/4 240.0.0.0/5 248.0.0.0/5 192.0.2.0/24″
BADIPS=$( [[ -f ${BLOCKED_IP_TDB} ]] && egrep -v “^#|^$” ${BLOCKED_IP_TDB})
### Interfaces ###
PUB_IF=”eth0″ # public interface
LO_IF=”lo” # loopback
VPN_IF=”eth1″ # vpn / private net
### start firewall ###
echo “Setting LB1 $(hostname) Firewall…”
# DROP and close everything
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
# Unlimited lo access
$IPT -A INPUT -i ${LO_IF} -j ACCEPT
$IPT -A OUTPUT -o ${LO_IF} -j ACCEPT
# Unlimited vpn / pnet access
$IPT -A INPUT -i ${VPN_IF} -j ACCEPT
$IPT -A OUTPUT -o ${VPN_IF} -j ACCEPT
# Drop sync
$IPT -A INPUT -i ${PUB_IF} -p tcp ! –syn -m state –state NEW -j DROP
# Drop Fragments
$IPT -A INPUT -i ${PUB_IF} -f -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL FIN,URG,PSH -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL ALL -j DROP
# Drop NULL packets
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL NONE -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” NULL Packets ”
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL NONE -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,RST SYN,RST -j DROP
# Drop XMAS
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,FIN SYN,FIN -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” XMAS Packets ”
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,FIN SYN,FIN -j DROP
# Drop FIN packet scans
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags FIN,ACK FIN -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” Fin Packets Scan ”
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags FIN,ACK FIN -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -j
DROP
# Log and get rid of broadcast / multicast and invalid
$IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type broadcast -j LOG –log-prefix ” Broadcast ”
$IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type broadcast -j DROP
$IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type multicast -j LOG –log-prefix ” Multicast ”
$IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type multicast -j DROP
$IPT -A INPUT -i ${PUB_IF} -m state –state INVALID -j LOG –log-prefix ” Invalid ”
$IPT
-A INPUT -i ${PUB_IF} -m state –state INVALID -j DROP
# Log and block spoofed ips
$IPT -N spooflist
for ipblock in $SPOOFIP
do
$IPT -A spooflist -i ${PUB_IF} -s $ipblock -j LOG –log-prefix ” SPOOF List Block ”
$IPT -A spooflist -i ${PUB_IF} -s $ipblock -j DROP
done
$IPT -I INPUT -j spooflist
$IPT -I OUTPUT -j spooflist
$IPT -I FORWARD -j spooflist
# Allow ssh only from selected public ips
for ip in ${PUB_SSH_ONLY}
do
$IPT -A INPUT -i ${PUB_IF} -s ${ip} -p tcp -d ${SERVER_IP} –destination-port 22 -j ACCEPT
$IPT -A OUTPUT -o ${PUB_IF} -d ${ip} -p tcp -s ${SERVER_IP} –sport 22 -j ACCEPT
done
# allow incoming ICMP ping pong stuff
$IPT -A INPUT -i ${PUB_IF} -p icmp –icmp-type 8 -s 0/0 -m state –state NEW,ESTABLISHED,RELATED -m limit –limit 30/sec
-j ACCEPT
$IPT -A OUTPUT -o ${PUB_IF} -p icmp –icmp-type 0 -d 0/0 -m state –state ESTABLISHED,RELATED -j ACCEPT
# allow incoming HTTP port 80
$IPT -A INPUT -i ${PUB_IF} -p tcp -s 0/0 –sport 1024:65535 –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o ${PUB_IF} -p tcp –sport 80 -d 0/0 –dport 1024:65535 -m state –state ESTABLISHED -j ACCEPT
# allow outgoing ntp
$IPT -A OUTPUT -o ${PUB_IF} -p udp –dport 123 -m state –state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i ${PUB_IF} -p udp –sport 123 -m state –state ESTABLISHED -j ACCEPT
# allow outgoing smtp
$IPT -A OUTPUT -o ${PUB_IF} -p tcp –dport 25 -m state –state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i ${PUB_IF} -p tcp –sport 25 -m state –state ESTABLISHED -j ACCEPT
### add your other rules here ####
#######################
# drop and log everything else
$IPT -A INPUT -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” DEFAULT DROP ”
$IPT -A INPUT -j DROP
exit 0

توجه کنید که اسکریپت بالا همه پورت ها را در سیستم میبندد بجز پورت ورودی ۸۰ و پروتکل icmp و پورتهای خروجی ۱۲۳ و ۲۵

نکته: شما میتوانید مازول mod_security را به عنوان WAF بر روی سرویس دهنده خود نصب کنید. (در مقاله ای جداگانه به بررسی این ماژول و تنظیمات آن خواهیم پرداخت.)

برای خواندن قسمت دوم اینجا را کیلیک کنید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *