Pasos para asegurar nuestro VPS

Este tutorial muestra cómo preparar y asegurar un Servidor Privado Virtual (Virtual Private Server, o VPS) con Debian GNU/Linux. Antes de comenzar, se asumen ciertas cosas:

  1. Se posee un nivel intermedio de familiaridad con GNU/Linux.
  2. Se posee un VPS para uso personal al cual tenemos acceso via SSH.
  3. El VPS tiene la ipv4 externa dedicada 250.250.250.155 y nuestro proveedor es propietario del bloque 250.250.0.0/16. (1)
  4. En nuestro VPS solamente tendremos habilitados para el acceso desde el exterior los servicios http, https y ssh.
  5. No se habilitará DNS externo puesto que usualmente se hace en el panel de nuestro proveedor. (2)
  6. Se trabajará como superusuario.

Instalación

Como primer paso, actualicemos el servidor e instalemos algunos paquetes que necesitaremos:

# aptitude update & aptitude safe-upgrade
# aptitude -RvW install dropbear gesftpserver sslh iptables-persistent ulogd fail2ban nginx-light apache2-utils dnsutils telnet ghostscript poppler-utils zip unzip unrar-free p7zip-full less multitail tee mc

Configuración

Ahora vamos a crear un usuario de trabajo. Trabajar como root en un servidor es inseguro, de modo que primeramente crearemos un usuario especial:

adduser operador
usermod -aG sudo operador

El primer comando crea el usuario operador, el segundo lo agrega al grupo sudo, lo cual permitirá ejecutar aplicaciones como superusuario.

Ajustar los permisos para superusuarios

Como para trabajar regularmente utilizaremos el usuario operador anteriormente creado, necesitamos ajustar las opciones de ejecución de comandos como superusuario, para lo cual ejecutamos el siguiente comando:

visudo

Este comando básicamente permite modificar el archivo /etc/sudoers; en el cual deberíamos contener estas líneas:

Defaults env_reset,timestamp_timeout=0
%sudo ALL=(ALL:ALL) ALL

En la primera línea se agrega a los valores predeterminados la opción timestamp_timeout que permite establecer el tiempo de expiración (en minutos) de la contraseña cuando se ejecuta el comando sudo. El valor predeterminado es 5, pero en ocasiones esto es inseguro, por dos motivos:

  1. Si en un descuido abandonamos nuestro equipo con la sesión abierta antes que la contraseña expire, alguien podría ejecutar un comando como superusuario sin restricción alguna.
  2. Si por desconocimiento ejecutamos una aplicación o script que contiene código malicioso antes de que la contraseña expire, la aplicación podría tener acceso a nuestro sistema como superusuario, sin nuestro consentimiento explícito.

De manera que para evitar riesgos, hemos establecido el valor en cero, es decir, cada vez que se ejecute el comando sudo habrá que introducir la contraseña. Si se establece un valor negativo como -1 el efecto es que la contraseña no expire nunca, lo cual produciría el resultado opuesto al que deseamos.

En la segunda línea se aclara que el grupo sudo puede ejecutar cualquier comando en cualquier equipo, que es lo habitual, aunque puede ajustarse. (3) Hay quienes por comodidad ponen la línea de la siguiente manera para evitar tener que teclear la contraseña:

%sudo ALL=(ALL:ALL) NOPASSWD:ALL

No obstante, como explicamos antes esto es riesgoso, y por ello no es recomendable.

Deshabilitar reinicio

Por una cuestión de seguridad, también deshabilitaremos el reinicio utilizando la combinación de teclas Ctrl+Alt+Del, para lo cual debemos agregar esta línea en el archivo /etc/inittab:

ca:12345:ctrlaltdel:/bin/echo "Ctrl+Alt+Del se ha deshabilitado."

Reemplazar OpenSSH con DropBear

La mayoría de los VPS viene con OpenSSH instalado, lo cual sin dudas es muy útil, pero a menos que necesitemos explotar toda la funcionalidad de OpenSSH, hay alternativas más livianas para un VPS, como Dropbear, que suele ser suficiente para el uso habitual. No obstante, un inconveniente de esta aplicación es que no viene con un servidor SFTP integrado, y es por esto que al principio instalamos el paquete gesftpserver.

Para configurar Dropbear, modificaremos el archivo /etc/default/dropbear para que contenga estas dos líneas:

NO_START=0
DROPBEAR_EXTRA_ARGS="-w -p 127.0.0.1:22 -I 1200 -m"

La primera línea simplemente habilita el servicio, y la segunda hace varias cosas:

  1. Evita el acceso como root.
  2. Pone a escuchar el servicio en el puerto 22 de la interfaz local (más adelante explicaremos por qué).
  3. Establece el tiempo de espera (20 minutos).

SSLH

El puerto 22 (SSH) es bien conocido y generalmente es uno de los primeros que los hackers intentan vulnerar, de modo que en su lugar utilizaremos el puerto 443 (SSL). Sucede que ese puerto se utiliza para la navegación segura por HTTPS.

Por esto utilizaremos el paquete sslh que no es más que un multiplexador que analiza los paquetes que llegan al puerto 443, y los enruta internamente a un servicio u otro en dependencia de si el tipo de tráfico es SSH o SSL.

SSLH no puede escuchar en una interfaz donde ya esté escuchando otro servicio, y es por esto que anteriormente pusimos a escuchar Dropbear en la interfaz local.

Ahora lo que necesitamos hacer es indicar a sslh la interfaz y el puerto por el cual debe escuchar y hacia dónde redirigir los paquetes en dependencia del tipo de servicio, y para esto modificaremos el archivo de configuración /etc/default/sslh:

DAEMON=/usr/sbin/sslh
DAEMON_OPTS="--user sslh --listen 250.250.250.155:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"
RUN=yes

Finalmente, reiniciamos los servicios:

service ssh stop && service dropbear start && service sslh restart

Tras el comando anterior probablemente se interrumpa nuestra sesión segura, en cuyo caso basta con volver a iniciar sesión, pero esta vez con el usuario de trabajo y usando el puerto 443. Si la sesión no se interrumpe, de cualquier manera conviene cerrarla e iniciar nuevamente con los valores apropiados.

Si todo funciona correctamente, podemos seguir trabajando como root y si deseamos, desinstalar OpenSSH:

sudo su -
aptitude -r purge openssh-server

Cortafuegos

Lo próximo que realizaremos es separar los registros del cortafuegos hacia el archivo independiente /var/log/firewall.log para facilitar su posterior análisis, que es el motivo por el cual instalamos el paquete ulogd al inicio. Para esto editaremos el archivo /etc/logd.conf para ajustar la sección relevante:

[LOGEMU]
file="/var/log/firewall.log"
sync=1

A continuación, modificaremos el archivo de rotación de registros /etc/logrotate/ulogd para mantener una rotación diaria (con fecha) y guardar las salvas comprimidas en el directorio /var/log/ulog/:

/var/log/ulog/*.log /var/log/firewall.log {
  daily
  dateext
  missingok
  compress
  delaycompress
  sharedscripts
  create 640 root adm
  postrotate
    /etc/init.d/ulogd reload
    mv /var/log/firewall.log-*.gz /var/log/ulog/
  endscript
}

Entonces crearemos las reglas de netfilter ejecutando lo siguiente:

IPT=$(which iptables)
IPEXT=250.250.250.155
IPEXTBLK=250.250.0.0/16
IPBCAST=255.255.255.255
$IPT -F
$IPT -X
$IPT -Z
$IPT -A INPUT -i lo -j ACCEPT
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT
$IPT -A INPUT -m state --state INVALID -j ULOG --ulog-prefix IN_INVALID
$IPT -A INPUT -p igmp -j ULOG --ulog-prefix IN_IGMP
$IPT -A INPUT -m pkttype --pkt-type broadcast -j ULOG --ulog-prefix IN_BCAST
$IPT -A INPUT -m pkttype --pkt-type multicast -j ULOG --ulog-prefix IN_MCAST
$IPT -A FORWARD -j ULOG --ulog-prefix FORWARD
$IPT -N ICMP_IN
$IPT -A INPUT ! -i lo -p icmp -j ICMP_IN
$IPT -A ICMP_IN -p icmp -f -j ULOG --ulog-prefix IN_ICMP_FRAGMENTED
$IPT -A ICMP_IN -p icmp -m icmp -m length ! --length 28:1322 -j ULOG --ulog-prefix IN_ICMP_INVALIDSIZE
$IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-above 4/sec --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-name icmpflood -j ULOG --ulog-prefix IN_ICMP_FLOOD
$IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-upto 64kb/min --hashlimit-mode srcip --hashlimit-srcmask 24 --hashlimit-name icmpattack -j ULOG --ulog-prefix IN_ICMP_FLOOD
$IPT -A ICMP_IN -p icmp -m icmp -m u32 ! --u32 "0x4&0x3fff=0x0" -j ULOG --ulog-prefix IN_ICMP_ATTACK
$IPT -A ICMP_IN -p icmp -m icmp ! --icmp-type echo-request -m state --state NEW -j ULOG --ulog-prefix IN_ICMP_INVALID
$IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-request -j ULOG --ulog-prefix IN_ICMP
$IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-request -m limit --limit 1/sec --limit-burst 4 -j ACCEPT
$IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-reply -m limit --limit 2/sec --limit-burst 4 -j ACCEPT
$IPT -A ICMP_IN -p icmp -m icmp --icmp-type destination-unreachable -m limit --limit 2/sec --limit-burst 4 -j ACCEPT
$IPT -A ICMP_IN -p icmp -m icmp --icmp-type time-exceeded -m limit --limit 2/sec --limit-burst 4 -j ACCEPT
$IPT -A ICMP_IN -p icmp -m icmp --icmp-type parameter-problem -m limit --limit 2/sec --limit-burst 4 -j ACCEPT
$IPT -A ICMP_IN -j RETURN
$IPT -N UDP_IN
$IPT -A INPUT ! -i lo -p udp -j UDP_IN
$IPT -A UDP_IN ! -i lo ! -p udp -f -j ULOG --ulog-prefix IN_UDP_FRAGMENTED
$IPT -A UDP_IN -p udp -m udp --sport 53 -m length ! --length 28:576 -j ULOG --ulog-prefix IN_UDP_DNS_INVALIDSIZE
$IPT -A UDP_IN -p udp -m udp --dport 53 -m -state --state NEW -j ULOG --ulog-prefix IN_UDP_DNSREQUEST
$IPT -A UDP_IN -p udp -m udp --dport 53 -m -state --state NEW -j REJECT --reject-with icmp-port-unreachable
$IPT -A UDP_IN -p udp -m udp ! --sport 53 ! -s $IPEXTBLK ! -d $IPBCAST -m state --state NEW -j ULOG --ulog-prefix IN_UDP
$IPT -A UDP_IN -p udp -m udp -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A UDP_IN -j RETURN
$IPT -N TCP_IN
$IPT -A INPUT ! -i lo -p tcp -j TCP_IN
$IPT -A TCP_IN ! -i lo ! -p tcp -f -j ULOG --ulog-prefix IN_TCP_FRAGMENTED
$IPT -A TCP_IN -p tcp -m tcp --sport 53 -m state --state ESTABLISHED,RELATED -m length ! --length 513:1500 -j ULOG --ulog-prefix IN_TCP_DNS_INVALIDSIZE
$IPT -A TCP_IN -p tcp -m tcp --dport 53 -m state --state NEW -j ULOG --ulog-prefix IN_TCP_DNS
$IPT -A TCP_IN -p tcp -m tcp --dport 53 -m state --state NEW -j REJECT --reject-with icmp-port-unreachable
$IPT -A TCP_IN -p tcp -m tcp -m multiport ! --dports 80,443 -m state --state NEW -j ULOG --ulog-prefix IN_TCP
$IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -m hashlimit --hashlimit-upto 4/seg --hashlimit-burst 16 --hashlimit-mode srcip --hashlimit-name navreq -j ACCEPT
$IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m state --state ESTABLISHED -m connlimit ! --connlimit-above 16 -j ACCEPT
$IPT -A TCP_IN -p tcp -m tcp -m multiport ! --dports 80,443 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A TCP_IN -j RETURN
unset IPEXT
unset IPEXTBLK
unset IPBCAST
unset IPT

Con la configuración anterior, nuestro VPS debería quedar razonablemente asegurado, pero si deseamos podemos asegurarlo un poco más, para lo cual podemos usar algunas reglas más avanzadas.

No todos los VPS permiten la instalación de módulos extra para netfilter, pero uno muy útil es psd, que permite evitar los escaneos de puertos. Lamentablemente este módulo no viene integrado en netfilter por defecto, por lo que es necesario instalar ciertos paquetes y luego construir el módulo:

aptitude -RvW install iptables-dev xtables-addons-source module-assistant
module-assistant --verbose --text-mode auto-install xtables-addons-source

Una vez hecho lo anterior, podemos agregar una regla como esta:

iptables -A INPUT -m psd --psd-weight-threshold 15 --psd-delay-threshold 2000 --psd-lo-port-weight 3 --psd-hi-ports-weight 1 -j ULOG --ulog-prefix IN_PORTSCAN

La regla anterior básicamente significa que crearemos un contador que se incrementará en 3 cada vez que se intente acceder a un puerto inferior al 1024 y en 1 cada vez que se intente acceder a un puerto superior al 1023, y cuando este contador llegue a 15 en un lapso inferior a 20 segundos, se registrarán los paquetes mediante ulog como un intento de portscan. Igual podrían descartarse los paquetes de una vez, pero en este caso pretendemos utilizar fail2ban, que configuraremos más adelante.

Una vez creadas las reglas, debemos tomar ciertas precauciones para hacerlas persistentes, pues en caso contrario las perderemos al reiniciar el servidor. Hay varias maneras de lograr esto; en este tutorial utilizaremos el paquete iptables-persistent que instalamos al principio, que almacena las reglas en /etc/iptables/rules.v4 y /etc/iptables/rules.v6 para ipv6.

iptables-save > /etc/iptables/rules.v4

De hecho, aunque el uso de ipv6 en Cuba aun no está extendido, bien podríamos crear unas reglas básicas:

IPT=$(which ip6tables)
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT ! -i lo -m state --state ESTABLISHED,RELATED -j ACCEPT
unset IPT

Estas reglas también pueden hacerse persistentes:

ip6tables-save > /etc/iptables/rules.v6

Finalmente para mayor seguridad, limpiamos el registro del cortafuegos y reiniciamos los servicios:

echo -n > /var/log/firewall.log
service logrotate restart
service ulogd restart
service iptables-persistent restart

Nginx

Utilizaremos Nginx como servidor web, porque los VPS suelen tener una cantidad de memoria RAM reducida en comparación con un servidor real, de modo que generalmente conviene tener algo más liviano que Apache.

Antes de configurar Nginx, crearemos un certificado (sin contraseña) para su uso por HTTPS:

cd /etc/nginx
openssl genrsa -des3 -out cert.key 4096
cp -v cert.key cert.key.original
openssl req -new -key cert.key -out cert.csr
openssl rsa -in cert.key.original -out cert.key
openssl x509 -req -days 365 -in cert.csr -signkey cert.key -out cert.crt

Una vez realizado esto, crearemos un archivo de contraseñas para el usuario “elusuario”:

htpasswd -c .htpasswd elusuario

A continuación, modificaremos el archivo /etc/nginx/sites-available/default para ajustar las preferencias del sitio por defecto. Podría quedar aproximadamente así:

server {
  server_name localhost;

  index index.html index.htm default.html default.htm;
  root /var/www;

  location / {
    # establecer el orden de verificacion y la pagina a cargar, de no encontrarse la URI
    try_files $uri $uri/ /index.html;
  }
}

server {
  listen 127.0.0.1:443;
  server_name localhost;

  index index.html index.htm default.html default.htm;
  root /var/www;

  ssl on;
  ssl_certificate cert.crt;
  ssl_certificate_key cert.key;

  ssl_session_timeout 5m;

  # Habilitar HTTPS solo sobre TLS (mas seguro que SSL)
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  # dar preferencia a los cifrados de fuerza alta [HIGH],
  # mover los cifrados de fuerza media [MEDIUM] al final de la lista,
  # deshabilitar los cifrados de fuerza baja [LOW] (40 y 56 bits)
  # deshabilitar los cifrados con algoritmos de exportacion [EXP]
  # deshabilitar cifrados nulos [eNULL], sin autentificación [aNULL], SSL (versiones 2 y 3) y DSS (solo permite llaves de hasta 1024 bits)
  ssl_ciphers HIGH:+MEDIUM:!LOW:!EXP:!aNULL:!eNULL:!SSLv3:!SSLv2:!DSS;
  # Preferir los metodos de cifrado del servidor (por defecto se usan los del cliente)
  ssl_prefer_server_ciphers on;

  location / {
    # habilitar autentificacion
    auth_basic "Login";
    auth_basic_user_file /etc/nginx/.htpasswd;
    # establecer el orden de verificacion y el código de pagina a cargar, de no encontrarse la URI
    try_files $uri $uri/ =404;
    # permitir la creacion de un indice para los usuarios autentificados
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;
  }
}

Comprobamos que la configuración esté correcta:

nginx -t

Finalmente, reiniciamos el servicio:

service nginx restart

Fail2Ban

Antes de comenzar a configurar Fail2Ban, para mayor seguridad detenemos el servicio y limpiamos el registro:

fail2ban-client stop
echo -n > /var/log/fail2ban.log

A continuación, creamos el archivo de configuración /etc/fail2ban/jail.local con el siguiente contenido personalizado:

# Custom configuration file /etc/fail2ban/jail.local
#
[DEFAULT]
findtime = 43200 ; 12 hours
bantime = 86400 ; 1 day
maxretry = 3 ; ban will take effect after the 4th attempt

[ssh]
enabled = false

[nginx-auth]
enabled = true
filter = nginx-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath = /var/log/nginx*/*error*.log

[nginx-badbots]
enabled = true
filter = apache-badbots
action = iptables-multiport[name=BadBots, port="http,https"]
logpath = /var/log/nginx*/*access*.log
bantime = 604800 ; 1 week
maxretry = 0

[nginx-login]
enabled = true
filter = nginx-login
action = iptables-multiport[name=NoLoginFailures, port="http,https"]
logpath = /var/log/nginx*/*access*.log
bantime = 1800 ; 30 minutes

[nginx-noscript]
enabled = true
action = iptables-multiport[name=NoScript, port="http,https"]
filter = nginx-noscript
logpath = /var/log/nginx*/*access*.log
maxretry = 0

[nginx-proxy]
enabled = true
action = iptables-multiport[name=NoProxy, port="http,https"]
filter = nginx-proxy
logpath = /var/log/nginx*/*access*.log
bantime = 604800 ; 1 week
maxretry = 0

[firewall]
enabled = true
action = iptables-multiport[name=Firewall]
filter = firewall
logpath = /var/log/firewall.log
maxretry = 0

Una vez realizado esto, creamos en el directorio /etc/fail2ban/filters.d/ los siguientes archivos:

# /etc/fail2ban/filter.d/nginx-auth.conf
# Auth filter
# Blocks IPs that fail to authenticate using basic authentication
#
[Definition]
failregex = no user/password was provided for basic authentication.*client: <HOST>
user .* was not found in.*client: <HOST>
user .* password mismatch.*client: <HOST>
ignoreregex =
# /etc/fail2ban/filter.d/nginx-login.conf
# Login filter
# Blocks IPs that fail to authenticate using web application's log in page
# Scan access log for HTTP 200 + POST /sessions => failed log in
#
[Definition]
failregex = ^<HOST> -.*POST /sessions HTTP/1\.." 200
ignoreregex =
# /etc/fail2ban/filter.d/nginx-noscript.conf
# Noscript filter
# Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts.
# Matches e.g.
# 192.168.1.1 - - "GET /something.php
#
[Definition]
failregex = ^<HOST> -.*GET .*(\.php|\.asp|\.exe|\.pl|\.cgi|\scgi)
ignoreregex =
# /etc/fail2ban/filter.d/proxy.conf
# Proxy filter
# Block IPs trying to use server as proxy.
# Matches e.g.
# 192.168.1.1 - - "GET http://www.something.com/
#
[Definition]
failregex = ^<HOST> -.*GET http.*
ignoreregex =
# /etc/fail2ban/filter.d/firewall.conf
# Firewall filter
#
[Definition]
failregex = ^.* IN_(INVALID|PORTSCAN|UDP|TCP|) .* SRC=<HOST> .*$
ignoreregex =

Finalmente, iniciamos el servicio y cargamos la configuración:

fail2ban-service -b
fail2ban-client reload

Comprobación

Como último paso, podemos visualizar los registros con tail -f o multitail –follow-all. De hecho, esta última aplicación ofrece la ventaja de que permite visualizar varios archivos al mismo tiempo y proporciona un resaltado de sintaxis básico.

En caso de que no se configure en el VPS una cuenta de correo, conviente deshabilitar un mensaje de advertencia que sale al iniciar multitail, para lo cual ejecutaremos el siguiente comando:

echo "check_mail:0" > ~/.multitailrc

De hecho bien podríamos hacer un alias (4) para visualizar los registros rápidamente con un comando breve, por ejemplo, “flog”:

alias flog='multitail --follow-all /var/log/firewall.log /var/log/fail2ban.log'

1) Estos son valores ficticios.
2) Habilitar otros servicios es fácil una vez comprendido el funcionamiento.
3) Para más detalles, ejecutar man sudoers.
4) Opcionalmente podría añadirse al archivo ~/.bash_aliases


6 comentarios, deja el tuyo

Deja tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.

  1.   msx dijo

    Hay algunas cosas interesantes, +1

  2.   Yukiteru dijo

    @Hugo esta linea en la configuración:

    ssl_protocols SSLv3 TLSv1;

    Yo le quitaría el SSLv3 debido a que ese protocolo ya no es seguro, incluso en Debian Jessie, se ha configurado muchos servicios para evitar usar ese protocolo por dicha razón.

    Información del tema acá:

    https://www.linode.com/docs/security/security-patches/disabling-sslv3-for-poodle
    http://disablessl3.com/

    1.    Hugo dijo

      La idea realmente no era ofrecer los servicios principales por HTTPS, sino explicar como usar el puerto 443 para SSH sin perder la posibilidad de utilizarlo para HTTPS de ser necesario, pero gracias por el aviso.

      De todas formas he actualizado el artículo para modificar un poco la configuración de nginx y de paso incluir algunos comentarios para aclarar un poco más las cosas con esto de los mecanismos de cifrado, y arreglar algunos errores menores.

  3.   Daniel P Z dijo

    Muchas gracias por este estupendo tutorial, ahora lo pondré en practica! :D, Sigan así DesdeLinux, siempre me sorprenden, Saludos desde Perú.

  4.   Ñandekuera dijo

    Muchas gracias por compartir.

  5.   fernando dijo

    muy buena guia y me viene de perlas ahora que me inicio en esto de los blogs pero mas aun ahora que estoy por montar mi primer vps y aun con muchos problemas pero pues este articulo me ha sacado de muchas dudas, gracias y saludos