Bitacora config vps en OVH

Bitacora de configuración de un servidor web y email en un VPS de OVH. Como servidor web: nginx y como servidor de email: postfix con un servidor ubuntu 14.04.


KERNEL

 /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

 
REDIMENSIONADO PARTICION

  1. arrancar en modo rescate desde la consola de gestión de OVH.
  2. Reducir partición para crear una partición sin permisos de execución para dotar de mas seguridad al webserver / mysql
        - e2fsck -f /dev/sda1
        - resize2fs /dev/sda1 50G
   
        - fdisk -l /dev/sda -> ver donde se inicia la particion (bloque 4096)
        - fdisk /dev/sda -> d 1 -> borrar la particion 1
                                -> n, p, 1 -> crear particion nueva primaria la nº 1
                                -> el primer sector que sea igual que la original (4096) y de un tamaño ligeramente superior a lo que hemos puesto en el resize2fs
                                -> w -> escribir cambios

        - resize2fs /dev/sda1
  1. Crear particion nueva en el hueco que hemos generado para tener nuestra nueva particion para datos. Crear el sistema de archivos: mkfs.ext4 /dev/sda3
  2. Montar / y Modificar el fstab para que la monte con opciones de seguridad (rw,auto,nouser,nodev,noexec,nosuid,async (defaults pero con noexec)).
  3. Reiniciar


MYSQL

Este post se explica
Al finalizar ejecutar: mysql-secure-installation


NGINX

  1. apt-get install ngingx php5-fpm php-pear php5-mysql
  2. /etc/php5/fpm/php.ini -> poner cgi.fix_pathinfo = 0
  3. /etc/php5/fpm/pool.d/www.conf -> listen = /var/run/php5-fpm.sock  -> para conectar con php por socket y no por TCP.
  4. Protección a /etc/ngingx/nginx.conf
 
 http {
        ##
        # Basic Settings
        ##
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        ##keepalive_timeout 65;
        types_hash_max_size 2048;
        server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

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

        ##
        # Buffer overflow
        ##
        client_body_buffer_size 128K;
        #client_header_buffer_size 4 256K;
        #client_max_body_size 1K;
        large_client_header_buffers 4 256K;
        client_body_timeout 10;
        client_header_timeout 10;
        keepalive_timeout 5 5;
        send_timeout 10;

        ##
        # Limits
        ##
        limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
        limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=50r/s;
        limit_conn conn_limit_per_ip 20;
        limit_req zone=req_limit_per_ip burst=20;

  1.  Creamos los sitios web en /etc/nginx/sites-available y crear el correspondiente link en /etc/nginx/sites-enabled
 Fallback.conf:
   server {
        listen ip:80;
        server_name "";
        return 444; 
    }

    server {
        listen ip:80 default_server;
        server_name _;
        return 444;
   }
  
   site1.conf:
   server {
        listen ip:80;
        server_name site1.com www.site1.com;
        root /home/www/test1;
        index index.html index.htm index.php;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
                # Uncomment to enable naxsi on this location
                # include /etc/nginx/naxsi.rules
        }

        # errores los redirigimos
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;

        location = /50x.html {
                root /home/www/error;
        }
        location = /404.html {
                root /home/www/error;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
                try_files $uri = 404;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\. {
                deny all;
        }

        # en los directiorios de upload no damos php. OJO REVISAR LOS DIRECTIORIOS!!
        location ~* /(?:uploads|files)/.*\.php$ {
                deny all;
        }


FIREWALL

#!/bin/bash                                                                               
#################                                                                         
# FIREWALL script                                                                         
#################                                                                         
                                                                                          
ipt=/sbin/iptables                                                                        
EXTIP="ip"                                                                    
EXTIF="eth0"                                                                              
LOIF="lo"                                                                                 
                                                                                          
# Se bloquea todo                                                                         
$ipt -P INPUT DROP                                                                        
$ipt -P FORWARD DROP                                                                      
$ipt -P OUTPUT ACCEPT                                                                     
$ipt -F                                                                                   
$ipt -X bad_packets                                                                       
$ipt -X broadcasts                                                                        

# conexiones locales si
$ipt -A INPUT -i $LOIF -j ACCEPT
$ipt -A OUTPUT -o $LOIF -j ACCEPT

# creamos chain para paquetes malformados
$ipt -N bad_packets
$ipt -N broad$ipt -A bad_packets -p tcp ! --syn -m state --state NEW -j DROP
$ipt -A bad_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$ipt -A bad_packets -p tcp --tcp-flags ALL ALL -j DROP
$ipt -A bad_packets -p tcp --tcp-flags ALL NONE -j DROP
$ipt -A bad_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$ipt -A bad_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$ipt -A bad_packets -p tcp --tcp-flags FIN,ACK FIN -j DROP
$ipt -A bad_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
#byebye broadcasts, multicasts
$ipt -A broadcasts -m pkttype --pkt-type broadcast -j DROP
$ipt -A broadcasts -m pkttype --pkt-type multicast -j DROP
$ipt -A broadcasts -m state --state INVALID -j DROP

#####################################
# INPUT
####################################

# si los paquetes son ok permitimos las conexiones establecidas i pings
$ipt -A INPUT -i $EXTIF -j bad_packets
$ipt -A INPUT -i $EXTIF -j broadcasts
$ipt -A INPUT -i $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
$ipt -A INPUT -i $EXTIF -p icmp --icmp-type 8 -j ACCEPT

# Dejamos acceder por ssh i HTTP
$ipt -A INPUT -i $EXTIF -d $EXTIP -p tcp --dport 22 -j ACCEPT
$ipt -A INPUT -i $EXTIF -d $EXTIP -p tcp --dport 80 -j ACCEPT

#####################################
# OUTPUT
#####################################

#el usuario www-data no puede salir a internete
$ipt -A OUTPUT -o $EXTIF -m owner --uid-owner www-data -m multiport -p tcp --dports 80,21,23,22,443,445,8080,81 -j DROP

$ipt -A OUTPUT -o $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
#$ipt -A OUTPUT -o $EXTIF -p icmp --icmp-type 0 -j ACCEPT
#$ipt -A OUTPUT -o $EXTIF -p tcp --sport 22 -j ACCEPT
#$ipt -A OUTPUT -o $EXTIF -p tcp --sport 80 -j ACCEPT 
 

PHPMYADMIN

  1. apt-get install phpmyadmin mcrypt -> responder a las preguntas que si
  2. php5enmod mcrypt
  3. restart php5-fpm
  4. ln -s /usr/share/phpmyadmin /.../html
  5. mv /.../html/phpmyadmin /.../html/sqladmin
ahora el site que sirva /.../html se podra acceder al phpmyadmin a traves de site.com/sqladmin

Protejer directorio:

  1. apt-get install apache2-utils
  2. httpasswd -c /etc/nginx/pass --> introducir password
  3. chmod 640 /etc/nginx/pass
  4. chown root.www-data /etc/nginx/pass

crear en el archivo de configuración del site de nginx:

location /sqladmin {
               allow 127.0.0.1;
                allow ip;
                deny all;
                auth_basic "Login";
                auth_basic_user_file /etc/nginx/pass_sql;
  }       

No dejamos el acceso a root a phpmyadmin:

editar /etc/phpmyadmin/config.inc.php y buscar la linea:

    /* Authentication type */
    $cfg['Servers'][$i]['auth_type'] = 'cookie';

añadir:

    /* Authentication type */
    $cfg['Servers'][$i]['auth_type'] = 'cookie';
    $cfg['Servers'][$i]['AllowRoot'] = FALSE;


FAIL2BAN 

Para detener ataques de fuerza bruta usamos fail2ban contra el acceso SSH y el acceso a /sqladmin del SITE

- editamos el /etc/fail2ban/jail.conf
   -> ponemos mail de destino
   -> ponemos en ignoreip las ip que queremos que salten el filtro
   -> action = %(action_mwl)s
  
- comentamos los servicios que no queremos monitorizar dejando:

[ssh]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 6

[nginx-http-auth]
enabled = true
filter  = nginx-http-auth
port    = http,https
logpath = /var/log/nginx/error.log


POSTFIX 

Nos interesa recibir mails dirigidos a nuestos dominios (@site1, @site2, etc) y que estos sean reenviados a cuentas nuestras, es decir a gmail. P.e: un mail a comercial@site1.com -> mi sevidor postfix -> micuenta@gmail.com

  • apt-get install postfix -> aplicamos configuracion de Internet Site
  • modificamos /etc/postfix/main.cf:
smtpd_banner = MailServer
biff = no
append_dot_mydomain = no
readme_directory = no

smtpd_relay_restrictions = permit_mynetworks reject_unauth_destination
myhostname = vpsXXXXX.ovh.net
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
#myorigin = site1.com
mydestination = vpsXXXXX.ovh.net, localhost.ovh.net, , localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
disable_vrfy_command = yes
initial_destination_concurrency = 2
default_destination_concurrency_limit = 5
home_mailbox=Maildir/

#anti dos
default_process_limit = 100
smtpd_client_connection_count_limit = 10
smtpd_client_connection_rate_limit = 30
header_size_limit = 51200
message_size_limit = 10485760
smtpd_recipient_limit = 100

#redireccion de los @sites
virtual_alias_domains = site1.com site2.com
virtual_alias_maps = hash:/etc/postfix/virtual

  • en /etc/postfix/virtual:

contact@site1.com       micuenta@gmail.com
contact@site2.com       micuenta@gmail.com
@localhost                 root
@                                root
@vpsXXXXXX.net      root

De manera que si recibo un mail dirigido a contact@site1.com o site2.com lo envia a la cuenta de gmail. Cualquier otra cosa que se envie a los "mydestination" se envia al usuario local root.
 
OJO! gmail te puede tachar de spammer por lo que los registros de DNS i SPF deben estar bien configurados. Por lo que se puede hacer es redirigir los emails a una cuenta local del servidor + instalar un servidor pop3 para que mi cuenta de gmail se descarge los emails del servidor.


DOVECOT 

apt-get install dovecot-pop3d

/etc/dovecot/conf.d/10-auth.conf -> disable_plaintext_auth = no
/etc/dovecot/conf.d/10-master.conf -> inet_listener pop3s { port = 0 }
/etc/dovecot/conf.d/10-mail.conf -> mail_location = maildir:~/Maildir

Asi dejamos acceder al servidor por pop3 sin seguridad.

Configuramos postfix via /etc/postfix/virtual que entregue los correos a un usuario local sin permisos y sin capacidad de hacer login (/bin/false como shell). Configuramos la cuenta de google para que recupere por pop3 los mails de nuestro servidor de ese usuario.

Modificamos el script de firewall:

GOOGLE="64.18.0.0/20 64.233.160.0/19 66.102.0.0/20 66.249.80.0/20 72.14.192.0/18 74.125.0.0/16 173.194.0.0/16 207.126.144.0/20 209.85.128.0/17 216.58.208.0/20 216.239.32.0/19"

for ipgoogle in $GOOGLE
do
   $ipt -A INPUT -i $EXTIF -s $ipgoogle -d $EXTIP -p tcp --dport 110 -j ACCEPT
done

Así solo dejamos acceder al pop3 desde los servidores de google.

Comentarios