25 Melhores práticas de segurança para o Nginx Web Server no Linux

Core NGINX agora é o servidor web Freenginx
Nginx

O Nginx é um servidor web/proxy reverso leve e de alto desempenho e proxy de e-mail (IMAP/POP3). Ele é executado em UNIX, GNU/Linux, variantes BSD, Mac OS X, Solaris e Microsoft Windows. De acordo com a Netcraft, 13,50% de todos os domínios na Internet usam o servidor web Nginx. Hoje, trazemos as melhores práticas de segurança para o servidor Nginx.

Ele é um dos poucos servidores escritos para solucionar o problema do C10K. Ao contrário dos servidores tradicionais, o Nginx não depende de threads para lidar com pedidos. Em vez disso, ele usa uma arquitetura muito mais escalável baseada em eventos (assíncrona). O Nginx alimenta vários sites de alto tráfego, como WordPress, Hulu, Github e SourceForge.

Arquivos de Configuração Padrão e Porta Nginx

  • /usr/local/nginx/conf/ ou /etc/nginx/ – Diretório de configuração do Nginx
  • /usr/local/nginx/conf/nginx.conf – Principal arquivo de configuração
  • /usr/local/nginx/html/ ou /var/www/html – Localização padrão dos arquivos
  • /usr/local/nginx/logs/ ou /var/log/nginx – Localização padrão dos logs
  • Porta HTTP padrão: TCP 80
  • Porta HTTPS padrão: TCP 443

Você pode testar as mudanças de configuração com o seguinte comando:

Terminal
/usr/local/nginx/sbin/nginx -t

ou

Terminal
nginx -t

Para carregar as mudanças de configuração:

Terminal
/usr/local/nginx/sbin/nginx -s reload

Ou

Terminal
nginx -s reload

Para parar o servidor, digite:

Terminal
/usr/local/nginx/sbin/nginx -s stop

Ou

Terminal
nginx -s stop

Melhores práticas de segurança para o servidor Nginx

1 – Habilite o SELinux

O Linux com segurança aprimorada (SELinux) é um recurso de kernel do Linux que fornece um mecanismo para suportar políticas de segurança de controle de acesso que oferecem uma ótima proteção. Pode interromper muitos ataques antes que seu sistema seja infectado. Veja como ativar o SELinux para sistemas baseados em CentOS/RHEL.

Faça um bloqueio booleano

Para proteger a máquina, e como parte das melhores práticas de segurança para Nginx, veja as configurações que estão configuradas em ‘on’ e mude para ‘off’ se elas não se aplicam à sua configuração com a ajuda do comando getsebool. Defina o SE Linux corretamente para manter a funcionalidade e a proteção.

Execute o comando getsebool -a e bloqueie o sistema:

Terminal
getsebool -a | less
getsebool -a | grep off
getsebool -a | grep on

2 – Permitir privilégios mínimos por meio de opções de montagem

Servir todas as suas páginas da web html e php através de partições separadas. Por exemplo, crie uma partição chamada /dev/sda5 e monte no /nginx. Certifique-se de que /nginx esteja montado com permissões noexec, nodev e nosetuid. Aqui está a minha entrada /etc/fstab para montagem /nginx:

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

Note que você precisa criar uma partição usando os comandos fdisk e mkfs.ext3.

3 – Hardening no arquivo /etc/sysctl.conf

Você pode controlar e configurar configurações de kernel e rede do Linux através do arquivo /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

# Tuen 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

4 – Como remover todos os módulos Nginx indesejados

Você precisa minimizar o número de módulos compilados diretamente no binário nginx. Isso minimiza o risco limitando os recursos permitidos pelo servidor web. Você pode configurar e instalar o nginx usando apenas os módulos necessários. Por exemplo, para desativar o módulo SSI e autoindex, você pode digitar:

Terminal
./configure --without-http_autoindex_module --without-http_ssi_module
make

Digite o seguinte comando para ver quais módulos podem ser ativados ou desativados ao compilar o servidor nginx:

Terminal
./configure --help | less

Desative os módulos nginx que você não precisa.

Alterar o cabeçalho da versão Nginx (Opcional)

Edite src/http/ngx_http_header_filter_module.c, digite:

Terminal
vi +48 src/http/ngx_http_header_filter_module.c

Ache a linha:

Terminal
static char ngx_http_server_string[] = "Server: nginx" CRLF; static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;

E mude para:

Terminal
static char ngx_http_server_string[] = "Server: Ninja Web Server" CRLF; static char ngx_http_server_full_string[] = "Server: Ninja Web Server" CRLF;

Salve e feche o arquivo. Agora, você pode compilar o servidor. Adicione o seguinte no nginx.conf para desligar o número da versão nginx exibido em todas as páginas de erro geradas automaticamente:

Terminal
server_tokens off

5 – Use mod_security (somente para servidores Apache no backend)

O mod_security fornece um firewall de nível de aplicativo para o Apache. Instale mod_security para todos os servidores web do Apache. Isso irá parar muitos ataques de injeção.

6 – Instale a política SELinux para proteger o servidor Web Nginx

Por padrão, o SELinux não protegerá o servidor web nginx. No entanto, você pode instalar e compilar a proteção da seguinte maneira. Primeiro, instale o suporte de tempo de compilação SELinux necessário:

Terminal
yum -y install selinux-policy-targeted selinux-policy-devel

Baixe as diretivas SELinux direcionadas para endurecer o servidor web nginx em servidores Linux da página inicial do projeto:

Terminal
cd /opt
wget http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz

Descompacte o arquivo:

Terminal
tar -zxvf se-ngix_1_0_10.tar.gz

Compile o arquivo:

Terminal
cd se-ngix_1_0_10/nginx
make

Exemplo de saída do Terminal:

Saída do Terminal
sempreupdate@lab:$ Compiling targeted nginx module /usr/bin/checkmodule: loading policy configuration from tmp/nginx.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 6) to tmp/nginx.mod Creating targeted nginx.pp policy package rm tmp/nginx.mod.fc tmp/nginx.mod

Instale o módulo nginx.pp SELinux resultante:

Terminal
/usr/sbin/semodule -i nginx.pp

7 – Acesso restrito com Firewall baseado em Iptables

O seguinte script de firewall bloqueia tudo e só permite:

  • Solicitações HTTP (Porta TCP 80) recebidas
  • Solicitações de ping ICMP recebidas
  • Pedidos de saída ntp (porta 123)
  • Pedidos de saída smtp (TCP porta 25)
Terminal
!/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="204.54.1.1" LB2_IP="204.54.1.2"   # 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

8 – Controlando ataques de estouro de buffer

Edite nginx.conf e defina as limitações do tamanho do buffer para todos os clientes.

Terminal
vi /usr/local/nginx/conf/nginx.conf

Edite e defina as limitações do tamanho do buffer para todos os clientes da seguinte maneira:

Terminal
Start: Size Limits & Buffer Overflows ## client_body_buffer_size 1K; client_header_buffer_size 1k; client_max_body_size 1k; large_client_header_buffers 2 1k; ## END: Size Limits & Buffer Overflows

Onde:

  • client_body_buffer_size 1k: (o padrão é 8k ou 16k) A diretiva específica o tamanho do buffer do corpo do pedido do cliente.
  • client_header_buffer_size 1k: A diretiva define o tamanho do buffer de cabeçalho para o cabeçalho da solicitação do cliente. Para a grande maioria dos pedidos, um tamanho de buffer de 1K é suficiente. Aumente isso se você tiver um cabeçalho personalizado ou um grande cookie enviado pelo cliente (por exemplo, cliente wap).
  • client_max_body_size 1k: A diretiva atribui o tamanho máximo aceito do pedido do cliente, indicado pela linha Content-Length no cabeçalho da solicitação. Se o tamanho for maior, o cliente obtém o erro “Request Entity Too Large” (413). Aumente isso quando você estiver recebendo uploads de arquivos através do método POST.
  • large_client_header_buffers 21k: A diretiva atribui o número e tamanho máximo de buffers para cabeçalhos grandes para ler a partir do pedido do cliente. Por padrão, o tamanho de um buffer é igual ao tamanho da página, dependendo da plataforma, seja 4K ou 8K, se no final da conexão de solicitação de trabalho converte para o estado keep-alive, esses buffers serão liberados. 2x1k aceitará URI de dados de 2kB. Isso também ajudará a combater erros e ataques DoS.

Você também precisa controlar os tempos limite para melhorar o desempenho do servidor e reduzir os clientes. Edite-o da seguinte maneira:

Terminal
Start: Timeouts ## client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; ## End: Timeouts
  • client_body_timeout 10: A diretiva define o tempo limite de leitura para o corpo de solicitação do cliente. O tempo limite é configurado apenas se um corpo não for inserido em um readstep. Se depois deste tempo o cliente não envia nada, o nginx retorna o erro “Solicitar tempo limite” (408). O padrão é 60.
  • client_header_timeout 10: A diretiva atribui tempo limite com a leitura do título do pedido do cliente. O tempo limite é configurado somente se um cabeçalho não for obtido em um passo de leitura. Se depois deste tempo o cliente não envia nada, o nginx retorna o erro “Solicitar tempo limite” (408).
  • keepalive_timeout 5 5: O primeiro parâmetro atribui o tempo limite para conexões keep-alive com o cliente. O servidor fechará conexões após esse tempo. O segundo parâmetro opcional atribui o valor do tempo no cabeçalho Keep-Alive: timeout = tempo da resposta. Este cabeçalho pode convencer alguns navegadores para fechar a conexão, de modo que o servidor não precisa. Sem esse parâmetro, o nginx não envia um cabeçalho Keep-Alive (embora isso não seja o que faz uma conexão “keep-alive”).
  • send_timeout 10: A diretiva atribui tempo limite de resposta ao cliente. O tempo limite é estabelecido não em transferência total de resposta, mas apenas entre duas operações de leitura, se depois deste tempo o cliente não demora nada, então o nginx está desligando a conexão.

9 – Controlar Conexões Simultâneas

Você pode usar o módulo Nginx Http Limit Zone para limitar o número de conexões simultâneas para a sessão atribuída ou, como caso especial, a partir de um endereço IP. Edite nginx.conf:

Terminal
Directive describes the zone, in which the session states are stored i.e. store in slimits. ### ### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ### limit_zone slimits $binary_remote_addr 5m;   ### Control maximum number of simultaneous connections for one session i.e. ### ### restricts the amount of connections from a single ip address ### limit_conn slimits 5;

A configuração acima limitará os clientes remotos a não mais de 5 conexões “abertas” simultaneamente por endereço IP remoto.

10 – Permitir acesso apenas a nosso domínio

Se o bot estiver fazendo apenas varredura aleatória do servidor para todos os domínios, basta negar isso. Você só deve permitir pedidos de proxy de domínio virtual ou reverso configurados. Você não deseja exibir solicitação usando um endereço IP:

Terminal
Only requests to our Host are allowed i.e. nixcraft.in, images.nixcraft.in and www.nixcraft.in if ($host !~ ^(nixcraft.in|www.nixcraft.in|images.nixcraft.in)$ ) { return 444; }

11 – Limitar Métodos Disponíveis

GET e POST são os métodos mais comuns na Internet. Os métodos do servidor da Web são definidos no RFC 2616. Se um servidor web não requer a implementação de todos os métodos disponíveis, eles devem ser desativados. O seguinte irá filtrar e permitir somente os métodos GET, HEAD e POST:

Terminal
Only allow these request methods ## if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } ## Do not accept DELETE, SEARCH and other methods

Mais sobre Métodos HTTP

  • O método GET é usado para solicitar um documento como https://sempreupdate.com.br/index.php.
  • O método HEAD é idêntico ao GET, exceto que o servidor NÃO DEVE retornar um corpo de mensagem na resposta.
  • O método POST pode envolver qualquer coisa, como armazenar ou atualizar dados, ou solicitar um produto, ou enviar e-mail enviando o formulário. Isso geralmente é processado usando o script do lado do servidor, como PHP, PERL, Python e assim por diante. Você deve usar isso se desejar carregar arquivos e processar formulários no servidor.

12 – Como eu recuso certos User-Agents?

Você pode facilmente bloquear agentes de usuário, ou seja, scanners, bots e spammers que podem estar abusando do seu servidor.

Terminal
Block download agents ## if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; }

Bloquear robôs chamados msnbot e scrapbot:

Terminal
## Block some robots ## if ($http_user_agent ~* msnbot|scrapbot) { return 403; }

Bloquear Spam de Referência

Referer spam é perigoso. Pode prejudicar o seu ranking de SEO através de web-logs (se publicado). Você pode bloquear o acesso de spammers com essas linhas.

Terminal
Deny certain Referers ### if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { # return 404; return 403; }

A imagem ou HTML hotlinking significa que alguém faz um link para o seu site para uma das suas imagens, mas a exibe em seu próprio site. O resultado final você acabará por pagar contas de largura de banda e tornar o conteúdo parecido com parte do site do sequestrador. Isso é geralmente feito em fóruns e blogs. Eu sugiro fortemente que você bloqueie e pare o hotlinking da imagem no próprio nível do servidor.

Terminal
Stop deep linking or hot linking location /images/ { valid_referers none blocked www.example.com example.com; if ($invalid_referer) { return 403; } }

14 – Restrições de Diretório

Você pode definir o controle de acesso para um diretório especificado. Todos os diretórios da Web devem ser configurados caso a caso, permitindo o acesso somente quando necessário.

Limitando o acesso por endereço IP

Você pode limitar o acesso ao diretório por endereço IP no diretório /docs/:

Terminal
location /docs/ { ## block one workstation deny 192.168.1.1; ## allow anyone in 192.168.1.0/24 allow 192.168.1.0/24;  ## drop rest of the world deny all; }

Proteger com senha o diretório

Primeiro crie o arquivo de senha e adicione um usuário chamado kallklen:

Terminal
mkdir /usr/local/nginx/conf/.htpasswd/
htpasswd -c /usr/local/nginx/conf/.htpasswd/passwd kallklen

Edite o nginx.conf e proteja os diretórios necessários da seguinte maneira:

Terminal
Password Protect /personal-images/ and /delta/ directories ### location ~ /(personal-images/.|delta/.) { auth_basic "Restricted"; auth_basic_user_file /usr/local/nginx/conf/.htpasswd/passwd; }

Uma vez que um arquivo de senha foi gerado, os usuários subsequentes podem ser adicionados com o seguinte comando:

Terminal
htpasswd -s /usr/local/nginx/conf/.htpasswd/passwd userName

15 – Configuração SSL

HTTP é um protocolo de texto simples e está aberto para monitoramento passivo. Você deve usar SSL para criptografar seu conteúdo para usuários. Uma opção gratuita de certificado SSL é a Let`s Encrypt, uma iniciativa trazida pelo Internet Security Research Group (ISRG).

16 – Dicas de segurança do Nginx e do PHP

O PHP é uma das linguagens de script mais populares do lado do servidor. Edite /etc/php.ini da seguinte maneira:

# Disallow dangerous functions disable_functions = phpinfo, system, mail, exec   ## Try to limit resources ##   # Maximum execution time of each script, in seconds max_execution_time = 30   # Maximum amount of time each script may spend parsing request data max_input_time = 60   # Maximum amount of memory a script may consume (8MB) memory_limit = 8M   # Maximum size of POST data that PHP will accept. post_max_size = 8M   # Whether to allow HTTP file uploads. file_uploads = Off   # Maximum allowed size for uploaded files. upload_max_filesize = 2M   # Do not expose PHP error messages to external users display_errors = Off   # Turn on safe mode safe_mode = On   # Only allow access to executables in isolated directory safe_mode_exec_dir = php-required-executables-path   # Limit external access to PHP environment safe_mode_allowed_env_vars = PHP_   # Restrict PHP information leakage expose_php = Off   # Log all errors log_errors = On   # Do not register globals for input data register_globals = Off   # Minimize allowable PHP post size post_max_size = 1K   # Ensure PHP redirects appropriately cgi.force_redirect = 0   # Disallow uploading unless necessary file_uploads = Off   # Enable SQL safe mode sql.safe_mode = On   # Avoid Opening remote files allow_url_fopen = Off

17 – Execute Nginx Em Uma Cadeia de Chroot (Containers) Se Possível

Colocar nginx em uma cadeia de chroot minimiza o dano causado por um possível bloqueio ao isolar o servidor da Web em uma pequena seção do sistema de arquivos. Você pode usar o tipo de configuração chroot tradicional com o nginx. Se possível, use reservatórios do FreeBSD, XEN, Linux em um Debian/Ubuntu, LXD em um Fedora ou OpenVZ que use o conceito de contêineres.

18 – Limite conexões por IP no nível de firewall

Um servidor web deve manter um olho nas conexões e limitar as conexões por segundo. Tanto Pf quanto iptables podem acelerar usuários finais antes de acessar seu servidor nginx.

IPTables

O exemplo a seguir negará conexões recebidas se o IP fizer mais de 15 tentativas de conexão na porta 80 dentro de 60 segundos:

/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set 
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --
seconds 60 --hitcount 15 -j DROP service iptables save

BSD PF

Edite seu /etc/pf.conf e atualize-o da seguinte maneira. A configuração limita o número máximo de conexões por fonte a 100. 15/5 especifica o número de conexões por segundo ou intervalo de segundos, ou seja, a taxa limita o número de conexões a 15 em uma extensão de 5 segundos. Se alguém romper as regras, adicione-os à nossa tabela abusive_ips e bloqueie-os para fazer conexões adicionais. Finalmente, a palavra-chave de descarga mata todos os estados criados pela regra de correspondência que se originam do host que excede esses limites.

webserver_ip="202.54.1.1"
table <abusive_ips> persist
block in quick from <abusive_ips>
pass in on $ext_if proto tcp to $webserver_ip port www flags S/SA keep state (max-src-conn 100, max-src-conn-rate 15/5, overload <abusive_ips> flush)

19 – Configurar o sistema operacional para proteger o servidor Web

Ative o SELinux conforme descrito acima. Defina as permissões corretas na raiz do documento / nginx. O nginx é executado como um usuário chamado nginx. No entanto, os arquivos no DocumentRoot (/nginx ou /usr/local/nginx/html) não devem ser de propriedade ou graváveis por esse usuário. Para encontrar arquivos com permissões erradas, use:

Terminal
find /nginx -user nginx
find /usr/local/nginx/html -user nginx

Certifique-se de alterar a propriedade do arquivo para root ou outro usuário. Um conjunto típico de permissão /usr/local/nginx/html:

Terminal
ls -l /usr/local/nginx/html/
-rw-r--r-- 1 root root 925 May 3 00:50 error4xx.html
-rw-r--r-- 1 root root 52 May 3 10:00 error5xx.html
-rw-r--r-- 1 root root 134 May 3 00:52 index.html

Você deve excluir arquivos de backup indesejados criados pelo vi ou outro editor de texto:

Terminal
find /nginx -name '.?' -not -name .ht -or -name '~' -or -name '.bak' -or -name '.old*'
find /usr/local/nginx/html/ -name '.?' -not -name .ht -or -name '~' -or -name '.bak' -or -name '.old*'

Passe -delete como opção para o comando find e irá livrar-se desses arquivos também.

20 – Restringir conexões Nginx de saída

Os crackers baixam o arquivo localmente em seu servidor usando ferramentas como o wget. Use iptables para bloquear conexões de saída do usuário nginx. O módulo ipt_owner tenta combinar várias características do criador de pacotes, para pacotes gerados localmente. É válido apenas na cadeia OUTPUT. Neste exemplo, permita que o usuário kallklen se conecte externamente usando a porta 80 (útil para o acesso da RHN ou para capturar atualizações do CentOS por repos):

Terminal
/sbin/iptables -A OUTPUT -o eth0 -m owner --uid-owner kallklen -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

Adicione a regra acima ao script de shell baseado em iptables. Não permita que o usuário do servidor web do nginx se conecte externamente.

21 – Mantenha seu software atualizado

Você deve manter seu software e kernel atualizados o tempo todo. Aplique o patch conforme sua versão ou distro. Se você estiver usando o comando apt-get Debian/Ubuntu Linux para aplicar patches:

Terminal
sudo apt-get update
sudo apt-get upgrade

Se estiver usando RHEL/CentOS/Oracle/Scientific Linux, use o yum:

Terminal
sudo yum update

22 – Evite clickjacking

Adicione o seguinte no seu nginx.conf ou domínio virtual para evitar clickjacking:

Terminal
add_header X-Frame-Options SAMEORIGIN;

23 – Desativar content-type sniffing em alguns navegadores

Adicione o seguinte no seu nginx.conf ou domínio virtual:

Terminal
add_header X-Content-Type-Options nosniff;

Habilitar Filtro Cross-site scripting (XSS)

Adicione o seguinte ao nginx.conf ou domínio virtual:

Terminal
add_header X-XSS-Protection "1; mode=block";

24 – Force o uso de HTTPS

Se você configurou o certificado SSL no seu servidor, não tem porque usar HTTP. Adicione a seguinte linha em seu nginx.conf na configuração do HTTP:

Terminal
return 301 https://$server_name$request_uri;

25 – Monitorando o Nginx

O Stub Status permite ver o número total de pedidos de clientes e outras informações. Para habilitá-lo adicione as seguintes linhas no contexto local do seu nginx.conf:

Terminal
location /nginx_status { # Turn on stats stub_status on; access_log off; # only allow access from 192.168.1.5 # allow 192.168.1.5; deny all; }

Dica extra: observando seus registros e auditoria

Verifique os arquivos de log. Eles vão lhe dar uma compreensão de quais ataques são lançados contra o servidor e permitir que você verifique se o nível de segurança necessário está presente ou não.

grep "/login.php??" /usr/local/nginx/logs/access_log
grep "...etc/passwd" /usr/local/nginx/logs/access_log
egrep -i "denied|error|warn" /usr/local/nginx/logs/error_log

Esse foi um hardening para seu servidor nginx. No entanto, você deve consultar mais recursos para as necessidades de segurança de suas aplicações web. Por exemplo, o Wordpress ou qualquer outro aplicativo de terceiros possui seus próprios requisitos de segurança.

Acesse a versão completa
Sair da versão mobile