Passos per assegurar el nostre VPS

Aquest tutorial mostra com preparar i assegurar un Servidor Virtual (Virtual Private Server, o VPS) amb Debian GNU / Linux. Abans de començar, s'assumeixen certes coses:

  1. Es posseeix un nivell intermedi de familiaritat amb GNU / Linux.
  2. Es posseeix un VPS per a ús personal a el qual tenim accés via SSH.
  3. El VPS té la ipv4 externa dedicada 250.250.250.155 i el nostre proveïdor és propietari de l'bloc 250.250.0.0/16. (1)
  4. En el nostre VPS només tindrem habilitats per a l'accés des de l'exterior dels serveis http, https i ssh.
  5. No s'habilitarà DNS extern ja que usualment es fa en el panell del nostre proveïdor. (2)
  6. Es treballarà com a superusuari.

Instal·lador

Com a primer pas, actualitzem el servidor i instal·lem alguns paquets que necessitarem:

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

Ara crearem un usuari de treball. Treballar com a root en un servidor és insegur, de manera que primerament crearem un usuari especial:

adduser operador usermod -aG suo operador

El primer ordre crea l'usuari operador, el segon el agrega a el grup suo, La qual cosa permetrà executar aplicacions com a superusuari.

Ajustar els permisos per superusuaris

Com per treballar regularment utilitzarem l'usuari operador anteriorment creat, necessitem ajustar les opcions d'execució d'ordres com a superusuari, per a això executem la següent comanda:

visut

Aquesta comanda bàsicament permet modificar el fitxer / Etc / sudoers; en el qual hauríem de contenir aquestes línies:

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

A la primera línia s'afegeix als valors predeterminats l'opció timestamp_timeout que permet establir el temps de termini (en minuts) de la contrasenya quan s'executa la comanda sudo. El valor per omissió és 5, però de vegades això és insegur, per dos motius:

  1. Si al moment menys pensat abandonem el nostre equip amb la sessió oberta abans que la contrasenya expiri, algú podria executar una ordre com a superusuari sense cap restricció.
  2. Si per desconeixement executem una aplicació o script que conté codi maliciós abans que la contrasenya expiri, l'aplicació podria tenir accés al nostre sistema com a root, sense el nostre consentiment explícit.

De manera que per evitar riscos, hem establert el valor en zero, és a dir, cada vegada que s'executi la comanda sudo caldrà introduir la contrasenya. Si s'estableix un valor negatiu com -1 l'efecte és que la contrasenya no expiri mai, la qual cosa produiria el resultat oposat a què volem.

En la segona línia s'aclareix que el grup sudo pot executar qualsevol ordre en qualsevol equip, que és l'habitual, encara que pot ajustar-se. (3) N'hi ha que per comoditat posen la línia de la següent manera per evitar haver de teclejar la contrasenya:

% Suo ALL = (ALL: ALL) NOPASSWD: ALL

No obstant això, com vam explicar abans això és arriscat, i per això no és recomanable.

deshabilitar reinici

Per una qüestió de seguretat, també deshabilitarem el reinici utilitzant la combinació de tecles Ctrl + Alt + Supr, Per a això hem d'afegir aquesta línia a l'arxiu / Etc / inittab:

es: 12345: ctrlaltdel: / bin / echo "Ctrl + Alt + De l's'ha deshabilitat."

Substitueix OpenSSH amb DropBear

La majoria dels VPS ve amb OpenSSH instal·lat, la qual cosa sense dubte és molt útil, però a menys que necessitem explotar tota la funcionalitat d'OpenSSH, hi ha alternatives més lleugeres per a un VPS, com Dropbear, Que sol ser suficient per a l'ús habitual. No obstant això, un inconvenient d'aquesta aplicació és que no inclou un servidor SFTP integrat, i és per això que a principi vam instal·lar el paquet gesftpserver.

Per configurar Dropbear, modificarem l'arxiu / Etc / default / dropbear perquè contingui aquestes dues línies:

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

La primera línia simplement habilita el servei, i la segona fa diverses coses:

  1. Evita l'accés com a root.
  2. Posa a escoltar el servei al port 22 de la interfície local (més endavant explicarem per què).
  3. Estableix el temps d'espera (20 minuts).

SSLH

El port 22 (SSH) és ben conegut i generalment és un dels primers que els hackers intenten vulnerar, de manera que en el seu lloc utilitzarem el port 443 (SSL). Passa que aquest port s'utilitza per a la navegació segura per HTTPS.

Per això utilitzarem el paquet sslh que no és més que un multiplexador que analitza els paquets que arriben a port 443, i els enruta internament a un servei o un altre en dependència de si el tipus de trànsit és SSH o SSL.

SSLH no pot escoltar en una interfície on ja es reprodueixi un altre servei, i és per això que anteriorment vam posar a escoltar Dropbear a la interfície local.

Ara el que ens cal fer és indicar a sslh la interfície i el port pel qual ha d'escoltar i cap a on redirigir els paquets en dependència de l'tipus de servei, i per això modificarem el fitxer de configuració / 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

Finalment, reiniciem els serveis:

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

Després la comanda anterior probablement s'interrompi la nostra sessió segura, en aquest cas n'hi ha prou amb tornar a iniciar sessió, però aquesta vegada amb l'usuari de treball i usant el port 443. Si la sessió no s'interromp, de qualsevol manera convé tancar-la i iniciar novament amb els valors apropiats.

Si tot funciona correctament, podem seguir treballant com a root i si volem, desinstal·lar OpenSSH:

suo seu - aptitude -r purga openssh-server

tallafocs

El pròxim que realitzarem és separar els registres de l'tallafocs cap al fitxer independent /var/log/firewall.log per facilitar la seva posterior anàlisi, que és el motiu pel qual instal·lem el paquet ulogd a l'inici. Per això editarem l'arxiu /etc/logd.conf per ajustar la secció rellevant:

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

A continuació, modificarem l'arxiu de rotació de registres / Etc / logrotate / ulogd per mantenir una rotació diària (amb data) i guardar les salves comprimides en el directori / 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}

Llavors crearem les regles de netfilter executant el següent:

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 ho -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 ho -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 ho -p udp -j UDP_IN $ IPT -A UDP_IN!  -i ho!  -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 ho -p tcp -j TCP_IN $ IPT -A TCP_IN!  -i ho!  -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! 

Amb la configuració anterior, el nostre VPS hauria de quedar raonablement assegurat, però si volem podem assegurar-ho una mica més, per la qual cosa podem fer servir algunes regles més avançades.

No tots els VPS permeten la instal·lació de mòduls extra per netfilter, però un de molt útil és psd, Que permet evitar els escanejos de ports. Lamentablement aquest mòdul no ve integrat en netfilter per defecte, de manera que cal instal·lar alguns paquets i després construir el mòdul:

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

Un cop fet això, podem afegir una regla com aquesta:

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

La regla anterior bàsicament vol dir que crearem un comptador que s'incrementarà en 3 cada vegada que s'intenti accedir a un port inferior a l'1024 i en 1 cada vegada que s'intenti accedir a un port superior a l'1023, i quan aquest comptador arribi a 15 en un lapse inferior a 20 segons, es registraran els paquets mitjançant ulog com un intent de portscan. Igual podrien descartar els paquets d'una vegada, però en aquest cas pretenem utilitzar falla2ban, Que configurarem més endavant.

Un cop creades les regles, hem de prendre certes precaucions per fer-les persistents, ja que en cas contrari les perdrem a l'reiniciar el servidor. Hi ha diverses maneres d'aconseguir això; en aquest tutorial utilitzarem el paquet iptables-persistent que instal·lem a del principi, que emmagatzema les regles a /etc/iptables/rules.v4 y /etc/iptables/rules.v6 per ipv6.

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

De fet, encara que l'ús d'ipv6 a Cuba encara no està estès, bé podríem crear unes regles bàsiques:

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

Aquestes regles també poden fer-se persistents:

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

Finalment per a més seguretat, netegem el registre de l'tallafocs i reiniciem els serveis:

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

Nginx

Utilitzarem Nginx com a servidor web, perquè els VPS solen tenir una quantitat de memòria RAM reduïda en comparació amb un servidor real, de manera que generalment convé tenir una mica més lleuger que Apache.

Abans de configurar Nginx, crearem un certificat (sense contrasenya) per al seu ús per 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

Un cop fet això, crearem un arxiu de contrasenyes per a l'usuari "elusuario":

htpasswd -c .htpasswd l'usuari

A continuació, modificarem l'arxiu / Etc / nginx / sites-available / default per ajustar les preferències de el lloc per defecte. Podria quedar aproximadament així:

server {SERVER_NAME localhost; index index.html index.htm default.html default.htm; root / var / www; location / {# establir l'ordre de verificació i la pàgina a carregar, de no trobar l'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 només sobre TLS (mes segur que SSL) ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Donar preferència als xifrats de força alta [HIGH], # moure els xifrats de força mitjana [MEDIUM] a la fi de la llista, # desactivar els xifrats de força baixa [LOW] (40 i 56 bits) # desactivar els xifrats amb algoritmes d'exportacion [EXP] # desactivar xifrats nuls [eNULL], sense autenticació [aNULL], SSL (versions 2 i 3) i DSS (només permet claus de fins a 1024 bits) ssl_ciphers HIGH: + MEDIUM:! LOW:! EXP: ! aNULL:! eNULL:! SSLv3:! SSLv2:! DSS; # Preferir els mètodes de xifrat de servidor (per defecte es fan servir els de el client) ssl_prefer_server_ciphers on; location / {# habilitar autentificacion auth_basic "Entra"; auth_basic_user_file /etc/nginx/.htpasswd; # Establir l'ordre de verificacion i el codi de pàgina a carregar, de no trobar l'URI try_files $ uri $ uri / = 404; # Permetre la creació d'un índex per als usuaris autentificats autoindex on; autoindex_exact_size off; autoindex_localtime on; }}

Vam comprovar que la configuració estigui correcta:

nginx -t

Finalment, reiniciem el servei:

servei nginx reiniciar

fail2ban

Abans de començar a configurar fail2ban, per a major seguretat aturem el servei i netegem el registre:

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

A continuació, vam crear el fitxer de configuració /etc/fail2ban/jail.local amb el següent contingut personalitzat:

# 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 = apatxe-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 [tallafocs] enabled = true action = iptables-multiport [name = Firewall] filter = tallafocs logpath = /var/log/firewall.log maxretry = 0

Un cop fet això, vam crear en el directori /etc/fail2ban/filters.d/ els següents arxius:

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

Finalment, vam iniciar el servei i carreguem la configuració:

fail2ban-service -b fail2ban-client reload

comprovació

Com a últim pas, podem visualitzar els registres amb cua -f o multitail -follow-all. De fet, aquesta última aplicació ofereix l'avantatge que permet visualitzar diversos arxius a el mateix temps i proporciona un ressaltat de sintaxi bàsic.

En cas que no es configuri en el VPS un compte de correu, conviente desactivar un missatge d'advertència que surt a l'iniciar multitail, per a això executarem la següent comanda:

echo "check_mail: 0"> ~ / .multitailrc

De fet bé podríem fer un àlies (4) per visualitzar els registres ràpidament amb una ordre breu, per exemple, "flog":

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

1) Aquests són valors ficticis.
2) Habilitar altres serveis és fàcil un cop entès el funcionament.
3) Per a més detalls, executar man sudoers.
4) Opcionalment podria afegir-se a l'arxiu ~ / .bash_aliases


Deixa el teu comentari

La seva adreça de correu electrònic no es publicarà. Els camps obligatoris estan marcats amb *

*

*

  1. Responsable de les dades: Miguel Ángel Gatón
  2. Finalitat de les dades: Controlar l'SPAM, gestió de comentaris.
  3. Legitimació: El teu consentiment
  4. Comunicació de les dades: No es comunicaran les dades a tercers excepte per obligació legal.
  5. Emmagatzematge de les dades: Base de dades allotjada en Occentus Networks (UE)
  6. Drets: En qualsevol moment pots limitar, recuperar i esborrar la teva informació.

  1.   MSX va dir

    Hi ha algunes coses interessants, +1

  2.   Yukiteru va dir

    @Hugo aquesta línia en la configuració:

    ssl_protocols SSLv3 TLSv1;

    Jo li trauria el SSLv3 causa que aquest protocol ja no és segur, fins i tot en Debian Jessie, s'ha configurat molts serveis per evitar usar aquest protocol per aquesta raó.

    Informació de el tema aquí:

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

    1.    Hugo va dir

      La idea realment no era oferir els serveis principals per HTTPS, sinó explicar com utilitzar el port 443 per SSH sense perdre la possibilitat de utilitzar-lo per HTTPS de ser necessari, però gràcies per l'avís.

      De tota manera he actualitzat l'article per modificar una mica la configuració de nginx i de pas incloure alguns comentaris per aclarir una mica més les coses amb això dels mecanismes de xifrat, i arreglar alguns errors menors.

  3.   Daniel PZ va dir

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

  4.   Ñandekuera va dir

    Moltes gràcies per compartir.

  5.   fernando va dir

    molt bona guia i em va de primera ara que em inici en això dels blocs però més encara ara que estic per muntar el meu primer vps i tot amb molts problemes però ja que aquest article m'ha tret de molts dubtes, gràcies i salutacions